Skip to content

Commit c5dd279

Browse files
committed
cpu/rp2350: move to new uart
1 parent 9a1fce2 commit c5dd279

File tree

4 files changed

+182
-107
lines changed

4 files changed

+182
-107
lines changed

cpu/riscv_common/irq_arch.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include "sched.h"
3131
#include "plic.h"
3232
#include "clic.h"
33-
#include "xh3irq.h"
3433
#include "architecture.h"
3534

3635
#if MODULE_PERIPH_XH3IRQ || DOXYGEN

cpu/rp2350_riscv/cpu.c

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
#include "periph/uart.h"
2424
#include "periph_conf.h"
2525

26-
#include "stdio_uart.h"
27-
#include <stdio.h>
2826
#include <sys/unistd.h>
2927

3028
void gpio_reset(void)
@@ -38,12 +36,6 @@ void gpio_reset(void)
3836
*/
3937
void cpu_init(void)
4038
{
41-
riscv_init();
42-
43-
uint32_t ra_register = 0;
44-
45-
__asm__ volatile ("mv %0, ra" : "=r"(ra_register));
46-
4739
/* Reset GPIO state */
4840
gpio_reset();
4941

@@ -53,18 +45,15 @@ void cpu_init(void)
5345
/* initialize the CPU clock */
5446
cpu_clock_init();
5547

48+
/* initialize the RISC-V core */
49+
riscv_init();
50+
5651
/* initialize the early peripherals */
5752
early_init();
5853

5954
/* trigger static peripheral initialization */
6055
periph_init();
6156

57+
/* initialize the board */
6258
board_init();
63-
64-
xosc_sleep(1000);
65-
printf("Enabling IRQ 50\n");
66-
67-
printf("ra register at start of cpu_init: 0x%lx\n", ra_register);
68-
69-
__asm__ volatile ("nop");
7059
}

cpu/rp2350_riscv/include/cpu_conf.h

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -24,64 +24,6 @@ extern "C" {
2424
#define CPU_DEFAULT_IRQ_PRIO 1u
2525
#define CPU_IRQ_NUMOF 52u
2626

27-
/**
28-
* @brief Interrupt numbers for RP2350 RISC-V
29-
*/
30-
typedef enum {
31-
TIMER0_IRQ_0_IRQn = 0, /**< Timer 0 interrupt 0 */
32-
TIMER0_IRQ_1_IRQn = 1, /**< Timer 0 interrupt 1 */
33-
TIMER0_IRQ_2_IRQn = 2, /**< Timer 0 interrupt 2 */
34-
TIMER0_IRQ_3_IRQn = 3, /**< Timer 0 interrupt 3 */
35-
TIMER1_IRQ_0_IRQn = 4, /**< Timer 1 interrupt 0 */
36-
TIMER1_IRQ_1_IRQn = 5, /**< Timer 1 interrupt 1 */
37-
TIMER1_IRQ_2_IRQn = 6, /**< Timer 1 interrupt 2 */
38-
TIMER1_IRQ_3_IRQn = 7, /**< Timer 1 interrupt 3 */
39-
PWM_IRQ_WRAP_0_IRQn = 8, /**< PWM wrap interrupt 0 */
40-
PWM_IRQ_WRAP_1_IRQn = 9, /**< PWM wrap interrupt 1 */
41-
DMA_IRQ_0_IRQn = 10, /**< DMA interrupt 0 */
42-
DMA_IRQ_1_IRQn = 11, /**< DMA interrupt 1 */
43-
DMA_IRQ_2_IRQn = 12, /**< DMA interrupt 2 */
44-
DMA_IRQ_3_IRQn = 13, /**< DMA interrupt 3 */
45-
USBCTRL_IRQ_IRQn = 14, /**< USB controller interrupt */
46-
PIO0_IRQ_0_IRQn = 15, /**< PIO 0 interrupt 0 */
47-
PIO0_IRQ_1_IRQn = 16, /**< PIO 0 interrupt 1 */
48-
PIO1_IRQ_0_IRQn = 17, /**< PIO 1 interrupt 0 */
49-
PIO1_IRQ_1_IRQn = 18, /**< PIO 1 interrupt 1 */
50-
PIO2_IRQ_0_IRQn = 19, /**< PIO 2 interrupt 0 */
51-
PIO2_IRQ_1_IRQn = 20, /**< PIO 2 interrupt 1 */
52-
IO_IRQ_BANK0_IRQn = 21, /**< IO bank 0 interrupt */
53-
IO_IRQ_BANK0_NS_IRQn = 22, /**< IO bank 0 non-secure interrupt */
54-
IO_IRQ_QSPI_IRQn = 23, /**< IO QSPI interrupt */
55-
IO_IRQ_QSPI_NS_IRQn = 24, /**< IO QSPI non-secure interrupt */
56-
SIO_IRQ_FIFO_IRQn = 25, /**< SIO FIFO interrupt */
57-
SIO_IRQ_BELL_IRQn = 26, /**< SIO bell interrupt */
58-
SIO_IRQ_FIFO_NS_IRQn = 27, /**< SIO FIFO non-secure interrupt */
59-
SIO_IRQ_BELL_NS_IRQn = 28, /**< SIO bell non-secure interrupt */
60-
SIO_IRQ_MTIMECMP_IRQn = 29, /**< SIO MTIMECMP interrupt */
61-
CLOCKS_IRQ_IRQn = 30, /**< Clocks interrupt */
62-
SPI0_IRQ_IRQn = 31, /**< SPI 0 interrupt */
63-
SPI1_IRQ_IRQn = 32, /**< SPI 1 interrupt */
64-
UART0_IRQ_IRQn = 33, /**< UART 0 interrupt */
65-
UART1_IRQ_IRQn = 34, /**< UART 1 interrupt */
66-
ADC_IRQ_FIFO_IRQn = 35, /**< ADC FIFO interrupt */
67-
I2C0_IRQ_IRQn = 36, /**< I2C 0 interrupt */
68-
I2C1_IRQ_IRQn = 37, /**< I2C 1 interrupt */
69-
OTP_IRQ_IRQn = 38, /**< OTP interrupt */
70-
TRNG_IRQ_IRQn = 39, /**< TRNG interrupt */
71-
PROC0_IRQ_CTI_IRQn = 40, /**< Processor 0 CTI interrupt */
72-
PROC1_IRQ_CTI_IRQn = 41, /**< Processor 1 CTI interrupt */
73-
PLL_SYS_IRQ_IRQn = 42, /**< PLL SYS interrupt */
74-
PLL_USB_IRQ_IRQn = 43, /**< PLL USB interrupt */
75-
POWMAN_IRQ_POW_IRQn = 44, /**< Power manager power interrupt */
76-
POWMAN_IRQ_TIMER_IRQn = 45, /**< Power manager timer interrupt */
77-
SPAREIRQ_IRQ_0_IRQn = 46, /**< Spare interrupt 0 */
78-
SPAREIRQ_IRQ_1_IRQn = 47, /**< Spare interrupt 1 */
79-
SPAREIRQ_IRQ_2_IRQn = 48, /**< Spare interrupt 2 */
80-
SPAREIRQ_IRQ_3_IRQn = 49, /**< Spare interrupt 3 */
81-
SPAREIRQ_IRQ_4_IRQn = 50, /**< Spare interrupt 4 */
82-
SPAREIRQ_IRQ_5_IRQn = 51 /**< Spare interrupt 5 */
83-
} IRQn_Type;
84-
8527
#ifdef __cplusplus
8628
}
8729
#endif

