diff --git a/irr_main.c b/irr_main.c index 92c77ff..ec5d287 100644 --- a/irr_main.c +++ b/irr_main.c @@ -164,11 +164,12 @@ struct chaninfo { GPIO_TypeDef *bank; uint16_t pinnum; bool init; + bool invert; } chans[] = { - [0] = { .bank = GPIOB, .pinnum = GPIO_PIN_5, .init = true, }, - [1] = { .bank = GPIOB, .pinnum = GPIO_PIN_6, .init = true, }, - [2] = { .bank = GPIOB, .pinnum = GPIO_PIN_7, .init = true, }, - [3] = { .bank = GPIOB, .pinnum = GPIO_PIN_9, .init = true, }, + [0] = { .bank = GPIOB, .pinnum = GPIO_PIN_5, .init = true, .invert = true, }, + [1] = { .bank = GPIOB, .pinnum = GPIO_PIN_6, .init = true, .invert = true, }, + [2] = { .bank = GPIOB, .pinnum = GPIO_PIN_7, .init = true, .invert = true, }, + [3] = { .bank = GPIOB, .pinnum = GPIO_PIN_9, .init = true, .invert = true, }, [4] = { .bank = GPIOB, .pinnum = GPIO_PIN_8, .init = true, }, }; #define nitems(x) (sizeof(x) / sizeof *(x)) @@ -180,7 +181,8 @@ set_chan(uint32_t chan, bool val) if (chan < nitems(chans)) { ci = chans[chan]; - HAL_GPIO_WritePin(ci.bank, ci.pinnum, val ? GPIO_PIN_SET : GPIO_PIN_RESET); + HAL_GPIO_WritePin(ci.bank, ci.pinnum, val ^ ci.invert ? + GPIO_PIN_SET : GPIO_PIN_RESET); } } @@ -202,7 +204,70 @@ setup_gpio() } } -void +static struct sched { + uint32_t cmd; + uint32_t end_wait_tick; /* end if running, otherwise how long to wait */ + uint32_t chan; +} schedule[20]; +static int schedpos; /* position in schedule, % nitems(schedule)*/ +static int schedcnt; /* total items waiting */ + +#define SCHED_HEAD (schedule[(schedpos) % nitems(schedule)]) +#define SCHED_TAIL (schedule[(schedpos + schedcnt) % nitems(schedule)]) + +static void +start_sched(struct sched *sched) +{ + + sched->end_wait_tick += uwTick; + + if (sched->cmd == CMD_RUNFOR) + set_chan(sched->chan, 1); +} + +static void +process_sched() +{ + + /* nothing to do? */ + if (schedcnt == 0) + return; + + /* not yet expired */ + if (uwTick < SCHED_HEAD.end_wait_tick) + return; + + if (SCHED_HEAD.cmd == CMD_RUNFOR) + set_chan(SCHED_HEAD.chan, 0); + + /* we are done, advance */ + schedpos++; + schedcnt--; + + if (schedcnt) + start_sched(&SCHED_HEAD); +} + +static void +enqueue_sched(uint32_t cmd, uint32_t ticks, uint32_t chan) +{ + + if (schedcnt >= nitems(schedule)) + return; + + SCHED_TAIL = (struct sched){ + .cmd = cmd, + .end_wait_tick = ticks, + .chan = chan, + }; + + if (schedcnt == 0) + start_sched(&SCHED_HEAD); + + schedcnt++; +} + +static void procmsg(struct pktbuf inbuf, struct pktbuf *outbuf) { uint32_t args[5]; @@ -220,6 +285,19 @@ procmsg(struct pktbuf inbuf, struct pktbuf *outbuf) outbuf->pkt[0] = inbuf.pkt[0]; switch (inbuf.pkt[0]) { + case CMD_WAITFOR: + if (apos == 1) + enqueue_sched(CMD_WAITFOR, args[0], -1); + break; + + case CMD_RUNFOR: + if (apos == 2) + enqueue_sched(CMD_RUNFOR, args[0], args[1]); + break; + + case CMD_PING: + break; + case CMD_SETUNSET: if (apos == 2) set_chan(args[0], args[1]); @@ -298,6 +376,8 @@ main() //Radio.Rx(0); loop: + process_sched(); + BoardLowPowerHandler(); if (Radio.IrqProcess != NULL) Radio.IrqProcess();