44
55// Shared RAM (control input)
66
7+ #define NUM_I2C_CHANNELS 4
8+
79#define I2C_CMD_QUIRK 0x02
810
911typedef struct i2c_command {
@@ -18,7 +20,7 @@ typedef struct i2c_command {
1820typedef struct shared_ram {
1921 // Declare this as a u32 to force more-efficient codegen
2022 uint32_t pwms ;
21- i2c_command i2c ;
23+ i2c_command i2c [ NUM_I2C_CHANNELS ] ;
2224 uint32_t profiling_test ;
2325} shared_ram ;
2426// XXX: The real address in use here is 0x80010000
@@ -79,7 +81,7 @@ typedef struct i2c_state_struct {
7981 uint8_t scl_bit ;
8082 uint8_t sda_bit ;
8183} i2c_state_struct ;
82- i2c_state_struct i2c_states [1 ];
84+ i2c_state_struct i2c_states [NUM_I2C_CHANNELS ];
8385
8486static inline __attribute__((always_inline )) void i2c_low (uint8_t gpio_bit ) {
8587 uint32_t r = GPIO_BANK_01 -> dir ;
@@ -99,7 +101,21 @@ static inline __attribute__((always_inline)) void i2c_hi(uint8_t gpio_bit) {
99101 :: handle_timeout \
100102 )
101103
102- static void handle_i2c (i2c_state_struct * i2c ) {
104+ static inline __attribute__((always_inline )) uint32_t shared_i2c_get_flags (uint8_t cmd_offs ) {
105+ uint32_t x ;
106+ asm("lbco %0, 30, %1, 4" : "=r" (x ) : "r" ((uint8_t )(cmd_offs + __builtin_offsetof (i2c_command , flags ))));
107+ return x ;
108+ }
109+ static inline __attribute__((always_inline )) void shared_i2c_set_flags (uint8_t cmd_offs , uint32_t x ) {
110+ asm("sbco %0, 30, %1, 4" :: "r" (x ), "r" ((uint8_t )(cmd_offs + __builtin_offsetof (i2c_command , flags ))));
111+ }
112+ static inline __attribute__((always_inline )) uint8_t * shared_i2c_get_buffer (uint8_t cmd_offs ) {
113+ uint8_t * x ;
114+ asm("lbco %0, 30, %1, 4" : "=r" (x ) : "r" ((uint8_t )(cmd_offs + __builtin_offsetof (i2c_command , buffer ))));
115+ return x ;
116+ }
117+
118+ static void handle_i2c (uint8_t cmd_offs , i2c_state_struct * i2c ) {
103119 uint8_t state = i2c -> state ;
104120 uint8_t phase = i2c -> phase ;
105121 uint8_t work_byte = i2c -> work_byte ;
@@ -110,12 +126,12 @@ static void handle_i2c(i2c_state_struct *i2c) {
110126
111127 switch (state ) {
112128 case I2C_STATE_IDLE : {
113- uint32_t flags = SHARED -> i2c . flags ;
129+ uint32_t flags = shared_i2c_get_flags ( cmd_offs ) ;
114130 if ((flags & 0x81 ) != 0x01 ) {
115131 break ;
116132 }
117133
118- i2c -> buffer = SHARED -> i2c . buffer ;
134+ i2c -> buffer = shared_i2c_get_buffer ( cmd_offs ) ;
119135 i2c -> addr = flags >> 24 ;
120136 i2c -> rlen = flags >> 16 ;
121137 i2c -> wlen = flags >> 8 ;
@@ -125,7 +141,7 @@ static void handle_i2c(i2c_state_struct *i2c) {
125141 phase = 0 ;
126142 i2c -> timeout = I2C_TIMEOUT_LOOPS ;
127143
128- SHARED -> i2c . flags = 0 ;
144+ shared_i2c_set_flags ( cmd_offs , 0 ) ;
129145
130146 __attribute__((fallthrough ));
131147 }
@@ -270,7 +286,7 @@ static void handle_i2c(i2c_state_struct *i2c) {
270286 phase = 0 ;
271287 } else {
272288 state = I2C_STATE_IDLE ;
273- SHARED -> i2c . flags = 0xaa80 ;
289+ shared_i2c_set_flags ( cmd_offs , 0xaa80 ) ;
274290 }
275291 }
276292 break ;
@@ -353,14 +369,14 @@ static void handle_i2c(i2c_state_struct *i2c) {
353369
354370 if (0 ) {
355371handle_nak :
356- SHARED -> i2c . flags = 0x4e80 ;
372+ shared_i2c_set_flags ( cmd_offs , 0x4e80 ) ;
357373 state = I2C_STATE_IDLE ;
358374 }
359375
360376 if (0 ) {
361377handle_timeout :
362378 if (-- i2c -> timeout == 0 ) {
363- SHARED -> i2c . flags = 0x5480 ;
379+ shared_i2c_set_flags ( cmd_offs , 0x5480 ) ;
364380 state = I2C_STATE_IDLE ;
365381 }
366382 }
@@ -376,8 +392,14 @@ void main() {
376392 bool debug_profile_thing = false;
377393
378394 // We initialize this in code to avoid having to copy a data ram binary
379- i2c_states [0 ].scl_bit = 12 ;
380- i2c_states [0 ].sda_bit = 14 + 16 ;
395+ i2c_states [0 ].scl_bit = 2 ;
396+ i2c_states [0 ].sda_bit = 15 ;
397+ i2c_states [1 ].scl_bit = 14 ;
398+ i2c_states [1 ].sda_bit = 13 ;
399+ i2c_states [2 ].scl_bit = 12 ;
400+ i2c_states [2 ].sda_bit = 14 + 16 ;
401+ i2c_states [3 ].scl_bit = 1 ;
402+ i2c_states [3 ].sda_bit = 15 + 16 ;
381403
382404 while (1 ) {
383405 // 24 MHz / 256 ==> 93.75 kHz tick rate for this counter
@@ -399,7 +421,10 @@ void main() {
399421 * TIMER2_INTCTLSTAT = TIMER_INTCTLSTAT_PRDINTSTAT12 ;
400422
401423 // This code runs at 20 kHz, which is 2x the I2C clock rate
402- handle_i2c (& i2c_states [0 ]);
424+ handle_i2c (__builtin_offsetof (shared_ram , i2c [0 ]), & i2c_states [0 ]);
425+ handle_i2c (__builtin_offsetof (shared_ram , i2c [1 ]), & i2c_states [1 ]);
426+ handle_i2c (__builtin_offsetof (shared_ram , i2c [2 ]), & i2c_states [2 ]);
427+ handle_i2c (__builtin_offsetof (shared_ram , i2c [3 ]), & i2c_states [3 ]);
403428
404429 if (debug_profile_thing ) {
405430 uint32_t tim_profile = * TIMER2_TIM12 ;
0 commit comments