cpu/rp2350_riscv/periph/uart.c

Lines changed: 178 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66

77
/**
8-
* @ingroup cpu_rp2350_riscv
8+
* @ingroup cpu_rp2350
99
* @{
1010
*
1111
* @file
@@ -18,69 +18,214 @@
1818

1919
#include "periph_cpu.h"
2020

21-
int uart_init(uart_t uart, uint32_t baud, uart_rx_cb_t rx_cb, void *arg) {
22-
(void)uart;
23-
(void)baud;
24-
(void)rx_cb;
25-
(void)arg;
26-
/* Set the UART pins to the correct function */
27-
IO_BANK0->GPIO0_CTRL = FUNCTION_SELECT_UART;
28-
IO_BANK0->GPIO1_CTRL = FUNCTION_SELECT_UART;
29-
/* Clear the ISO bits */
30-
atomic_clear(&PADS_BANK0->GPIO0, PADS_BANK0_ISO_BITS);
31-
atomic_clear(&PADS_BANK0->GPIO1, PADS_BANK0_ISO_BITS);
32-
/* Set IE bit for gpio1 */
33-
PADS_BANK0->GPIO1 = PADS_BANK0->GPIO1 | PADS_BANK0_GPIO0_IE_BITS;
21+
#include "regs/uart.h"
22+
#include <RP2350.h>
3423

35-
/* We reset UART0 here, so we can be sure it is in a known state */
36-
reset_component(RESET_UART0, RESET_UART0);
24+
#define ENABLE_DEBUG 0
25+
#include "debug.h"
26+
27+
#include "xh3irq.h"
28+
29+
#include "board.h"
30+
31+
static uart_isr_ctx_t ctx[UART_NUMOF];
3732

