|
|
@@ -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(); |
|
|
|