123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- /*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2019-02-02 xuzhuoyi first version
- */
- #include "rtdevice.h"
- #include "board.h"
- #include "drv_sci.h"
- #include "F2837xD_device.h"
- #include "F2837xD_sci.h"
- typedef long off_t;
- #include "F2837xD_sci_io.h"
- #ifdef RT_USING_SERIAL
- #define LOG_TAG "drv.sci"
- /* c28x uart driver class */
- struct c28x_uart
- {
- const char *name;
- volatile struct SCI_REGS *sci_regs;
- struct rt_serial_device serial;
- };
- static struct c28x_uart uart_obj[3] = {0};
- static rt_err_t c28x_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
- {
- struct c28x_uart *uart;
- RT_ASSERT(serial != RT_NULL);
- RT_ASSERT(cfg != RT_NULL);
- uart = (struct c28x_uart *)serial->parent.user_data;
- RT_ASSERT(uart != RT_NULL);
- EALLOW;
- // default config
- // 1 stop bit, No loopback
- // No parity,8 char bits,
- // async mode, idle-line protocol
- uart->sci_regs->SCICCR.all = 0x0007;
- // enable TX, RX, internal SCICLK,
- // Disable RX ERR, SLEEP, TXWAKE
- uart->sci_regs->SCICTL1.all = 0x0003;
- uart->sci_regs->SCICTL2.bit.TXINTENA = 1;
- uart->sci_regs->SCICTL2.bit.RXBKINTENA = 1;
- uart->sci_regs->SCIHBAUD.all = 0x0000; // 115200 baud @LSPCLK = 22.5MHz (90 MHz SYSCLK).
- uart->sci_regs->SCILBAUD.all = 53;
- uart->sci_regs->SCICTL1.all = 0x0023; // Relinquish SCI from Reset
- switch (cfg->data_bits)
- {
- case DATA_BITS_5:
- uart->sci_regs->SCICCR.bit.SCICHAR = 4;
- break;
- case DATA_BITS_6:
- uart->sci_regs->SCICCR.bit.SCICHAR = 5;
- break;
- case DATA_BITS_7:
- uart->sci_regs->SCICCR.bit.SCICHAR = 6;
- break;
- case DATA_BITS_8:
- uart->sci_regs->SCICCR.bit.SCICHAR = 7;
- break;
- default:
- uart->sci_regs->SCICCR.bit.SCICHAR = 7;
- break;
- }
- switch (cfg->stop_bits)
- {
- case STOP_BITS_1:
- uart->sci_regs->SCICCR.bit.STOPBITS = 0;
- break;
- case STOP_BITS_2:
- uart->sci_regs->SCICCR.bit.STOPBITS = 1;
- break;
- default:
- uart->sci_regs->SCICCR.bit.STOPBITS = 0;
- break;
- }
- switch (cfg->parity)
- {
- case PARITY_NONE:
- uart->sci_regs->SCICCR.bit.PARITYENA = 0;
- break;
- case PARITY_ODD:
- uart->sci_regs->SCICCR.bit.PARITYENA = 1;
- uart->sci_regs->SCICCR.bit.PARITY = 0;
- break;
- case PARITY_EVEN:
- uart->sci_regs->SCICCR.bit.PARITYENA = 1;
- uart->sci_regs->SCICCR.bit.PARITY = 1;
- break;
- default:
- uart->sci_regs->SCICCR.bit.PARITYENA = 0;
- break;
- }
- EDIS;
- return RT_EOK;
- }
- static rt_err_t c28x_control(struct rt_serial_device *serial, int cmd, void *arg)
- {
- struct c28x_uart *uart;
- uart = (struct c28x_uart *)serial->parent.user_data;
- EALLOW;
- switch (cmd)
- {
- /* disable interrupt */
- case RT_DEVICE_CTRL_CLR_INT:
- /* disable interrupt */
- uart->sci_regs->SCICTL2.bit.TXINTENA = 0;
- uart->sci_regs->SCICTL2.bit.RXBKINTENA = 0;
- break;
- /* enable interrupt */
- case RT_DEVICE_CTRL_SET_INT:
- /* enable interrupt */
- uart->sci_regs->SCICTL2.bit.TXINTENA = 1;
- uart->sci_regs->SCICTL2.bit.RXBKINTENA = 1;
- break;
- }
- return RT_EOK;
- }
- static int c28x_putc(struct rt_serial_device *serial, char c)
- {
- SCI_write(0, &c, 1);
- return 1;
- }
- static int c28x_getc(struct rt_serial_device *serial)
- {
- char ch;
- if(SCI_read(0, &ch, 1))
- return ch;
- else
- return -1;
- }
- /**
- * Uart common interrupt process. This need add to uart ISR.
- *
- * @param serial serial device
- */
- static void uart_isr(struct rt_serial_device *serial) {
- struct c28x_uart *uart = (struct c28x_uart *) serial->parent.user_data;
- RT_ASSERT(uart != RT_NULL);
- rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
- SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1; // Clear Interrupt flag
- PieCtrlRegs.PIEACK.all |= 0x100; // Issue PIE ack
- }
- static const struct rt_uart_ops c28x_uart_ops =
- {
- .configure = c28x_configure,
- .control = c28x_control,
- .putc = c28x_putc,
- .getc = c28x_getc,
- };
- //
- // sciaRxFifoIsr - SCIA Receive FIFO ISR
- //
- interrupt void sciaRxFifoIsr(void)
- {
- /* enter interrupt */
- rt_interrupt_enter();
- uart_isr(&uart_obj[0].serial);
- /* leave interrupt */
- rt_interrupt_leave();
- }
- int rt_hw_sci_init(void)
- {
- EALLOW;
- GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 3;
- GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 3;
- GpioCtrlRegs.GPBGMUX1.bit.GPIO42 = 3;
- GpioCtrlRegs.GPBGMUX1.bit.GPIO43 = 3;
- GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 2;
- GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 2;
- GpioCtrlRegs.GPAGMUX2.bit.GPIO18 = 0;
- GpioCtrlRegs.GPAGMUX2.bit.GPIO19 = 0;
- GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 2;
- GpioCtrlRegs.GPEMUX1.bit.GPIO139 = 2;
- GpioCtrlRegs.GPBGMUX2.bit.GPIO56 = 1;
- GpioCtrlRegs.GPEGMUX1.bit.GPIO139 = 1;
- CpuSysRegs.PCLKCR7.bit.SCI_A = 1;
- CpuSysRegs.PCLKCR7.bit.SCI_B = 1;
- CpuSysRegs.PCLKCR7.bit.SCI_C = 1;
- PieVectTable.SCIA_RX_INT = &sciaRxFifoIsr;
- EDIS;
- //
- // Enable interrupts required for this example
- //
- PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
- PieCtrlRegs.PIEIER9.bit.INTx1 = 1; // PIE Group 9, INT1
- IER |= 0x100; // Enable CPU INT
- struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
- rt_err_t result = 0;
- uart_obj[0].serial.ops = &c28x_uart_ops;
- uart_obj[0].serial.config = config;
- uart_obj[0].name = "scia";
- uart_obj[0].sci_regs = &SciaRegs;
- uart_obj[1].serial.ops = &c28x_uart_ops;
- uart_obj[1].serial.config = config;
- uart_obj[1].name = "scib";
- uart_obj[1].sci_regs = &ScibRegs;
- uart_obj[2].serial.ops = &c28x_uart_ops;
- uart_obj[2].serial.config = config;
- uart_obj[2].name = "scic";
- uart_obj[2].sci_regs = &ScicRegs;
- /* register UART device */
- result = rt_hw_serial_register(&uart_obj[0].serial, uart_obj[0].name,
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
- &uart_obj[0]);
- /* register UART device */
- result = rt_hw_serial_register(&uart_obj[1].serial, uart_obj[1].name,
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
- &uart_obj[1]);
- /* register UART device */
- result = rt_hw_serial_register(&uart_obj[2].serial, uart_obj[2].name,
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
- &uart_obj[2]);
- return result;
- }
- #endif /* RT_USING_SERIAL */
|