38-
UART0->UARTIBRD = IBRD;
39-
UART0->UARTFBRD = FBRD;
40-
uart_mode(0, 8, UART_PARITY_NONE, 1);
41-
return 0;
33+
/* back up values of registers used during uart_poweroff() / uart_poweron() */
34+
static uint32_t uartibrd;
35+
static uint32_t uartfbrd;
36+
static uint32_t uartlcr_h;
37+
static uint32_t uartcr;
38+
39+
/** Pico1 uart uses non-sdk conform defines
40+
* @todo Change Pico1 defines if I ever get around to it
41+
*/
42+
#define UART0_UARTIMSC_RXIM_Msk (UART_UARTIMSC_RXIM_BITS)
43+
44+
void _irq_enable(uart_t uart) {
45+
UART0_Type *dev = uart_config[uart].dev;
46+
/* We set the UART Receive Interrupt Mask (Bit 4) [See p979 UART 12.1]*/
47+
dev->UARTIMSC = UART0_UARTIMSC_RXIM_Msk;
48+
/* Enable the IRQ in the NVIC */
49+
xh3irq_enable_irq(uart_config[uart].irqn);
4250
}
4351

4452
int uart_mode(uart_t uart, uart_data_bits_t data_bits, uart_parity_t parity,
45-
uart_stop_bits_t stop_bits) {
46-
(void)uart;
53+
uart_stop_bits_t stop_bits) {
54+
assert((unsigned)uart < UART_NUMOF);
55+
UART0_Type *dev = uart_config[uart].dev;
56+
4757
(void)data_bits;
4858
(void)stop_bits;
49-
atomic_clear(&UART0->UARTCR, UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS |
50-
UART_UARTCR_TXE_BITS);
59+
60+
/* Disable the UART before changing the mode */
61+
atomic_clear(&dev->UARTCR, UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS |
62+
UART_UARTCR_TXE_BITS);
5163

5264
/* Set the data bits, parity, and stop bits
5365
* Set to 8 bits (0b11) based on Table 1035 page 976
66+
* @todo allow different data bits
5467
*/
55-
UART0->UARTLCR_H = 0b11 << 5;
68+
dev->UARTLCR_H = 0b11 << 5;
5669

5770
switch (parity) {
58-
case UART_PARITY_NONE:
71+
case UART_PARITY_NONE:
5972
break;
60-
default:
73+
// case UART_PARITY_EVEN:
74+
// io_reg_atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_EPS_Msk | UART0_UARTLCR_H_PEN_Msk);
75+
// break;
76+
// case UART_PARITY_ODD:
77+
// io_reg_atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_PEN_Msk);
78+
// break;
79+
default:
6180
return UART_NOMODE;
6281
}
6382

64-
UART0->UARTCR = UART_UARTCR_TXE_BITS | UART_UARTCR_UARTEN_BITS;
83+
dev->UARTCR = UART_UARTCR_TXE_BITS | UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS;
84+
85+
return UART_OK;
86+
}
87+
88+
static void _reset_uart(uart_t uart) {
89+
switch (uart) {
90+
case 0:
91+
/* We reset UART0 here, so we can be sure it is in a known state */
92+
reset_component(RESET_UART0, RESET_UART0);
93+
break;
94+
case 1:
95+
/* We reset UART1 here, so we can be sure it is in a known state */
96+
reset_component(RESET_UART1, RESET_UART1);
97+
break;
98+
default:
99+
break;
100+
}
101+
}
102+
103+
void uart_init_pins(uart_t uart) {
104+
assert((unsigned)uart < UART_NUMOF);
105+
UART0_Type *dev = uart_config[uart].dev;
106+
107+
/* Set the UART pins to the correct function */
108+
*(uint32_t *)calculate_gpio_io_ctrl_register_addr(uart_config[uart].tx_pin) = FUNCTION_SELECT_UART;
109+
*(uint32_t *)calculate_gpio_io_ctrl_register_addr(uart_config[uart].rx_pin) = FUNCTION_SELECT_UART;
110+
/* Clear the ISO bits */
111+
atomic_clear((uint32_t *)calculate_gpio_pad_register_addr(uart_config[uart].tx_pin), PADS_BANK0_ISO_BITS);
112+
atomic_clear((uint32_t *)calculate_gpio_pad_register_addr(uart_config[uart].rx_pin), PADS_BANK0_ISO_BITS);
113+
114+
/* Set Input Enable Flag */
115+
atomic_set((uint32_t *)calculate_gpio_pad_register_addr(uart_config[uart].rx_pin), PADS_BANK0_GPIO0_IE_BITS);
116+
117+
/* We reset UART0 here, so we can be sure it is in a known state */
118+
_reset_uart(uart);
119+
120+
dev->UARTIBRD = IBRD;
121+
dev->UARTFBRD = FBRD;
122+
}
123+
124+
int uart_init(uart_t uart, uint32_t baud, uart_rx_cb_t rx_cb, void *arg) {
125+
(void)baud;
126+
127+
if (uart >= UART_NUMOF) {
128+
return UART_NODEV;
129+
}
130+
131+
UART0_Type *dev = uart_config[uart].dev;
132+
ctx[uart].rx_cb = rx_cb;
133+
ctx[uart].arg = arg;
134+
135+
uart_init_pins(uart);
136+
137+
if (uart_mode(uart, UART_DATA_BITS_8, UART_PARITY_NONE, UART_STOP_BITS_1) != UART_OK) {
138+
return UART_NOMODE;
139+
}
140+
141+
/* enable RX and IRQs, if needed */
142+
if (rx_cb != NULL) {
143+
_irq_enable(uart);
144+
/* clear any pending data and IRQ to avoid receiving a garbage char */
145+
uint32_t status = dev->UARTRIS;
146+
dev->UARTICR = status;
147+
(void)dev->UARTDR;
148+
atomic_set(&dev->UARTCR, UART_UARTCR_RXE_BITS);
149+
}
65150

66151
return UART_OK;
67152
}
68153

