diff --git a/module06/ex01/header.h b/module06/ex01/header.h index a3ad99b..63cc113 100644 --- a/module06/ex01/header.h +++ b/module06/ex01/header.h @@ -29,15 +29,15 @@ 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); -void i2c_read(void); +uint8_t i2c_read(void); void i2c_stop(void); // uart.c void uart_init(); void uart_tx(char c); -void uart_printstr(const char* str); -void uart_printstr_endl(const char* str); -void uart_printstr_itoa_base(uint64_t value, uint8_t base); -void uart_printstr_itoa_base_endl(uint64_t value, uint8_t base); +uint16_t uart_printstr(const char* str); +uint16_t uart_printstr_endl(const char* str); +uint16_t uart_printstr_itoa_base(uint64_t value, uint8_t base); +uint16_t uart_printstr_itoa_base_endl(uint64_t value, uint8_t base); // math.c void int_to_hex_string(uint64_t value, char *out, uint8_t num_digits); void int_to_string_base(uint64_t value, char *buffer, uint8_t base); diff --git a/module06/ex01/i2c.c b/module06/ex01/i2c.c index 3253abe..c208e2e 100644 --- a/module06/ex01/i2c.c +++ b/module06/ex01/i2c.c @@ -71,7 +71,7 @@ void i2c_send_addr_r(uint8_t slave_address) { // } } -void i2c_write(unsigned char data) { +void i2c_write(uint8_t data) { if (i2c_status == STOP) { return; } @@ -85,18 +85,20 @@ void i2c_write(unsigned char data) { // } } -void i2c_read(void) { +uint8_t i2c_read(void) { if (i2c_status == STOP) { 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(); // } + + return TWDR; // 22.9.4 : (Data Register) load data into TWDR register } void i2c_stop(void) { diff --git a/module06/ex01/main.c b/module06/ex01/main.c index 91fc3dd..f5693ec 100644 --- a/module06/ex01/main.c +++ b/module06/ex01/main.c @@ -278,6 +278,52 @@ send stop : 110000 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 + +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 + +send repeat start : 101000 + after repeat start : 10000 + +send SLA+R : 10000 + after SLA+R : 1000000 + +read 1 data : 1000000 + after read : 1011000 +````````````````````````read 2 data : 1011000 + after read : 1011000 +read 3 data : 1011000 + after read : 1011000 +```````````````````````````````````````` : read 4 data : 1011000 + after read : 1011000 +`read 5 data : 1011000 + after read : 1011000 +read 6 data : 1011000 + after read : 1011000 +read 7 data : 1011000 + after read : 1011000 +```````````````````````````` : read 8 data : 1011000 + after read : 1011000 +` : read 9 data : 1011000 + after read : 1011000 +` : +send stop : 1011000 + after stop : 11111000 +*/ + // status codes : // -- Master -- // TW_BUS_ERROR 0x00 = 0b0 = 0 -> illegal start or stop condition @@ -303,12 +349,41 @@ send stop : 110000 void print_hex_value(char c) {} +void print_status_meaning(uint16_t status) { + switch (status) { + case 0x00: uart_printstr("TW_BUS_ERROR -> Illegal start or stop condition"); break; + case 0x08: uart_printstr("TW_START -> Start condition transmitted"); break; + case 0x10: uart_printstr("TW_REP_START -> Repeated start condition transmitted"); break; + case 0x18: uart_printstr("TW_MT_SLA_ACK -> SLA+W transmitted, ACK received"); break; + case 0x20: uart_printstr("TW_MT_SLA_NACK -> SLA+W transmitted, NACK received"); break; + case 0x28: uart_printstr("TW_MT_DATA_ACK -> Data transmitted, ACK received"); break; + case 0x30: uart_printstr("TW_MT_DATA_NACK -> Data transmitted, NACK received"); break; + case 0x38: uart_printstr("TW_MT_ARB_LOST/TW_MR_ARB_LOST -> Arbitration lost in SLA+W/R or Nack"); break; + case 0x40: uart_printstr("TW_MR_SLA_ACK -> SLA+R transmitted, ACK received"); break; + case 0x48: uart_printstr("TW_MR_SLA_NACK -> SLA+R transmitted, NACK received"); break; + case 0x50: uart_printstr("TW_MR_DATA_ACK -> Data received, ACK returned"); break; + case 0x58: uart_printstr("TW_MR_DATA_NACK -> Data received, NACK returned"); break; + case 0x98: uart_printstr("TW_SR_GCALL_DATA_NACK -> General call data received, NACK returned"); break; + case 0xA8: uart_printstr("TW_ST_SLA_ACK -> SLA+R received, ACK returned"); break; + case 0xF8: uart_printstr("TW_NO_INFO -> No state information available"); break; + default: uart_printstr("Unknown status code"); + } +} + void print_status(char *str) { uint8_t status; status = TWSR & 0b11111000; // Table 22-2. Status codes for Master Transmitter Mode - uart_printstr(str); - uart_printstr(" : "); - uart_printstr_itoa_base_endl(status, 2); + uint16_t size = 53; + size -= uart_printstr(str); + size -= uart_printstr(" : "); + size -= uart_printstr_itoa_base(status, 2); + + // print status meaning + while (size--) { + uart_tx(' '); + } + print_status_meaning(status); + uart_printstr_endl(""); } // description @@ -376,33 +451,71 @@ int main() { 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\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"); + + uint8_t data; + print_status("\r\nread 1 data"); + data = i2c_read(); + print_status(" after read"); + uart_printstr_itoa_base_endl(data, 10); + print_status("read 2 data"); + data = i2c_read(); + print_status(" after read"); + uart_printstr_itoa_base_endl(data, 10); + print_status("read 3 data"); + data = i2c_read(); + print_status(" after read"); + uart_printstr_itoa_base_endl(data, 10); + print_status("read 4 data"); + data = i2c_read(); + print_status(" after read"); + uart_printstr_itoa_base_endl(data, 10); + print_status("read 5 data"); + data = i2c_read(); + print_status(" after read"); + uart_printstr_itoa_base_endl(data, 10); + print_status("read 6 data"); + data = i2c_read(); + print_status(" after read"); + uart_printstr_itoa_base_endl(data, 10); + print_status("read 7 data"); + data = i2c_read(); + print_status(" after read"); + uart_printstr_itoa_base_endl(data, 10); + print_status("read 8 data"); + data = i2c_read(); + print_status(" after read"); + uart_printstr_itoa_base_endl(data, 10); + print_status("read 9 data"); + data = i2c_read(); + print_status(" after read"); + uart_printstr_itoa_base_endl(data, 10); print_status("\r\nsend stop"); i2c_stop(); diff --git a/module06/ex01/uart.c b/module06/ex01/uart.c index 541b05e..c25afe0 100644 --- a/module06/ex01/uart.c +++ b/module06/ex01/uart.c @@ -27,27 +27,36 @@ void uart_tx(char c) { UDR0 = (unsigned char) c; // 20.11.1 : Put data into buffer, UDRn – USART I/O Data Register (read and write) } -void uart_printstr(const char* str) { +uint16_t uart_printstr(const char* str) { + uint16_t size = 0; while (*str) { uart_tx(*str); str++; + size++; } + return size; } -void uart_printstr_endl(const char* str) { - uart_printstr(str); - uart_printstr("\r\n"); +uint16_t uart_printstr_endl(const char* str) { + uint16_t size = 0; + size += uart_printstr(str); + size += uart_printstr("\r\n"); + return size; } -void uart_printstr_itoa_base(uint64_t value, uint8_t base) { +uint16_t uart_printstr_itoa_base(uint64_t value, uint8_t base) { char buffer[100] = {0}; + uint16_t size = 0; int_to_string_base((uint16_t)value, buffer, base); - uart_printstr(buffer); + size += uart_printstr(buffer); + return size; } -void uart_printstr_itoa_base_endl(uint64_t value, uint8_t base) { - uart_printstr_itoa_base(value, base); - uart_printstr("\r\n"); +uint16_t uart_printstr_itoa_base_endl(uint64_t value, uint8_t base) { + uint16_t size = 0; + size += uart_printstr_itoa_base(value, base); + size += uart_printstr("\r\n"); + return size; } // ISR(USART_RX_vect) { // Table 12-6 : we select the code for USART Receive