diff --git a/module06/ex01/header.h b/module06/ex01/header.h index e9ebeb7..a3ad99b 100644 --- a/module06/ex01/header.h +++ b/module06/ex01/header.h @@ -25,6 +25,7 @@ void print_hex_value(char c); // i2c.c void i2c_init(void); void i2c_start(void); +void i2c_start_repeat(void); void i2c_send_addr_w(uint8_t slave_address); void i2c_send_addr_r(uint8_t slave_address); void i2c_write(unsigned char data); diff --git a/module06/ex01/i2c.c b/module06/ex01/i2c.c index bb7c9e4..3253abe 100644 --- a/module06/ex01/i2c.c +++ b/module06/ex01/i2c.c @@ -14,15 +14,19 @@ void i2c_init(void) { TWBR = ((F_CPU / TWI_FREQ) - 16) / (2 * TWI_PRESCALE_VALUE); // 22.9.1 : (Bit Rate Register) set SCL frequency (formula from datasheet, 22.5.2) } +void i2c_start_repeat(void) { // 22.7.1 : "Repeated START enables the Master to switch between Slaves, Master Transmitter mode and Master Receiver mode without losing control of the bus" + i2c_start(); +} + void i2c_start(void) { i2c_status = START; TWCR = SEND_START_CONDITION; // 22.9.2 : (Control Register) send Start condition (22.7.1) ! writting 1 to TWINT clears it (set it to 0) - while (!(TEST(TWCR, TWINT))); // p225 example code : Wait for TWINT Flag set. This indicates that the START condition has been transmitted + while (!(TEST(TWCR, TWINT))); // 22.7.1 : Wait for TWINT Flag set. This indicates that the SLA+R/W has been transmitted, and ACK/NACK has been received - uint8_t status = TWSR & 0b11111000; // Table 22-2. Status codes for Master Transmitter Mode - if (status != TW_START && status != TW_REP_START) { - return i2c_stop(); - } + // uint8_t status = TWSR & 0b11111000; // Table 22-2. Status codes for Master Transmitter Mode + // if (status != TW_START && status != TW_REP_START) { + // return i2c_stop(); + // } } void i2c_send_addr_w(uint8_t slave_address) { @@ -34,16 +38,16 @@ void i2c_send_addr_w(uint8_t slave_address) { TWCR = SEND_CONTINUE_TRANSMISSION; // 22.7.1 : Master Transmitter Mode while (!(TEST(TWCR, TWINT))); // 22.7.1 : Wait for TWINT Flag set. This indicates that the SLA+R/W has been transmitted, and ACK/NACK has been received - uint8_t status = TWSR & 0b11111000; // Table 22-2 : check status for Transmitter mode, mask prescaler bits - if (status == TW_MT_SLA_ACK) { // status 0x18 : slave address transmitted, slave acknoledged (continue transmission) - return; - } else if (status == TW_MT_SLA_NACK) { // status 0x20 : slave address transmitted, slave did not acknoledge (retry or send STOP) - return i2c_stop(); - } else if (status == TW_MT_ARB_LOST) { // status 0x38 : Arbitration Lost, Another I2C master took control of the bus (wait for bus to be free and retry) - return i2c_stop(); - } else { - return i2c_stop(); - } + // uint8_t status = TWSR & 0b11111000; // Table 22-2 : check status for Transmitter mode, mask prescaler bits + // if (status == TW_MT_SLA_ACK) { // status 0x18 : slave address transmitted, slave acknoledged (continue transmission) + // return; + // } else if (status == TW_MT_SLA_NACK) { // status 0x20 : slave address transmitted, slave did not acknoledge (retry or send STOP) + // return i2c_stop(); + // } else if (status == TW_MT_ARB_LOST) { // status 0x38 : Arbitration Lost, Another I2C master took control of the bus (wait for bus to be free and retry) + // return i2c_stop(); + // } else { + // return; + // } } void i2c_send_addr_r(uint8_t slave_address) { @@ -55,16 +59,16 @@ void i2c_send_addr_r(uint8_t slave_address) { TWCR = SEND_CONTINUE_TRANSMISSION; // 22.7.1 : Master Transmitter Mode while (!(TEST(TWCR, TWINT))); // 22.7.1 : Wait for TWINT Flag set. This indicates that the SLA+R/W has been transmitted, and ACK/NACK has been received - uint8_t status = TWSR & 0b11111000; // Table 22-3 : check status for Receiver mode, mask prescaler bits - if (status == TW_MR_SLA_ACK) { // status 0x40 : slave address transmitted, slave acknoledged (continue transmission) - return; - } else if (status == TW_MR_SLA_NACK) { // status 0x48 : slave address transmitted, slave did not acknoledge (retry or send STOP) - return i2c_stop(); - } else if (status == TW_MR_ARB_LOST) { // status 0x38 : Arbitration Lost, Another I2C master took control of the bus (wait for bus to be free and retry) - return i2c_stop(); - } else { - return i2c_stop(); - } + // uint8_t status = TWSR & 0b11111000; // Table 22-3 : check status for Receiver mode, mask prescaler bits + // if (status == TW_MR_SLA_ACK) { // status 0x40 : slave address transmitted, slave acknoledged (continue transmission) + // return; + // } else if (status == TW_MR_SLA_NACK) { // status 0x48 : slave address transmitted, slave did not acknoledge (retry or send STOP) + // return i2c_stop(); + // } else if (status == TW_MR_ARB_LOST) { // status 0x38 : Arbitration Lost, Another I2C master took control of the bus (wait for bus to be free and retry) + // return i2c_stop(); + // } else { + // return; + // } } void i2c_write(unsigned char data) { @@ -72,13 +76,13 @@ void i2c_write(unsigned char data) { return; } TWDR = data; // 22.9.4 : (Data Register) load data into TWDR register - TWCR = SEND_CONTINUE_TRANSMISSION; // p225 example code : Load DATA into TWDR Register. Clear TWINT bit in TWCR to start transmission of data - while (!(TEST(TWCR, TWINT))); // p225 example code : Wait for TWINT Flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received + TWCR = SEND_CONTINUE_TRANSMISSION; // 22.7.1 : Master Transmitter Mode + while (!(TEST(TWCR, TWINT))); // 22.7.1 : Wait for TWINT Flag set. This indicates that the SLA+R/W has been transmitted, and ACK/NACK has been received - uint8_t status = TWSR & 0b11111000; // p225 example code : Check status for Receiver mode. Mask prescaler bits. If status different from MT_DATA_ACK go to ERROR - if (status != TW_MT_DATA_ACK) { - return i2c_stop(); - } + // uint8_t status = TWSR & 0b11111000; // Table 22-3 : check status for Receiver mode, mask prescaler bits + // if (status != TW_MT_DATA_ACK) { + // return i2c_stop(); + // } } void i2c_read(void) { diff --git a/module06/ex01/main.c b/module06/ex01/main.c index 3fe5830..91fc3dd 100644 --- a/module06/ex01/main.c +++ b/module06/ex01/main.c @@ -1,26 +1,305 @@ #include "header.h" -// sqtatus codes : -// -- Master -- -// TW_BUS_ERROR 0x00 = 0b0 = 0 -> illegal start or stop condition -// TW_START 0x08 = 0b1000 = 8 -> start condition transmitted -// TW_REP_START 0x10 = 0b10000 = 16 -> repeated start condition transmitted -// -- Master Transmitter -- -// TW_MT_SLA_ACK 0x18 = 0b11000 = 24 -> SLA+W transmitted, ACK received -// TW_MT_SLA_NACK 0x20 = 0b100000 = 32 -> SLA+W transmitted, NACK received -// TW_MT_DATA_ACK 0x28 = 0b101000 = 40 -> data transmitted, ACK received -// TW_MT_DATA_NACK 0x30 = 0b110000 = 48 -> data transmitted, NACK received -// TW_MT_ARB_LOST 0x38 = 0b111000 = 56 -> arbitration lost in SLA+W or data -// -- Master Receiver -- -// TW_MR_ARB_LOST 0x38 = 0b111000 = 56 -> arbitration lost in SLA+R or NACK -// TW_MR_SLA_ACK 0x40 = 0b1000000 = 64 -> SLA+R transmitted, ACK received -// TW_MR_SLA_NACK 0x48 = 0b1001000 = 72 -> SLA+R transmitted, NACK received -// TW_MR_DATA_ACK 0x50 = 0b1010000 = 80 -> data received, ACK returned -// TW_MR_DATA_NACK 0x58 = 0b1011000 = 88 -> data received, NACK returned -// TW_ST_SLA_ACK 0xA8 = 0b10101000 = 168 -> SLA+R received, ACK returned -// TW_NO_INFO 0xF8 = 0b11111000 = 248 -> no state information available +/* +before init : 11111000 +after init : 11111000 +after start : 1000 +after SLA+W : 11000 +1 : 11000 +2 : 11000 +3 : 11000 +4 : 11000 +5 : 11000 +6 : 11000 +7 : 11000 +8 : 11000 +9 : 11000 +10 : 11000 +20 : 11000 +30 : 11000 +40 : 11000 +50 : 11000 +60 : 11000 +70 : 11000 +80 : 11000 +90 : 11000 +100 : 11000 +110 : 11000 +120 : 11000 +130 : 11000 +140 : 11000 +150 : 11000 +160 : 11000 +170 : 11000 +180 : 11000 +190 : 11000 +200 : 11000 +1200 : 11000 +after stop : 11111000 +*/ -#define SLAVE_ADDRESS 0x38 // doc AHT20, 7.3 : address of thermistor +/* +before init : 11111000 + after init : 11111000 +before start : 11111000 + after start : 1000 +waiting 200ms... : 1000 + done waiting : 1000 +send SLA+W : 1000 + after SLA+W : 11000 +waiting 10ms... : 11000 + done waiting : 11000 +send 0xAC (trigger measurement) : 11000 + after 0xAC : 101000 +send parameter 1st byte 0x33 : 101000 + after 0x33 : 101000 +send parameter 2nd byte 0x00 : 101000 + after 0x00 : 101000 +status ? 0 : 101000 +status ? 10 : 101000 +status ? 20 : 101000 +status ? 30 : 101000 +status ? 40 : 101000 +status ? 50 : 101000 +status ? 60 : 101000 +status ? 70 : 101000 +status ? 80 : 101000 +status ? 90 : 101000 +status ? 100 : 101000 +status ? 110 : 101000 +status ? 120 : 101000 +status ? 130 : 101000 +after stop : 11111000 +*/ + +/* +before init : 11111000 no state information available + after init : 11111000 +before start : 11111000 + after start : 1000 start condition transmitted +waiting 200ms... : 1000 + done waiting : 1000 +send SLA+W : 1000 + after SLA+W : 11000 SLA+W transmitted, ACK received +waiting 10ms... : 11000 + done waiting : 11000 +send 0xAC (trigger measurement) : 11000 + after 0xAC : 101000 data transmitted, ACK received +send parameter 1st byte 0x33 : 101000 + after 0x33 : 101000 +send parameter 2nd byte 0x00 : 101000 + after 0x00 : 101000 +send repeat start : 101000 + after repeat start : 10000 repeated start condition transmitted +send SLA+R : 10000 + after SLA+R : 1000000 SLA+R transmitted, ACK received +status ? 0 : 1000000 +status ? 10 : 1000000 +status ? 20 : 1000000 +status ? 30 : 1000000 +status ? 40 : 1000000 +status ? 50 : 1000000 +status ? 60 : 1000000 +status ? 70 : 1000000 +status ? 80 : 1000000 +status ? 90 : 1000000 +status ? 100 : 1000000 +status ? 110 : 1000000 +status ? 120 : 1000000 +status ? 130 : 1000000 +after stop : 11111000 +*/ + +/* +before init : 11111000 no state information available + after init : 11111000 +before start : 11111000 + after start : 1000 start condition transmitted +send 0x71 to get a byte of status word : 1000 + after 0x71 : 1000000 SLA+R transmitted, ACK received +waiting 200ms... : 1000000 + done waiting : 1000000 +send 0x71 to get a byte of status word : 1000000 + after 0x71 : 1011000 data received, NACK returned +send SLA+W : 1011000 + after SLA+W : 1011000 +waiting 10ms... : 1011000 + done waiting : 1011000 +send 0xAC (trigger measurement) : 1011000 + after 0xAC : 11111000 no state information available +send parameter 1st byte 0x33 : 11111000 + after 0x33 : 11111000 +send parameter 2nd byte 0x00 : 11111000 + after 0x00 : 11111000 +send repeat start : 11111000 + after repeat start : 1000 start condition transmitted +send SLA+R : 1000 + after SLA+R : 1000000 SLA+R transmitted, ACK received +status ? 0 : 1000000 +status ? 10 : 1000000 +status ? 20 : 1000000 +status ? 30 : 1000000 +status ? 40 : 1000000 +status ? 50 : 1000000 +status ? 60 : 1000000 +status ? 70 : 1000000 +status ? 80 : 1000000 +status ? 90 : 1000000 +status ? 100 : 1000000 +status ? 110 : 1000000 +status ? 120 : 1000000 +status ? 130 : 1000000 +after stop : 11111000 +*/ + +/* +init i2c : 11111000 no state information available + after init : 11111000 + +start transmission : 11111000 + after start : 1000 start condition transmitted + +send SLA+W : 1000 + after SLA+W : 11000 SLA+W transmitted, ACK received + +waiting 10ms... : 11000 + done waiting : 11000 + +send 0xAC (trigger measurement) : 11000 + after 0xAC : 101000 data transmitted, ACK received +send parameter 1st byte 0x33 : 101000 + after 0x33 : 101000 +send parameter 2nd byte 0x00 : 101000 + after 0x00 : 101000 + +send repeat start : 101000 + after repeat start : 10000 repeated start condition transmitted + +send SLA+R : 10000 + after SLA+R : 1000000 SLA+R transmitted, ACK received + +status ? 0 : 1000000 +status ? 10 : 1000000 +status ? 20 : 1000000 +status ? 30 : 1000000 +status ? 40 : 1000000 +status ? 50 : 1000000 +status ? 60 : 1000000 +status ? 70 : 1000000 +status ? 80 : 1000000 +status ? 90 : 1000000 +status ? 100 : 1000000 +status ? 110 : 1000000 +status ? 120 : 1000000 +status ? 130 : 1000000 + +send stop : 1000000 + after stop : 11111000 no state information available +*/ + +/* +init i2c : 11111000 no state information available + after init : 11111000 + +start transmission : 11111000 + after start : 1000 start condition transmitted + +send SLA+W : 1000 + after SLA+W : 11000 SLA+W transmitted, ACK received + +send 0xAC (trigger measurement) : 11000 + after 0xAC : 101000 data transmitted, ACK received +send parameter 1st byte 0x33 : 101000 + after 0x33 : 101000 +send parameter 2nd byte 0x00 : 101000 + after 0x00 : 101000 + +send repeat start : 101000 + after repeat start : 10000 repeated start condition transmitted + +send SLA+R : 10000 + after SLA+R : 1000000 SLA+R transmitted, ACK received + +status ? 0 : 1000000 +status ? 10 : 1000000 +status ? 20 : 1000000 +status ? 30 : 1000000 +status ? 40 : 1000000 +status ? 50 : 1000000 +status ? 60 : 1000000 +status ? 70 : 1000000 +status ? 80 : 1000000 +status ? 90 : 1000000 +status ? 100 : 1000000 +status ? 110 : 1000000 +status ? 120 : 1000000 +status ? 130 : 1000000 + +send stop : 1000000 + after stop : 11111000 no state information available +*/ + +/* +init i2c : 11111000 no state information available + after init : 11111000 + +start transmission : 11111000 + after start : 1000 start condition transmitted + +send SLA+W : 1000 + after SLA+W : 11000 SLA+W transmitted, ACK received + +send 0xAC (trigger measurement) : 11000 + after 0xAC : 101000 data transmitted, ACK received +send parameter 1st byte 0x33 : 101000 + after 0x33 : 101000 +send parameter 2nd byte 0x00 : 101000 + after 0x00 : 101000 + +send SLA+R : 101000 + after SLA+R : 110000 data transmitted, NACK received + +status ? 0 : 110000 +status ? 10 : 110000 +status ? 20 : 110000 +status ? 30 : 110000 +status ? 40 : 110000 +status ? 50 : 110000 +status ? 60 : 110000 +status ? 70 : 110000 +status ? 80 : 110000 +status ? 90 : 110000 +status ? 100 : 110000 +status ? 110 : 110000 +status ? 120 : 110000 +status ? 130 : 110000 + +send stop : 110000 + after stop : 11111000 +*/ + +// status codes : +// -- Master -- +// TW_BUS_ERROR 0x00 = 0b0 = 0 -> illegal start or stop condition +// TW_START 0x08 = 0b1000 = 8 -> start condition transmitted +// TW_REP_START 0x10 = 0b10000 = 16 -> repeated start condition transmitted +// -- Master Transmitter -- +// TW_MT_SLA_ACK 0x18 = 0b11000 = 24 -> SLA+W transmitted, ACK received +// TW_MT_SLA_NACK 0x20 = 0b100000 = 32 -> SLA+W transmitted, NACK received +// TW_MT_DATA_ACK 0x28 = 0b101000 = 40 -> data transmitted, ACK received +// TW_MT_DATA_NACK 0x30 = 0b110000 = 48 -> data transmitted, NACK received +// TW_MT_ARB_LOST 0x38 = 0b111000 = 56 -> arbitration lost in SLA+W or data +// -- Master Receiver -- +// TW_MR_ARB_LOST 0x38 = 0b111000 = 56 -> arbitration lost in SLA+R or NACK +// TW_MR_SLA_ACK 0x40 = 0b1000000 = 64 -> SLA+R transmitted, ACK received +// TW_MR_SLA_NACK 0x48 = 0b1001000 = 72 -> SLA+R transmitted, NACK received +// TW_MR_DATA_ACK 0x50 = 0b1010000 = 80 -> data received, ACK returned +// TW_MR_DATA_NACK 0x58 = 0b1011000 = 88 -> data received, NACK returned +// TW_SR_GCALL_DATA_NACK 0x98 = 0b10011000 = 152 -> general call data received, NACK returned +// TW_ST_SLA_ACK 0xA8 = 0b10101000 = 168 -> SLA+R received, ACK returned +// TW_NO_INFO 0xF8 = 0b11111000 = 248 -> no state information available + +#define SLAVE_ADDRESS 0x38 // doc AHT20, 7.3 : address of thermistor : 0b111000, 56 void print_hex_value(char c) {} @@ -36,33 +315,98 @@ void print_status(char *str) { int main() { uart_init(); - print_status("before init"); + // 0x18 : 11000 : 24 + // 0x33 : 110011 : 51 -> DATA0 + // 0x38 : 111000 : 56 + // 0x70 : 1110000 : 112 -> SLA+W + // 0x71 : 1110001 : 113 -> SLA+R + // + // doc AHT20 7.4 : trigger measurement data and read temperature and humidity + // 0. init i2c + // 1. after power on, wait >= 100ms + // 2. send SLA+W 0x70 + // 3. wait 10ms + // 4. send 0xAC command (172, 0b10101100) (trigger measurement), this command parameter has 2 bytes : + // 5. send DATA0 : 0x33 + // 6. send DATA1 : 0x00 + // 7. delay >= 80ms (wait for status[7] == 0) + // 8. send SLA+R + // 9. read 6 bytes + // 10. read CRC + + print_status("init i2c"); i2c_init(); - print_status("after init"); + print_status(" after init"); + print_status("\r\nstart transmission"); i2c_start(); - print_status("after start"); + print_status(" after start"); + // print_status("\r\nwaiting 200ms..."); + // _delay_ms(200); + // print_status(" done waiting"); + + print_status("\r\nsend SLA+W"); i2c_send_addr_w(SLAVE_ADDRESS); - print_status("after SLA+W"); + print_status(" after SLA+W"); - i2c_write('t'); - print_status("after write t"); + // print_status("\r\nwaiting 10ms..."); + // _delay_ms(10); + // print_status(" done waiting"); - i2c_write('e'); - print_status("after write e"); + print_status("\r\nsend 0xAC (trigger measurement)"); + i2c_write(0xAC); + print_status(" after 0xAC"); + print_status("send parameter 1st byte 0x33"); + i2c_write(0x33); + print_status(" after 0x33"); + print_status("send parameter 2nd byte 0x00"); + i2c_write(0x00); + print_status(" after 0x00"); - i2c_write('e'); - print_status("after write e"); + // print_status("\r\nwaiting 10ms..."); + // _delay_ms(10); + // print_status(" done waiting"); - i2c_write('a'); - print_status("after write a"); + print_status("\r\nsend repeat start"); + i2c_start_repeat(); + print_status(" after repeat start"); - i2c_write('t'); - print_status("after write t"); + print_status("\r\nsend SLA+R"); + i2c_send_addr_r(SLAVE_ADDRESS); + print_status(" after SLA+R"); + print_status("\r\nstatus ? 0"); + _delay_ms(10); + print_status("status ? 10"); + _delay_ms(10); + print_status("status ? 20"); + _delay_ms(10); + print_status("status ? 30"); + _delay_ms(10); + print_status("status ? 40"); + _delay_ms(10); + print_status("status ? 50"); + _delay_ms(10); + print_status("status ? 60"); + _delay_ms(10); + print_status("status ? 70"); + _delay_ms(10); + print_status("status ? 80"); + _delay_ms(10); + print_status("status ? 90"); + _delay_ms(10); + print_status("status ? 100"); + _delay_ms(10); + print_status("status ? 110"); + _delay_ms(10); + print_status("status ? 120"); + _delay_ms(10); + print_status("status ? 130"); + + print_status("\r\nsend stop"); i2c_stop(); - print_status("after stop"); + print_status(" after stop"); while(1); }