2323
2424// Constructors ////////////////////////////////////////////////////////////////
2525
26- USARTClass::USARTClass ( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer )
26+ USARTClass::USARTClass ( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer ) : UARTClass((Uart*)pUsart, dwIrq, dwId, pRx_buffer, pTx_buffer)
2727{
28- _rx_buffer = pRx_buffer;
29- _tx_buffer = pTx_buffer;
3028
31- _pUsart=pUsart ;
32- _dwIrq=dwIrq ;
33- _dwId=dwId ;
29+ _pUsart=pUsart ; // In case anyone needs USART specific functionality in the future
3430}
3531
3632// Public Methods //////////////////////////////////////////////////////////////
@@ -42,140 +38,26 @@ void USARTClass::begin( const uint32_t dwBaudRate )
4238
4339void USARTClass::begin ( const uint32_t dwBaudRate, const uint32_t config )
4440{
45- // Configure PMC
46- pmc_enable_periph_clk ( _dwId ) ;
47-
48- // Disable PDC channel
49- _pUsart->US_PTCR = US_PTCR_RXTDIS | US_PTCR_TXTDIS ;
50-
51- // Reset and disable receiver and transmitter
52- _pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RXDIS | US_CR_TXDIS ;
53-
54- // Configure mode
55- _pUsart->US_MR = config;
56-
57-
58- // Configure baudrate, asynchronous no oversampling
59- _pUsart->US_BRGR = (SystemCoreClock / dwBaudRate) / 16 ;
60-
61- // Configure interrupts
62- _pUsart->US_IDR = 0xFFFFFFFF ;
63- _pUsart->US_IER = US_IER_RXRDY | US_IER_OVRE | US_IER_FRAME;
64-
65- // Enable UART interrupt in NVIC
66- NVIC_EnableIRQ ( _dwIrq ) ;
67-
68- // make sure both ring buffers are initialized back to empty.
69- _rx_buffer->_iHead = _rx_buffer->_iTail = 0 ;
70- _tx_buffer->_iHead = _tx_buffer->_iTail = 0 ;
71-
72- // Enable receiver and transmitter
73- _pUsart->US_CR = US_CR_RXEN | US_CR_TXEN ;
41+ UARTClass::begin (dwBaudRate, config);
7442}
7543
7644void USARTClass::end ( void )
7745{
78- // clear any received data
79- _rx_buffer->_iHead = _rx_buffer->_iTail ;
80-
81- while (_tx_buffer->_iHead != _tx_buffer->_iTail ); // wait for transmit data to be sent
82-
83- // Disable UART interrupt in NVIC
84- NVIC_DisableIRQ ( _dwIrq ) ;
85-
86- // Wait for any outstanding data to be sent
87- flush ();
88-
89- pmc_disable_periph_clk ( _dwId ) ;
90- }
91-
92- int USARTClass::available ( void )
93- {
94- return (uint32_t )(SERIAL_BUFFER_SIZE + _rx_buffer->_iHead - _rx_buffer->_iTail ) % SERIAL_BUFFER_SIZE ;
95- }
96-
97- int USARTClass::availableForWrite (void )
98- {
99- int head = _tx_buffer->_iHead ;
100- int tail = _tx_buffer->_iTail ;
101- if (head >= tail) return SERIAL_BUFFER_SIZE - 1 - head + tail;
102- return tail - head - 1 ;
103- }
104-
105- int USARTClass::peek ( void )
106- {
107- if ( _rx_buffer->_iHead == _rx_buffer->_iTail )
108- return -1 ;
109-
110- return _rx_buffer->_aucBuffer [_rx_buffer->_iTail ] ;
111- }
112-
113- int USARTClass::read ( void )
114- {
115- // if the head isn't ahead of the tail, we don't have any characters
116- if ( _rx_buffer->_iHead == _rx_buffer->_iTail )
117- return -1 ;
118-
119- uint8_t uc = _rx_buffer->_aucBuffer [_rx_buffer->_iTail ] ;
120- _rx_buffer->_iTail = (unsigned int )(_rx_buffer->_iTail + 1 ) % SERIAL_BUFFER_SIZE ;
121- return uc ;
46+ UARTClass::end ();
12247}
12348
12449void USARTClass::flush ( void )
12550{
126- // Wait for transmission to complete
127- while ((_pUsart->US_CSR & US_CSR_TXRDY) != US_CSR_TXRDY)
128- ;
51+ UARTClass::flush ();
12952}
13053
13154size_t USARTClass::write ( const uint8_t uc_data )
13255{
133- if ((_pUsart->US_CSR & US_CSR_TXRDY) != US_CSR_TXRDY) // is the hardware currently busy?
134- {
135- // if busy we buffer
136- unsigned int l = (_tx_buffer->_iHead + 1 ) % SERIAL_BUFFER_SIZE;
137- while (_tx_buffer->_iTail == l); // spin locks if we're about to overwrite the buffer. This continues once the data is sent
138-
139- _tx_buffer->_aucBuffer [_tx_buffer->_iHead ] = uc_data;
140- _tx_buffer->_iHead = l;
141- _pUsart->US_IER = US_IER_TXRDY; // make sure TX interrupt is enabled
142- }
143- else
144- {
145- // Send character
146- _pUsart->US_THR = uc_data ;
147- }
148- return 1 ;
56+ return UARTClass::write (uc_data);
14957}
15058
15159void USARTClass::IrqHandler ( void )
15260{
153- uint32_t status = _pUsart->US_CSR ;
154-
155- // Did we receive data ?
156- if ((status & US_CSR_RXRDY) == US_CSR_RXRDY)
157- {
158- _rx_buffer->store_char (_pUsart->US_RHR );
159- }
160- // Do we need to keep sending data?
161- if ((status & US_CSR_TXRDY) == US_CSR_TXRDY)
162- {
163- if (_tx_buffer->_iTail != _tx_buffer->_iHead ) { // just in case
164- _pUsart->US_THR = _tx_buffer->_aucBuffer [_tx_buffer->_iTail ];
165- _tx_buffer->_iTail = (unsigned int )(_tx_buffer->_iTail + 1 ) % SERIAL_BUFFER_SIZE;
166- }
167- else
168- {
169- _pUsart->US_IDR = US_IDR_TXRDY; // mask off transmit interrupt so we don't get it anymore
170- }
171- }
172-
173- // Acknowledge errors
174- if ((status & US_CSR_OVRE) == US_CSR_OVRE ||
175- (status & US_CSR_FRAME) == US_CSR_FRAME)
176- {
177- // TODO: error reporting outside ISR
178- _pUsart->US_CR |= US_CR_RSTSTA;
179- }
61+ UARTClass::IrqHandler ();
18062}
18163
0 commit comments