Skip to content

Commit 64bd33e

Browse files
committed
cpu/rp2350_common: create shared folder for RISCV & ARM
1 parent 62815c1 commit 64bd33e

File tree

2 files changed

+89
-36
lines changed

2 files changed

+89
-36
lines changed

cpu/rp2350_common/include/uart_conf.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,27 @@
4444
/** UART transmit FIFO empty flag bit in flag register */
4545
#define UART_UARTFR_TXFE_BITS (1u << 7u)
4646

47+
/** UART data register break error mask */
48+
#define UART0_UARTDR_BE_Msk (0x400UL)
49+
50+
/** UART data register parity error mask */
51+
#define UART0_UARTDR_PE_Msk (0x200UL)
52+
53+
/** UART data register framing error mask */
54+
#define UART0_UARTDR_FE_Msk (0x100UL)
55+
56+
/** UART raw interrupt status transmit interrupt mask */
57+
#define UART0_UARTRIS_TXRIS_Msk (0x20UL)
58+
59+
/** UART line control register two stop bits mask */
60+
#define UART0_UARTLCR_H_STP2_Msk (0x8UL)
61+
62+
/** UART line control register even parity select mask */
63+
#define UART0_UARTLCR_H_EPS_Msk (0x4UL)
64+
65+
/** UART line control register parity enable mask */
66+
#define UART0_UARTLCR_H_PEN_Msk (0x2UL)
67+
4768
#ifdef __cplusplus
4869
extern "C" {
4970
#endif

cpu/rp2350_common/periph/uart.c

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -38,52 +38,75 @@ static uint32_t uartfbrd;
3838
static uint32_t uartlcr_h;
3939
static uint32_t uartcr;
4040

41-
/** Pico1 uart uses non-sdk conform defines
42-
* @todo Change Pico1 defines if I ever get around to it
43-
*/
44-
#define UART0_UARTIMSC_RXIM_Msk (UART_UARTIMSC_RXIM_BITS)
45-
46-
void _irq_enable(uart_t uart) {
41+
void _irq_enable(uart_t uart)
42+
{
4743
UART0_Type *dev = uart_config[uart].dev;
4844
/* We set the UART Receive Interrupt Mask (Bit 4) [See p979 UART 12.1]*/
49-
dev->UARTIMSC = UART0_UARTIMSC_RXIM_Msk;
45+
dev->UARTIMSC = UART_UARTIMSC_RXIM_BITS;
5046
/* Enable the IRQ */
5147
rp_irq_enable(uart_config[uart].irqn);
5248
}
5349

50+
void _set_symbolrate(uart_t uart, uint32_t baud)
51+
{
52+
assert(baud != 0);
53+
UART0_Type *dev = uart_config[uart].dev;
54+
uint32_t baud_rate_div = (8 * CPUFREQ / baud);
55+
uint32_t baud_ibrd = baud_rate_div >> 7;
56+
uint32_t baud_fbrd;
57+
58+
if (baud_ibrd == 0) {
59+
baud_ibrd = 1;
60+
baud_fbrd = 0;
61+
}
62+
else if (baud_ibrd >= 65535) {
63+
baud_ibrd = 65535;
64+
baud_fbrd = 0;
65+
}
66+
else {
67+
baud_fbrd = ((baud_rate_div & 0x7f) + 1) / 2;
68+
}
69+
70+
dev->UARTIBRD = baud_ibrd;
71+
dev->UARTFBRD = baud_fbrd;
72+
}
73+
5474
int uart_mode(uart_t uart, uart_data_bits_t data_bits, uart_parity_t parity,
5575
uart_stop_bits_t stop_bits) {
5676
assert((unsigned)uart < UART_NUMOF);
5777
UART0_Type *dev = uart_config[uart].dev;
5878

59-
(void)data_bits;
60-
(void)stop_bits;
61-
6279
/* Disable the UART before changing the mode */
6380
atomic_clear(&dev->UARTCR, UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS |
64-
UART_UARTCR_TXE_BITS);
65-
66-
/* Set the data bits, parity, and stop bits
67-
* Set to 8 bits (0b11) based on Table 1035 page 976
68-
* @todo allow different data bits
69-
*/
70-
dev->UARTLCR_H = 0b11 << 5;
81+
UART_UARTCR_TXE_BITS | 1 << 7);
82+
83+
/* Beware of strange hardware bug: If the configuration bitmask is prepared in register and
84+
* transferred with a single 32 bit write (updating both parity and number of data bits at the
85+
* same time), the configuration change of the parity bits will not take place until after the
86+
* next char send out. If the configuration is updated in multiple bus accesses, it will apply
87+
* directly to the next char. So: Double check e.g. with tests/periph/uart_mode after touching
88+
* the initialization code here
89+
* based on Table 1035 page 976 */
90+
dev->UARTLCR_H = (uint32_t)data_bits << 5;
91+
92+
if (stop_bits == UART_STOP_BITS_2) {
93+
atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_STP2_Msk);
94+
}
7195

7296
switch (parity) {
7397
case UART_PARITY_NONE:
7498
break;
75-
/* Currently we don't support parity settings yet
76-
* case UART_PARITY_EVEN:
77-
* io_reg_atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_EPS_Msk | UART0_UARTLCR_H_PEN_Msk);
78-
* break;
79-
* case UART_PARITY_ODD:
80-
* io_reg_atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_PEN_Msk);
81-
* break; */
99+
case UART_PARITY_EVEN:
100+
atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_EPS_Msk | UART0_UARTLCR_H_PEN_Msk);
101+
break;
102+
case UART_PARITY_ODD:
103+
atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_PEN_Msk);
104+
break;
82105
default:
83106
return UART_NOMODE;
84107
}
85108

