Hello
This is the first time I'm using attiny microprocessors and I have a little bit of trouble with setting up and communicating using I2C. I've read the datasheet and I think I did everything they said, but I can't get it to work. When I read data register I get the same thing that I put in it (register address). And I don't think I am even sending a device address correctly because even when I send a start condition to a I2C address that doesn't exist in my circuit, I get a OK from my Start function, which should mean that the slave acknowledged the call, but of course, there is no one to acknowledge it on that address.
Correction. When writing to UART the return value of the I2C_Start_W function, I get a <break> in cutecom terminal, not 0.
My code is this:
/* * File: main.c * Author: mario * * Created on May 8, 2022, 11:00 PM */ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <avr/io.h> #define F_CPU_REAL 20000000UL #define F_CPU F_CPU_REAL/6 // 3.3 MHz #define F_SCL 100000 #include <util/delay.h> #define BAUD_Rate 38400 /* * */ /*return 0 if ok*/ int I2C_Start_W(uint8_t addr){ TWI0.MADDR=addr<<1; while(!(TWI0.MSTATUS && TWI_WIF_bm)); if(TWI0.MSTATUS && ~(1<<TWI_RXACK_bp)){ return 0; } else { TWI0.MCTRLB|=0x03<<TWI_MCMD_gp; return 1; } } int I2C_Start_R(uint8_t addr){ TWI0.MADDR=(addr<<1)|0b00000001; while(!(TWI0.MSTATUS && TWI_WIF_bm)); if(TWI0.MSTATUS && ~(1<<TWI_RXACK_bp)) return 0; else { TWI0.MCTRLB|=0x03<<TWI_MCMD_gp; return 1; } } int I2C_Write(uint8_t data){ TWI0.MDATA=data; while(!(TWI0.MSTATUS && TWI_WIF_bm)); if(TWI0.MSTATUS && ~(1<<TWI_RXACK_bp)) return 0; else { TWI0.MCTRLB|=0x03<<TWI_MCMD_gp; return 1; } } /*no more data*/ uint8_t I2C_Read_Nack(){ uint8_t data; while(!(TWI0.MSTATUS && TWI_RIF_bm)); data=TWI0.MDATA; TWI0.MCTRLB|=1<<TWI_ACKACT_bp; TWI0.MCTRLB|=0x3<<TWI_MCMD_gp; return data; } /*want more data*/ uint8_t I2C_Read_Ack(){ uint8_t data; while(!(TWI0.MSTATUS && TWI_RIF_bm)); data=TWI0.MDATA; TWI0.MCTRLB|=0x2<<TWI_MCMD_gp; return data; } void I2C_Stop(){ TWI0.MCTRLB|=0x03<<TWI_MCMD_gp; } void UART_Write(uint8_t data) { if(USART0.STATUS&&(1<<USART_DREIF_bp)) USART0.TXDATAL=data; while(!(USART0.STATUS && (1<<USART_TXCIF_bp))); } int main(int argc, char** argv) { /////////////////////////////////////////////////////setting up UART float tr=500*pow(10,-9); int baudReg= ((64UL * F_CPU)/(16UL * BAUD_Rate)); USART0.BAUD=baudReg; USART0.CTRLB|=(1<<USART_RXEN_bp)|(1<<USART_TXEN_bp); PORTB.DIR|=1<<PIN2_bp; /////////////////////////////////////////////////////setting up I2C PORTB.DIR|=(1<<PIN0_bp)|(1<<PIN1_bp); TWI0.CTRLA|=0x02<<TWI_SDAHOLD_gp; TWI0.MBAUD=F_CPU/(2*F_SCL) - (5+ ((F_CPU*tr)/2)); TWI0.CTRLA|=0x02<<TWI_SDAHOLD_gp; TWI0.MCTRLA|=(1<<TWI_ENABLE_bp)|(1<<TWI_WIEN_bp)|(1<<TWI_RIEN_bp); TWI0.MSTATUS|=0x1<<TWI_BUSSTATE_gp; uint8_t rdata[6]={0}; int status=0; while(1){ status=I2C_Start_W(0b1110111);//send Start condition UART_Write(status); I2C_Write(0xac);//write register address //I2C_Stop(); //not sure if I need this I2C_Start_R(0b1110111);//read that register rdata[0]=I2C_Read_Ack(); UART_Write(rdata[0]);//send over UART and I get 0Xac, exactly what I wrote _delay_ms(1000); } return (EXIT_SUCCESS); }
Any help would be appreciated.