Files
hugo LAMY 3cd6e72b8d add doc
2025-03-17 09:09:52 +01:00

135 lines
3.8 KiB
C

#include "header.h"
// 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 AHT20_ADDRESS 0x38 // doc AHT20, 7.3 : address of thermistor : 0b111000, 56
void print_hex_value(char c) {
char buffer[3] = {0};
int_to_hex_string(c, buffer, 2);
uart_printstr(buffer);
}
void print_data() {
uint8_t data;
for (uint8_t i = 0; i < 7; i++) { // doc AHT20, 7.4 : >= 7 bytes -> CRC (Cyclic Redundancy Check), an error-detecting code
data = i2c_read_nack();
print_hex_value(data);
if (i == 0) {
uart_tx('(');
uart_printstr_itoa_base(data, 2);
uart_tx(')');
}
if (i < 9) {
uart_tx(' ');
}
}
uart_printstr_endl("");
}
Boolean aht20_is_status_ready(void) {
uint8_t status;
// i2c_start();
// i2c_send_addr_w(AHT20_ADDRESS);
// i2c_write(0xAC);
// i2c_write(0x33);
// i2c_write(0x00);
i2c_start_repeat();
i2c_send_addr_r(AHT20_ADDRESS); // AHT20 doc 7.4 : "get a byte of status word by sending 0x71" -> SLA+R == 0x71
status = i2c_read_nack();
i2c_stop();
uart_printstr("- status : ");
uart_printstr_itoa_base_endl(status, 2);
if (status & 0b10000000) {
// if ((status & 0x18) != 0x18) { // AHT20 doc 7.4 : "If the status word and 0x18 are not equal to 0x18 ..., if they are equal proceed to the next step"
return FALSE;
} else {
return TRUE;
}
}
void aht20_wait_for_status() {
for (uint8_t i = 0; i < 30; i++) {
uart_tx('|');
if (aht20_is_status_ready()) {
break;
}
_delay_ms(50);
}
}
// description
int main() {
uart_init();
uart_printstr("\r\n");
// 0x18 : 11000 : 24
// 0x33 : 110011 : 51 -> DATA0
// 0x38 : 111000 : 56
// 0x70 : 1110000 : 112 -> SLA+W
// 0x71 : 1110001 : 113 -> SLA+R
// 0x80 : 10000000 : 128
//
// 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
i2c_init();
i2c_start();
_delay_ms(200);
// aht20_wait_for_status();
// while(1) {
for (uint8_t i = 0; i < 6; i++) {
i2c_start_repeat();
i2c_send_addr_w(AHT20_ADDRESS);
_delay_ms(10);
// aht20_wait_for_status();
i2c_write(0xAC);
i2c_write(0x33);
i2c_write(0x00);
aht20_wait_for_status();
i2c_start_repeat();
i2c_send_addr_r(AHT20_ADDRESS);
print_data();
}
}