86-
dev->UARTCR = UART_UARTCR_TXE_BITS | UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS;
109+
atomic_set(&dev->UARTCR, UART_UARTCR_TXE_BITS | UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS);
87110

88111
return UART_OK;
89112
}
@@ -105,6 +128,10 @@ static void _reset_uart(uart_t uart) {
105128

106129
void uart_init_pins(uart_t uart) {
107130
assert((unsigned)uart < UART_NUMOF);
131+
132+
/* We reset UART0 here, so we can be sure it is in a known state */
133+
_reset_uart(uart);
134+
108135
UART0_Type *dev = uart_config[uart].dev;
109136

110137
/* Set the UART pins to the correct function */
@@ -123,16 +150,12 @@ void uart_init_pins(uart_t uart) {
123150
calculate_gpio_pad_register_addr(uart_config[uart].rx_pin),
124151
PADS_BANK0_GPIO0_IE_BITS);
125152

126-
/* We reset UART0 here, so we can be sure it is in a known state */
127-
_reset_uart(uart);
128-
129153
dev->UARTIBRD = IBRD;
130154
dev->UARTFBRD = FBRD;
131155
}
132156

133-
int uart_init(uart_t uart, uint32_t baud, uart_rx_cb_t rx_cb, void *arg) {
134-
(void)baud;
135-
157+
int uart_init(uart_t uart, uint32_t baud, uart_rx_cb_t rx_cb, void *arg)
158+
{
136159
if (uart >= UART_NUMOF) {
137160
return UART_NODEV;
138161
}
@@ -143,6 +166,8 @@ int uart_init(uart_t uart, uint32_t baud, uart_rx_cb_t rx_cb, void *arg) {
143166

144167
uart_init_pins(uart);
145168

169+
_set_symbolrate(uart, baud);
170+
146171
if (uart_mode(
147172
uart,
148173
UART_DATA_BITS_8,
@@ -164,13 +189,15 @@ int uart_init(uart_t uart, uint32_t baud, uart_rx_cb_t rx_cb, void *arg) {
164189
return UART_OK;
165190
}
166191

167-
void uart_write(uart_t uart, const uint8_t *data, size_t len) {
192+
void uart_write(uart_t uart, const uint8_t *data, size_t len)
193+
{
194+
assert((unsigned)uart < UART_NUMOF);
168195
UART0_Type *dev = uart_config[uart].dev;
196+
169197
for (size_t i = 0; i < len; i++) {
170198
dev->UARTDR = data[i];
171199
/* Wait until the TX FIFO is empty before sending the next byte */
172-
while (!(dev->UARTFR & UART_UARTFR_TXFE_BITS)) {
173-
}
200+
while (!(dev->UARTRIS & UART0_UARTRIS_TXRIS_Msk)) { }
174201
}
175202
}
176203

@@ -218,11 +245,16 @@ void isr_handler(uint8_t num) {
218245
UART0_Type *dev = uart_config[num].dev;
219246

220247
uint32_t status = dev->UARTMIS;
221-
dev->UARTICR = status;
248+
atomic_set(&dev->UARTICR, status);
222249

223250
if (status & UART_UARTMIS_RXMIS_BITS) {
224251
uint32_t data = dev->UARTDR;
225-
ctx[num].rx_cb(ctx[num].arg, (uint8_t)data);
252+
if (data & (UART0_UARTDR_BE_Msk | UART0_UARTDR_PE_Msk | UART0_UARTDR_FE_Msk)) {
253+
puts("[rpx0xx] uart RX error (parity, break, or framing error");
254+
}
255+
else {
256+
ctx[num].rx_cb(ctx[num].arg, (uint8_t)data);
257+
}
226258
}
227259
}
228260

0 commit comments

Comments
 (0)