static void UARTConfigInternal(int uart_num, int rate, int speed4x, int two_stop_bits, int parity, int external) { volatile UART* regs = uart_reg[uart_num]; UART_STATE* uart = &uarts[uart_num]; if (external) { log_printf("UARTConfig(%d, %d, %d, %d, %d)", uart_num, rate, speed4x, two_stop_bits, parity); } SAVE_UART_FOR_LOG(uart_num); AssignUxRXIE(uart_num, 0); // disable RX int. AssignUxTXIE(uart_num, 0); // disable TX int. regs->uxmode = 0x0000; // disable UART. // clear SW buffers ByteQueueInit(&uart->rx_queue, uart->rx_buffer, RX_BUF_SIZE); ByteQueueInit(&uart->tx_queue, uart->tx_buffer, TX_BUF_SIZE); uart->num_tx_since_last_report = 0; if (rate) { if (external) { UARTSendStatus(uart_num, 1); } regs->uxbrg = rate; AssignUxRXIF(uart_num, 0); // clear RX int. AssignUxTXIF(uart_num, 1); // set TX int, since the hardware FIFO is empty. AssignUxRXIE(uart_num, 1); // enable RX int. regs->uxmode = 0x8000 | (speed4x ? 0x0008 : 0x0000) | two_stop_bits | (parity << 1); // enable regs->uxsta = 0x8400; // IRQ when TX buffer is empty, enable TX, IRQ when character received. uart->num_tx_since_last_report = TX_BUF_SIZE; } else { if (external) { UARTSendStatus(uart_num, 0); } } }
void SetPinUart(int pin, int uart_num, int dir, int enable) { log_printf("SetPinUart(%d, %d, %d, %d)", pin, uart_num, dir, enable); SAVE_PIN_FOR_LOG(pin); SAVE_UART_FOR_LOG(uart_num); if (dir) { // TX const BYTE rp[] = { 3, 5, 28, 30 }; PinSetRpor(pin, enable ? rp[uart_num] : 0); } else { // RX int rpin = enable ? PinToRpin(pin) : 0x3F; switch (uart_num) { case 0: _U1RXR = rpin; break; case 1: _U2RXR = rpin; break; case 2: _U3RXR = rpin; break; case 3: _U4RXR = rpin; break; } } }
void UARTTransmit(int uart_num, const void* data, int size) { log_printf("UARTTransmit(%d, %p, %d)", uart_num, data, size); SAVE_UART_FOR_LOG(uart_num); BYTE_QUEUE* q = &uarts[uart_num].tx_queue; PRIORITY(TX_PRIORITY) { ByteQueuePushBuffer(q, data, size); AssignUxTXIE(uart_num, 1); // enable TX int. } }