void enet_mac_init_pins() { printf("enet_mac_init_pins()\r\n"); pin_set_alternate_function(GPIOA, PORTA_ETH_REFCLK, AF_ENET); pin_set_alternate_function(GPIOA, PORTA_ETH_MDIO , AF_ENET); pin_set_alternate_function(GPIOC, PORTC_ETH_MDC , AF_ENET); pin_set_alternate_function(GPIOB, PORTB_ETH_TXEN , AF_ENET); pin_set_alternate_function(GPIOB, PORTB_ETH_TXD0 , AF_ENET); pin_set_alternate_function(GPIOB, PORTB_ETH_TXD1 , AF_ENET); pin_set_alternate_function(GPIOA, PORTA_ETH_CRSDV , AF_ENET); pin_set_alternate_function(GPIOC, PORTC_ETH_RXD0 , AF_ENET); pin_set_alternate_function(GPIOC, PORTC_ETH_RXD1 , AF_ENET); pin_set_output_speed(GPIOB, PORTB_ETH_TXEN, 3); // max beef pin_set_output_speed(GPIOB, PORTB_ETH_TXD0, 3); // max beef pin_set_output_speed(GPIOB, PORTB_ETH_TXD1, 3); // max beef pin_set_output(GPIOE, PORTE_PHY_RESET, 1); delay_ms(100); pin_set_output_state(GPIOE, PORTE_PHY_RESET, 0); delay_ms(100); pin_set_output_state(GPIOE, PORTE_PHY_RESET, 1); delay_ms(100); }
static void dmxl_tx(const uint8_t *payload, const uint8_t payload_len) { if (g_dmxl_chain.port_state != DMXL_PORT_STATE_IDLE) return; // don't clobber the polls. TODO: buffer until it's free uint8_t pkt[255]; pkt[0] = 0xff; pkt[1] = 0xff; memcpy(pkt+2, payload, payload_len); uint8_t csum = 0; for (uint8_t i = 0; i < payload_len; i++) csum += payload[i]; pkt[payload_len+2] = ~csum; USART1->CR1 &= ~USART_CR1_RE; // disable receiver during transmit pin_set_output_state(GPIOB, DMXL_PORTB_TXE_PIN, 1); // assert txe delay_us(5); for (int i = 0; i < payload_len+3; i++) { while (!(USART1->SR & USART_SR_TXE)) { } // spin for tx buffer to clear USART1->DR = pkt[i]; } while (!(USART1->SR & USART_SR_TC)) { } // spin for completion of last byte delay_us(5); pin_set_output_state(GPIOB, DMXL_PORTB_TXE_PIN, 0); // de-assert txe USART1->CR1 |= USART_CR1_RE; // re-enable receiver }
void serial_tx(const uint8_t port, const uint8_t *data, const uint8_t len) { if (port >= NUM_PORTS) return; // adios amigo serial_port_t *p = &g_ports[port]; USART_TypeDef *u = p->uart; u->CR1 &= ~USART_CR1_RE; // disable receiver during transmit //u->CR1 |= USART_CR1_TE; // enable transmitter pin_set_output_state(p->txe_gpio, p->txe_pin, 1); delay_us(5); for (int i = 0; i < len; i++) { while (!(u->SR & USART_SR_TXE)) { } // spin for tx buffer to clear u->DR = data[i]; } while (!(u->SR & USART_SR_TC)) { } // spin waiting for completion delay_us(5); pin_set_output_state(p->txe_gpio, p->txe_pin, 0); // de-assert TXE u->CR1 |= USART_CR1_RE; // re-enable receiver //u->CR1 &= ~USART_CR1_TE; // disable transmitter }
void led_off(void) { pin_set_output_state(GPIOI, PORTI_LED, 0); }
void led_on(void) { pin_set_output_state(GPIOI, PORTI_LED, 1); }
void led_off(void) { pin_set_output_state(LED_GPIO, LED_PIN, 0); }
void led_on(void) { pin_set_output_state(LED_GPIO, LED_PIN, 1); }
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; } }