diff options
Diffstat (limited to 'libcpu/arm/AT91SAM7S/serial.c')
| -rw-r--r-- | libcpu/arm/AT91SAM7S/serial.c | 512 |
1 files changed, 256 insertions, 256 deletions
diff --git a/libcpu/arm/AT91SAM7S/serial.c b/libcpu/arm/AT91SAM7S/serial.c index adbe8609d6..583443f4cb 100644 --- a/libcpu/arm/AT91SAM7S/serial.c +++ b/libcpu/arm/AT91SAM7S/serial.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -22,46 +22,46 @@ typedef volatile rt_uint32_t REG32; struct rt_at91serial_hw { - REG32 US_CR; // Control Register - REG32 US_MR; // Mode Register - REG32 US_IER; // Interrupt Enable Register - REG32 US_IDR; // Interrupt Disable Register - REG32 US_IMR; // Interrupt Mask Register - REG32 US_CSR; // Channel Status Register - REG32 US_RHR; // Receiver Holding Register - REG32 US_THR; // Transmitter Holding Register - REG32 US_BRGR; // Baud Rate Generator Register - REG32 US_RTOR; // Receiver Time-out Register - REG32 US_TTGR; // Transmitter Time-guard Register - REG32 Reserved0[5]; // - REG32 US_FIDI; // FI_DI_Ratio Register - REG32 US_NER; // Nb Errors Register - REG32 Reserved1[1]; // - REG32 US_IF; // IRDA_FILTER Register - REG32 Reserved2[44]; // - REG32 US_RPR; // Receive Pointer Register - REG32 US_RCR; // Receive Counter Register - REG32 US_TPR; // Transmit Pointer Register - REG32 US_TCR; // Transmit Counter Register - REG32 US_RNPR; // Receive Next Pointer Register - REG32 US_RNCR; // Receive Next Counter Register - REG32 US_TNPR; // Transmit Next Pointer Register - REG32 US_TNCR; // Transmit Next Counter Register - REG32 US_PTCR; // PDC Transfer Control Register - REG32 US_PTSR; // PDC Transfer Status Register + REG32 US_CR; // Control Register + REG32 US_MR; // Mode Register + REG32 US_IER; // Interrupt Enable Register + REG32 US_IDR; // Interrupt Disable Register + REG32 US_IMR; // Interrupt Mask Register + REG32 US_CSR; // Channel Status Register + REG32 US_RHR; // Receiver Holding Register + REG32 US_THR; // Transmitter Holding Register + REG32 US_BRGR; // Baud Rate Generator Register + REG32 US_RTOR; // Receiver Time-out Register + REG32 US_TTGR; // Transmitter Time-guard Register + REG32 Reserved0[5]; // + REG32 US_FIDI; // FI_DI_Ratio Register + REG32 US_NER; // Nb Errors Register + REG32 Reserved1[1]; // + REG32 US_IF; // IRDA_FILTER Register + REG32 Reserved2[44]; // + REG32 US_RPR; // Receive Pointer Register + REG32 US_RCR; // Receive Counter Register + REG32 US_TPR; // Transmit Pointer Register + REG32 US_TCR; // Transmit Counter Register + REG32 US_RNPR; // Receive Next Pointer Register + REG32 US_RNCR; // Receive Next Counter Register + REG32 US_TNPR; // Transmit Next Pointer Register + REG32 US_TNCR; // Transmit Next Counter Register + REG32 US_PTCR; // PDC Transfer Control Register + REG32 US_PTSR; // PDC Transfer Status Register }; struct rt_at91serial { - struct rt_device parent; + struct rt_device parent; - struct rt_at91serial_hw* hw_base; - rt_uint16_t peripheral_id; - rt_uint32_t baudrate; + struct rt_at91serial_hw* hw_base; + rt_uint16_t peripheral_id; + rt_uint32_t baudrate; - /* reception field */ - rt_uint16_t save_index, read_index; - rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE]; + /* reception field */ + rt_uint16_t save_index, read_index; + rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE]; }; #ifdef RT_USING_UART1 struct rt_at91serial serial1; @@ -72,312 +72,312 @@ struct rt_at91serial serial2; static void rt_hw_serial_isr(int irqno) { - rt_base_t level; - struct rt_device* device; - struct rt_at91serial* serial = RT_NULL; + rt_base_t level; + struct rt_device* device; + struct rt_at91serial* serial = RT_NULL; - if (irqno == AT91C_ID_US0) - { + if (irqno == AT91C_ID_US0) + { #ifdef RT_USING_UART1 - /* serial 1 */ - serial = &serial1; + /* serial 1 */ + serial = &serial1; #endif - } - else if (irqno == AT91C_ID_US1) - { + } + else if (irqno == AT91C_ID_US1) + { #ifdef RT_USING_UART2 - /* serial 2 */ - serial = &serial2; + /* serial 2 */ + serial = &serial2; #endif - } - RT_ASSERT(serial != RT_NULL); + } + RT_ASSERT(serial != RT_NULL); - /* get generic device object */ - device = (rt_device_t)serial; + /* get generic device object */ + device = (rt_device_t)serial; - /* disable interrupt */ - level = rt_hw_interrupt_disable(); + /* disable interrupt */ + level = rt_hw_interrupt_disable(); - /* get received character */ - serial->rx_buffer[serial->save_index] = serial->hw_base->US_RHR; + /* get received character */ + serial->rx_buffer[serial->save_index] = serial->hw_base->US_RHR; - /* move to next position */ - serial->save_index ++; - if (serial->save_index >= RT_UART_RX_BUFFER_SIZE) - serial->save_index = 0; + /* move to next position */ + serial->save_index ++; + if (serial->save_index >= RT_UART_RX_BUFFER_SIZE) + serial->save_index = 0; - /* if the next position is read index, discard this 'read char' */ - if (serial->save_index == serial->read_index) - { - serial->read_index ++; - if (serial->read_index >= RT_UART_RX_BUFFER_SIZE) - serial->read_index = 0; - } + /* if the next position is read index, discard this 'read char' */ + if (serial->save_index == serial->read_index) + { + serial->read_index ++; + if (serial->read_index >= RT_UART_RX_BUFFER_SIZE) + serial->read_index = 0; + } - /* enable interrupt */ - rt_hw_interrupt_enable(level); + /* enable interrupt */ + rt_hw_interrupt_enable(level); - /* indicate to upper layer application */ - if (device->rx_indicate != RT_NULL) - device->rx_indicate(device, 1); + /* indicate to upper layer application */ + if (device->rx_indicate != RT_NULL) + device->rx_indicate(device, 1); - /* ack interrupt */ - AT91C_AIC_EOICR = 1; + /* ack interrupt */ + AT91C_AIC_EOICR = 1; } static rt_err_t rt_serial_init (rt_device_t dev) { - rt_uint32_t bd; - struct rt_at91serial* serial = (struct rt_at91serial*) dev; + rt_uint32_t bd; + struct rt_at91serial* serial = (struct rt_at91serial*) dev; - RT_ASSERT(serial != RT_NULL); - /* must be US0 or US1 */ - RT_ASSERT(((serial->peripheral_id == AT91C_ID_US0) || - (serial->peripheral_id == AT91C_ID_US1))); + RT_ASSERT(serial != RT_NULL); + /* must be US0 or US1 */ + RT_ASSERT(((serial->peripheral_id == AT91C_ID_US0) || + (serial->peripheral_id == AT91C_ID_US1))); - /* Enable Clock for USART */ - AT91C_PMC_PCER = 1 << serial->peripheral_id; + /* Enable Clock for USART */ + AT91C_PMC_PCER = 1 << serial->peripheral_id; - /* Enable RxD0 and TxDO Pin */ - if (serial->peripheral_id == AT91C_ID_US0) - { - /* set pinmux */ - AT91C_PIO_PDR = (1 << 5) | (1 << 6); - } - else if (serial->peripheral_id == AT91C_ID_US1) - { - /* set pinmux */ - AT91C_PIO_PDR = (1 << 21) | (1 << 22); - } + /* Enable RxD0 and TxDO Pin */ + if (serial->peripheral_id == AT91C_ID_US0) + { + /* set pinmux */ + AT91C_PIO_PDR = (1 << 5) | (1 << 6); + } + else if (serial->peripheral_id == AT91C_ID_US1) + { + /* set pinmux */ + AT91C_PIO_PDR = (1 << 21) | (1 << 22); + } - serial->hw_base->US_CR = AT91C_US_RSTRX | /* Reset Receiver */ - AT91C_US_RSTTX | /* Reset Transmitter */ - AT91C_US_RXDIS | /* Receiver Disable */ - AT91C_US_TXDIS; /* Transmitter Disable */ + serial->hw_base->US_CR = AT91C_US_RSTRX | /* Reset Receiver */ + AT91C_US_RSTTX | /* Reset Transmitter */ + AT91C_US_RXDIS | /* Receiver Disable */ + AT91C_US_TXDIS; /* Transmitter Disable */ - serial->hw_base->US_MR = AT91C_US_USMODE_NORMAL | /* Normal Mode */ - AT91C_US_CLKS_CLOCK | /* Clock = MCK */ - AT91C_US_CHRL_8_BITS | /* 8-bit Data */ - AT91C_US_PAR_NONE | /* No Parity */ - AT91C_US_NBSTOP_1_BIT; /* 1 Stop Bit */ + serial->hw_base->US_MR = AT91C_US_USMODE_NORMAL | /* Normal Mode */ + AT91C_US_CLKS_CLOCK | /* Clock = MCK */ + AT91C_US_CHRL_8_BITS | /* 8-bit Data */ + AT91C_US_PAR_NONE | /* No Parity */ + AT91C_US_NBSTOP_1_BIT; /* 1 Stop Bit */ - /* set baud rate divisor */ - bd = ((MCK*10)/(serial->baudrate * 16)); - if ((bd % 10) >= 5) bd = (bd / 10) + 1; - else bd /= 10; + /* set baud rate divisor */ + bd = ((MCK*10)/(serial->baudrate * 16)); + if ((bd % 10) >= 5) bd = (bd / 10) + 1; + else bd /= 10; - serial->hw_base->US_BRGR = bd; - serial->hw_base->US_CR = AT91C_US_RXEN | /* Receiver Enable */ - AT91C_US_TXEN; /* Transmitter Enable */ + serial->hw_base->US_BRGR = bd; + serial->hw_base->US_CR = AT91C_US_RXEN | /* Receiver Enable */ + AT91C_US_TXEN; /* Transmitter Enable */ - /* reset rx index */ - serial->save_index = 0; - serial->read_index = 0; + /* reset rx index */ + serial->save_index = 0; + serial->read_index = 0; - /* reset rx buffer */ - rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE); + /* reset rx buffer */ + rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE); - return RT_EOK; + return RT_EOK; } static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag) { - struct rt_at91serial *serial = (struct rt_at91serial*)dev; - RT_ASSERT(serial != RT_NULL); + struct rt_at91serial *serial = (struct rt_at91serial*)dev; + RT_ASSERT(serial != RT_NULL); - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - /* enable UART rx interrupt */ - serial->hw_base->US_IER = 1 << 0; /* RxReady interrupt */ - serial->hw_base->US_IMR |= 1 << 0; /* umask RxReady interrupt */ + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + /* enable UART rx interrupt */ + serial->hw_base->US_IER = 1 << 0; /* RxReady interrupt */ + serial->hw_base->US_IMR |= 1 << 0; /* umask RxReady interrupt */ - /* install UART handler */ - rt_hw_interrupt_install(serial->peripheral_id, rt_hw_serial_isr, RT_NULL); - AT91C_AIC_SMR(serial->peripheral_id) = 5 | (0x01 << 5); - rt_hw_interrupt_umask(serial->peripheral_id); - } + /* install UART handler */ + rt_hw_interrupt_install(serial->peripheral_id, rt_hw_serial_isr, RT_NULL); + AT91C_AIC_SMR(serial->peripheral_id) = 5 | (0x01 << 5); + rt_hw_interrupt_umask(serial->peripheral_id); + } - return RT_EOK; + return RT_EOK; } static rt_err_t rt_serial_close(rt_device_t dev) { - struct rt_at91serial *serial = (struct rt_at91serial*)dev; - RT_ASSERT(serial != RT_NULL); + struct rt_at91serial *serial = (struct rt_at91serial*)dev; + RT_ASSERT(serial != RT_NULL); - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - /* disable interrupt */ - serial->hw_base->US_IDR = 1 << 0; /* RxReady interrupt */ - serial->hw_base->US_IMR &= ~(1 << 0); /* mask RxReady interrupt */ - } + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + /* disable interrupt */ + serial->hw_base->US_IDR = 1 << 0; /* RxReady interrupt */ + serial->hw_base->US_IMR &= ~(1 << 0); /* mask RxReady interrupt */ + } - return RT_EOK; + return RT_EOK; } static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) { - rt_uint8_t* ptr; - struct rt_at91serial *serial = (struct rt_at91serial*)dev; - RT_ASSERT(serial != RT_NULL); + rt_uint8_t* ptr; + struct rt_at91serial *serial = (struct rt_at91serial*)dev; + RT_ASSERT(serial != RT_NULL); - /* point to buffer */ - ptr = (rt_uint8_t*) buffer; + /* point to buffer */ + ptr = (rt_uint8_t*) buffer; - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - while (size) - { - /* interrupt receive */ - rt_base_t level; + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + while (size) + { + /* interrupt receive */ + rt_base_t level; - /* disable interrupt */ - level = rt_hw_interrupt_disable(); - if (serial->read_index != serial->save_index) - { - *ptr = serial->rx_buffer[serial->read_index]; + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + if (serial->read_index != serial->save_index) + { + *ptr = serial->rx_buffer[serial->read_index]; - serial->read_index ++; - if (serial->read_index >= RT_UART_RX_BUFFER_SIZE) - serial->read_index = 0; - } - else - { - /* no data in rx buffer */ + serial->read_index ++; + if (serial->read_index >= RT_UART_RX_BUFFER_SIZE) + serial->read_index = 0; + } + else + { + /* no data in rx buffer */ - /* enable interrupt */ - rt_hw_interrupt_enable(level); - break; - } + /* enable interrupt */ + rt_hw_interrupt_enable(level); + break; + } - /* enable interrupt */ - rt_hw_interrupt_enable(level); + /* enable interrupt */ + rt_hw_interrupt_enable(level); - ptr ++; size --; - } + ptr ++; size --; + } - return (rt_uint32_t)ptr - (rt_uint32_t)buffer; - } - else if (dev->flag & RT_DEVICE_FLAG_DMA_RX) - { - /* not support right now */ - RT_ASSERT(0); - } - else - { - /* poll mode */ - while (size) - { - /* Wait for Full Rx Buffer */ - while (!(serial->hw_base->US_CSR & AT91C_US_RXRDY)); + return (rt_uint32_t)ptr - (rt_uint32_t)buffer; + } + else if (dev->flag & RT_DEVICE_FLAG_DMA_RX) + { + /* not support right now */ + RT_ASSERT(0); + } + else + { + /* poll mode */ + while (size) + { + /* Wait for Full Rx Buffer */ + while (!(serial->hw_base->US_CSR & AT91C_US_RXRDY)); - /* Read Character */ - *ptr = serial->hw_base->US_RHR; - ptr ++; - size --; - } + /* Read Character */ + *ptr = serial->hw_base->US_RHR; + ptr ++; + size --; + } - return (rt_size_t)ptr - (rt_size_t)buffer; - } + return (rt_size_t)ptr - (rt_size_t)buffer; + } - return 0; + return 0; } static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) { - rt_uint8_t* ptr; - struct rt_at91serial *serial = (struct rt_at91serial*)dev; - RT_ASSERT(serial != RT_NULL); + rt_uint8_t* ptr; + struct rt_at91serial *serial = (struct rt_at91serial*)dev; + RT_ASSERT(serial != RT_NULL); - ptr = (rt_uint8_t*) buffer; - if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY) - { - if (dev->flag & RT_DEVICE_FLAG_STREAM) - { - /* it's a stream mode device */ - while (size) - { - /* stream mode */ - if (*ptr == '\n') - { - while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY)); - serial->hw_base->US_THR = '\r'; - } + ptr = (rt_uint8_t*) buffer; + if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY) + { + if (dev->flag & RT_DEVICE_FLAG_STREAM) + { + /* it's a stream mode device */ + while (size) + { + /* stream mode */ + if (*ptr == '\n') + { + while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY)); + serial->hw_base->US_THR = '\r'; + } - /* Wait for Empty Tx Buffer */ - while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY)); + /* Wait for Empty Tx Buffer */ + while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY)); - /* Transmit Character */ - serial->hw_base->US_THR = *ptr; - ptr ++; size --; - } - } - else - { - while (size) - { - /* Wait for Empty Tx Buffer */ - while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY)); + /* Transmit Character */ + serial->hw_base->US_THR = *ptr; + ptr ++; size --; + } + } + else + { + while (size) + { + /* Wait for Empty Tx Buffer */ + while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY)); - /* Transmit Character */ - serial->hw_base->US_THR = *ptr; - ptr ++; size --; - } - } - } + /* Transmit Character */ + serial->hw_base->US_THR = *ptr; + ptr ++; size --; + } + } + } - return (rt_size_t)ptr - (rt_size_t)buffer; + return (rt_size_t)ptr - (rt_size_t)buffer; } static rt_err_t rt_serial_control (rt_device_t dev, int cmd, void *args) { - return RT_EOK; + return RT_EOK; } rt_err_t rt_hw_serial_init() { - rt_device_t device; + rt_device_t device; #ifdef RT_USING_UART1 - device = (rt_device_t) &serial1; + device = (rt_device_t) &serial1; - /* init serial device private data */ - serial1.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US0; - serial1.peripheral_id = AT91C_ID_US0; - serial1.baudrate = 115200; + /* init serial device private data */ + serial1.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US0; + serial1.peripheral_id = AT91C_ID_US0; + serial1.baudrate = 115200; - /* set device virtual interface */ - device->init = rt_serial_init; - device->open = rt_serial_open; - device->close = rt_serial_close; - device->read = rt_serial_read; - device->write = rt_serial_write; - device->control = rt_serial_control; + /* set device virtual interface */ + device->init = rt_serial_init; + device->open = rt_serial_open; + device->close = rt_serial_close; + device->read = rt_serial_read; + device->write = rt_serial_write; + device->control = rt_serial_control; - /* register uart1 on device subsystem */ - rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX); + /* register uart1 on device subsystem */ + rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX); #endif #ifdef RT_USING_UART2 - device = (rt_device_t) &serial2; + device = (rt_device_t) &serial2; - serial2.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US1; - serial2.peripheral_id = AT91C_ID_US1; - serial2.baudrate = 115200; + serial2.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US1; + serial2.peripheral_id = AT91C_ID_US1; + serial2.baudrate = 115200; - /* set device virtual interface */ - device->init = rt_serial_init; - device->open = rt_serial_open; - device->close = rt_serial_close; - device->read = rt_serial_read; - device->write = rt_serial_write; - device->control = rt_serial_control; + /* set device virtual interface */ + device->init = rt_serial_init; + device->open = rt_serial_open; + device->close = rt_serial_close; + device->read = rt_serial_read; + device->write = rt_serial_write; + device->control = rt_serial_control; - /* register uart2 on device subsystem */ - rt_device_register(device, "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX); + /* register uart2 on device subsystem */ + rt_device_register(device, "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX); #endif - return RT_EOK; + return RT_EOK; } /*@}*/ |
