bool frudp_listen(const uint32_t max_usec) { // just busy-wait here for the requested amount of time volatile uint32_t t_start = systime_usecs(); while (1) { enet_process_rx_ring(); volatile uint32_t t = systime_usecs(); if (t - t_start >= max_usec) break; } return true; }
void delay_ms(uint32_t ms) { // todo: care about wraparound volatile uint32_t t_start = systime_usecs(); while (1) { volatile uint32_t t[2]; // poll time twice in case we happen to poll during timer wrap glitch t[0] = systime_usecs(); t[1] = systime_usecs(); t[0] = t[1] < t[0] ? t[1] : t[0]; if (t[0] > t_start + 1000 * ms) break; } }
void dmxl_tick() { volatile uint32_t t = systime_usecs(); bool start_poll = false; if (t - g_dmxl_last_poll_time > DMXL_POLL_INTERVAL_USEC) { //start_poll = true; //printf("%d dmxl poll\r\n", (int)SYSTIME); if (g_dmxl_last_poll_time) g_dmxl_last_poll_time += DMXL_POLL_INTERVAL_USEC; else g_dmxl_last_poll_time = t; } // process the rx ring dmxl_chain_t *c = &g_dmxl_chain; while (c->rx_rpos != c->rx_wpos) { dmxl_process_byte(c, c->rxbuf[c->rx_rpos++]); __disable_irq(); if (c->rx_rpos >= DMXL_CHAIN_RXBUF_LEN) c->rx_rpos = 0; __enable_irq(); } // run the port state machine switch (c->port_state) { case DMXL_PORT_STATE_IDLE: if (start_poll) { USART1->CR1 &= ~USART_CR1_RE; c->port_state = DMXL_PORT_STATE_POLL_TX_EN; c->polling_id = c->id_base; // start with first servo c->t_state = t; dmxl_stuff_poll_pkt(c); pin_set_output_state(GPIOB, DMXL_PORTB_TXE_PIN, 1); // assert TXE } break; case DMXL_PORT_STATE_POLL_TX_EN: if (t - c->t_state > 3) { //printf("starting dmxl poll\r\n"); c->tx_byte_idx = 0; USART1->DR = c->txbuf[0]; c->port_state = DMXL_PORT_STATE_POLL_TX; c->t_state = systime_usecs(); } break; case DMXL_PORT_STATE_POLL_TX: if ((USART1->SR & USART_SR_TXE) || systime_usecs() - c->t_state > 100) { if (c->tx_byte_idx >= c->tx_pkt_len - 1) { c->port_state = DMXL_PORT_STATE_POLL_TX_LAST; c->t_state = systime_usecs(); } else USART1->DR = c->txbuf[++c->tx_byte_idx]; } break; case DMXL_PORT_STATE_POLL_TX_LAST: if ((USART1->SR & USART_SR_TC) || systime_usecs() - c->t_state > 100) { c->port_state = DMXL_PORT_STATE_POLL_TX_DIS; c->t_state = systime_usecs(); c->parser_state = DMXL_PARSER_STATE_PREAMBLE_0; } break; case DMXL_PORT_STATE_POLL_TX_DIS: if (systime_usecs() - c->t_state > 2) { pin_set_output_state(GPIOB, DMXL_PORTB_TXE_PIN, 0); // de-assert TXE c->port_state = DMXL_PORT_STATE_POLL_RX; c->t_state = systime_usecs(); USART1->CR1 |= USART_CR1_RE; //printf("%d starting rx\r\n", (int)SYSTIME); } break; case DMXL_PORT_STATE_POLL_RX: if ((c->parser_state == DMXL_PARSER_STATE_DONE) || (systime_usecs() - c->t_state > 1000)) { // if we haven't heard from it by 1ms, we're toast anyway //printf("%d exiting rx\r\n", (int)SYSTIME); // we need to either start polling the next servo, or we're done. c->polling_id++; //printf("%d poll complete\r\n", (int)SYSTIME); if (c->polling_id > c->num_nodes) c->port_state = DMXL_PORT_STATE_IDLE; else c->port_state = DMXL_PORT_STATE_POLL_RX_WAIT; dmxl_stuff_poll_pkt(c); USART1->CR1 &= ~USART_CR1_RE; c->t_state = systime_usecs(); } break; case DMXL_PORT_STATE_POLL_RX_WAIT: if (systime_usecs() - c->t_state > 100) { c->port_state = DMXL_PORT_STATE_POLL_TX_EN; pin_set_output_state(GPIOB, DMXL_PORTB_TXE_PIN, 1); // assert TXE c->t_state = systime_usecs(); } break; default: g_dmxl_chain.port_state = DMXL_PORT_STATE_IDLE; } }
void delay_ms(uint32_t ms) { // todo: care about wraparound volatile uint32_t t_start = systime_usecs(); while (t_start + 1000 * ms > systime_usecs()) { } }