Skip to content

Commit ec51746

Browse files
committed
4x ports
1 parent 9931dbf commit ec51746

File tree

1 file changed

+37
-12
lines changed

1 file changed

+37
-12
lines changed

main.c

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
// Shared RAM (control input)
66

7+
#define NUM_I2C_CHANNELS 4
8+
79
#define I2C_CMD_QUIRK 0x02
810

911
typedef struct i2c_command {
@@ -18,7 +20,7 @@ typedef struct i2c_command {
1820
typedef 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

8486
static 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) {
355371
handle_nak:
356-
SHARED->i2c.flags = 0x4e80;
372+
shared_i2c_set_flags(cmd_offs, 0x4e80);
357373
state = I2C_STATE_IDLE;
358374
}
359375

360376
if (0) {
361377
handle_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

Comments
 (0)