static int32_t USART_Control (uint32_t control, uint32_t arg, USART_RESOURCES *usart) { uint32_t mode; if ((usart->info->flags & USART_FLAG_POWERED) == 0) // USART not powered return ARM_DRIVER_ERROR; switch (control & ARM_USART_CONTROL_Msk) { // Control TX case ARM_USART_CONTROL_TX: if (arg) { usart->info->flags |= USART_FLAG_TX_ENABLED; usart->reg->CR |= UART_CR_TXE; usart->reg->IMSC |= UART_IMSC_TXIM; } else { usart->info->flags &= ~USART_FLAG_TX_ENABLED; usart->reg->CR &= ~UART_CR_TXE; usart->reg->IMSC &= ~UART_IMSC_TXIM; usart->reg->ICR |= UART_ICR_TXIC; } return ARM_DRIVER_OK; // Control RX case ARM_USART_CONTROL_RX: if (arg) { usart->info->flags |= USART_FLAG_RX_ENABLED; usart->reg->CR |= UART_CR_RXE; // RX Line interrupt enable (overrun, framing, parity error, break) usart->reg->IMSC |= (UART_IMSC_RXIM | UART_IMSC_FEIM | UART_IMSC_PEIM | UART_IMSC_BEIM | UART_IMSC_OEIM); } else { usart->info->flags &= ~USART_FLAG_RX_ENABLED; usart->reg->CR &= ~UART_CR_RXE; usart->reg->IMSC &= ~(UART_IMSC_RXIM | UART_IMSC_FEIM | UART_IMSC_PEIM | UART_IMSC_BEIM | UART_IMSC_OEIM); usart->reg->ICR |= (UART_ICR_RXIC | UART_ICR_FEIC | UART_ICR_PEIC | UART_ICR_BEIC | UART_ICR_OEIC); } return ARM_DRIVER_OK; // Control break case ARM_USART_CONTROL_BREAK: if (arg) { if (usart->info->flags & USART_FLAG_SEND_ACTIVE) return ARM_DRIVER_ERROR_BUSY; usart->reg->LCR_H |= UART_LCR_H_BRK; // Set Send active flag usart->info->flags |= USART_FLAG_SEND_ACTIVE; } else { usart->reg->LCR_H &= ~UART_LCR_H_BRK; // Clear Send active flag usart->info->flags &= ~USART_FLAG_SEND_ACTIVE; } return ARM_DRIVER_OK; // Abort Send case ARM_USART_ABORT_SEND: // Disable transmit interrupt usart->reg->IMSC &= ~UART_IMSC_TXIM; usart->reg->ICR |= UART_ICR_TXIC; // Clear Send active flag usart->info->flags &= ~USART_FLAG_SEND_ACTIVE; return ARM_DRIVER_OK; // Abort receive case ARM_USART_ABORT_RECEIVE: // Disable receive interrupt usart->reg->IMSC &= ~(UART_IMSC_RXIM | UART_IMSC_FEIM | UART_IMSC_PEIM | UART_IMSC_BEIM | UART_IMSC_OEIM); usart->reg->ICR |= (UART_ICR_RXIC | UART_ICR_FEIC | UART_ICR_PEIC | UART_ICR_BEIC | UART_ICR_OEIC); // Clear RX busy status usart->info->status.rx_busy = 0; return ARM_DRIVER_OK; // Abort transfer case ARM_USART_ABORT_TRANSFER: // Disable transmit and receive interrupts usart->reg->IMSC &= ~(UART_IMSC_RXIM | UART_IMSC_TXIM | UART_IMSC_FEIM | UART_IMSC_PEIM | UART_IMSC_BEIM | UART_IMSC_OEIM); usart->reg->ICR |= (UART_ICR_RXIC | UART_ICR_TXIC | UART_ICR_FEIC | UART_ICR_PEIC | UART_ICR_BEIC | UART_ICR_OEIC); // Clear busy statuses usart->info->status.rx_busy = 0; usart->info->flags &= ~USART_FLAG_SEND_ACTIVE; return ARM_DRIVER_OK; } switch (control & ARM_USART_CONTROL_Msk) { case ARM_USART_MODE_ASYNCHRONOUS: mode = ARM_USART_MODE_ASYNCHRONOUS; break; case ARM_USART_MODE_IRDA: if (usart->capabilities.irda) // Enable IrDA mode usart->reg->CR |= UART_CR_SIREN; else return ARM_USART_ERROR_MODE; mode = ARM_USART_MODE_IRDA; break; // IrDA pulse case ARM_USART_SET_IRDA_PULSE: if (usart->capabilities.irda) usart->reg->ILPR = RTE_HCLK / usart->clk.div / NomClkIrDA; else return ARM_DRIVER_ERROR; return ARM_DRIVER_OK; // Unsupported command default: return ARM_DRIVER_ERROR_UNSUPPORTED; } // Check if Receiver/Transmitter is busy if (usart->info->status.rx_busy || (usart->info->flags & USART_FLAG_SEND_ACTIVE)) return ARM_DRIVER_ERROR_BUSY; // USART Data bits switch (control & ARM_USART_DATA_BITS_Msk) { case ARM_USART_DATA_BITS_5: usart->reg->LCR_H &= ~UART_LCR_H_WLEN_Msk; usart->reg->LCR_H |= (UART_LCR_H_WLEN_5_BITS << UART_LCR_H_WLEN_Pos); break; case ARM_USART_DATA_BITS_6: usart->reg->LCR_H &= ~UART_LCR_H_WLEN_Msk; usart->reg->LCR_H |= (UART_LCR_H_WLEN_6_BITS << UART_LCR_H_WLEN_Pos); break; case ARM_USART_DATA_BITS_7: usart->reg->LCR_H &= ~UART_LCR_H_WLEN_Msk; usart->reg->LCR_H |= (UART_LCR_H_WLEN_7_BITS << UART_LCR_H_WLEN_Pos); break; case ARM_USART_DATA_BITS_8: usart->reg->LCR_H &= ~UART_LCR_H_WLEN_Msk; usart->reg->LCR_H |= (UART_LCR_H_WLEN_8_BITS << UART_LCR_H_WLEN_Pos); break; default: return ARM_USART_ERROR_DATA_BITS; } // USART Parity switch (control & ARM_USART_PARITY_Msk) { case ARM_USART_PARITY_NONE: usart->reg->LCR_H &= ~UART_LCR_H_PEN; break; case ARM_USART_PARITY_EVEN: usart->reg->LCR_H |= UART_LCR_H_PEN; usart->reg->LCR_H &= ~UART_LCR_H_EPS; break; case ARM_USART_PARITY_ODD: usart->reg->LCR_H |= (UART_LCR_H_PEN | UART_LCR_H_EPS); } // USART Stop bits switch (control & ARM_USART_STOP_BITS_Msk) { case ARM_USART_STOP_BITS_1: usart->reg->LCR_H &= ~UART_LCR_H_STP2; break; case ARM_USART_STOP_BITS_2: usart->reg->LCR_H |= UART_LCR_H_STP2; break; default: return ARM_USART_ERROR_STOP_BITS; } usart->reg->CR &= ~(UART_CR_RTSEN | UART_CR_CTSEN); switch (control & ARM_USART_FLOW_CONTROL_Msk) { case ARM_USART_FLOW_CONTROL_NONE: break; case ARM_USART_FLOW_CONTROL_RTS: if (usart->capabilities.flow_control_rts) usart->reg->CR |= UART_CR_RTSEN; else return ARM_USART_ERROR_FLOW_CONTROL; break; case ARM_USART_FLOW_CONTROL_CTS: if (usart->capabilities.flow_control_cts) usart->reg->CR |= UART_CR_CTSEN; else return ARM_USART_ERROR_FLOW_CONTROL; break; case ARM_USART_FLOW_CONTROL_RTS_CTS: if (usart->capabilities.flow_control_rts && usart->capabilities.flow_control_cts) usart->reg->CR |= (UART_CR_RTSEN | UART_CR_CTSEN); else return ARM_USART_ERROR_FLOW_CONTROL; break; default: return ARM_USART_ERROR_FLOW_CONTROL; } // USART Baudrate USART_SetBaudrate (arg, usart); // Configuration is OK - Mode is valid usart->info->mode = mode; // Set configured flag usart->info->flags |= USART_FLAG_CONFIGURED; return ARM_DRIVER_OK; }
/** * \brief Configures USART in LON mode */ static void _ConfigureUsart( void ) { /* Initialization for Sending/Receiving A LON Frame */ uint32_t mode; Usart *pUsart = USART; /* 1. Write TXEN and RXEN in US_CR to enable both the transmitter and the receiver. */ /* Enable receiver & transmitter */ USART_SetTransmitterEnabled(pUsart, 1); USART_SetReceiverEnabled(pUsart, 1); /* 2. Write USART_MODE in US_MR to select the LON mode configuration. */ /* Enable the peripheral clock in the PMC */ PMC_EnablePeripheral(ID_USART); mode = US_MR_USART_MODE_LON | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL //| US_MR_CHMODE_LOCAL_LOOPBACK //US_MR_CHMODE_NORMAL | US_MR_MAN; pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RXDIS | US_CR_TXDIS | US_CR_RSTSTA; pUsart->US_IDR = 0xFFFFFFFF; pUsart->US_MR = mode; /* 3. Write CD and FP in US_BRGR to configure the baud rate. */ USART_SetBaudrate(pUsart, 0, BAUDRATE, BOARD_MCK); /* 4. Write COMMT, COLDET, TCOL, CDTAIL, RDMNBM and DMAM in US_LONMR to configure the LON operating mode. */ pUsart->US_LONMR = US_LONMR_COMMT /* LON comm_type = 2 mode */ | US_LONMR_COLDET /* LON collision detection feature enabled */ | US_LONMR_DMAM /* The LON data length register US_LONDL is written by the DMA */ | US_LONMR_LCDS /* LON collision detection source is internal. */ | US_LONMR_EOFS(1); /* 5. Write BETA2, BETA1TX, BETA1RX, PCYCLE, PSNB, NPS, IDTTX and ITDRX respectively in US_FIDI, US_LONB1TX, US_LONB1RX, US_TTGR, US_LONPRIO, US_LONIDTTX and US_LONIDTRX to set the LON network configuration. */ pUsart->US_FIDI = 5; /* LON BETA2 length */ pUsart->US_LONB1TX = 5; /* LON Beta1 Tx */ pUsart->US_LONB1RX = 5; /* LON Beta1 Rx */ pUsart->US_TTGR = US_TTGR_PCYCLE(5); /* package cycle timer value */ pUsart->US_LONPRIO = US_LONPRIO_PSNB(5) /* Number of priority slots */ | US_LONPRIO_NPS(5); /* Node priority slot */ /* Set LON Indeterminate Time after Transmission or Reception * (comm_type = 1 mode only) */ if (0 == (pUsart->US_LONMR & US_LONMR_COMMT)) { pUsart->US_IDTTX = US_IDTTX_IDTTX(3); pUsart->US_IDTRX = US_IDTRX_IDTRX(3); } /* (TX) 6. Write TX_PL in US_MAN to select the preamble pattern to use. */ /* (RX) 6. Write RXIDLEV and RX_PL in US_MAN to indicate the receiver line value and select the preamble pattern to use. */ // preamble pattern pUsart->US_MAN = US_MAN_TX_PL(5) | US_MAN_TX_PP_ALL_ONE | US_MAN_RX_PL(5) | US_MAN_RX_PP_ALL_ONE | US_MAN_ONE | US_MAN_DRIFT; pUsart->US_LONPR = US_LONPR_LONPL(5); /* proceed by a software reset of the transmitter and the receiver and followed by a transmitter/receiver enable to avoid unpredictable behavior */ pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX; pUsart->US_CR = US_CR_RXEN | US_CR_TXEN; }