int console_tx_queue_ni (hBSP430halSERIAL uart, uint8_t c) { sConsoleTxBuffer * bufp = &tx_buffer_; while (1) { unsigned char head = bufp->head; unsigned char next_head = (head + 1) % (sizeof(bufp->buffer)/sizeof(*bufp->buffer)); if (next_head == bufp->tail) { if (0 == bufp->wake_available) { bufp->wake_available = 1; } BSP430_CORE_LPM_ENTER_NI(LPM0_bits | GIE); BSP430_CORE_DISABLE_INTERRUPT(); continue; } bufp->buffer[head] = c; bufp->head = next_head; if (head == bufp->tail) { vBSP430serialWakeupTransmit_ni(uart); } break; } return c; }
int iBSP430consoleTransmitUseInterrupts_ni (int enablep) { #if BSP430_CONSOLE_TX_BUFFER_SIZE - 0 if (enablep) { if (uartTransmit_ni != console_tx_queue_ni) { uartTransmit_ni = console_tx_queue_ni; vBSP430serialFlush_ni(console_hal_); iBSP430serialSetHold_ni(console_hal_, 1); BSP430_HAL_ISR_CALLBACK_LINK_NI(sBSP430halISRVoidChainNode, console_hal_->tx_cbchain_ni, tx_buffer_.cb_node, next_ni); iBSP430serialSetHold_ni(console_hal_, 0); if (tx_buffer_.head != tx_buffer_.tail) { vBSP430serialWakeupTransmit_ni(console_hal_); } } } else { if (uartTransmit_ni != iBSP430uartTxByte_ni) { uartTransmit_ni = iBSP430uartTxByte_ni; vBSP430serialFlush_ni(console_hal_); iBSP430serialSetHold_ni(console_hal_, 1); BSP430_HAL_ISR_CALLBACK_UNLINK_NI(sBSP430halISRVoidChainNode, console_hal_->tx_cbchain_ni, tx_buffer_.cb_node, next_ni); iBSP430serialSetHold_ni(console_hal_, 0); } } return 0; #else /* BSP430_CONSOLE_TX_BUFFER_SIZE */ return enablep ? -1 : 0; #endif /* BSP430_CONSOLE_TX_BUFFER_SIZE */ }
void main () { hBSP430halSERIAL console = NULL; hBSP430halSERIAL uart = NULL; unsigned long prep_utt = 0; unsigned long emit_utt = 0; unsigned long done_utt = 0; vBSP430platformInitialize_ni(); iBSP430consoleInitialize(); console = hBSP430console(); cprintf("\ntxcb " __DATE__ " " __TIME__ "\n"); cprintf("\nConsole %p is on %s: %s\n", console, xBSP430serialName(BSP430_CONSOLE_SERIAL_PERIPH_HANDLE), xBSP430platformPeripheralHelp(BSP430_CONSOLE_SERIAL_PERIPH_HANDLE, 0)); uart = hBSP430serialLookup(UART_PERIPH_HANDLE); if (NULL == uart) { cprintf("Failed to resolve secondary\n"); return; } cprintf("\nSecondary %p is on %s: %s\n", uart, xBSP430serialName(UART_PERIPH_HANDLE), xBSP430platformPeripheralHelp(UART_PERIPH_HANDLE, 0)); tx_buffer_.head = tx_buffer_.tail = 0; BSP430_HAL_ISR_CALLBACK_LINK_NI(sBSP430halISRVoidChainNode, uart->tx_cbchain_ni, tx_buffer_.cb_node, next_ni); uart = hBSP430serialOpenUART(uart, 0, 0, 9600); if (NULL == uart) { cprintf("Secondary open failed\n"); } /* Need to enable interrupts so timer overflow events are properly * acknowledged */ BSP430_CORE_ENABLE_INTERRUPT(); while (1) { unsigned long next_prep_utt; char * obp; char * ob_end; next_prep_utt = ulBSP430uptime(); obp = tx_buffer_.buffer; ob_end = obp + sizeof(tx_buffer_.buffer); obp += snprintf(obp, ob_end - obp, "prep %lu emit %lu\r\n", emit_utt - prep_utt, done_utt - emit_utt); ob_end = obp; BSP430_CORE_DISABLE_INTERRUPT(); emit_utt = ulBSP430uptime_ni(); prep_utt = next_prep_utt; tx_buffer_.tail = 0; tx_buffer_.head = obp - tx_buffer_.buffer; vBSP430serialWakeupTransmit_ni(uart); BSP430_CORE_LPM_ENTER_NI(LPM0_bits); /* Expect tail == head otherwise should not have awoken */ done_utt = ulBSP430uptime(); } }