/*---------------------------------------------------------------------------*/ static int stm32w_radio_prepare(const void *payload, unsigned short payload_len) { if(payload_len > STM32W_MAX_PACKET_LEN) { PRINTF("stm32w: payload length=%d is too long.\r\n", payload_len); return RADIO_TX_ERR; } #if !RADIO_WAIT_FOR_PACKET_SENT /* * Check if the txbuf is empty. Wait for a finite time. * This should not occur if we wait for the end of transmission in * stm32w_radio_transmit(). */ if(wait_for_tx()) { PRINTF("stm32w: tx buffer full.\r\n"); return RADIO_TX_ERR; } #endif /* RADIO_WAIT_FOR_PACKET_SENT */ /* * Copy to the txbuf. * The first byte must be the packet length. */ CLEAN_TXBUF(); memcpy(stm32w_txbuf + 1, payload, payload_len); return RADIO_TX_OK; }
static void serial_ambarella_poll_put_char(struct uart_port *port, unsigned char chr) { struct ambarella_uart_port_info *port_info; port_info = (struct ambarella_uart_port_info *)(port->private_data); if (!port->suspended) { wait_for_tx(port); amba_writel(port->membase + UART_TH_OFFSET, chr); } }
static void serial_ambarella_console_write(struct console *co, const char *s, unsigned int count) { u32 ie; struct uart_port *port; unsigned long flags; int locked = 1; port = (struct uart_port *)( ambarella_uart_ports.amba_port[co->index].port); if (!port->suspended) { local_irq_save(flags); if (port->sysrq) { locked = 0; } else if (oops_in_progress) { locked = spin_trylock(&port->lock); } else { spin_lock(&port->lock); locked = 1; } ie = amba_readl(port->membase + UART_IE_OFFSET); amba_writel(port->membase + UART_IE_OFFSET, ie & ~UART_IE_ETBEI); uart_console_write(port, s, count, serial_ambarella_console_putchar); wait_for_tx(port); amba_writel(port->membase + UART_IE_OFFSET, ie); if (locked) spin_unlock(&port->lock); local_irq_restore(flags); } }
/*---------------------------------------------------------------------------*/ static int stm32w_radio_transmit(unsigned short payload_len) { stm32w_txbuf[0] = payload_len + CHECKSUM_LEN; INIT_RETRY_CNT(); if(onoroff == OFF) { PRINTF("stm32w: Radio is off, turning it on.\r\n"); ST_RadioWake(); ENERGEST_ON(ENERGEST_TYPE_LISTEN); } #if RADIO_WAIT_FOR_PACKET_SENT GET_LOCK(); #endif /* RADIO_WAIT_FOR_PACKET_SENT */ last_tx_status = -1; LED_TX_ON(); if(ST_RadioTransmit(stm32w_txbuf) == ST_SUCCESS) { ENERGEST_OFF(ENERGEST_TYPE_LISTEN); ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); PRINTF("stm32w: sending %d bytes\r\n", payload_len); #if DEBUG > 1 for(uint8_t c = 1; c <= stm32w_txbuf[0] - 2; c++) { PRINTF("%x:", stm32w_txbuf[c]); } PRINTF("\r\n"); #endif #if RADIO_WAIT_FOR_PACKET_SENT if(wait_for_tx()) { PRINTF("stm32w: unknown tx error.\r\n"); TO_PREV_STATE(); LED_TX_OFF(); RELEASE_LOCK(); return RADIO_TX_ERR; } TO_PREV_STATE(); if(last_tx_status == ST_SUCCESS || last_tx_status == ST_PHY_ACK_RECEIVED || last_tx_status == ST_MAC_NO_ACK_RECEIVED) { RELEASE_LOCK(); if(last_tx_status == ST_PHY_ACK_RECEIVED) { return RADIO_TX_OK; /* ACK status */ } else if(last_tx_status == ST_MAC_NO_ACK_RECEIVED || last_tx_status == ST_SUCCESS) { return RADIO_TX_NOACK; } } LED_TX_OFF(); RELEASE_LOCK(); return RADIO_TX_ERR; #else /* RADIO_WAIT_FOR_PACKET_SENT */ TO_PREV_STATE(); LED_TX_OFF(); return RADIO_TX_OK; #endif /* RADIO_WAIT_FOR_PACKET_SENT */ } #if RADIO_WAIT_FOR_PACKET_SENT RELEASE_LOCK(); #endif /* RADIO_WAIT_FOR_PACKET_SENT */ TO_PREV_STATE(); PRINTF("stm32w: transmission never started.\r\n"); /* TODO: Do we have to retransmit? */ CLEAN_TXBUF(); LED_TX_OFF(); return RADIO_TX_ERR; }
static void serial_ambarella_console_putchar(struct uart_port *port, int ch) { wait_for_tx(port); amba_writel(port->membase + UART_TH_OFFSET, ch); }