16#include "uart_rp2350.h"
17#include "system_rp2350.h"
21using namespace _UART0_;
22using namespace _UART1_;
23using namespace _IO_BANK0_;
24using namespace _RESETS_;
26function<void(
char)> uart_rp2350::_intHandler[2];
28int8_t uart_rp2350::_uart_tx_pins[2][6] =
29 { { 0, 12, 16, 28, 32, 44 }, { 4, 8, 20, 24, 36, 40 } };
31uart_rp2350::uart_rp2350(gpio_pin_t tx_pin, gpio_pin_t rx_pin,
32 uint32_t baud, uart_mode_t mode)
33: _init(false), _tx(tx_pin), _rx(rx_pin), _baud(baud), _mode(mode) {
35 bool tx_found =
false;
36 bool rx_found =
false;
37 for (_index=0; _index < 2; ++_index) {
40 for (
size_t i = 0; i < 6; ++i) {
41 if ( (tx_pin == _uart_tx_pins[_index][i]+0) ||
42 (tx_pin == (_uart_tx_pins[_index][i]+2)) ) {
45 if ( (rx_pin == _uart_tx_pins[_index][i]+1) ||
46 (rx_pin == (_uart_tx_pins[_index][i]+3)) ) {
50 if (tx_found && rx_found)
break;
52 assert(tx_found && rx_found);
55 _uart = (_index==0) ? &UART0 : &UART1;
56 _uart_set = (_index==0) ? &UART0_SET : &UART1_SET;
57 _uart_clr = (_index==0) ? &UART0_CLR : &UART1_CLR;
60void uart_rp2350::init() {
62 if (_index) RESETS_CLR.RESET.UART1 = 1;
63 else RESETS_CLR.RESET.UART0 = 1;
65 if ((_tx.getGpio() % 4) == 0) {
66 _tx.setSEL(GPIO_CTRL_FUNCSEL__uart);
68 _tx.setSEL(GPIO_CTRL_FUNCSEL__uart_aux);
70 if (((_rx.getGpio()-1) % 4) == 0) {
71 _rx.setSEL(GPIO_CTRL_FUNCSEL__uart);
73 _rx.setSEL(GPIO_CTRL_FUNCSEL__uart_aux);
80 _uart_set->UARTCR.UARTEN <<= 1;
81 _uart_set->UARTLCR_H.FEN <<= 1;
85uart_rp2350::~uart_rp2350() {
89 while( (_uart->UARTFR.TXFE) == 0) ;
91 if (_index) RESETS_SET.RESET.UART1 = 1;
92 else RESETS_SET.RESET.UART0 = 1;
94 _tx.setSEL( GPIO_CTRL_FUNCSEL__null );
95 _rx.setSEL( GPIO_CTRL_FUNCSEL__null );
98bool uart_rp2350::available() {
100 return !_uart->UARTFR.RXFE;
103char uart_rp2350::getc() {
106 while(_uart->UARTFR.RXFE) ;
108 return _uart->UARTDR.DATA;
111void uart_rp2350::putc(
char c) {
114 while(_uart->UARTFR.TXFF) ;
116 _uart->UARTDR.DATA = (uint16_t)c;
119int uart_rp2350::puts(
const char *s) {
128void uart_rp2350::uartMode(uart_mode_t mode) {
130 if (mode & UART::BITS_7) {
131 _uart->UARTLCR_H.WLEN = 2;
133 if (mode & UART::BITS_8) {
134 _uart->UARTLCR_H.WLEN = 3;
136 if (mode & UART::NO_PARITY) {
137 _uart->UARTLCR_H.PEN = 0;
139 if (mode & UART::EVEN_PARITY) {
140 _uart->UARTLCR_H.PEN = 1;
141 _uart->UARTLCR_H.EPS = 1;
143 if (mode & UART::ODD_PARITY) {
144 _uart->UARTLCR_H.PEN = 1;
145 _uart->UARTLCR_H.EPS = 0;
147 if (mode & UART::STOPBITS_1) {
148 _uart->UARTLCR_H.STP2 = 0;
150 if (mode & UART::STOPBITS_2) {
151 _uart->UARTLCR_H.STP2 = 1;
155void uart_rp2350::setBaudrate(uint32_t baud) {
157 uint32_t baud_div = (8 * CLK_PERI) / _baud;
158 _uart->UARTIBRD = (baud_div >> 7);
159 _uart->UARTFBRD = ((baud_div & 0x7f) + 1) / 2;
161 _uart_set->UARTLCR_H <<= 0;
164void uart_rp2350::sendBreak(uint16_t ms) {
166 _uart_clr->UARTLCR_H.BRK <<= 1;
167 }
else if (ms == 0xffff) {
168 _uart_set->UARTLCR_H.BRK <<= 1;
170 _uart_set->UARTLCR_H.BRK <<= 1;
172 _uart_clr->UARTLCR_H.BRK <<= 1;
176void uart_rp2350::setDTR(
bool dtr) {
177 _uart->UARTCR.DTR = dtr;
180void uart_rp2350::setRTS(
bool rts) {
181 _uart->UARTCR.RTS = rts;
184void uart_rp2350::uartAttachIrq(function<
void(
char)> f) {
186 _intHandler[_index] = f;
188 _uart_set->UARTIMSC.RXIM <<= 1;
189 _uart_set->UARTIMSC.RTIM <<= 1;
191 NVIC_EnableIRQ((IRQn_Type)(UART0_IRQ_IRQn + _index));
194void uart_rp2350::uartDetachIrq () {
197 NVIC_DisableIRQ((IRQn_Type)(UART0_IRQ_IRQn + _index));
199 _uart_clr->UARTIMSC.RXIM <<= 1;
200 _uart_clr->UARTIMSC.RTIM <<= 1;
202 _uart_set->UARTICR.RXIC <<= 1;
203 _uart_set->UARTICR.RTIC <<= 1;
205 _intHandler[_index] =
nullptr;
208void uart_rp2350::uartEnableIrq () {
209 _uart_set->UARTIMSC.RXIM <<= 1;
210 _uart_set->UARTIMSC.RTIM <<= 1;
213void uart_rp2350::uartDisableIrq() {
214 _uart_clr->UARTIMSC.RXIM <<= 1;
215 _uart_clr->UARTIMSC.RTIM <<= 1;
218void uart_rp2350::enableFIFO(
bool val) {
220 _uart->UARTLCR_H.FEN = val;
227void UART0_IRQ_Handler(
void) {
228 while(!UART0.UARTFR.RXFE) {
229 uart_rp2350::_intHandler[0](UART0.UARTDR.DATA);
233void UART1_IRQ_Handler(
void) {
234 while(!UART1.UARTFR.RXFE) {
235 uart_rp2350::_intHandler[1](UART1.UARTDR.DATA);