69154
void uart_write(uart_t uart, const uint8_t *data, size_t len) {
70-
(void)uart;
155+
UART0_Type *dev = uart_config[uart].dev;
71156
for (size_t i = 0; i < len; i++) {
72-
UART0->UARTDR = data[i];
157+
dev->UARTDR = data[i];
73158
/* Wait until the TX FIFO is empty before sending the next byte */
74-
while (!(UART0->UARTFR & UART_UARTFR_TXFE_BITS)) {
159+
while (!(dev->UARTFR & UART_UARTFR_TXFE_BITS)) {
75160
}
76161
}
77162
}
78163

79164
void uart_poweron(uart_t uart) {
80-
(void)uart;
165+
assert((unsigned)uart < UART_NUMOF);
166+
/* Get into a save state where we know whats up */
167+
_reset_uart(uart);
168+
UART0_Type *dev = uart_config[uart].dev;
169+
/* Restore config from registers */
170+
dev->UARTIBRD = uartibrd;
171+
dev->UARTFBRD = uartfbrd;
172+
dev->UARTLCR_H = uartlcr_h;
173+
dev->UARTCR = uartcr;
174+
/* restore IRQs, if needed */
175+
if (ctx[uart].rx_cb != NULL) {
176+
_irq_enable(uart);
177+
}
178+
uart_init_pins(uart);
179+
}
180+
181+
void uart_deinit_pins(uart_t uart) {
182+
assert((unsigned)uart < UART_NUMOF);
183+
/* @TODO */
184+
/* gpio_reset_all_config(uart_config[uart].tx_pin); */
185+
SIO->GPIO_OE_CLR = 1LU << uart_config[uart].tx_pin;
186+
if (ctx[uart].rx_cb) {
187+
/* gpio_reset_all_config(uart_config[uart].rx_pin); */
188+
}
81189
}
190+
82191
void uart_poweroff(uart_t uart) {
83-
(void)uart;
192+
assert((unsigned)uart < UART_NUMOF);
193+
UART0_Type *dev = uart_config[uart].dev;
194+
/* backup configuration registers */
195+
uartibrd = dev->UARTIBRD;
196+
uartfbrd = dev->UARTFBRD;
197+
uartlcr_h = dev->UARTLCR_H;
198+
uartcr = dev->UARTCR;
199+
/* disconnect GPIOs and power off peripheral */
200+
uart_deinit_pins(uart);
201+
_reset_uart(uart);
202+
}
203+
204+
void isr_handler(uint8_t num) {
205+
UART0_Type *dev = uart_config[num].dev;
206+
207+
uint32_t status = dev->UARTMIS;
208+
dev->UARTICR = status;
209+
210+
if (status & UART_UARTMIS_RXMIS_BITS) {
211+
uint32_t data = dev->UARTDR;
212+
// if (data & (UART0_UARTDR_BE_Msk | UART0_UARTDR_PE_Msk | UART0_UARTDR_FE_Msk)) {
213+
// DEBUG_PUTS("[rpx0xx] uart RX error (parity, break, or framing error");
214+
// }
215+
// else {
216+
printf("UART%d received: %c\n", num, (char)(data & 0xFF));
217+
ctx[num].rx_cb(ctx[num].arg, (uint8_t)data);
218+
// }
219+
}
220+
}
221+
222+
/** Overwrites the WEAK_DEFAULT isr_uart0 */
223+
void isr_uart0(void) {
224+
isr_handler(0);
225+
}
226+
227+
void isr_uart1(void) {
228+
isr_handler(1);
84229
}
85230

86231
/** @} */

0 commit comments

Comments
 (0)