33#include "am1808.h"
44
55// Shared RAM (control input)
6+
7+ #define I2C_CMD_QUIRK 0x02
8+
69typedef struct i2c_command {
710 // bit[7:0] status and flags
811 // bit[15:8] write length
5760 I2C_STATE_NXT_QUIRK_WIGGLE ,
5861 I2C_STATE_RX_BYTE ,
5962 I2C_STATE_W_ACK ,
63+ I2C_STATE_REP_START ,
6064};
6165
6266typedef struct i2c_state_struct {
@@ -65,6 +69,7 @@ typedef struct i2c_state_struct {
6569 uint8_t addr ;
6670 uint8_t wlen ;
6771 uint8_t rlen ;
72+ uint8_t flags ;
6873
6974 uint8_t state ;
7075 uint8_t phase ;
@@ -94,8 +99,6 @@ static inline __attribute__((always_inline)) void i2c_hi(uint8_t gpio_bit) {
9499 :: handle_timeout \
95100 )
96101
97- uint32_t debug_i ;
98-
99102static void handle_i2c (i2c_state_struct * i2c ) {
100103 uint8_t state = i2c -> state ;
101104 uint8_t phase = i2c -> phase ;
@@ -108,14 +111,15 @@ static void handle_i2c(i2c_state_struct *i2c) {
108111 switch (state ) {
109112 case I2C_STATE_IDLE : {
110113 uint32_t flags = SHARED -> i2c .flags ;
111- if ((flags & 0xff ) != 0xaa ) {
114+ if ((flags & 0x81 ) != 0x01 ) {
112115 break ;
113116 }
114117
115118 i2c -> buffer = SHARED -> i2c .buffer ;
116119 i2c -> addr = flags >> 24 ;
117120 i2c -> rlen = flags >> 16 ;
118121 i2c -> wlen = flags >> 8 ;
122+ i2c -> flags = flags ;
119123
120124 state = I2C_STATE_START ;
121125 phase = 0 ;
@@ -216,17 +220,31 @@ static void handle_i2c(i2c_state_struct *i2c) {
216220
217221 phase = 0 ;
218222 if (i2c -> wlen == 0 ) {
219- // TODO: Normal repeated start
220223 if (state == I2C_STATE_R_ACK_ADDR && i2c -> rlen > 0 ) {
224+ // There is data to be a read, and we just sent the device address.
225+ // We now turn around the bus and get ready for reading.
221226 state = I2C_STATE_RX_BYTE ;
222227 work_bit = 7 ;
223228 work_byte = 0 ;
224229 goto i2c_state_rx ;
230+ } else if (i2c -> rlen > 0 ) {
231+ if (i2c -> flags & I2C_CMD_QUIRK ) {
232+ // The ultrasonic sensor needs a stoP, an extra clock, and then a Start
233+ state = I2C_STATE_STOP ;
234+ goto i2c_state_stop ;
235+ } else {
236+ state = I2C_STATE_REP_START ;
237+ goto i2c_state_rep_start ;
238+ }
225239 } else {
240+ // Empty ping
226241 state = I2C_STATE_STOP ;
227242 goto i2c_state_stop ;
228243 }
229244 } else {
245+ // There is data to send, either for a "write" type transaction
246+ // or for the initial register number for a "read" type transaction
247+ // before a repeated start (it works the same either way).
230248 i2c -> wlen -- ;
231249 state = I2C_STATE_TX_BYTE ;
232250 work_bit = 7 ;
@@ -252,12 +270,14 @@ static void handle_i2c(i2c_state_struct *i2c) {
252270 phase = 0 ;
253271 } else {
254272 state = I2C_STATE_IDLE ;
255- SHARED -> i2c .flags = 0xaa55 ;
273+ SHARED -> i2c .flags = 0xaa80 ;
256274 }
257275 }
258276 break ;
259277
260278 case I2C_STATE_NXT_QUIRK_WIGGLE :
279+ case I2C_STATE_REP_START :
280+ i2c_state_rep_start :
261281 if (phase == 0 ) {
262282 i2c_low (scl_bit );
263283 phase = 1 ;
@@ -333,14 +353,14 @@ static void handle_i2c(i2c_state_struct *i2c) {
333353
334354 if (0 ) {
335355handle_nak :
336- SHARED -> i2c .flags = 0x4e55 ;
356+ SHARED -> i2c .flags = 0x4e80 ;
337357 state = I2C_STATE_IDLE ;
338358 }
339359
340360 if (0 ) {
341361handle_timeout :
342362 if (-- i2c -> timeout == 0 ) {
343- SHARED -> i2c .flags = 0x5455 ;
363+ SHARED -> i2c .flags = 0x5480 ;
344364 state = I2C_STATE_IDLE ;
345365 }
346366 }
0 commit comments