Skip to content

Commit aed0867

Browse files
Properly map IO and PAD register offsets for QSPI (#697)
* Properly map IO and PAD register offsets for QSPI In the UART bootloader example the QSPI pins are used for normal IO and a `qspi_gpio_set_function()` function is used locally to setup the pins. This function didn't take into account that the IO and PAD register banks for the QSPI IOs are not in the same order. We correct this by adding a lookup table to map between the two. * Use function defines from QSPI definitions * remove 'static' per PR discussion
1 parent d3c4bac commit aed0867

File tree

1 file changed

+26
-5
lines changed

1 file changed

+26
-5
lines changed

bootloaders/uart/uart_binary.c

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,37 @@ void pico_set_led(bool led_on) {
3131
#endif
3232
}
3333

34+
enum qspi_gpio {
35+
// arbitrarily choose PAD register bank to set the order
36+
QSPI_GPIO_SCLK = 0,
37+
QSPI_GPIO_SD0 = 1,
38+
QSPI_GPIO_SD1 = 2,
39+
QSPI_GPIO_SD2 = 3,
40+
QSPI_GPIO_SD3 = 4,
41+
QSPI_GPIO_SS = 5,
42+
};
43+
44+
// curiously the IO and PAD register banks for the QSPI GPIOs are not in the same order
45+
// This look up table will map the PAD offset to the IO offset for the same pin
46+
const uint QSPI_GPIO_PAD_TO_IO_OFFSET[] = {
47+
0, // SCLK
48+
2, // SD0
49+
3, // SD1
50+
4, // SD2
51+
5, // SD3
52+
1, // SS
53+
};
54+
3455
// Set function for QSPI GPIO pin
35-
void qspi_gpio_set_function(uint gpio, gpio_function_t fn) {
56+
void qspi_gpio_set_function(enum qspi_gpio gpio, gpio_function_t fn) {
3657
// Set input enable on, output disable off
3758
hw_write_masked(&pads_qspi_hw->io[gpio],
3859
PADS_QSPI_GPIO_QSPI_SD2_IE_BITS,
3960
PADS_QSPI_GPIO_QSPI_SD2_IE_BITS | PADS_QSPI_GPIO_QSPI_SD2_OD_BITS
4061
);
4162
// Zero all fields apart from fsel; we want this IO to do what the peripheral tells it.
4263
// This doesn't affect e.g. pullup/pulldown, as these are in pad controls.
43-
io_qspi_hw->io[gpio].ctrl = fn << IO_QSPI_GPIO_QSPI_SD2_CTRL_FUNCSEL_LSB;
64+
io_qspi_hw->io[QSPI_GPIO_PAD_TO_IO_OFFSET[gpio]].ctrl = fn << IO_QSPI_GPIO_QSPI_SD2_CTRL_FUNCSEL_LSB;
4465

4566
// Remove pad isolation now that the correct peripheral is in control of the pad
4667
hw_clear_bits(&pads_qspi_hw->io[gpio], PADS_QSPI_GPIO_QSPI_SD2_ISO_BITS);
@@ -49,9 +70,9 @@ void qspi_gpio_set_function(uint gpio, gpio_function_t fn) {
4970
int main() {
5071
pico_led_init();
5172

52-
// SD2 is QSPI GPIO 3, SD3 is QSPI GPIO 4
53-
qspi_gpio_set_function(3, GPIO_FUNC_UART_AUX);
54-
qspi_gpio_set_function(4, GPIO_FUNC_UART_AUX);
73+
// SD2 is UART0 TX, SD3 is UART0 RX (same as the ROM UART bootloader)
74+
qspi_gpio_set_function(QSPI_GPIO_SD2, GPIO_FUNC1_UART_AUX);
75+
qspi_gpio_set_function(QSPI_GPIO_SD3, GPIO_FUNC1_UART_AUX);
5576

5677
uart_init(uart0, 1000000);
5778

0 commit comments

Comments
 (0)