mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
cpu/rpx0xx: add support for the RP2040 MCU
Co-authored-by: Fabian Hüßler <fabian.huessler@st.ovgu.de>
This commit is contained in:
parent
c52da5745f
commit
ea56dfc3ff
33
cpu/rpx0xx/Kconfig
Normal file
33
cpu/rpx0xx/Kconfig
Normal file
@ -0,0 +1,33 @@
|
||||
# Copyright (C) 2021 Otto-von-Guericke-Universität Magdeburg
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU Lesser
|
||||
# General Public License v2.1. See the file LICENSE in the top level
|
||||
# directory for more details.
|
||||
#
|
||||
|
||||
config CPU_FAM_RPX0XX
|
||||
bool
|
||||
select CPU_CORE_CORTEX_M0PLUS
|
||||
select HAS_CPU_RPX0XX
|
||||
select HAS_PERIPH_GPIO
|
||||
select HAS_PERIPH_GPIO_IRQ
|
||||
|
||||
config CPU_FAM
|
||||
default "RPX0XX" if CPU_FAM_RPX0XX
|
||||
|
||||
config CPU_MODEL_RP2040
|
||||
bool
|
||||
select CPU_FAM_RPX0XX
|
||||
|
||||
config CPU_MODEL
|
||||
default "RP2040" if CPU_MODEL_RP2040
|
||||
|
||||
config CPU
|
||||
default "rpx0xx" if CPU_FAM_RPX0XX
|
||||
|
||||
config HAS_CPU_RPX0XX
|
||||
bool
|
||||
help
|
||||
Indicates that a RPX0XX CPU (e.g. the RP2040) is used
|
||||
|
||||
source "$(RIOTCPU)/cortexm_common/Kconfig"
|
5
cpu/rpx0xx/Makefile
Normal file
5
cpu/rpx0xx/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
MODULE = cpu
|
||||
|
||||
DIRS = $(RIOTCPU)/cortexm_common periph
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
1
cpu/rpx0xx/Makefile.default
Normal file
1
cpu/rpx0xx/Makefile.default
Normal file
@ -0,0 +1 @@
|
||||
DEFAULT_MODULE += stdio_null
|
1
cpu/rpx0xx/Makefile.dep
Normal file
1
cpu/rpx0xx/Makefile.dep
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTCPU)/cortexm_common/Makefile.dep
|
7
cpu/rpx0xx/Makefile.features
Normal file
7
cpu/rpx0xx/Makefile.features
Normal file
@ -0,0 +1,7 @@
|
||||
CPU_CORE := cortex-m0plus
|
||||
CPU_FAM := RPX0XX
|
||||
|
||||
include $(RIOTCPU)/cortexm_common/Makefile.features
|
||||
|
||||
FEATURES_PROVIDED += periph_gpio
|
||||
FEATURES_PROVIDED += periph_gpio_irq
|
21
cpu/rpx0xx/Makefile.include
Normal file
21
cpu/rpx0xx/Makefile.include
Normal file
@ -0,0 +1,21 @@
|
||||
PICO_DEBUG ?=
|
||||
ROM_LEN ?= 2097152 # = 2 MiB used in the RPi Pico
|
||||
ROM_OFFSET := 256 # bootloader size
|
||||
RAM_LEN := 270336 # = 264 KiB
|
||||
ROM_START_ADDR := 0x10000000
|
||||
RAM_START_ADDR := 0x20000000
|
||||
|
||||
CFLAGS += -D$(CPU_MODEL)
|
||||
CFLAGS += -DROM_START_ADDR=$(ROM_START_ADDR)
|
||||
CFLAGS += -DRAM_START_ADDR=$(RAM_START_ADDR)
|
||||
|
||||
INCLUDES += -I$(RIOTCPU)/rpx0xx/include
|
||||
|
||||
VECTORS_O ?= $(BINDIR)/cpu/vectors.o
|
||||
VECTORS_FILE := $(RIOTCPU)/rpx0xx/vectors.c
|
||||
|
||||
PROGRAMMERS_SUPPORTED := uf2conv openocd jlink
|
||||
PROGRAMMER ?= openocd
|
||||
OPENOCD_DEBUG_ADAPTER ?= dap
|
||||
|
||||
include $(RIOTMAKE)/arch/cortexm.inc.mk
|
23
cpu/rpx0xx/boot2_w25q080_padded_checksummed.S
Normal file
23
cpu/rpx0xx/boot2_w25q080_padded_checksummed.S
Normal file
@ -0,0 +1,23 @@
|
||||
// Padded and checksummed version of: boot2_w25q080.bin
|
||||
|
||||
.cpu cortex-m0plus
|
||||
.thumb
|
||||
|
||||
.section .boot2, "ax"
|
||||
|
||||
.byte 0x00, 0xb5, 0x32, 0x4b, 0x21, 0x20, 0x58, 0x60, 0x98, 0x68, 0x02, 0x21, 0x88, 0x43, 0x98, 0x60
|
||||
.byte 0xd8, 0x60, 0x18, 0x61, 0x58, 0x61, 0x2e, 0x4b, 0x00, 0x21, 0x99, 0x60, 0x02, 0x21, 0x59, 0x61
|
||||
.byte 0x01, 0x21, 0xf0, 0x22, 0x99, 0x50, 0x2b, 0x49, 0x19, 0x60, 0x01, 0x21, 0x99, 0x60, 0x35, 0x20
|
||||
.byte 0x00, 0xf0, 0x44, 0xf8, 0x02, 0x22, 0x90, 0x42, 0x14, 0xd0, 0x06, 0x21, 0x19, 0x66, 0x00, 0xf0
|
||||
.byte 0x34, 0xf8, 0x19, 0x6e, 0x01, 0x21, 0x19, 0x66, 0x00, 0x20, 0x18, 0x66, 0x1a, 0x66, 0x00, 0xf0
|
||||
.byte 0x2c, 0xf8, 0x19, 0x6e, 0x19, 0x6e, 0x19, 0x6e, 0x05, 0x20, 0x00, 0xf0, 0x2f, 0xf8, 0x01, 0x21
|
||||
.byte 0x08, 0x42, 0xf9, 0xd1, 0x00, 0x21, 0x99, 0x60, 0x1b, 0x49, 0x19, 0x60, 0x00, 0x21, 0x59, 0x60
|
||||
.byte 0x1a, 0x49, 0x1b, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60, 0xeb, 0x21, 0x19, 0x66, 0xa0, 0x21
|
||||
.byte 0x19, 0x66, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0x21, 0x99, 0x60, 0x16, 0x49, 0x14, 0x48, 0x01, 0x60
|
||||
.byte 0x01, 0x21, 0x99, 0x60, 0x01, 0xbc, 0x00, 0x28, 0x00, 0xd0, 0x00, 0x47, 0x12, 0x48, 0x13, 0x49
|
||||
.byte 0x08, 0x60, 0x03, 0xc8, 0x80, 0xf3, 0x08, 0x88, 0x08, 0x47, 0x03, 0xb5, 0x99, 0x6a, 0x04, 0x20
|
||||
.byte 0x01, 0x42, 0xfb, 0xd0, 0x01, 0x20, 0x01, 0x42, 0xf8, 0xd1, 0x03, 0xbd, 0x02, 0xb5, 0x18, 0x66
|
||||
.byte 0x18, 0x66, 0xff, 0xf7, 0xf2, 0xff, 0x18, 0x6e, 0x18, 0x6e, 0x02, 0xbd, 0x00, 0x00, 0x02, 0x40
|
||||
.byte 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x5f, 0x00, 0x21, 0x22, 0x00, 0x00
|
||||
.byte 0xf4, 0x00, 0x00, 0x18, 0x22, 0x20, 0x00, 0xa0, 0x00, 0x01, 0x00, 0x10, 0x08, 0xed, 0x00, 0xe0
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0xb2, 0x4e, 0x7a
|
179
cpu/rpx0xx/clock.c
Normal file
179
cpu/rpx0xx/clock.c
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Otto-von-Guericke Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_rpx0xx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the CPU clock configuration
|
||||
*
|
||||
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "vendor/RP2040.h"
|
||||
#include "vendor/system_RP2040.h"
|
||||
#include "io_reg.h"
|
||||
#include "periph_cpu.h"
|
||||
|
||||
static void _clk_sys_set_source(CLOCKS_CLK_SYS_CTRL_SRC_Enum source)
|
||||
{
|
||||
io_reg_write_dont_corrupt(&CLOCKS->CLK_SYS_CTRL.reg, source << CLOCKS_CLK_SYS_CTRL_SRC_Pos,
|
||||
CLOCKS_CLK_SYS_CTRL_SRC_Msk);
|
||||
}
|
||||
|
||||
static void _clk_sys_set_aux_source(CLOCKS_CLK_SYS_CTRL_AUXSRC_Enum source)
|
||||
{
|
||||
io_reg_write_dont_corrupt(&CLOCKS->CLK_SYS_CTRL.reg, source << CLOCKS_CLK_SYS_CTRL_AUXSRC_Pos,
|
||||
CLOCKS_CLK_SYS_CTRL_AUXSRC_Msk);
|
||||
}
|
||||
|
||||
static void _clk_ref_set_source(CLOCKS_CLK_REF_CTRL_SRC_Enum source)
|
||||
{
|
||||
io_reg_write_dont_corrupt(&CLOCKS->CLK_REF_CTRL.reg, source << CLOCKS_CLK_REF_CTRL_SRC_Pos,
|
||||
CLOCKS_CLK_REF_CTRL_SRC_Msk);
|
||||
}
|
||||
|
||||
static void _clk_ref_set_aux_source(CLOCKS_CLK_REF_CTRL_AUXSRC_Enum source)
|
||||
{
|
||||
io_reg_write_dont_corrupt(&CLOCKS->CLK_REF_CTRL.reg, source << CLOCKS_CLK_REF_CTRL_AUXSRC_Pos,
|
||||
CLOCKS_CLK_REF_CTRL_AUXSRC_Msk);
|
||||
}
|
||||
|
||||
static void _gpout_set_aux_source(volatile uint32_t *reg, uint32_t value)
|
||||
{
|
||||
io_reg_write_dont_corrupt(reg,
|
||||
value << CLOCKS_CLK_GPOUT0_CTRL_AUXSRC_Pos,
|
||||
CLOCKS_CLK_GPOUT0_CTRL_AUXSRC_Msk);
|
||||
}
|
||||
|
||||
void clock_sys_configure_source(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_SYS_CTRL_SRC_Enum source)
|
||||
{
|
||||
assert(f_out <= f_in);
|
||||
assert(source != CLOCKS_CLK_SYS_CTRL_SRC_clksrc_clk_sys_aux);
|
||||
uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_SYS_DIV_INT_Pos) / f_out;
|
||||
/* switch the glitchless mux to clk_ref */
|
||||
_clk_sys_set_source(source);
|
||||
/* apply divider */
|
||||
CLOCKS->CLK_SYS_DIV.reg = div;
|
||||
/* poll SELECTED until the switch is completed */
|
||||
while (!(CLOCKS->CLK_SYS_SELECTED & (1U << source))) { }
|
||||
}
|
||||
|
||||
void clock_sys_configure_aux_source(uint32_t f_in, uint32_t f_out,
|
||||
CLOCKS_CLK_SYS_CTRL_AUXSRC_Enum aux)
|
||||
{
|
||||
assert(f_out <= f_in);
|
||||
uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_SYS_DIV_INT_Pos) / f_out;
|
||||
/* switch the glitchless mux to a source that is not the aux mux */
|
||||
_clk_sys_set_source(CLOCKS_CLK_SYS_CTRL_SRC_clk_ref);
|
||||
/* poll SELECTED until the switch is completed */
|
||||
while (!(CLOCKS->CLK_SYS_SELECTED & (1U << CLOCKS_CLK_SYS_CTRL_SRC_clk_ref))) { }
|
||||
/* change the auxiliary mux */
|
||||
_clk_sys_set_aux_source(aux);
|
||||
/* apply divider */
|
||||
CLOCKS->CLK_SYS_DIV.reg = div;
|
||||
/* switch the glitchless mux to clk_sys_aux */
|
||||
_clk_sys_set_source(CLOCKS_CLK_SYS_CTRL_SRC_clksrc_clk_sys_aux);
|
||||
/* poll SELECTED until the switch is completed */
|
||||
while (!(CLOCKS->CLK_SYS_SELECTED & (1U << CLOCKS_CLK_SYS_CTRL_SRC_clksrc_clk_sys_aux))) { }
|
||||
}
|
||||
|
||||
void clock_ref_configure_source(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_REF_CTRL_SRC_Enum source)
|
||||
{
|
||||
assert(f_out <= f_in);
|
||||
assert(source != CLOCKS_CLK_REF_CTRL_SRC_clksrc_clk_ref_aux);
|
||||
uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_REF_DIV_INT_Pos) / f_out;
|
||||
/* switch the glitchless mux to clock source */
|
||||
_clk_ref_set_source(source);
|
||||
/* apply divider */
|
||||
CLOCKS->CLK_REF_DIV.reg = div & CLOCKS_CLK_REF_DIV_INT_Msk;
|
||||
/* poll SELECTED until the switch is completed */
|
||||
while (!(CLOCKS->CLK_REF_SELECTED & (1U << source))) { }
|
||||
}
|
||||
|
||||
void clock_ref_configure_aux_source(uint32_t f_in, uint32_t f_out,
|
||||
CLOCKS_CLK_REF_CTRL_AUXSRC_Enum aux)
|
||||
{
|
||||
assert(f_out <= f_in);
|
||||
uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_REF_DIV_INT_Pos) / f_out;
|
||||
/* switch the glitchless mux to a source that is not the aux mux */
|
||||
_clk_ref_set_source(CLOCKS_CLK_REF_CTRL_SRC_rosc_clksrc_ph);
|
||||
/* poll SELECTED until the switch is completed */
|
||||
while (!(CLOCKS->CLK_REF_SELECTED & (1U << CLOCKS_CLK_REF_CTRL_SRC_rosc_clksrc_ph))) { }
|
||||
/* change the auxiliary mux */
|
||||
_clk_ref_set_aux_source(aux);
|
||||
/* apply divider */
|
||||
CLOCKS->CLK_REF_DIV.reg = div & CLOCKS_CLK_REF_DIV_INT_Msk;
|
||||
/* switch the glitchless mux to clk_ref_aux */
|
||||
_clk_ref_set_source(CLOCKS_CLK_REF_CTRL_SRC_clksrc_clk_ref_aux);
|
||||
/* poll SELECTED until the switch is completed */
|
||||
while (!(CLOCKS->CLK_REF_SELECTED & (1U << CLOCKS_CLK_REF_CTRL_SRC_clksrc_clk_ref_aux))) { }
|
||||
}
|
||||
|
||||
void clock_periph_configure(CLOCKS_CLK_PERI_CTRL_AUXSRC_Enum aux)
|
||||
{
|
||||
io_reg_atomic_clear(&CLOCKS->CLK_PERI_CTRL.reg, (1u << CLOCKS_CLK_PERI_CTRL_ENABLE_Pos));
|
||||
io_reg_write_dont_corrupt(&CLOCKS->CLK_PERI_CTRL.reg, aux << CLOCKS_CLK_PERI_CTRL_AUXSRC_Pos,
|
||||
CLOCKS_CLK_PERI_CTRL_AUXSRC_Msk);
|
||||
io_reg_atomic_set(&CLOCKS->CLK_PERI_CTRL.reg, (1u << CLOCKS_CLK_PERI_CTRL_ENABLE_Pos));
|
||||
}
|
||||
|
||||
void clock_gpout0_configure(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_GPOUT0_CTRL_AUXSRC_Enum aux)
|
||||
{
|
||||
assert(f_out <= f_in);
|
||||
uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_REF_DIV_INT_Pos) / f_out;
|
||||
io_reg_atomic_clear(&CLOCKS->CLK_GPOUT0_CTRL.reg, 1U << CLOCKS_CLK_GPOUT0_CTRL_ENABLE_Pos);
|
||||
_gpout_set_aux_source(&CLOCKS->CLK_GPOUT0_CTRL.reg, aux);
|
||||
CLOCKS->CLK_GPOUT0_DIV.reg = div;
|
||||
io_reg_atomic_set(&CLOCKS->CLK_GPOUT0_CTRL.reg, 1U << CLOCKS_CLK_GPOUT0_CTRL_ENABLE_Pos);
|
||||
io_reg_atomic_set(&PADS_BANK0->GPIO21.reg, 1U << PADS_BANK0_GPIO21_IE_Pos);
|
||||
gpio_set_function_select(21, FUNCTION_SELECT_CLOCK);
|
||||
}
|
||||
|
||||
void clock_gpout1_configure(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_GPOUT1_CTRL_AUXSRC_Enum aux)
|
||||
{
|
||||
assert(f_out <= f_in);
|
||||
uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_REF_DIV_INT_Pos) / f_out;
|
||||
io_reg_atomic_clear(&CLOCKS->CLK_GPOUT1_CTRL.reg, 1U << CLOCKS_CLK_GPOUT1_CTRL_ENABLE_Pos);
|
||||
_gpout_set_aux_source(&CLOCKS->CLK_GPOUT1_CTRL.reg, aux);
|
||||
CLOCKS->CLK_GPOUT1_DIV.reg = div;
|
||||
io_reg_atomic_set(&CLOCKS->CLK_GPOUT1_CTRL.reg, 1U << CLOCKS_CLK_GPOUT1_CTRL_ENABLE_Pos);
|
||||
io_reg_atomic_set(&PADS_BANK0->GPIO23.reg, 1U << PADS_BANK0_GPIO23_IE_Pos);
|
||||
gpio_set_function_select(23, FUNCTION_SELECT_CLOCK);
|
||||
}
|
||||
|
||||
void clock_gpout2_configure(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_GPOUT2_CTRL_AUXSRC_Enum aux)
|
||||
{
|
||||
assert(f_out <= f_in);
|
||||
uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_REF_DIV_INT_Pos) / f_out;
|
||||
io_reg_atomic_clear(&CLOCKS->CLK_GPOUT2_CTRL.reg, 1U << CLOCKS_CLK_GPOUT2_CTRL_ENABLE_Pos);
|
||||
_gpout_set_aux_source(&CLOCKS->CLK_GPOUT2_CTRL.reg, aux);
|
||||
CLOCKS->CLK_GPOUT2_DIV.reg = div;
|
||||
io_reg_atomic_set(&CLOCKS->CLK_GPOUT2_CTRL.reg, 1U << CLOCKS_CLK_GPOUT2_CTRL_ENABLE_Pos);
|
||||
io_reg_atomic_set(&PADS_BANK0->GPIO24.reg, 1U << PADS_BANK0_GPIO24_IE_Pos);
|
||||
gpio_set_function_select(24, FUNCTION_SELECT_CLOCK);
|
||||
}
|
||||
|
||||
void clock_gpout3_configure(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_GPOUT3_CTRL_AUXSRC_Enum aux)
|
||||
{
|
||||
assert(f_out <= f_in);
|
||||
uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_REF_DIV_INT_Pos) / f_out;
|
||||
io_reg_atomic_clear(&CLOCKS->CLK_GPOUT3_CTRL.reg, 1U << CLOCKS_CLK_GPOUT3_CTRL_ENABLE_Pos);
|
||||
_gpout_set_aux_source(&CLOCKS->CLK_GPOUT3_CTRL.reg, aux);
|
||||
CLOCKS->CLK_GPOUT3_DIV.reg = div;
|
||||
io_reg_atomic_set(&CLOCKS->CLK_GPOUT3_CTRL.reg, 1U << CLOCKS_CLK_GPOUT3_CTRL_ENABLE_Pos);
|
||||
io_reg_atomic_set(&PADS_BANK0->GPIO25.reg, 1U << PADS_BANK0_GPIO25_IE_Pos);
|
||||
gpio_set_function_select(25, FUNCTION_SELECT_CLOCK);
|
||||
}
|
96
cpu/rpx0xx/cpu.c
Normal file
96
cpu/rpx0xx/cpu.c
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Otto-von-Guericke Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_rpx0xx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the CPU initialization
|
||||
*
|
||||
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "macros/units.h"
|
||||
#include "periph/init.h"
|
||||
#include "periph_cpu.h"
|
||||
#include "io_reg.h"
|
||||
#include "stdio_base.h"
|
||||
#include "vendor/RP2040.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
static void _cpu_reset(void)
|
||||
{
|
||||
/* 2.14 subsystem resets */
|
||||
uint32_t rst;
|
||||
/* Reset hardware components except for critical ones */
|
||||
rst = RESETS_RESET_MASK
|
||||
& ~(RESETS_RESET_usbctrl_Msk
|
||||
| RESETS_RESET_syscfg_Msk
|
||||
| RESETS_RESET_pll_usb_Msk
|
||||
| RESETS_RESET_pll_sys_Msk
|
||||
| RESETS_RESET_pads_qspi_Msk
|
||||
| RESETS_RESET_io_qspi_Msk);
|
||||
periph_reset(rst);
|
||||
/* Assert that reset has completed except for those components which
|
||||
are not clocked by clk_ref or clk_sys */
|
||||
rst = RESETS_RESET_MASK
|
||||
& ~(RESETS_RESET_usbctrl_Msk
|
||||
| RESETS_RESET_uart1_Msk
|
||||
| RESETS_RESET_uart0_Msk
|
||||
| RESETS_RESET_spi1_Msk
|
||||
| RESETS_RESET_spi0_Msk
|
||||
| RESETS_RESET_rtc_Msk
|
||||
| RESETS_RESET_adc_Msk);
|
||||
periph_reset_done(rst);
|
||||
|
||||
/* power the reference clock from its default source: the ROSC */
|
||||
clock_ref_configure_source(MHZ(12), MHZ(12), CLOCKS_CLK_REF_CTRL_SRC_rosc_clksrc_ph);
|
||||
/* power the system clock from its default source: the reference clock */
|
||||
clock_sys_configure_source(MHZ(12), MHZ(12), CLOCKS_CLK_SYS_CTRL_SRC_clk_ref);
|
||||
/* start XOSC, typically running at 12 MHz */
|
||||
xosc_start(CLOCK_XOSC);
|
||||
/* reset system PLL */
|
||||
pll_reset_sys();
|
||||
/* start the system PLL (typically takes the 12 MHz XOSC to generate 125 MHz) */
|
||||
pll_start_sys(PLL_SYS_REF_DIV, PLL_SYS_VCO_FEEDBACK_SCALE, PLL_SYS_POSTDIV1, PLL_SYS_POSTDIV2);
|
||||
/* configure reference clock to run from XOSC (typically 12 MHz) */
|
||||
clock_ref_configure_source(CLOCK_XOSC, CLOCK_XOSC,
|
||||
CLOCKS_CLK_REF_CTRL_SRC_xosc_clksrc);
|
||||
/* configure system clock output */
|
||||
clock_sys_configure_aux_source(CLOCK_CORECLOCK, CLOCK_CORECLOCK,
|
||||
CLOCKS_CLK_SYS_CTRL_AUXSRC_clksrc_pll_sys);
|
||||
/* configure the peripheral clock to run from the system clock */
|
||||
clock_periph_configure(CLOCK_PERIPH_SOURCE);
|
||||
if (IS_USED(ENABLE_DEBUG)) {
|
||||
/* check clk_ref with logic analyzer */
|
||||
clock_gpout0_configure(CLOCK_XOSC, CLOCK_XOSC,
|
||||
CLOCKS_CLK_GPOUT0_CTRL_AUXSRC_clk_ref);
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_init(void)
|
||||
{
|
||||
/* initialize the Cortex-M core */
|
||||
cortexm_init();
|
||||
|
||||
_cpu_reset();
|
||||
|
||||
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
|
||||
stdio_init();
|
||||
|
||||
DEBUG_PUTS("[rpx0xx] GPOUT0 (GPIO pin 21) is clocked from XOSC (typically 12 MHz)");
|
||||
|
||||
/* trigger static peripheral initialization */
|
||||
periph_init();
|
||||
}
|
9
cpu/rpx0xx/doc.txt
Normal file
9
cpu/rpx0xx/doc.txt
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
@defgroup cpu_rpx0xx RPx0xx MCUs
|
||||
@ingroup cpu
|
||||
@brief RPx0xx MCU code and definitions
|
||||
|
||||
This module contains the code and definitions for MCUs of the RPx0xx family, of which only the
|
||||
RP2040 is currently released.
|
||||
|
||||
*/
|
1
cpu/rpx0xx/include/.gitignore
vendored
Normal file
1
cpu/rpx0xx/include/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
irqs/
|
47
cpu/rpx0xx/include/cpu_conf.h
Normal file
47
cpu/rpx0xx/include/cpu_conf.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Otto-von-Guericke-Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_rpx0xx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation specific CPU configuration options
|
||||
*
|
||||
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
|
||||
*/
|
||||
|
||||
#ifndef CPU_CONF_H
|
||||
#define CPU_CONF_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "macros/units.h"
|
||||
#include "cpu_conf_common.h"
|
||||
#include "vendor/RP2040.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ARM Cortex-M specific CPU configuration
|
||||
* @{
|
||||
*/
|
||||
#define CPU_DEFAULT_IRQ_PRIO (1U)
|
||||
#define CPU_FLASH_BASE ROM_START_ADDR
|
||||
#define CPU_IRQ_NUMOF (32U)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CPU_CONF_H */
|
||||
/** @} */
|
138
cpu/rpx0xx/include/io_reg.h
Normal file
138
cpu/rpx0xx/include/io_reg.h
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Otto-von-Guericke-Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_rpx0xx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief RP2040 atomic register access macros
|
||||
* @details This allows individual fields of a control register to be
|
||||
* modified without performing a read-modify-write sequence.
|
||||
* See section "2.1.2. Atomic Register Access" in
|
||||
* https://datasheets.raspberrypi.org/rpx0xx/rpx0xx-datasheet.pdf
|
||||
*
|
||||
* @warning The Single-cycle IO block (SIO), which contains the GPIO, does not support
|
||||
* atomic access using these aliases.
|
||||
*
|
||||
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
||||
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
|
||||
*/
|
||||
|
||||
#ifndef IO_REG_H
|
||||
#define IO_REG_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Bit to be set if an atomic XOR operation shall be done
|
||||
*/
|
||||
#define REG_ATOMIC_XOR_BIT (0x1000U)
|
||||
|
||||
/**
|
||||
* @brief Bit to be set if an atomic set operation shall be done
|
||||
*/
|
||||
#define REG_ATOMIC_SET_BIT (0x2000U)
|
||||
|
||||
/**
|
||||
* @brief Bits to be set if an atomic clear operation shall be done
|
||||
*/
|
||||
#define REG_ATOMIC_CLEAR_BIT (0x3000U)
|
||||
|
||||
/**
|
||||
* @brief The operation to be performed to the register at address @p reg
|
||||
* will be an atomic XOR of the bits of the right-hand-side operand
|
||||
*/
|
||||
#define REG_ATOMIC_XOR(reg) ((volatile uint32_t *)(((uintptr_t)(reg)) | REG_ATOMIC_XOR_BIT))
|
||||
|
||||
/**
|
||||
* @brief The operation to be performed to the register at address @p reg
|
||||
* will be an atomic set of the bits of the right-hand-side operand
|
||||
*/
|
||||
#define REG_ATOMIC_SET(reg) ((volatile uint32_t *)(((uintptr_t)(reg)) | REG_ATOMIC_SET_BIT))
|
||||
|
||||
/**
|
||||
* @brief The operation to be performed to the register at address @p reg
|
||||
* will be an atomic clear of the bits of the right-hand-side operand
|
||||
*/
|
||||
#define REG_ATOMIC_CLEAR(reg) ((volatile uint32_t *)(((uintptr_t)(reg)) | REG_ATOMIC_CLEAR_BIT))
|
||||
|
||||
/**
|
||||
* @brief Performed an atomic XOR of the set bits in @p op
|
||||
* with the bits in the register at address @p reg
|
||||
*
|
||||
* @param reg Register address
|
||||
* @param mask Mask of bits to be XORed
|
||||
*/
|
||||
static inline void io_reg_atomic_xor(volatile uint32_t *reg, uint32_t mask)
|
||||
{
|
||||
*REG_ATOMIC_XOR(reg) = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the bits in the register at address @p reg as given by
|
||||
* the set bits in operand @p op
|
||||
*
|
||||
* @param reg Register address
|
||||
* @param mask Mask of bits to be set
|
||||
*/
|
||||
static inline void io_reg_atomic_set(volatile uint32_t *reg, uint32_t mask)
|
||||
{
|
||||
*REG_ATOMIC_SET(reg) = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the bits in the register at address @p reg as given by
|
||||
* the set bits in operand @p op
|
||||
*
|
||||
* @param reg Register address
|
||||
* @param mask Mask of bits to be cleared
|
||||
*/
|
||||
static inline void io_reg_atomic_clear(volatile uint32_t *reg, uint32_t mask)
|
||||
{
|
||||
*REG_ATOMIC_CLEAR(reg) = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates part of an I/O register without corrupting its contents
|
||||
*
|
||||
* @param reg Register address
|
||||
* @param value bits to set in the register (e.g. the new value shifted to the right position)
|
||||
* @param mask bits to clear in the register (e.g. bitmask indicating the part to update with
|
||||
* one bits, and everything else with zero bits)
|
||||
*
|
||||
* @details The RP2040 only correctly implements 32 bit writes to I/O register. When
|
||||
* updating parts of an I/O register using the structs in the CMSIS header, the
|
||||
* C compiler might implement those updates e.g. using 8-bit writes, especially
|
||||
* when the part to update is 8-bit in size and byte-aligned. The RP2040 will then
|
||||
* sneakily corrupt the I/O register, rather than triggering a hard fault. This
|
||||
* hard to debug silent corruption issue is *NOT* a bug, but an intentional
|
||||
* feature, obviously.
|
||||
* @pre `value & (~mask) == 0`
|
||||
*
|
||||
* Example use:
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c}
|
||||
* io_reg_write_dont_corrupt(&CLOCKS->CLK_SYS_CTRL.reg, source << CLOCKS_CLK_SYS_CTRL_SRC_Pos,
|
||||
* CLOCKS_CLK_SYS_CTRL_SRC_Msk);
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
static inline void io_reg_write_dont_corrupt(volatile uint32_t *reg, uint32_t value, uint32_t mask)
|
||||
{
|
||||
*reg = (*reg & (~mask)) | value;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* IO_REG_H */
|
||||
/** @} */
|
689
cpu/rpx0xx/include/periph_cpu.h
Normal file
689
cpu/rpx0xx/include/periph_cpu.h
Normal file
@ -0,0 +1,689 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Otto-von-Guericke-Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_rpx0xx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief RP2040 specific definitions for handling peripherals
|
||||
*
|
||||
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
|
||||
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
||||
*/
|
||||
|
||||
#ifndef PERIPH_CPU_H
|
||||
#define PERIPH_CPU_H
|
||||
|
||||
#include "cpu.h"
|
||||
#include "vendor/RP2040.h"
|
||||
#include "io_reg.h"
|
||||
#include "macros/units.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined(PLL_SYS_REF_DIV) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief For generating the system clock via PLL, the XOSC reference clock can be divided. The
|
||||
* datasheet says for the supported frequency range of the crystal, only a divider of 1 is
|
||||
* reasonable.
|
||||
*/
|
||||
#define PLL_SYS_REF_DIV 1
|
||||
#endif
|
||||
|
||||
#if !defined(PLL_USB_REF_DIV) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Same as @ref PLL_SYS_REF_DIV but for the PLL generating the USB clock
|
||||
*/
|
||||
#define PLL_USB_REF_DIV 1
|
||||
#endif
|
||||
|
||||
#if !defined(PLL_SYS_VCO_FEEDBACK_SCALE) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief VCO feedback scale used for system clock
|
||||
*
|
||||
* @note The result of `PLL_SYS_VCO_FEEDBACK_SCALE * CLOCK_XOSC` must be in the range of
|
||||
* 400 MHz to 1600 MHz
|
||||
*/
|
||||
#define PLL_SYS_VCO_FEEDBACK_SCALE 125
|
||||
#endif
|
||||
|
||||
#if !defined(PLL_SYS_POSTDIV1) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief First post-PLL clock divider for system clock
|
||||
*
|
||||
* @note Must be in rage 1..7
|
||||
*/
|
||||
#define PLL_SYS_POSTDIV1 6
|
||||
#endif
|
||||
|
||||
#if !defined(PLL_SYS_POSTDIV2) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Second post-PLL clock divider for system clock
|
||||
*
|
||||
* @note Must be in rage 1..7
|
||||
*/
|
||||
#define PLL_SYS_POSTDIV2 2
|
||||
#endif
|
||||
|
||||
#if !defined(PLL_USB_VCO_FEEDBACK_SCALE) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief VCO feedback scale used for USB clock
|
||||
*
|
||||
* @note The result of `PLL_USB_VCO_FEEDBACK_SCALE * CLOCK_XOSC` must be in the range of
|
||||
* 400 MHz to 1600 MHz
|
||||
*/
|
||||
#define PLL_USB_VCO_FEEDBACK_SCALE 40
|
||||
#endif
|
||||
|
||||
#if !defined(PLL_USB_POSTDIV1) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief First post-PLL clock divider for USB clock
|
||||
*
|
||||
* @note Must be in rage 1..7
|
||||
*/
|
||||
#define PLL_USB_POSTDIV1 5
|
||||
#endif
|
||||
|
||||
#if !defined(PLL_USB_POSTDIV2) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Second post-PLL clock divider for USB clock
|
||||
*
|
||||
* @note Must be in rage 1..7
|
||||
*/
|
||||
#define PLL_USB_POSTDIV2 2
|
||||
#endif
|
||||
|
||||
#if !defined(CLOCK_XOSC) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief The RP2040 reference design attaches a 12 MHz crystal to the MCU, so we take this
|
||||
* value as default
|
||||
*/
|
||||
#define CLOCK_XOSC MHZ(12)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Calculate the resulting PLL clock frequency for the given parameters
|
||||
*/
|
||||
#define PLL_CLOCK(vco_feedback, postdiv1, postdiv2) \
|
||||
(CLOCK_XOSC * (vco_feedback) / (postdiv1) / (postdiv2))
|
||||
|
||||
/**
|
||||
* @brief System core clock speed, 125 MHz unless board changes parameters
|
||||
*/
|
||||
#define CLOCK_CORECLOCK \
|
||||
PLL_CLOCK(PLL_SYS_VCO_FEEDBACK_SCALE, PLL_SYS_POSTDIV1, PLL_SYS_POSTDIV2)
|
||||
|
||||
/**
|
||||
* @brief USB clock speed
|
||||
*/
|
||||
#define CLOCK_USB \
|
||||
PLL_CLOCK(PLL_USB_VCO_FEEDBACK_SCALE, PLL_USB_POSTDIV1, PLL_USB_POSTDIV2)
|
||||
|
||||
/**
|
||||
* @name Ranges for clock frequencies and clock settings
|
||||
* @{
|
||||
*/
|
||||
#define CLOCK_XOSC_MAX MHZ(15) /**< Maximum crystal frequency */
|
||||
#define CLOCK_XOSC_MIN MHZ(5) /**< Minimum crystal frequency */
|
||||
#define PLL_POSTDIV_MIN (1U) /**< Minimum value of the post PLL clock divers */
|
||||
#define PLL_POSTDIV_MAX (7U) /**< Maximum value of the post PLL clock divers */
|
||||
#define PLL_VCO_FEEDBACK_SCALE_MIN (16U) /**< Minimum value of the PLL VCO feedback scaler */
|
||||
#define PLL_VCO_FEEDBACK_SCALE_MAX (320U) /**< Maximum value of the PLL VCO feedback scaler */
|
||||
#define PLL_REF_DIV_MIN (1U) /**< Minimum value of the clock divider applied before
|
||||
* feeding in the reference clock into the PLL */
|
||||
#define PLL_REF_DIV_MAX (1U) /**< Minimum value of the clock divider applied before
|
||||
* feeding in the reference clock into the PLL */
|
||||
/** @} */
|
||||
|
||||
#if CLOCK_USB != MHZ(48)
|
||||
#error "USB clock != 48 MHz, check PLL_USB_VCO_FEEDBACK_SCALE, PLL_USB_POSTDIV1, PLL_SYS_POSTDIV2"
|
||||
#endif
|
||||
|
||||
#if (CLOCK_XOSC > CLOCK_XOSC_MAX) || (CLOCK_XOSC < CLOCK_XOSC_MIN)
|
||||
#error "Value for CLOCK_XOSC out of range, check config"
|
||||
#endif
|
||||
|
||||
#if (PLL_SYS_REF_DIV < PLL_REF_DIV_MIN) || (PLL_SYS_REF_DIV > PLL_REF_DIV_MAX)
|
||||
#error "Value for PLL_SYS_REF_DIV out of range, check config"
|
||||
#endif
|
||||
|
||||
#if (PLL_USB_REF_DIV < PLL_REF_DIV_MIN) || (PLL_USB_REF_DIV > PLL_REF_DIV_MAX)
|
||||
#error "Value for PLL_USB_REF_DIV out of range, check config"
|
||||
#endif
|
||||
|
||||
#if (PLL_SYS_VCO_FEEDBACK_SCALE < PLL_VCO_FEEDBACK_SCALE_MIN) \
|
||||
|| (PLL_SYS_VCO_FEEDBACK_SCALE > PLL_VCO_FEEDBACK_SCALE_MAX)
|
||||
#error "Value for PLL_SYS_VCO_FEEDBACK_SCALE out of range, check config"
|
||||
#endif
|
||||
|
||||
#if (PLL_USB_VCO_FEEDBACK_SCALE < PLL_VCO_FEEDBACK_SCALE_MIN) \
|
||||
|| (PLL_USB_VCO_FEEDBACK_SCALE > PLL_VCO_FEEDBACK_SCALE_MAX)
|
||||
#error "Value for PLL_USB_VCO_FEEDBACK_SCALE out of range, check config"
|
||||
#endif
|
||||
|
||||
#if (PLL_SYS_POSTDIV1 < PLL_POSTDIV_MIN) || (PLL_SYS_POSTDIV1 > PLL_POSTDIV_MAX)
|
||||
#error "Value for PLL_SYS_POSTDIV1 out of range, check config"
|
||||
#endif
|
||||
|
||||
#if (PLL_SYS_POSTDIV2 < PLL_POSTDIV_MIN) || (PLL_SYS_POSTDIV2 > PLL_POSTDIV_MAX)
|
||||
#error "Value for PLL_SYS_POSTDIV2 out of range, check config"
|
||||
#endif
|
||||
|
||||
#if (PLL_USB_POSTDIV1 < PLL_POSTDIV_MIN) || (PLL_USB_POSTDIV1 > PLL_POSTDIV_MAX)
|
||||
#error "Value for PLL_USB_POSTDIV1 out of range, check config"
|
||||
#endif
|
||||
|
||||
#if (PLL_USB_POSTDIV2 < PLL_POSTDIV_MIN) || (PLL_USB_POSTDIV2 > PLL_POSTDIV_MAX)
|
||||
#error "Value for PLL_USB_POSTDIV2 out of range, check config"
|
||||
#endif
|
||||
|
||||
#if !defined(CLOCK_PERIPH_SOURCE) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief How to source the peripheral clock (default: 125 MHz system clock)
|
||||
*/
|
||||
#define CLOCK_PERIPH_SOURCE CLOCKS_CLK_PERI_CTRL_AUXSRC_clk_sys
|
||||
#endif
|
||||
|
||||
#if !defined(CLOCK_PERIPH) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Peripheral clock (by default source from system clock)
|
||||
*/
|
||||
#define CLOCK_PERIPH CLOCK_CORECLOCK
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Periphery blocks that can be reset
|
||||
*/
|
||||
#define RESETS_RESET_MASK \
|
||||
(RESETS_RESET_usbctrl_Msk | \
|
||||
RESETS_RESET_uart1_Msk | \
|
||||
RESETS_RESET_uart0_Msk | \
|
||||
RESETS_RESET_timer_Msk | \
|
||||
RESETS_RESET_tbman_Msk | \
|
||||
RESETS_RESET_sysinfo_Msk | \
|
||||
RESETS_RESET_syscfg_Msk | \
|
||||
RESETS_RESET_spi1_Msk | \
|
||||
RESETS_RESET_spi0_Msk | \
|
||||
RESETS_RESET_rtc_Msk | \
|
||||
RESETS_RESET_pwm_Msk | \
|
||||
RESETS_RESET_pll_usb_Msk | \
|
||||
RESETS_RESET_pll_sys_Msk | \
|
||||
RESETS_RESET_pio1_Msk | \
|
||||
RESETS_RESET_pio0_Msk | \
|
||||
RESETS_RESET_pads_qspi_Msk | \
|
||||
RESETS_RESET_pads_bank0_Msk | \
|
||||
RESETS_RESET_jtag_Msk | \
|
||||
RESETS_RESET_io_qspi_Msk | \
|
||||
RESETS_RESET_io_bank0_Msk | \
|
||||
RESETS_RESET_i2c1_Msk | \
|
||||
RESETS_RESET_i2c0_Msk | \
|
||||
RESETS_RESET_dma_Msk | \
|
||||
RESETS_RESET_busctrl_Msk | \
|
||||
RESETS_RESET_adc_Msk)
|
||||
|
||||
/**
|
||||
* @brief Convert (port, pin) tuple to a @ref gpio_t value
|
||||
*
|
||||
* @note The RPX0XX MCU family only has a single GPIO port. Still the API requires a
|
||||
* port parameter, which is currently ignored.
|
||||
*/
|
||||
#define GPIO_PIN(port, pin) (pin)
|
||||
|
||||
/**
|
||||
* @brief Overwrite the default gpio_t type definition
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_GPIO_T
|
||||
typedef uint32_t gpio_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Definition of a fitting UNDEF value
|
||||
*/
|
||||
#define GPIO_UNDEF UINT32_MAX
|
||||
|
||||
/**
|
||||
* @brief Override GPIO active flank values
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_GPIO_FLANK_T
|
||||
typedef enum {
|
||||
GPIO_LEVEL_LOW = 0x1, /**< emit interrupt level-triggered on low input */
|
||||
GPIO_LEVEL_HIGH = 0x2, /**< emit interrupt level-triggered on low input */
|
||||
GPIO_FALLING = 0x4, /**< emit interrupt on falling flank */
|
||||
GPIO_RISING = 0x8, /**< emit interrupt on rising flank */
|
||||
GPIO_BOTH = 0xc /**< emit interrupt on both flanks */
|
||||
} gpio_flank_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name GPIO pad configuration register defines and types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Reset value of the GPIO pad configuration register
|
||||
*/
|
||||
#define GPIO_PAD_REGISTER_RESET_VALUE (0x00000056)
|
||||
/**
|
||||
* @brief Possible drive strength values for @ref gpio_pad_ctrl_t::drive_strength
|
||||
*/
|
||||
enum {
|
||||
DRIVE_STRENGTH_2MA, /**< set driver strength to 2 mA */
|
||||
DRIVE_STRENGTH_4MA, /**< set driver strength to 4 mA */
|
||||
DRIVE_STRENGTH_8MA, /**< set driver strength to 8 mA */
|
||||
DRIVE_STRENGTH_12MA, /**< set driver strength to 12 mA */
|
||||
DRIVE_STRENGTH_NUMOF /**< number of different drive strength options */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Memory layout of GPIO control register in pads bank 0
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t slew_rate_fast : 1; /**< set slew rate control to fast */
|
||||
uint32_t schmitt_trig_enable : 1; /**< enable Schmitt trigger */
|
||||
uint32_t pull_down_enable : 1; /**< enable pull down resistor */
|
||||
uint32_t pull_up_enable : 1; /**< enable pull up resistor */
|
||||
uint32_t drive_strength : 2; /**< GPIO driver strength */
|
||||
uint32_t input_enable : 1; /**< enable as input */
|
||||
uint32_t output_disable : 1; /**< disable output, overwrite output enable from
|
||||
* peripherals */
|
||||
uint32_t : 24; /**< 24 bits reserved for future use */
|
||||
} gpio_pad_ctrl_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name GPIO I/O configuration register defines and types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Reset value of the GPIO I/O configuration register
|
||||
*/
|
||||
#define GPIO_IO_REGISTER_RESET_VALUE (0x0000001f)
|
||||
/**
|
||||
* @brief Possible function values for @ref gpio_io_ctrl_t::function_select
|
||||
*/
|
||||
typedef enum {
|
||||
FUNCTION_SELECT_SPI = 1, /**< connect pin to the SPI peripheral
|
||||
* (MISO/MOSI/SCK depends on pin) */
|
||||
FUNCTION_SELECT_UART = 2, /**< connect pin to the UART peripheral
|
||||
* (TXD/RXD depends on pin) */
|
||||
FUNCTION_SELECT_I2C = 3, /**< connect pin to the I2C peripheral
|
||||
* (SCL/SDA depends on pin) */
|
||||
FUNCTION_SELECT_PWM = 4, /**< connect pin to the timer for PWM
|
||||
* (channel depends on pin) */
|
||||
FUNCTION_SELECT_SIO = 5, /**< use pin as vanilla GPIO */
|
||||
FUNCTION_SELECT_PIO0 = 6, /**< connect pin to the first PIO peripheral */
|
||||
FUNCTION_SELECT_PIO1 = 7, /**< connect pin to the second PIO peripheral */
|
||||
FUNCTION_SELECT_CLOCK = 8, /**< connect pin to the timer (depending on pin: external clock,
|
||||
* clock output, or not supported) */
|
||||
FUNCTION_SELECT_USB = 9, /**< connect pin to the USB peripheral
|
||||
* (function depends on pin) */
|
||||
FUNCTION_SELECT_NONE = 31, /**< Reset value, pin unconnected */
|
||||
} gpio_function_select_t;
|
||||
|
||||
/**
|
||||
* @brief Possible function values for @ref gpio_io_ctrl_t::output_override
|
||||
*/
|
||||
enum {
|
||||
OUTPUT_OVERRIDE_NORMAL, /**< drive pin from connected peripheral */
|
||||
OUTPUT_OVERRIDE_INVERT, /**< drive pin from connected peripheral, but invert output */
|
||||
OUTPUT_OVERRIDE_LOW, /**< drive pin low, overriding peripheral signal */
|
||||
OUTPUT_OVERRIDE_HIGH, /**< drive pin high, overriding peripheral signal */
|
||||
OUTPUT_OVERRIDE_NUMOF /**< number of possible output override settings */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Possible function values for @ref gpio_io_ctrl_t::output_enable_override
|
||||
*/
|
||||
enum {
|
||||
OUTPUT_ENABLE_OVERRIDE_NOMARL, /**< enable output as specified by connected peripheral */
|
||||
OUTPUT_ENABLE_OVERRIDE_INVERT, /**< invert output enable setting of peripheral */
|
||||
OUTPUT_ENABLE_OVERRIDE_DISABLE, /**< disable output, overriding peripheral signal */
|
||||
OUTPUT_ENABLE_OVERRIDE_ENABLE, /**< enable output, overriding peripheral signal */
|
||||
OUTPUT_ENABLE_OVERRIDE_NUMOF /**< number of possible output enable override settings */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Possible function values for @ref gpio_io_ctrl_t::input_override
|
||||
*/
|
||||
enum {
|
||||
INPUT_OVERRIDE_NOMARL, /**< don't mess with peripheral input signal */
|
||||
INPUT_OVERRIDE_INVERT, /**< invert signal to connected peripheral */
|
||||
INPUT_OVERRIDE_LOW, /**< signal low to connected peripheral */
|
||||
INPUT_OVERRIDE_HIGH, /**< signal high to connected peripheral */
|
||||
INPUT_OVERRIDE_NUMOF /**< number of possible input override settings */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Possible function values for @ref gpio_io_ctrl_t::irq_override
|
||||
*/
|
||||
enum {
|
||||
IRQ_OVERRIDE_NORMAL, /**< don't mess with IRQ signal */
|
||||
IRQ_OVERRIDE_INVERT, /**< invert IRQ signal */
|
||||
IRQ_OVERRIDE_LOW, /**< set IRQ signal to low */
|
||||
IRQ_OVERRIDE_HIGH, /**< set IRQ signal to high */
|
||||
IRQ_OVERRIDE_NUMOF /**< number of possible IRQ override settings */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Memory layout of GPIO control register in IO bank 0
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t function_select : 5; /**< select GPIO function */
|
||||
uint32_t : 3; /**< 3 bits reserved for future use */
|
||||
uint32_t output_override : 2; /**< output value override */
|
||||
uint32_t : 2; /**< 2 bits reserved for future use */
|
||||
uint32_t output_enable_override : 2; /**< output enable override */
|
||||
uint32_t : 2; /**< 2 bits reserved for future use */
|
||||
uint32_t input_override : 2; /**< input value override */
|
||||
uint32_t : 10; /**< 10 bits reserved for future use */
|
||||
uint32_t irq_override : 2; /**< interrupt inversion override */
|
||||
uint32_t : 2; /**< 2 bits reserved for future use */
|
||||
} gpio_io_ctrl_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Get the PAD control register for the given GPIO pin as word
|
||||
*
|
||||
* Note: Only perform 32-bit writes to I/O registers.
|
||||
*/
|
||||
static inline volatile uint32_t * gpio_pad_register(uint8_t pin)
|
||||
{
|
||||
return (uint32_t *)(PADS_BANK0_BASE + 4 + (pin << 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convenience function to set the pad configuration of the given pin
|
||||
* using the bit-field convenience type
|
||||
*/
|
||||
static inline void gpio_set_pad_config(uint8_t pin, gpio_pad_ctrl_t config)
|
||||
{
|
||||
*(volatile gpio_pad_ctrl_t*)gpio_pad_register(pin) = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the IO control register for the given GPIO pin as word
|
||||
*/
|
||||
static inline volatile uint32_t * gpio_io_register(uint8_t pin)
|
||||
{
|
||||
return (uint32_t *)(IO_BANK0_BASE + 4 + (pin << 3));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convenience function to set the I/O configuration of the given pin
|
||||
* using the bit-field convenience type
|
||||
*/
|
||||
static inline void gpio_set_io_config(uint8_t pin, gpio_io_ctrl_t config)
|
||||
{
|
||||
*(volatile gpio_io_ctrl_t*)gpio_io_register(pin) = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the function select subregister for the given pin to the given value
|
||||
*/
|
||||
static inline void gpio_set_function_select(uint8_t pin, gpio_function_select_t funcsel)
|
||||
{
|
||||
io_reg_write_dont_corrupt(gpio_io_register(pin), funcsel << IO_BANK0_GPIO0_CTRL_FUNCSEL_Pos,
|
||||
IO_BANK0_GPIO0_CTRL_FUNCSEL_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Restore the default I/O and PAD configuration of the given GPIO pin
|
||||
*/
|
||||
static inline void gpio_reset_all_config(uint8_t pin)
|
||||
{
|
||||
*gpio_io_register(pin) = GPIO_IO_REGISTER_RESET_VALUE;
|
||||
*gpio_pad_register(pin) = GPIO_PAD_REGISTER_RESET_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset hardware components
|
||||
*
|
||||
* @param components bitmask of components to be reset,
|
||||
* @see RESETS_RESET_MASK
|
||||
*/
|
||||
static inline void periph_reset(uint32_t components)
|
||||
{
|
||||
io_reg_atomic_set(&RESETS->RESET.reg, components);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Waits until hardware components have been reset
|
||||
*
|
||||
* @param components bitmask of components that must have reset,
|
||||
* @see RESETS_RESET_MASK
|
||||
*/
|
||||
static inline void periph_reset_done(uint32_t components)
|
||||
{
|
||||
io_reg_atomic_clear(&RESETS->RESET.reg, components);
|
||||
while ((~RESETS->RESET_DONE.reg) & components) { }
|
||||
}
|
||||
|
||||
/**
|
||||
* @name RP2040 clock configuration
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configure the system clock to run from the reference clock,
|
||||
* which is the default on boot
|
||||
*
|
||||
* @param f_in Input frequency of the reference clock
|
||||
* @param f_out Output frequency of the system clock
|
||||
* @param source Clock source
|
||||
*/
|
||||
void clock_sys_configure_source(uint32_t f_in, uint32_t f_out,
|
||||
CLOCKS_CLK_SYS_CTRL_SRC_Enum source);
|
||||
|
||||
/**
|
||||
* @brief Configure the system clock to run from an auxiliary clock source,
|
||||
* like PLL
|
||||
*
|
||||
* @note The auxiliary must have been configured beforehand
|
||||
*
|
||||
* @param f_in Input frequency of the auxiliary clock source
|
||||
* @param f_out Output frequency of the system clock
|
||||
* @param aux Which auxiliary clock source to use
|
||||
*/
|
||||
void clock_sys_configure_aux_source(uint32_t f_in, uint32_t f_out,
|
||||
CLOCKS_CLK_SYS_CTRL_AUXSRC_Enum aux);
|
||||
|
||||
/**
|
||||
* @brief Configure the reference clock to run from a clock source,
|
||||
* which is either the ROSC or the XOSC
|
||||
*
|
||||
* @note Make sure that ROSC or XOSC are properly set up
|
||||
*
|
||||
* @param f_in Input frequency of the reference clock
|
||||
* @param f_out Output frequency of the system clock
|
||||
* @param source Clock source
|
||||
*/
|
||||
void clock_ref_configure_source(uint32_t f_in, uint32_t f_out,
|
||||
CLOCKS_CLK_REF_CTRL_SRC_Enum source);
|
||||
|
||||
/**
|
||||
* @brief Configure the reference clock to run from an auxiliary clock source,
|
||||
* like PLL
|
||||
*
|
||||
* @note The auxiliary must have been configured beforehand
|
||||
*
|
||||
* @param f_in Input frequency of the auxiliary clock source
|
||||
* @param f_out Output frequency of the reference clock
|
||||
* @param aux Which auxiliary clock source to use
|
||||
*/
|
||||
void clock_ref_configure_aux_source(uint32_t f_in, uint32_t f_out,
|
||||
CLOCKS_CLK_REF_CTRL_AUXSRC_Enum aux);
|
||||
|
||||
/**
|
||||
* @brief Configure the peripheral clock to run from a dedicated auxiliary
|
||||
* clock source
|
||||
*
|
||||
* @param aux Auxiliary clock source
|
||||
*/
|
||||
void clock_periph_configure(CLOCKS_CLK_PERI_CTRL_AUXSRC_Enum aux);
|
||||
|
||||
/**
|
||||
* @brief Configure gpio21 as clock output pin
|
||||
*
|
||||
* @details Can be used as an external clock source for another circuit or
|
||||
* to check the expected signal with a logic analyzer
|
||||
*
|
||||
* @param f_in Input frequency
|
||||
* @param f_out Output frequency
|
||||
* @param aux Auxiliary clock source
|
||||
*/
|
||||
void clock_gpout0_configure(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_GPOUT0_CTRL_AUXSRC_Enum aux);
|
||||
|
||||
/**
|
||||
* @brief Configure gpio23 as clock output pin
|
||||
*
|
||||
* @details Can be used as an external clock source for another circuit or
|
||||
* to check the expected signal with a logic analyzer
|
||||
*
|
||||
* @param f_in Input frequency
|
||||
* @param f_out Output frequency
|
||||
* @param aux Auxiliary clock source
|
||||
*/
|
||||
void clock_gpout1_configure(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_GPOUT1_CTRL_AUXSRC_Enum aux);
|
||||
|
||||
/**
|
||||
* @brief Configure gpio24 as clock output pin
|
||||
*
|
||||
* @details Can be used as an external clock source for another circuit or
|
||||
* to check the expected signal with a logic analyzer
|
||||
*
|
||||
* @param f_in Input frequency
|
||||
* @param f_out Output frequency
|
||||
* @param aux Auxiliary clock source
|
||||
*/
|
||||
void clock_gpout2_configure(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_GPOUT2_CTRL_AUXSRC_Enum aux);
|
||||
|
||||
/**
|
||||
* @brief Configure gpio25 as clock output pin
|
||||
*
|
||||
* @details Can be used as an external clock source for another circuit or
|
||||
* to check the expected signal with a logic analyzer
|
||||
*
|
||||
* @param f_in Input frequency
|
||||
* @param f_out Output frequency
|
||||
* @param aux Auxiliary clock source
|
||||
*/
|
||||
void clock_gpout3_configure(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_GPOUT3_CTRL_AUXSRC_Enum aux);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name RP2040 PLL configuration
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Start the PLL for the system clock
|
||||
* output[MHz] = f_ref / @p ref_div * @p vco_feedback_scale / @p post_div_1 / @p post_div_2
|
||||
*
|
||||
* @note Usual setting should be (12 MHz, 1, 125, 6, 2) to get a 125 MHz system clock signal
|
||||
*
|
||||
* @param ref_div Input clock divisor
|
||||
* @param vco_feedback_scale VCO feedback scales
|
||||
* @param post_div_1 Output post divider factor 1
|
||||
* @param post_div_2 Output post divider factor 2
|
||||
*/
|
||||
void pll_start_sys(uint8_t ref_div,
|
||||
uint16_t vco_feedback_scale,
|
||||
uint8_t post_div_1, uint8_t post_div_2);
|
||||
|
||||
/**
|
||||
* @brief Start the PLL for the system clock
|
||||
* output[MHz] = f_ref / @p ref_div * @p vco_feedback_scale / @p post_div_1 / @p post_div_2
|
||||
*
|
||||
* @note Usual setting should be (12 MHz, 1, 40, 5, 2) to get a 48 MHz USB clock signal
|
||||
*
|
||||
* @param ref_div Input clock divisor
|
||||
* @param vco_feedback_scale VCO feedback scales
|
||||
* @param post_div_1 Output post divider factor 1
|
||||
* @param post_div_2 Output post divider factor 2
|
||||
*/
|
||||
void pll_start_usb(uint8_t ref_div,
|
||||
uint16_t vco_feedback_scale,
|
||||
uint8_t post_div_1, uint8_t post_div_2);
|
||||
|
||||
/**
|
||||
* @brief Stop the PLL of the system clock
|
||||
*/
|
||||
void pll_stop_sys(void);
|
||||
|
||||
/**
|
||||
* @brief Stop the PLL of the USB clock
|
||||
*/
|
||||
void pll_stop_usb(void);
|
||||
|
||||
/**
|
||||
* @brief Reset the PLL of the system clock
|
||||
*/
|
||||
void pll_reset_sys(void);
|
||||
|
||||
/**
|
||||
* @brief Reset the PLL of the USB clock
|
||||
*/
|
||||
void pll_reset_usb(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name RP2040 XOSC configuration
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Configures the Crystal to run.
|
||||
*
|
||||
* @param f_ref Desired frequency in Hz
|
||||
*
|
||||
* @pre 1 MHz <= @p f_ref <= 15 MHz.
|
||||
*
|
||||
* The reference hardware manual suggests to use a 12 MHz crystal.
|
||||
*/
|
||||
void xosc_start(uint32_t f_ref);
|
||||
|
||||
/**
|
||||
* @brief Stop the crystal.
|
||||
*/
|
||||
void xosc_stop(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name RP2040 ROSC configuration
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Start the ring oscillator in default mode.
|
||||
*
|
||||
* The ROSC is running at boot time but may be turned off to save power when switching to the
|
||||
* accurate XOSC. The default ROSC provides an instable frequency of 1.8 MHz to 12 MHz.
|
||||
*/
|
||||
void rosc_start(void);
|
||||
|
||||
/**
|
||||
* @brief Turn off the ROSC to save power.
|
||||
* The system clock must be switched to to another lock source
|
||||
* before the ROSC is stopped, other wise the chip will be lock up.
|
||||
*/
|
||||
void rosc_stop(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PERIPH_CPU_H */
|
||||
/** @} */
|
29410
cpu/rpx0xx/include/vendor/RP2040.h
vendored
Normal file
29410
cpu/rpx0xx/include/vendor/RP2040.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
67
cpu/rpx0xx/include/vendor/system_RP2040.h
vendored
Normal file
67
cpu/rpx0xx/include/vendor/system_RP2040.h
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
/*************************************************************************//**
|
||||
* @file system_RP2040.h
|
||||
* @brief CMSIS-Core(M) Device Peripheral Access Layer Header File for
|
||||
* Device RP2040
|
||||
* @version V1.0.0
|
||||
* @date 5. May 2021
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2021 Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _CMSIS_SYSTEM_RP2040_H
|
||||
#define _CMSIS_SYSTEM_RP2040_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
\brief Exception / Interrupt Handler Function Prototype
|
||||
*/
|
||||
typedef void(*VECTOR_TABLE_Type)(void);
|
||||
|
||||
/**
|
||||
\brief System Clock Frequency (Core Clock)
|
||||
*/
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
/**
|
||||
\brief Setup the microcontroller system.
|
||||
|
||||
Initialize the System and update the SystemCoreClock variable.
|
||||
*/
|
||||
extern void SystemInit (void);
|
||||
|
||||
|
||||
/**
|
||||
\brief Update SystemCoreClock variable.
|
||||
|
||||
Updates the SystemCoreClock with current core Clock retrieved from cpu registers.
|
||||
*/
|
||||
extern void SystemCoreClockUpdate (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CMSIS_SYSTEM_RP2040_H */
|
46
cpu/rpx0xx/ldscripts/RP2040.ld
Normal file
46
cpu/rpx0xx/ldscripts/RP2040.ld
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Otto-von-Guericke-Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_rp2040
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Memory definitions for the RP2040 MCU
|
||||
*
|
||||
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
INCLUDE cortexm.ld
|
||||
|
||||
MEMORY
|
||||
{
|
||||
boot_loader (rx) : ORIGIN = 0x10000000, LENGTH = 0x100
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
.boot_loader :
|
||||
{
|
||||
__boot_loader_start__ = .;
|
||||
KEEP(*(.boot2));
|
||||
__boot_loader_end__ = .;
|
||||
KEEP(*(.boot2));
|
||||
} > boot_loader
|
||||
|
||||
ASSERT(__boot_loader_end__ - __boot_loader_start__ == 256,
|
||||
"ERROR: RP2040 second stage bootloader must be 256 bytes in size")
|
||||
|
||||
/* Reserve 16 KiB of RAM for virtual CMSIS-DAP on-chip debugging adapter
|
||||
* running on the second core */
|
||||
.pico-debug 0x2003C000:
|
||||
{
|
||||
. = . + 16K;
|
||||
} > ram
|
||||
}
|
1
cpu/rpx0xx/periph/Makefile
Normal file
1
cpu/rpx0xx/periph/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTMAKE)/periph.mk
|
235
cpu/rpx0xx/periph/gpio.c
Normal file
235
cpu/rpx0xx/periph/gpio.c
Normal file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Otto-von-Guericke Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_rpx0xx
|
||||
* @ingroup drivers_periph_gpio
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief GPIO driver implementation for the RP2040
|
||||
*
|
||||
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "bitarithm.h"
|
||||
#include "board.h"
|
||||
#include "irq.h"
|
||||
#include "periph/gpio.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph_cpu.h"
|
||||
#include "io_reg.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define GPIO_PIN_NUMOF 30U
|
||||
|
||||
#ifdef MODULE_PERIPH_GPIO_IRQ
|
||||
static gpio_cb_t _cbs[GPIO_PIN_NUMOF];
|
||||
static void *_args[GPIO_PIN_NUMOF];
|
||||
#endif /* MODULE_PERIPH_GPIO_IRQ */
|
||||
|
||||
int gpio_init(gpio_t pin, gpio_mode_t mode)
|
||||
{
|
||||
assert(pin < GPIO_PIN_NUMOF);
|
||||
SIO->GPIO_OE_CLR.reg = 1LU << pin;
|
||||
SIO->GPIO_OUT_CLR.reg = 1LU << pin;
|
||||
|
||||
switch (mode) {
|
||||
case GPIO_IN:
|
||||
{
|
||||
gpio_pad_ctrl_t pad_config = {
|
||||
.input_enable = 1,
|
||||
.schmitt_trig_enable = 1
|
||||
};
|
||||
gpio_io_ctrl_t io_config = {
|
||||
.function_select = FUNCTION_SELECT_SIO,
|
||||
};
|
||||
gpio_set_pad_config(pin, pad_config);
|
||||
gpio_set_io_config(pin, io_config);
|
||||
}
|
||||
break;
|
||||
case GPIO_IN_PD:
|
||||
{
|
||||
gpio_pad_ctrl_t pad_config = {
|
||||
.pull_down_enable = 1,
|
||||
.input_enable = 1,
|
||||
.schmitt_trig_enable = 1
|
||||
};
|
||||
gpio_io_ctrl_t io_config = {
|
||||
.function_select = FUNCTION_SELECT_SIO,
|
||||
};
|
||||
gpio_set_pad_config(pin, pad_config);
|
||||
gpio_set_io_config(pin, io_config);
|
||||
}
|
||||
break;
|
||||
case GPIO_IN_PU:
|
||||
{
|
||||
gpio_pad_ctrl_t pad_config = {
|
||||
.pull_up_enable = 1,
|
||||
.input_enable = 1,
|
||||
.schmitt_trig_enable = 1
|
||||
};
|
||||
gpio_io_ctrl_t io_config = {
|
||||
.function_select = FUNCTION_SELECT_SIO,
|
||||
};
|
||||
gpio_set_pad_config(pin, pad_config);
|
||||
gpio_set_io_config(pin, io_config);
|
||||
}
|
||||
break;
|
||||
case GPIO_OUT:
|
||||
{
|
||||
gpio_pad_ctrl_t pad_config = {
|
||||
.drive_strength = DRIVE_STRENGTH_12MA,
|
||||
};
|
||||
gpio_io_ctrl_t io_config = {
|
||||
.function_select = FUNCTION_SELECT_SIO,
|
||||
};
|
||||
gpio_set_pad_config(pin, pad_config);
|
||||
gpio_set_io_config(pin, io_config);
|
||||
}
|
||||
SIO->GPIO_OE_SET.reg = 1LU << pin;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gpio_read(gpio_t pin)
|
||||
{
|
||||
if (SIO->GPIO_OE.reg & (1LU << pin)) {
|
||||
/* pin is output: */
|
||||
return SIO->GPIO_OUT.reg & (1LU << pin);
|
||||
}
|
||||
/* pin is input: */
|
||||
return SIO->GPIO_IN.reg & (1LU << pin);
|
||||
}
|
||||
|
||||
void gpio_set(gpio_t pin)
|
||||
{
|
||||
SIO->GPIO_OUT_SET.reg = 1LU << pin;
|
||||
}
|
||||
|
||||
void gpio_clear(gpio_t pin)
|
||||
{
|
||||
SIO->GPIO_OUT_CLR.reg = 1LU << pin;
|
||||
}
|
||||
|
||||
void gpio_toggle(gpio_t pin)
|
||||
{
|
||||
SIO->GPIO_OUT_XOR.reg = 1LU << pin;
|
||||
}
|
||||
|
||||
void gpio_write(gpio_t pin, int value)
|
||||
{
|
||||
if (value) {
|
||||
gpio_set(pin);
|
||||
}
|
||||
else {
|
||||
gpio_clear(pin);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MODULE_PERIPH_GPIO_IRQ
|
||||
static void _irq_enable(gpio_t pin, unsigned flank)
|
||||
{
|
||||
volatile uint32_t *irq_enable_regs = &IO_BANK0->PROC0_INTE0.reg;
|
||||
volatile uint32_t *irq_ack_regs = &IO_BANK0->INTR0.reg;
|
||||
/* There are 4 bits to control IRQs per pin, hence the configuration is split across multiple
|
||||
* I/O registers. The following calculates the position the four bits matching the given pin,
|
||||
* where idx refers to the I/O register and shift_amount to the position in the I/O register.
|
||||
*/
|
||||
unsigned shift_amount = (pin & 0x7) << 2;
|
||||
unsigned idx = pin >> 3;
|
||||
/* make access atomic by disabling IRQs */
|
||||
unsigned irq_state = irq_disable();
|
||||
uint32_t value = irq_enable_regs[idx];
|
||||
/* clear any stray IRQs */
|
||||
io_reg_atomic_clear(&irq_ack_regs[idx], 0xFLU << shift_amount);
|
||||
/* first, clear previous setting */
|
||||
value &= ~(0xFLU << shift_amount);
|
||||
/* then, apply new setting */
|
||||
value |= flank << shift_amount;
|
||||
irq_enable_regs[idx] = value;
|
||||
irq_restore(irq_state);
|
||||
NVIC_EnableIRQ(IO_IRQ_BANK0_IRQn);
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_t pin)
|
||||
{
|
||||
io_reg_atomic_clear(gpio_io_register(pin), IO_BANK0_GPIO1_CTRL_IRQOVER_Msk);
|
||||
}
|
||||
|
||||
void gpio_irq_disable(gpio_t pin)
|
||||
{
|
||||
/* Beware: The two-bit IRQOVER value needs to be set to 0b10 == IRQ_OVERRIDE_LOW. This
|
||||
* implementation will set IRQOVER only to either 0b00 == IRQ_OVERRIDE_NORMAL or
|
||||
* 0b10 == IRQ_OVERRIDE_LOW. If we just set the most significant bit, this will result in
|
||||
* IRQOVER set to IRQ_OVERRIDE_LOW.
|
||||
*
|
||||
* IRQOVER must not be set by user code for this to work, though.
|
||||
*/
|
||||
io_reg_atomic_set(gpio_io_register(pin), IRQ_OVERRIDE_LOW << IO_BANK0_GPIO1_CTRL_IRQOVER_Pos);
|
||||
}
|
||||
|
||||
int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, gpio_cb_t cb, void *arg)
|
||||
{
|
||||
assert(pin < GPIO_PIN_NUMOF);
|
||||
int retval = gpio_init(pin, mode);
|
||||
if (retval) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
_cbs[pin] = cb;
|
||||
_args[pin] = arg;
|
||||
_irq_enable(pin, flank);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void isr_io_bank0(void)
|
||||
{
|
||||
unsigned offset = 0;
|
||||
volatile uint32_t *irq_status_regs = &IO_BANK0->PROC0_INTS0.reg;
|
||||
volatile uint32_t *irq_ack_regs = &IO_BANK0->INTR0.reg;
|
||||
|
||||
DEBUG("[rp0x00] GPIO IRQ mask: %08x, %08x, %08x, %08x\n",
|
||||
(unsigned)IO_BANK0->PROC0_INTE0.reg, (unsigned)IO_BANK0->PROC0_INTE1.reg,
|
||||
(unsigned)IO_BANK0->PROC0_INTE2.reg, (unsigned)IO_BANK0->PROC0_INTE3.reg);
|
||||
DEBUG("[rp0x00] GPIO IRQ status: %08x, %08x, %08x, %08x\n",
|
||||
(unsigned)IO_BANK0->PROC0_INTS0.reg, (unsigned)IO_BANK0->PROC0_INTS1.reg,
|
||||
(unsigned)IO_BANK0->PROC0_INTS2.reg, (unsigned)IO_BANK0->PROC0_INTS3.reg);
|
||||
|
||||
/* There are four IRQ status bits per pin, so there is info for 8 pins per I/O register.
|
||||
* We will iterate over all IRQ status I/O registers in the outer loop, and over all 8 pins
|
||||
* per register in the inner loop */
|
||||
for (unsigned i = 0; i < (GPIO_PIN_NUMOF + 7) / 8; i++, offset += 8) {
|
||||
unsigned status = irq_status_regs[i];
|
||||
irq_ack_regs[i] = status;
|
||||
for (unsigned pin = 0; pin < 8; pin++) {
|
||||
/* Note: Not use bitarithm_test_and_clear() here, since two bits for a single pin could
|
||||
* be set. This happens if both rising and falling flank (1 bit used to track each) have
|
||||
* occurred until the ISR started to handle the first IRQ.
|
||||
*/
|
||||
if (status & (0xFLU << (pin << 2))) {
|
||||
if (_cbs[pin + offset]) {
|
||||
_cbs[pin + offset](_args[pin + offset]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cortexm_isr_end();
|
||||
}
|
||||
|
||||
#endif /* MODULE_PERIPH_GPIO_IRQ */
|
118
cpu/rpx0xx/pll.c
Normal file
118
cpu/rpx0xx/pll.c
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Otto-von-Guericke Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_rpx0xx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the phase locked loop (PLL)
|
||||
* to drive the ROSC or XOSC to a higher frequency
|
||||
*
|
||||
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "macros/units.h"
|
||||
#include "periph_cpu.h"
|
||||
#include "vendor/RP2040.h"
|
||||
#include "io_reg.h"
|
||||
|
||||
/**
|
||||
* @brief Start the PLL for the system clock (@p pll = PLL_SYS) or
|
||||
* the USB clock (@p pll = PLL_USB)
|
||||
*/
|
||||
static void _pll_start(PLL_SYS_Type *pll, uint8_t ref_div,
|
||||
uint16_t vco_feedback_scale,
|
||||
uint8_t post_div_1, uint8_t post_div_2)
|
||||
{
|
||||
assert(PLL_REF_DIV_MIN <= ref_div);
|
||||
assert(ref_div <= PLL_REF_DIV_MAX);
|
||||
assert(PLL_VCO_FEEDBACK_SCALE_MIN <= vco_feedback_scale);
|
||||
assert(vco_feedback_scale <= PLL_VCO_FEEDBACK_SCALE_MAX);
|
||||
assert(PLL_POSTDIV_MIN <= post_div_1);
|
||||
assert(post_div_1 <= PLL_POSTDIV_MAX);
|
||||
assert(PLL_POSTDIV_MIN <= post_div_2);
|
||||
assert(post_div_2 <= PLL_POSTDIV_MAX);
|
||||
|
||||
/* program reference clock divider */
|
||||
io_reg_write_dont_corrupt(&pll->CS.reg, ref_div << PLL_SYS_CS_REFDIV_Pos,
|
||||
PLL_SYS_CS_REFDIV_Msk);
|
||||
/* program feedback divider */
|
||||
io_reg_write_dont_corrupt(&pll->FBDIV_INT.reg,
|
||||
vco_feedback_scale << PLL_SYS_FBDIV_INT_FBDIV_INT_Pos,
|
||||
PLL_SYS_FBDIV_INT_FBDIV_INT_Msk);
|
||||
/* turn on the main power */
|
||||
io_reg_atomic_clear(&pll->PWR.reg, (1U << PLL_SYS_PWR_VCOPD_Pos)
|
||||
| (1U << PLL_SYS_PWR_DSMPD_Pos)
|
||||
| (1U << PLL_SYS_PWR_PD_Pos));
|
||||
/* wait for VCO to lock (i.e. keep its output stable) */
|
||||
while (!pll->CS.bit.LOCK) { }
|
||||
/* set up post divisors and turn them on */
|
||||
pll->PRIM.reg = (post_div_1 << PLL_SYS_PRIM_POSTDIV1_Pos)
|
||||
| (post_div_2 << PLL_SYS_PRIM_POSTDIV2_Pos);
|
||||
io_reg_atomic_clear(&pll->PWR.reg, 1U << PLL_SYS_PWR_POSTDIVPD_Pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop the PLL for the system clock (@p pll = PLL_SYS) or
|
||||
* the USB clock (@p pll = PLL_USB)
|
||||
*/
|
||||
static void _pll_stop(PLL_SYS_Type *pll)
|
||||
{
|
||||
uint32_t reg = (1U << PLL_SYS_PWR_VCOPD_Pos)
|
||||
| (1U << PLL_SYS_PWR_POSTDIVPD_Pos)
|
||||
| (1U << PLL_SYS_PWR_DSMPD_Pos)
|
||||
| (1U << PLL_SYS_PWR_PD_Pos);
|
||||
io_reg_atomic_set(&pll->PWR.reg, reg);
|
||||
}
|
||||
|
||||
void pll_start_sys(uint8_t ref_div,
|
||||
uint16_t vco_feedback_scale,
|
||||
uint8_t post_div_1, uint8_t post_div_2)
|
||||
{
|
||||
_pll_start(PLL_SYS, ref_div, vco_feedback_scale, post_div_1, post_div_2);
|
||||
}
|
||||
|
||||
void pll_start_usb(uint8_t ref_div,
|
||||
uint16_t vco_feedback_scale,
|
||||
uint8_t post_div_1, uint8_t post_div_2)
|
||||
{
|
||||
_pll_start(PLL_USB, ref_div, vco_feedback_scale, post_div_1, post_div_2);
|
||||
}
|
||||
|
||||
void pll_stop_sys(void)
|
||||
{
|
||||
_pll_stop(PLL_SYS);
|
||||
}
|
||||
|
||||
void pll_stop_usb(void)
|
||||
{
|
||||
_pll_stop(PLL_USB);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the PLL of the system clock
|
||||
*/
|
||||
void pll_reset_sys(void)
|
||||
{
|
||||
periph_reset(1U << RESETS_RESET_pll_sys_Pos);
|
||||
periph_reset_done(1U << RESETS_RESET_pll_sys_Pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the PLL of the USB clock
|
||||
*/
|
||||
void pll_reset_usb(void)
|
||||
{
|
||||
periph_reset(1U << RESETS_RESET_pll_usb_Pos);
|
||||
periph_reset_done(1U << RESETS_RESET_pll_usb_Pos);
|
||||
}
|
57
cpu/rpx0xx/rosc.c
Normal file
57
cpu/rpx0xx/rosc.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Otto-von-Guericke Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_rpx0xx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the ring oscillator (ROSC)
|
||||
*
|
||||
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
||||
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "vendor/RP2040.h"
|
||||
#include "io_reg.h"
|
||||
|
||||
/**
|
||||
* @brief Start the ring oscillator in default mode.
|
||||
* The ROSC is running at boot time but may be turned off
|
||||
* to save power when switching to the accurate XOSC.
|
||||
* The default ROSC provides an instable frequency of 1.8 MHz to 12 MHz.
|
||||
*/
|
||||
void rosc_start(void)
|
||||
{
|
||||
/* set drive strengths to default 0 */
|
||||
io_reg_atomic_clear(&ROSC->FREQA.reg, ROSC_FREQA_PASSWD_Msk);
|
||||
io_reg_atomic_clear(&ROSC->FREQB.reg, ROSC_FREQB_PASSWD_Msk);
|
||||
/* apply settings with magic value 0x9696 */
|
||||
const uint32_t magic = 0x9696U;
|
||||
io_reg_write_dont_corrupt(&ROSC->FREQA.reg, magic << ROSC_FREQA_PASSWD_Pos,
|
||||
ROSC_FREQA_PASSWD_Msk);
|
||||
io_reg_write_dont_corrupt(&ROSC->FREQB.reg, magic << ROSC_FREQB_PASSWD_Pos,
|
||||
ROSC_FREQB_PASSWD_Msk);
|
||||
|
||||
/* default divider is 16 */
|
||||
io_reg_write_dont_corrupt(&ROSC->DIV.reg, 16 << ROSC_DIV_DIV_Pos, ROSC_DIV_DIV_Msk);
|
||||
io_reg_atomic_set(&ROSC->CTRL.reg, ROSC_CTRL_ENABLE_ENABLE << ROSC_CTRL_ENABLE_Pos);
|
||||
while (!ROSC->STATUS.bit.STABLE) { }
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turn off the ROSC to save power.
|
||||
* The system clock must be switched to to another lock source
|
||||
* before the ROSC is stopped, other wise the chip will be lock up.
|
||||
*/
|
||||
void rosc_stop(void)
|
||||
{
|
||||
io_reg_atomic_set(&ROSC->CTRL.reg, ROSC_CTRL_ENABLE_DISABLE << ROSC_CTRL_ENABLE_Pos);
|
||||
}
|
95
cpu/rpx0xx/vectors.c
Normal file
95
cpu/rpx0xx/vectors.c
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Otto-von-Guericke Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_rpx0xx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief rpx0xx interrupt vector definitions
|
||||
*
|
||||
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "vectors_cortexm.h"
|
||||
|
||||
void dummy_handler(void) {
|
||||
dummy_handler_default();
|
||||
}
|
||||
|
||||
WEAK_DEFAULT void isr_timer0(void);
|
||||
WEAK_DEFAULT void isr_timer1(void);
|
||||
WEAK_DEFAULT void isr_timer2(void);
|
||||
WEAK_DEFAULT void isr_timer3(void);
|
||||
WEAK_DEFAULT void isr_pwm_wrap(void);
|
||||
WEAK_DEFAULT void isr_usbctrl(void);
|
||||
WEAK_DEFAULT void isr_xip(void);
|
||||
WEAK_DEFAULT void isr_pio00(void);
|
||||
WEAK_DEFAULT void isr_pio01(void);
|
||||
WEAK_DEFAULT void isr_pio10(void);
|
||||
WEAK_DEFAULT void isr_pio11(void);
|
||||
WEAK_DEFAULT void isr_dma0(void);
|
||||
WEAK_DEFAULT void isr_dma1(void);
|
||||
WEAK_DEFAULT void isr_io_bank0(void);
|
||||
WEAK_DEFAULT void isr_io_qspi(void);
|
||||
WEAK_DEFAULT void isr_sio_proc0(void);
|
||||
WEAK_DEFAULT void isr_sio_proc1(void);
|
||||
WEAK_DEFAULT void isr_clocks(void);
|
||||
WEAK_DEFAULT void isr_spi0(void);
|
||||
WEAK_DEFAULT void isr_spi1(void);
|
||||
WEAK_DEFAULT void isr_uart0(void);
|
||||
WEAK_DEFAULT void isr_uart1(void);
|
||||
WEAK_DEFAULT void isr_adc_fifo(void);
|
||||
WEAK_DEFAULT void isr_i2c0(void);
|
||||
WEAK_DEFAULT void isr_i2c1(void);
|
||||
WEAK_DEFAULT void isr_rtc0(void);
|
||||
WEAK_DEFAULT void isr_swi0(void);
|
||||
WEAK_DEFAULT void isr_swi1(void);
|
||||
WEAK_DEFAULT void isr_swi2(void);
|
||||
WEAK_DEFAULT void isr_swi3(void);
|
||||
WEAK_DEFAULT void isr_swi4(void);
|
||||
WEAK_DEFAULT void isr_swi5(void);
|
||||
|
||||
ISR_VECTOR(1) const isr_t vector_cpu[CPU_IRQ_NUMOF] = {
|
||||
isr_timer0,
|
||||
isr_timer1,
|
||||
isr_timer2,
|
||||
isr_timer3,
|
||||
isr_pwm_wrap,
|
||||
isr_usbctrl,
|
||||
isr_xip,
|
||||
isr_pio00,
|
||||
isr_pio01,
|
||||
isr_pio10,
|
||||
isr_pio11,
|
||||
isr_dma0,
|
||||
isr_dma1,
|
||||
isr_io_bank0,
|
||||
isr_io_qspi,
|
||||
isr_sio_proc0,
|
||||
isr_sio_proc1,
|
||||
isr_clocks,
|
||||
isr_spi0,
|
||||
isr_spi1,
|
||||
isr_uart0,
|
||||
isr_uart1,
|
||||
isr_adc_fifo,
|
||||
isr_i2c0,
|
||||
isr_i2c1,
|
||||
isr_rtc0,
|
||||
isr_swi0,
|
||||
isr_swi1,
|
||||
isr_swi2,
|
||||
isr_swi3,
|
||||
isr_swi4,
|
||||
isr_swi5,
|
||||
};
|
1
cpu/rpx0xx/vendor/boot_stage2/.gitignore
vendored
Normal file
1
cpu/rpx0xx/vendor/boot_stage2/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/*padded_checksummed.S
|
33
cpu/rpx0xx/vendor/boot_stage2/Makefile
vendored
Normal file
33
cpu/rpx0xx/vendor/boot_stage2/Makefile
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
CC := arm-none-eabi-gcc
|
||||
OBJCOPY := arm-none-eabi-objcopy
|
||||
CFLAGS := -mcpu=cortex-m0plus -mthumb -O3 -DNDEBUG -I$(abspath include)
|
||||
LDFLAGS := -Wl,--build-id=none --specs=nosys.specs -nostartfiles -Wl,--script=boot_stage2.ld
|
||||
PAD_CHECKSUM := ./pad_checksum
|
||||
CHECKSUM_SEED := 0xffffffff
|
||||
|
||||
.PHONY: clean all
|
||||
|
||||
all: \
|
||||
boot2_at25sf128a_padded_checksummed.S \
|
||||
boot2_generic_03h_padded_checksummed.S \
|
||||
boot2_is25lp080_padded_checksummed.S \
|
||||
boot2_usb_blinky_padded_checksummed.S \
|
||||
boot2_w25q080_padded_checksummed.S \
|
||||
boot2_w25x10cl_padded_checksummed.S \
|
||||
#
|
||||
|
||||
clean:
|
||||
rm -f *_padded_checksummed.S *.o *.bin *.elf
|
||||
|
||||
%.o: %.S
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
%.elf: %.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
|
||||
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) -Obinary $< $@
|
||||
|
||||
%_padded_checksummed.S: %.bin
|
||||
$(PAD_CHECKSUM) -s $(CHECKSUM_SEED) $< $@
|
||||
|
5
cpu/rpx0xx/vendor/boot_stage2/README.md
vendored
Normal file
5
cpu/rpx0xx/vendor/boot_stage2/README.md
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
How to Generate
|
||||
===============
|
||||
|
||||
Run `make` create the bootloader. The source is taken from the pico-sdk. Ideally, the
|
||||
boot loader needs to never be touched.
|
285
cpu/rpx0xx/vendor/boot_stage2/boot2_at25sf128a.S
vendored
Normal file
285
cpu/rpx0xx/vendor/boot_stage2/boot2_at25sf128a.S
vendored
Normal file
@ -0,0 +1,285 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Second stage boot code
|
||||
// Copyright (c) 2019-2021 Raspberry Pi (Trading) Ltd.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
//
|
||||
// Device: Adesto AT25SF128A
|
||||
// Based on W25Q080 code: main difference is the QE bit is being set
|
||||
// via command 0x31
|
||||
//
|
||||
// Description: Configures AT25SF128A to run in Quad I/O continuous read XIP mode
|
||||
//
|
||||
// Details: * Check status register 2 to determine if QSPI mode is enabled,
|
||||
// and perform an SR2 programming cycle if necessary.
|
||||
// * Use SSI to perform a dummy 0xEB read command, with the mode
|
||||
// continuation bits set, so that the flash will not require
|
||||
// 0xEB instruction prefix on subsequent reads.
|
||||
// * Configure SSI to write address, mode bits, but no instruction.
|
||||
// SSI + flash are now jointly in a state where continuous reads
|
||||
// can take place.
|
||||
// * Jump to exit pointer passed in via lr. Bootrom passes null,
|
||||
// in which case this code uses a default 256 byte flash offset
|
||||
//
|
||||
// Building: * This code must be position-independent, and use stack only
|
||||
// * The code will be padded to a size of 256 bytes, including a
|
||||
// 4-byte checksum. Therefore code size cannot exceed 252 bytes.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "pico/asm_helper.S"
|
||||
#include "hardware/regs/addressmap.h"
|
||||
#include "hardware/regs/ssi.h"
|
||||
#include "hardware/regs/pads_qspi.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Config section
|
||||
// ----------------------------------------------------------------------------
|
||||
// It should be possible to support most flash devices by modifying this section
|
||||
|
||||
// The serial flash interface will run at clk_sys/PICO_FLASH_SPI_CLKDIV.
|
||||
// This must be a positive, even integer.
|
||||
// The bootrom is very conservative with SPI frequency, but here we should be
|
||||
// as aggressive as possible.
|
||||
|
||||
#ifndef PICO_FLASH_SPI_CLKDIV
|
||||
#define PICO_FLASH_SPI_CLKDIV 4
|
||||
#endif
|
||||
#if PICO_FLASH_SPI_CLKDIV & 1
|
||||
#error PICO_FLASH_SPI_CLKDIV must be even
|
||||
#endif
|
||||
|
||||
// Define interface width: single/dual/quad IO
|
||||
#define FRAME_FORMAT SSI_CTRLR0_SPI_FRF_VALUE_QUAD
|
||||
|
||||
// For W25Q080 this is the "Read data fast quad IO" instruction:
|
||||
#define CMD_READ 0xeb
|
||||
|
||||
// "Mode bits" are 8 special bits sent immediately after
|
||||
// the address bits in a "Read Data Fast Quad I/O" command sequence.
|
||||
// On W25Q080, the four LSBs are don't care, and if MSBs == 0xa, the
|
||||
// next read does not require the 0xeb instruction prefix.
|
||||
#define MODE_CONTINUOUS_READ 0x20
|
||||
|
||||
// The number of address + mode bits, divided by 4 (always 4, not function of
|
||||
// interface width).
|
||||
#define ADDR_L 8
|
||||
|
||||
// How many clocks of Hi-Z following the mode bits. For W25Q080, 4 dummy cycles
|
||||
// are required.
|
||||
#define WAIT_CYCLES 4
|
||||
|
||||
// If defined, we will read status reg, compare to SREG_DATA, and overwrite
|
||||
// with our value if the SR doesn't match.
|
||||
// We do a two-byte write to SR1 (01h cmd) rather than a one-byte write to
|
||||
// SR2 (31h cmd) as the latter command isn't supported by WX25Q080.
|
||||
// This isn't great because it will remove block protections.
|
||||
// A better solution is to use a volatile SR write if your device supports it.
|
||||
#define PROGRAM_STATUS_REG
|
||||
|
||||
#define CMD_WRITE_ENABLE 0x06
|
||||
#define CMD_READ_STATUS 0x05
|
||||
#define CMD_READ_STATUS2 0x35
|
||||
#define CMD_WRITE_STATUS 0x01
|
||||
#define CMD_WRITE_STATUS2 0x31
|
||||
#define SREG_DATA 0x02 // Enable quad-SPI mode
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Start of 2nd Stage Boot Code
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m0plus
|
||||
.thumb
|
||||
|
||||
.section .text
|
||||
|
||||
// The exit point is passed in lr. If entered from bootrom, this will be the
|
||||
// flash address immediately following this second stage (0x10000100).
|
||||
// Otherwise it will be a return address -- second stage being called as a
|
||||
// function by user code, after copying out of XIP region. r3 holds SSI base,
|
||||
// r0...2 used as temporaries. Other GPRs not used.
|
||||
.global _stage2_boot
|
||||
.type _stage2_boot,%function
|
||||
.thumb_func
|
||||
_stage2_boot:
|
||||
push {lr}
|
||||
|
||||
// Set pad configuration:
|
||||
// - SCLK 8mA drive, no slew limiting
|
||||
// - SDx disable input Schmitt to reduce delay
|
||||
|
||||
ldr r3, =PADS_QSPI_BASE
|
||||
movs r0, #(2 << PADS_QSPI_GPIO_QSPI_SCLK_DRIVE_LSB | PADS_QSPI_GPIO_QSPI_SCLK_SLEWFAST_BITS)
|
||||
str r0, [r3, #PADS_QSPI_GPIO_QSPI_SCLK_OFFSET]
|
||||
ldr r0, [r3, #PADS_QSPI_GPIO_QSPI_SD0_OFFSET]
|
||||
movs r1, #PADS_QSPI_GPIO_QSPI_SD0_SCHMITT_BITS
|
||||
bics r0, r1
|
||||
str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD0_OFFSET]
|
||||
str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD1_OFFSET]
|
||||
str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD2_OFFSET]
|
||||
str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD3_OFFSET]
|
||||
|
||||
ldr r3, =XIP_SSI_BASE
|
||||
|
||||
// Disable SSI to allow further config
|
||||
movs r1, #0
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
|
||||
// Set baud rate
|
||||
movs r1, #PICO_FLASH_SPI_CLKDIV
|
||||
str r1, [r3, #SSI_BAUDR_OFFSET]
|
||||
|
||||
// Set 1-cycle sample delay. If PICO_FLASH_SPI_CLKDIV == 2 then this means,
|
||||
// if the flash launches data on SCLK posedge, we capture it at the time that
|
||||
// the next SCLK posedge is launched. This is shortly before that posedge
|
||||
// arrives at the flash, so data hold time should be ok. For
|
||||
// PICO_FLASH_SPI_CLKDIV > 2 this pretty much has no effect.
|
||||
|
||||
movs r1, #1
|
||||
movs r2, #SSI_RX_SAMPLE_DLY_OFFSET // == 0xf0 so need 8 bits of offset significance
|
||||
str r1, [r3, r2]
|
||||
|
||||
|
||||
// On QSPI parts we usually need a 01h SR-write command to enable QSPI mode
|
||||
// (i.e. turn WPn and HOLDn into IO2/IO3)
|
||||
#ifdef PROGRAM_STATUS_REG
|
||||
program_sregs:
|
||||
#define CTRL0_SPI_TXRX \
|
||||
(7 << SSI_CTRLR0_DFS_32_LSB) | /* 8 bits per data frame */ \
|
||||
(SSI_CTRLR0_TMOD_VALUE_TX_AND_RX << SSI_CTRLR0_TMOD_LSB)
|
||||
|
||||
ldr r1, =(CTRL0_SPI_TXRX)
|
||||
str r1, [r3, #SSI_CTRLR0_OFFSET]
|
||||
|
||||
// Enable SSI and select slave 0
|
||||
movs r1, #1
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
|
||||
// Check whether SR needs updating
|
||||
movs r0, #CMD_READ_STATUS2
|
||||
bl read_flash_sreg
|
||||
movs r2, #SREG_DATA
|
||||
cmp r0, r2
|
||||
beq skip_sreg_programming
|
||||
|
||||
// Send write enable command
|
||||
movs r1, #CMD_WRITE_ENABLE
|
||||
str r1, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
// Poll for completion and discard RX
|
||||
bl wait_ssi_ready
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
// Send status write command followed by data bytes
|
||||
movs r1, #CMD_WRITE_STATUS2
|
||||
str r1, [r3, #SSI_DR0_OFFSET]
|
||||
str r2, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
bl wait_ssi_ready
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
// Poll status register for write completion
|
||||
1:
|
||||
movs r0, #CMD_READ_STATUS
|
||||
bl read_flash_sreg
|
||||
movs r1, #1
|
||||
tst r0, r1
|
||||
bne 1b
|
||||
|
||||
skip_sreg_programming:
|
||||
|
||||
// Disable SSI again so that it can be reconfigured
|
||||
movs r1, #0
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
#endif
|
||||
|
||||
// Currently the flash expects an 8 bit serial command prefix on every
|
||||
// transfer, which is a waste of cycles. Perform a dummy Fast Read Quad I/O
|
||||
// command, with mode bits set such that the flash will not expect a serial
|
||||
// command prefix on *subsequent* transfers. We don't care about the results
|
||||
// of the read, the important part is the mode bits.
|
||||
|
||||
dummy_read:
|
||||
#define CTRLR0_ENTER_XIP \
|
||||
(FRAME_FORMAT /* Quad I/O mode */ \
|
||||
<< SSI_CTRLR0_SPI_FRF_LSB) | \
|
||||
(31 << SSI_CTRLR0_DFS_32_LSB) | /* 32 data bits */ \
|
||||
(SSI_CTRLR0_TMOD_VALUE_EEPROM_READ /* Send INST/ADDR, Receive Data */ \
|
||||
<< SSI_CTRLR0_TMOD_LSB)
|
||||
|
||||
ldr r1, =(CTRLR0_ENTER_XIP)
|
||||
str r1, [r3, #SSI_CTRLR0_OFFSET]
|
||||
|
||||
movs r1, #0x0 // NDF=0 (single 32b read)
|
||||
str r1, [r3, #SSI_CTRLR1_OFFSET]
|
||||
|
||||
#define SPI_CTRLR0_ENTER_XIP \
|
||||
(ADDR_L << SSI_SPI_CTRLR0_ADDR_L_LSB) | /* Address + mode bits */ \
|
||||
(WAIT_CYCLES << SSI_SPI_CTRLR0_WAIT_CYCLES_LSB) | /* Hi-Z dummy clocks following address + mode */ \
|
||||
(SSI_SPI_CTRLR0_INST_L_VALUE_8B \
|
||||
<< SSI_SPI_CTRLR0_INST_L_LSB) | /* 8-bit instruction */ \
|
||||
(SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C2A /* Send Command in serial mode then address in Quad I/O mode */ \
|
||||
<< SSI_SPI_CTRLR0_TRANS_TYPE_LSB)
|
||||
|
||||
ldr r1, =(SPI_CTRLR0_ENTER_XIP)
|
||||
ldr r0, =(XIP_SSI_BASE + SSI_SPI_CTRLR0_OFFSET) // SPI_CTRL0 Register
|
||||
str r1, [r0]
|
||||
|
||||
movs r1, #1 // Re-enable SSI
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
|
||||
movs r1, #CMD_READ
|
||||
str r1, [r3, #SSI_DR0_OFFSET] // Push SPI command into TX FIFO
|
||||
movs r1, #MODE_CONTINUOUS_READ // 32-bit: 24 address bits (we don't care, so 0) and M[7:4]=1010
|
||||
str r1, [r3, #SSI_DR0_OFFSET] // Push Address into TX FIFO - this will trigger the transaction
|
||||
|
||||
// Poll for completion
|
||||
bl wait_ssi_ready
|
||||
|
||||
// The flash is in a state where we can blast addresses in parallel, and get
|
||||
// parallel data back. Now configure the SSI to translate XIP bus accesses
|
||||
// into QSPI transfers of this form.
|
||||
|
||||
movs r1, #0
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET] // Disable SSI (and clear FIFO) to allow further config
|
||||
|
||||
// Note that the INST_L field is used to select what XIP data gets pushed into
|
||||
// the TX FIFO:
|
||||
// INST_L_0_BITS {ADDR[23:0],XIP_CMD[7:0]} Load "mode bits" into XIP_CMD
|
||||
// Anything else {XIP_CMD[7:0],ADDR[23:0]} Load SPI command into XIP_CMD
|
||||
configure_ssi:
|
||||
#define SPI_CTRLR0_XIP \
|
||||
(MODE_CONTINUOUS_READ /* Mode bits to keep flash in continuous read mode */ \
|
||||
<< SSI_SPI_CTRLR0_XIP_CMD_LSB) | \
|
||||
(ADDR_L << SSI_SPI_CTRLR0_ADDR_L_LSB) | /* Total number of address + mode bits */ \
|
||||
(WAIT_CYCLES << SSI_SPI_CTRLR0_WAIT_CYCLES_LSB) | /* Hi-Z dummy clocks following address + mode */ \
|
||||
(SSI_SPI_CTRLR0_INST_L_VALUE_NONE /* Do not send a command, instead send XIP_CMD as mode bits after address */ \
|
||||
<< SSI_SPI_CTRLR0_INST_L_LSB) | \
|
||||
(SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_2C2A /* Send Address in Quad I/O mode (and Command but that is zero bits long) */ \
|
||||
<< SSI_SPI_CTRLR0_TRANS_TYPE_LSB)
|
||||
|
||||
ldr r1, =(SPI_CTRLR0_XIP)
|
||||
ldr r0, =(XIP_SSI_BASE + SSI_SPI_CTRLR0_OFFSET)
|
||||
str r1, [r0]
|
||||
|
||||
movs r1, #1
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET] // Re-enable SSI
|
||||
|
||||
// Bus accesses to the XIP window will now be transparently serviced by the
|
||||
// external flash on cache miss. We are ready to run code from flash.
|
||||
|
||||
// Pull in standard exit routine
|
||||
#include "boot2_helpers/exit_from_boot2.S"
|
||||
|
||||
// Common functions
|
||||
#include "boot2_helpers/wait_ssi_ready.S"
|
||||
#ifdef PROGRAM_STATUS_REG
|
||||
#include "boot2_helpers/read_flash_sreg.S"
|
||||
#endif
|
||||
|
||||
.global literals
|
||||
literals:
|
||||
.ltorg
|
||||
|
||||
.end
|
103
cpu/rpx0xx/vendor/boot_stage2/boot2_generic_03h.S
vendored
Normal file
103
cpu/rpx0xx/vendor/boot_stage2/boot2_generic_03h.S
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Second stage boot code
|
||||
// Copyright (c) 2019-2021 Raspberry Pi (Trading) Ltd.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
//
|
||||
// Device: Anything which responds to 03h serial read command
|
||||
//
|
||||
// Details: * Configure SSI to translate each APB read into a 03h command
|
||||
// * 8 command clocks, 24 address clocks and 32 data clocks
|
||||
// * This enables you to boot from almost anything: you can pretty
|
||||
// much solder a potato to your PCB, or a piece of cheese
|
||||
// * The tradeoff is performance around 3x worse than QSPI XIP
|
||||
//
|
||||
// Building: * This code must be position-independent, and use stack only
|
||||
// * The code will be padded to a size of 256 bytes, including a
|
||||
// 4-byte checksum. Therefore code size cannot exceed 252 bytes.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "pico/asm_helper.S"
|
||||
#include "hardware/regs/addressmap.h"
|
||||
#include "hardware/regs/ssi.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Config section
|
||||
// ----------------------------------------------------------------------------
|
||||
// It should be possible to support most flash devices by modifying this section
|
||||
|
||||
// The serial flash interface will run at clk_sys/PICO_FLASH_SPI_CLKDIV.
|
||||
// This must be a positive, even integer.
|
||||
// The bootrom is very conservative with SPI frequency, but here we should be
|
||||
// as aggressive as possible.
|
||||
#ifndef PICO_FLASH_SPI_CLKDIV
|
||||
#define PICO_FLASH_SPI_CLKDIV 4
|
||||
#endif
|
||||
|
||||
#define CMD_READ 0x03
|
||||
|
||||
// Value is number of address bits divided by 4
|
||||
#define ADDR_L 6
|
||||
|
||||
#define CTRLR0_XIP \
|
||||
(SSI_CTRLR0_SPI_FRF_VALUE_STD << SSI_CTRLR0_SPI_FRF_LSB) | /* Standard 1-bit SPI serial frames */ \
|
||||
(31 << SSI_CTRLR0_DFS_32_LSB) | /* 32 clocks per data frame */ \
|
||||
(SSI_CTRLR0_TMOD_VALUE_EEPROM_READ << SSI_CTRLR0_TMOD_LSB) /* Send instr + addr, receive data */
|
||||
|
||||
#define SPI_CTRLR0_XIP \
|
||||
(CMD_READ << SSI_SPI_CTRLR0_XIP_CMD_LSB) | /* Value of instruction prefix */ \
|
||||
(ADDR_L << SSI_SPI_CTRLR0_ADDR_L_LSB) | /* Total number of address + mode bits */ \
|
||||
(2 << SSI_SPI_CTRLR0_INST_L_LSB) | /* 8 bit command prefix (field value is bits divided by 4) */ \
|
||||
(SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C1A << SSI_SPI_CTRLR0_TRANS_TYPE_LSB) /* command and address both in serial format */
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Start of 2nd Stage Boot Code
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.cpu cortex-m0
|
||||
.thumb
|
||||
|
||||
.section .text
|
||||
|
||||
.global _stage2_boot
|
||||
.type _stage2_boot,%function
|
||||
.thumb_func
|
||||
_stage2_boot:
|
||||
push {lr}
|
||||
|
||||
ldr r3, =XIP_SSI_BASE // Use as base address where possible
|
||||
|
||||
// Disable SSI to allow further config
|
||||
mov r1, #0
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
|
||||
// Set baud rate
|
||||
mov r1, #PICO_FLASH_SPI_CLKDIV
|
||||
str r1, [r3, #SSI_BAUDR_OFFSET]
|
||||
|
||||
ldr r1, =(CTRLR0_XIP)
|
||||
str r1, [r3, #SSI_CTRLR0_OFFSET]
|
||||
|
||||
ldr r1, =(SPI_CTRLR0_XIP)
|
||||
ldr r0, =(XIP_SSI_BASE + SSI_SPI_CTRLR0_OFFSET)
|
||||
str r1, [r0]
|
||||
|
||||
// NDF=0 (single 32b read)
|
||||
mov r1, #0x0
|
||||
str r1, [r3, #SSI_CTRLR1_OFFSET]
|
||||
|
||||
// Re-enable SSI
|
||||
mov r1, #1
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
|
||||
// We are now in XIP mode. Any bus accesses to the XIP address window will be
|
||||
// translated by the SSI into 03h read commands to the external flash (if cache is missed),
|
||||
// and the data will be returned to the bus.
|
||||
|
||||
// Pull in standard exit routine
|
||||
#include "boot2_helpers/exit_from_boot2.S"
|
||||
|
||||
.global literals
|
||||
literals:
|
||||
.ltorg
|
||||
|
||||
.end
|
262
cpu/rpx0xx/vendor/boot_stage2/boot2_is25lp080.S
vendored
Normal file
262
cpu/rpx0xx/vendor/boot_stage2/boot2_is25lp080.S
vendored
Normal file
@ -0,0 +1,262 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (c) 2019-2021 Raspberry Pi (Trading) Ltd.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
//
|
||||
// Device: ISSI IS25LP080D
|
||||
// Based on W25Q080 code: main difference is the QE bit being in
|
||||
// SR1 instead of SR2.
|
||||
//
|
||||
// Description: Configures IS25LP080D to run in Quad I/O continuous read XIP mode
|
||||
//
|
||||
// Details: * Check status register to determine if QSPI mode is enabled,
|
||||
// and perform an SR programming cycle if necessary.
|
||||
// * Use SSI to perform a dummy 0xEB read command, with the mode
|
||||
// continuation bits set, so that the flash will not require
|
||||
// 0xEB instruction prefix on subsequent reads.
|
||||
// * Configure SSI to write address, mode bits, but no instruction.
|
||||
// SSI + flash are now jointly in a state where continuous reads
|
||||
// can take place.
|
||||
// * Set VTOR = 0x10000100 (user vector table immediately after
|
||||
// this boot2 image).
|
||||
// * Read stack pointer (MSP) and reset vector from the flash
|
||||
// vector table; set SP and jump, as though the processor had
|
||||
// booted directly from flash.
|
||||
//
|
||||
// Building: * This code must be linked to run at 0x20027f00
|
||||
// * The code will be padded to a size of 256 bytes, including a
|
||||
// 4-byte checksum. Therefore code size cannot exceed 252 bytes.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "pico/asm_helper.S"
|
||||
#include "hardware/regs/addressmap.h"
|
||||
#include "hardware/regs/ssi.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Config section
|
||||
// ----------------------------------------------------------------------------
|
||||
// It should be possible to support most flash devices by modifying this section
|
||||
|
||||
// The serial flash interface will run at clk_sys/PICO_FLASH_SPI_CLKDIV.
|
||||
// This must be a positive, even integer.
|
||||
// The bootrom is very conservative with SPI frequency, but here we should be
|
||||
// as aggressive as possible.
|
||||
#ifndef PICO_FLASH_SPI_CLKDIV
|
||||
#define PICO_FLASH_SPI_CLKDIV 4
|
||||
#endif
|
||||
|
||||
|
||||
// Define interface width: single/dual/quad IO
|
||||
#define FRAME_FORMAT SSI_CTRLR0_SPI_FRF_VALUE_QUAD
|
||||
|
||||
// For W25Q080 this is the "Read data fast quad IO" instruction:
|
||||
#define CMD_READ 0xeb
|
||||
|
||||
// "Mode bits" are 8 special bits sent immediately after
|
||||
// the address bits in a "Read Data Fast Quad I/O" command sequence.
|
||||
// On W25Q080, the four LSBs are don't care, and if MSBs == 0xa, the
|
||||
// next read does not require the 0xeb instruction prefix.
|
||||
#define MODE_CONTINUOUS_READ 0xa0
|
||||
|
||||
// The number of address + mode bits, divided by 4 (always 4, not function of
|
||||
// interface width).
|
||||
#define ADDR_L 8
|
||||
|
||||
// How many clocks of Hi-Z following the mode bits. For W25Q080, 4 dummy cycles
|
||||
// are required.
|
||||
#define WAIT_CYCLES 4
|
||||
|
||||
// If defined, we will read status reg, compare to SREG_DATA, and overwrite
|
||||
// with our value if the SR doesn't match.
|
||||
// This isn't great because it will remove block protections.
|
||||
// A better solution is to use a volatile SR write if your device supports it.
|
||||
#define PROGRAM_STATUS_REG
|
||||
|
||||
#define CMD_WRITE_ENABLE 0x06
|
||||
#define CMD_READ_STATUS 0x05
|
||||
#define CMD_WRITE_STATUS 0x01
|
||||
#define SREG_DATA 0x40 // Enable quad-SPI mode
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Start of 2nd Stage Boot Code
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.cpu cortex-m0
|
||||
.thumb
|
||||
|
||||
.section .text
|
||||
|
||||
.global _stage2_boot
|
||||
.type _stage2_boot,%function
|
||||
.thumb_func
|
||||
_stage2_boot:
|
||||
push {lr}
|
||||
|
||||
ldr r3, =XIP_SSI_BASE // Use as base address where possible
|
||||
|
||||
// Disable SSI to allow further config
|
||||
mov r1, #0
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
|
||||
// Set baud rate
|
||||
mov r1, #PICO_FLASH_SPI_CLKDIV
|
||||
str r1, [r3, #SSI_BAUDR_OFFSET]
|
||||
|
||||
// On QSPI parts we usually need a 01h SR-write command to enable QSPI mode
|
||||
// (i.e. turn WPn and HOLDn into IO2/IO3)
|
||||
#ifdef PROGRAM_STATUS_REG
|
||||
program_sregs:
|
||||
#define CTRL0_SPI_TXRX \
|
||||
(7 << SSI_CTRLR0_DFS_32_LSB) | /* 8 bits per data frame */ \
|
||||
(SSI_CTRLR0_TMOD_VALUE_TX_AND_RX << SSI_CTRLR0_TMOD_LSB)
|
||||
|
||||
ldr r1, =(CTRL0_SPI_TXRX)
|
||||
str r1, [r3, #SSI_CTRLR0_OFFSET]
|
||||
|
||||
// Enable SSI and select slave 0
|
||||
mov r1, #1
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
|
||||
// Check whether SR needs updating
|
||||
ldr r0, =CMD_READ_STATUS
|
||||
bl read_flash_sreg
|
||||
ldr r2, =SREG_DATA
|
||||
cmp r0, r2
|
||||
beq skip_sreg_programming
|
||||
|
||||
// Send write enable command
|
||||
mov r1, #CMD_WRITE_ENABLE
|
||||
str r1, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
// Poll for completion and discard RX
|
||||
bl wait_ssi_ready
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
// Send status write command followed by data bytes
|
||||
mov r1, #CMD_WRITE_STATUS
|
||||
str r1, [r3, #SSI_DR0_OFFSET]
|
||||
mov r0, #0
|
||||
str r2, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
bl wait_ssi_ready
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
// Poll status register for write completion
|
||||
1:
|
||||
ldr r0, =CMD_READ_STATUS
|
||||
bl read_flash_sreg
|
||||
mov r1, #1
|
||||
tst r0, r1
|
||||
bne 1b
|
||||
|
||||
skip_sreg_programming:
|
||||
|
||||
// Send a 0xA3 high-performance-mode instruction
|
||||
// ldr r1, =0xa3
|
||||
// str r1, [r3, #SSI_DR0_OFFSET]
|
||||
// bl wait_ssi_ready
|
||||
|
||||
// Disable SSI again so that it can be reconfigured
|
||||
mov r1, #0
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
#endif
|
||||
|
||||
|
||||
// First we need to send the initial command to get us in to Fast Read Quad I/O
|
||||
// mode. As this transaction requires a command, we can't send it in XIP mode.
|
||||
// To enter Continuous Read mode as well we need to append 4'b0010 to the address
|
||||
// bits and then add a further 4 don't care bits. We will construct this by
|
||||
// specifying a 28-bit address, with the least significant bits being 4'b0010.
|
||||
// This is just a dummy transaction so we'll perform a read from address zero
|
||||
// and then discard what comes back. All we really care about is that at the
|
||||
// end of the transaction, the flash device is in Continuous Read mode
|
||||
// and from then on will only expect to receive addresses.
|
||||
dummy_read:
|
||||
#define CTRLR0_ENTER_XIP \
|
||||
(FRAME_FORMAT /* Quad I/O mode */ \
|
||||
<< SSI_CTRLR0_SPI_FRF_LSB) | \
|
||||
(31 << SSI_CTRLR0_DFS_32_LSB) | /* 32 data bits */ \
|
||||
(SSI_CTRLR0_TMOD_VALUE_EEPROM_READ /* Send INST/ADDR, Receive Data */ \
|
||||
<< SSI_CTRLR0_TMOD_LSB)
|
||||
|
||||
ldr r1, =(CTRLR0_ENTER_XIP)
|
||||
str r1, [r3, #SSI_CTRLR0_OFFSET]
|
||||
|
||||
mov r1, #0x0 // NDF=0 (single 32b read)
|
||||
str r1, [r3, #SSI_CTRLR1_OFFSET]
|
||||
|
||||
#define SPI_CTRLR0_ENTER_XIP \
|
||||
(ADDR_L << SSI_SPI_CTRLR0_ADDR_L_LSB) | /* Address + mode bits */ \
|
||||
(WAIT_CYCLES << SSI_SPI_CTRLR0_WAIT_CYCLES_LSB) | /* Hi-Z dummy clocks following address + mode */ \
|
||||
(SSI_SPI_CTRLR0_INST_L_VALUE_8B \
|
||||
<< SSI_SPI_CTRLR0_INST_L_LSB) | /* 8-bit instruction */ \
|
||||
(SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C2A /* Send Command in serial mode then address in Quad I/O mode */ \
|
||||
<< SSI_SPI_CTRLR0_TRANS_TYPE_LSB)
|
||||
|
||||
ldr r1, =(SPI_CTRLR0_ENTER_XIP)
|
||||
ldr r0, =(XIP_SSI_BASE + SSI_SPI_CTRLR0_OFFSET) // SPI_CTRL0 Register
|
||||
str r1, [r0]
|
||||
|
||||
mov r1, #1 // Re-enable SSI
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
|
||||
mov r1, #CMD_READ
|
||||
str r1, [r3, #SSI_DR0_OFFSET] // Push SPI command into TX FIFO
|
||||
mov r1, #MODE_CONTINUOUS_READ // 32-bit: 24 address bits (we don't care, so 0) and M[7:4]=1010
|
||||
str r1, [r3, #SSI_DR0_OFFSET] // Push Address into TX FIFO - this will trigger the transaction
|
||||
|
||||
// Poll for completion
|
||||
bl wait_ssi_ready
|
||||
|
||||
// At this point CN# will be deasserted and the SPI clock will not be running.
|
||||
// The Winbond WX25X10CL device will be in continuous read, dual I/O mode and
|
||||
// only expecting address bits after the next CN# assertion. So long as we
|
||||
// send 4'b0010 (and 4 more dummy HiZ bits) after every subsequent 24b address
|
||||
// then the Winbond device will remain in continuous read mode. This is the
|
||||
// ideal mode for Execute-In-Place.
|
||||
// (If we want to exit continuous read mode then we will need to switch back
|
||||
// to APM mode and generate a 28-bit address phase with the extra nibble set
|
||||
// to 4'b0000).
|
||||
|
||||
mov r1, #0
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET] // Disable SSI (and clear FIFO) to allow further config
|
||||
|
||||
// Note that the INST_L field is used to select what XIP data gets pushed into
|
||||
// the TX FIFO:
|
||||
// INST_L_0_BITS {ADDR[23:0],XIP_CMD[7:0]} Load "mode bits" into XIP_CMD
|
||||
// Anything else {XIP_CMD[7:0],ADDR[23:0]} Load SPI command into XIP_CMD
|
||||
configure_ssi:
|
||||
#define SPI_CTRLR0_XIP \
|
||||
(MODE_CONTINUOUS_READ /* Mode bits to keep flash in continuous read mode */ \
|
||||
<< SSI_SPI_CTRLR0_XIP_CMD_LSB) | \
|
||||
(ADDR_L << SSI_SPI_CTRLR0_ADDR_L_LSB) | /* Total number of address + mode bits */ \
|
||||
(WAIT_CYCLES << SSI_SPI_CTRLR0_WAIT_CYCLES_LSB) | /* Hi-Z dummy clocks following address + mode */ \
|
||||
(SSI_SPI_CTRLR0_INST_L_VALUE_NONE /* Do not send a command, instead send XIP_CMD as mode bits after address */ \
|
||||
<< SSI_SPI_CTRLR0_INST_L_LSB) | \
|
||||
(SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_2C2A /* Send Address in Quad I/O mode (and Command but that is zero bits long) */ \
|
||||
<< SSI_SPI_CTRLR0_TRANS_TYPE_LSB)
|
||||
|
||||
ldr r1, =(SPI_CTRLR0_XIP)
|
||||
ldr r0, =(XIP_SSI_BASE + SSI_SPI_CTRLR0_OFFSET)
|
||||
str r1, [r0]
|
||||
|
||||
mov r1, #1
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET] // Re-enable SSI
|
||||
|
||||
// We are now in XIP mode, with all transactions using Dual I/O and only
|
||||
// needing to send 24-bit addresses (plus mode bits) for each read transaction.
|
||||
|
||||
// Pull in standard exit routine
|
||||
#include "boot2_helpers/exit_from_boot2.S"
|
||||
|
||||
// Common functions
|
||||
#include "boot2_helpers/wait_ssi_ready.S"
|
||||
#ifdef PROGRAM_STATUS_REG
|
||||
#include "boot2_helpers/read_flash_sreg.S"
|
||||
#endif
|
||||
|
||||
.global literals
|
||||
literals:
|
||||
.ltorg
|
||||
|
||||
.end
|
53
cpu/rpx0xx/vendor/boot_stage2/boot2_usb_blinky.S
vendored
Normal file
53
cpu/rpx0xx/vendor/boot_stage2/boot2_usb_blinky.S
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
// Stub second stage which calls into USB bootcode, with parameters.
|
||||
// USB boot takes two parameters:
|
||||
// - A GPIO mask for activity LED -- if mask is 0, don't touch GPIOs at all
|
||||
// - A mask of interfaces to disable. Bit 0 disables MSC, bit 1 disables PICOBoot
|
||||
// The bootrom passes 0 for both of these parameters, but user code (or this
|
||||
// second stage) can pass anything.
|
||||
|
||||
#define USB_BOOT_MSD_AND_PICOBOOT 0x0
|
||||
#define USB_BOOT_MSD_ONLY 0x2
|
||||
#define USB_BOOT_PICOBOOT_ONLY 0x1
|
||||
|
||||
// Config
|
||||
#define ACTIVITY_LED 0
|
||||
#define BOOT_MODE USB_BOOT_MSD_AND_PICOBOOT
|
||||
|
||||
.cpu cortex-m0
|
||||
.thumb
|
||||
|
||||
.section .text
|
||||
|
||||
.global _stage2_boot
|
||||
.type _stage2_boot,%function
|
||||
|
||||
.thumb_func
|
||||
_stage2_boot:
|
||||
mov r7, #0x14 // Pointer to _well_known pointer table in ROM
|
||||
ldrh r0, [r7, #0] // Offset 0 is 16 bit pointer to function table
|
||||
ldrh r7, [r7, #4] // Offset 4 is 16 bit pointer to table lookup routine
|
||||
ldr r1, =('U' | ('B' << 8)) // Symbol for USB Boot
|
||||
blx r7
|
||||
cmp r0, #0
|
||||
beq dead
|
||||
|
||||
mov r7, r0
|
||||
ldr r0, =(1u << ACTIVITY_LED) // Mask of which GPIO (or GPIOs) to use
|
||||
mov r1, #BOOT_MODE
|
||||
blx r7
|
||||
|
||||
dead:
|
||||
wfi
|
||||
b dead
|
||||
|
||||
.global literals
|
||||
literals:
|
||||
.ltorg
|
||||
|
||||
.end
|
287
cpu/rpx0xx/vendor/boot_stage2/boot2_w25q080.S
vendored
Normal file
287
cpu/rpx0xx/vendor/boot_stage2/boot2_w25q080.S
vendored
Normal file
@ -0,0 +1,287 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Second stage boot code
|
||||
// Copyright (c) 2019-2021 Raspberry Pi (Trading) Ltd.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
//
|
||||
// Device: Winbond W25Q080
|
||||
// Also supports W25Q16JV (which has some different SR instructions)
|
||||
// Also supports AT25SF081
|
||||
// Also supports S25FL132K0
|
||||
//
|
||||
// Description: Configures W25Q080 to run in Quad I/O continuous read XIP mode
|
||||
//
|
||||
// Details: * Check status register 2 to determine if QSPI mode is enabled,
|
||||
// and perform an SR2 programming cycle if necessary.
|
||||
// * Use SSI to perform a dummy 0xEB read command, with the mode
|
||||
// continuation bits set, so that the flash will not require
|
||||
// 0xEB instruction prefix on subsequent reads.
|
||||
// * Configure SSI to write address, mode bits, but no instruction.
|
||||
// SSI + flash are now jointly in a state where continuous reads
|
||||
// can take place.
|
||||
// * Jump to exit pointer passed in via lr. Bootrom passes null,
|
||||
// in which case this code uses a default 256 byte flash offset
|
||||
//
|
||||
// Building: * This code must be position-independent, and use stack only
|
||||
// * The code will be padded to a size of 256 bytes, including a
|
||||
// 4-byte checksum. Therefore code size cannot exceed 252 bytes.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "pico/asm_helper.S"
|
||||
#include "hardware/regs/addressmap.h"
|
||||
#include "hardware/regs/ssi.h"
|
||||
#include "hardware/regs/pads_qspi.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Config section
|
||||
// ----------------------------------------------------------------------------
|
||||
// It should be possible to support most flash devices by modifying this section
|
||||
|
||||
// The serial flash interface will run at clk_sys/PICO_FLASH_SPI_CLKDIV.
|
||||
// This must be a positive, even integer.
|
||||
// The bootrom is very conservative with SPI frequency, but here we should be
|
||||
// as aggressive as possible.
|
||||
|
||||
#ifndef PICO_FLASH_SPI_CLKDIV
|
||||
#define PICO_FLASH_SPI_CLKDIV 4
|
||||
#endif
|
||||
#if PICO_FLASH_SPI_CLKDIV & 1
|
||||
#error PICO_FLASH_SPI_CLKDIV must be even
|
||||
#endif
|
||||
|
||||
// Define interface width: single/dual/quad IO
|
||||
#define FRAME_FORMAT SSI_CTRLR0_SPI_FRF_VALUE_QUAD
|
||||
|
||||
// For W25Q080 this is the "Read data fast quad IO" instruction:
|
||||
#define CMD_READ 0xeb
|
||||
|
||||
// "Mode bits" are 8 special bits sent immediately after
|
||||
// the address bits in a "Read Data Fast Quad I/O" command sequence.
|
||||
// On W25Q080, the four LSBs are don't care, and if MSBs == 0xa, the
|
||||
// next read does not require the 0xeb instruction prefix.
|
||||
#define MODE_CONTINUOUS_READ 0xa0
|
||||
|
||||
// The number of address + mode bits, divided by 4 (always 4, not function of
|
||||
// interface width).
|
||||
#define ADDR_L 8
|
||||
|
||||
// How many clocks of Hi-Z following the mode bits. For W25Q080, 4 dummy cycles
|
||||
// are required.
|
||||
#define WAIT_CYCLES 4
|
||||
|
||||
// If defined, we will read status reg, compare to SREG_DATA, and overwrite
|
||||
// with our value if the SR doesn't match.
|
||||
// We do a two-byte write to SR1 (01h cmd) rather than a one-byte write to
|
||||
// SR2 (31h cmd) as the latter command isn't supported by WX25Q080.
|
||||
// This isn't great because it will remove block protections.
|
||||
// A better solution is to use a volatile SR write if your device supports it.
|
||||
#define PROGRAM_STATUS_REG
|
||||
|
||||
#define CMD_WRITE_ENABLE 0x06
|
||||
#define CMD_READ_STATUS 0x05
|
||||
#define CMD_READ_STATUS2 0x35
|
||||
#define CMD_WRITE_STATUS 0x01
|
||||
#define SREG_DATA 0x02 // Enable quad-SPI mode
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Start of 2nd Stage Boot Code
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m0plus
|
||||
.thumb
|
||||
|
||||
.section .text
|
||||
|
||||
// The exit point is passed in lr. If entered from bootrom, this will be the
|
||||
// flash address immediately following this second stage (0x10000100).
|
||||
// Otherwise it will be a return address -- second stage being called as a
|
||||
// function by user code, after copying out of XIP region. r3 holds SSI base,
|
||||
// r0...2 used as temporaries. Other GPRs not used.
|
||||
.global _stage2_boot
|
||||
.type _stage2_boot,%function
|
||||
.thumb_func
|
||||
_stage2_boot:
|
||||
push {lr}
|
||||
|
||||
// Set pad configuration:
|
||||
// - SCLK 8mA drive, no slew limiting
|
||||
// - SDx disable input Schmitt to reduce delay
|
||||
|
||||
ldr r3, =PADS_QSPI_BASE
|
||||
movs r0, #(2 << PADS_QSPI_GPIO_QSPI_SCLK_DRIVE_LSB | PADS_QSPI_GPIO_QSPI_SCLK_SLEWFAST_BITS)
|
||||
str r0, [r3, #PADS_QSPI_GPIO_QSPI_SCLK_OFFSET]
|
||||
ldr r0, [r3, #PADS_QSPI_GPIO_QSPI_SD0_OFFSET]
|
||||
movs r1, #PADS_QSPI_GPIO_QSPI_SD0_SCHMITT_BITS
|
||||
bics r0, r1
|
||||
str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD0_OFFSET]
|
||||
str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD1_OFFSET]
|
||||
str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD2_OFFSET]
|
||||
str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD3_OFFSET]
|
||||
|
||||
ldr r3, =XIP_SSI_BASE
|
||||
|
||||
// Disable SSI to allow further config
|
||||
movs r1, #0
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
|
||||
// Set baud rate
|
||||
movs r1, #PICO_FLASH_SPI_CLKDIV
|
||||
str r1, [r3, #SSI_BAUDR_OFFSET]
|
||||
|
||||
// Set 1-cycle sample delay. If PICO_FLASH_SPI_CLKDIV == 2 then this means,
|
||||
// if the flash launches data on SCLK posedge, we capture it at the time that
|
||||
// the next SCLK posedge is launched. This is shortly before that posedge
|
||||
// arrives at the flash, so data hold time should be ok. For
|
||||
// PICO_FLASH_SPI_CLKDIV > 2 this pretty much has no effect.
|
||||
|
||||
movs r1, #1
|
||||
movs r2, #SSI_RX_SAMPLE_DLY_OFFSET // == 0xf0 so need 8 bits of offset significance
|
||||
str r1, [r3, r2]
|
||||
|
||||
|
||||
// On QSPI parts we usually need a 01h SR-write command to enable QSPI mode
|
||||
// (i.e. turn WPn and HOLDn into IO2/IO3)
|
||||
#ifdef PROGRAM_STATUS_REG
|
||||
program_sregs:
|
||||
#define CTRL0_SPI_TXRX \
|
||||
(7 << SSI_CTRLR0_DFS_32_LSB) | /* 8 bits per data frame */ \
|
||||
(SSI_CTRLR0_TMOD_VALUE_TX_AND_RX << SSI_CTRLR0_TMOD_LSB)
|
||||
|
||||
ldr r1, =(CTRL0_SPI_TXRX)
|
||||
str r1, [r3, #SSI_CTRLR0_OFFSET]
|
||||
|
||||
// Enable SSI and select slave 0
|
||||
movs r1, #1
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
|
||||
// Check whether SR needs updating
|
||||
movs r0, #CMD_READ_STATUS2
|
||||
bl read_flash_sreg
|
||||
movs r2, #SREG_DATA
|
||||
cmp r0, r2
|
||||
beq skip_sreg_programming
|
||||
|
||||
// Send write enable command
|
||||
movs r1, #CMD_WRITE_ENABLE
|
||||
str r1, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
// Poll for completion and discard RX
|
||||
bl wait_ssi_ready
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
// Send status write command followed by data bytes
|
||||
movs r1, #CMD_WRITE_STATUS
|
||||
str r1, [r3, #SSI_DR0_OFFSET]
|
||||
movs r0, #0
|
||||
str r0, [r3, #SSI_DR0_OFFSET]
|
||||
str r2, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
bl wait_ssi_ready
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
// Poll status register for write completion
|
||||
1:
|
||||
movs r0, #CMD_READ_STATUS
|
||||
bl read_flash_sreg
|
||||
movs r1, #1
|
||||
tst r0, r1
|
||||
bne 1b
|
||||
|
||||
skip_sreg_programming:
|
||||
|
||||
// Disable SSI again so that it can be reconfigured
|
||||
movs r1, #0
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
#endif
|
||||
|
||||
// Currently the flash expects an 8 bit serial command prefix on every
|
||||
// transfer, which is a waste of cycles. Perform a dummy Fast Read Quad I/O
|
||||
// command, with mode bits set such that the flash will not expect a serial
|
||||
// command prefix on *subsequent* transfers. We don't care about the results
|
||||
// of the read, the important part is the mode bits.
|
||||
|
||||
dummy_read:
|
||||
#define CTRLR0_ENTER_XIP \
|
||||
(FRAME_FORMAT /* Quad I/O mode */ \
|
||||
<< SSI_CTRLR0_SPI_FRF_LSB) | \
|
||||
(31 << SSI_CTRLR0_DFS_32_LSB) | /* 32 data bits */ \
|
||||
(SSI_CTRLR0_TMOD_VALUE_EEPROM_READ /* Send INST/ADDR, Receive Data */ \
|
||||
<< SSI_CTRLR0_TMOD_LSB)
|
||||
|
||||
ldr r1, =(CTRLR0_ENTER_XIP)
|
||||
str r1, [r3, #SSI_CTRLR0_OFFSET]
|
||||
|
||||
movs r1, #0x0 // NDF=0 (single 32b read)
|
||||
str r1, [r3, #SSI_CTRLR1_OFFSET]
|
||||
|
||||
#define SPI_CTRLR0_ENTER_XIP \
|
||||
(ADDR_L << SSI_SPI_CTRLR0_ADDR_L_LSB) | /* Address + mode bits */ \
|
||||
(WAIT_CYCLES << SSI_SPI_CTRLR0_WAIT_CYCLES_LSB) | /* Hi-Z dummy clocks following address + mode */ \
|
||||
(SSI_SPI_CTRLR0_INST_L_VALUE_8B \
|
||||
<< SSI_SPI_CTRLR0_INST_L_LSB) | /* 8-bit instruction */ \
|
||||
(SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C2A /* Send Command in serial mode then address in Quad I/O mode */ \
|
||||
<< SSI_SPI_CTRLR0_TRANS_TYPE_LSB)
|
||||
|
||||
ldr r1, =(SPI_CTRLR0_ENTER_XIP)
|
||||
ldr r0, =(XIP_SSI_BASE + SSI_SPI_CTRLR0_OFFSET) // SPI_CTRL0 Register
|
||||
str r1, [r0]
|
||||
|
||||
movs r1, #1 // Re-enable SSI
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
|
||||
movs r1, #CMD_READ
|
||||
str r1, [r3, #SSI_DR0_OFFSET] // Push SPI command into TX FIFO
|
||||
movs r1, #MODE_CONTINUOUS_READ // 32-bit: 24 address bits (we don't care, so 0) and M[7:4]=1010
|
||||
str r1, [r3, #SSI_DR0_OFFSET] // Push Address into TX FIFO - this will trigger the transaction
|
||||
|
||||
// Poll for completion
|
||||
bl wait_ssi_ready
|
||||
|
||||
// The flash is in a state where we can blast addresses in parallel, and get
|
||||
// parallel data back. Now configure the SSI to translate XIP bus accesses
|
||||
// into QSPI transfers of this form.
|
||||
|
||||
movs r1, #0
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET] // Disable SSI (and clear FIFO) to allow further config
|
||||
|
||||
// Note that the INST_L field is used to select what XIP data gets pushed into
|
||||
// the TX FIFO:
|
||||
// INST_L_0_BITS {ADDR[23:0],XIP_CMD[7:0]} Load "mode bits" into XIP_CMD
|
||||
// Anything else {XIP_CMD[7:0],ADDR[23:0]} Load SPI command into XIP_CMD
|
||||
configure_ssi:
|
||||
#define SPI_CTRLR0_XIP \
|
||||
(MODE_CONTINUOUS_READ /* Mode bits to keep flash in continuous read mode */ \
|
||||
<< SSI_SPI_CTRLR0_XIP_CMD_LSB) | \
|
||||
(ADDR_L << SSI_SPI_CTRLR0_ADDR_L_LSB) | /* Total number of address + mode bits */ \
|
||||
(WAIT_CYCLES << SSI_SPI_CTRLR0_WAIT_CYCLES_LSB) | /* Hi-Z dummy clocks following address + mode */ \
|
||||
(SSI_SPI_CTRLR0_INST_L_VALUE_NONE /* Do not send a command, instead send XIP_CMD as mode bits after address */ \
|
||||
<< SSI_SPI_CTRLR0_INST_L_LSB) | \
|
||||
(SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_2C2A /* Send Address in Quad I/O mode (and Command but that is zero bits long) */ \
|
||||
<< SSI_SPI_CTRLR0_TRANS_TYPE_LSB)
|
||||
|
||||
ldr r1, =(SPI_CTRLR0_XIP)
|
||||
ldr r0, =(XIP_SSI_BASE + SSI_SPI_CTRLR0_OFFSET)
|
||||
str r1, [r0]
|
||||
|
||||
movs r1, #1
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET] // Re-enable SSI
|
||||
|
||||
// Bus accesses to the XIP window will now be transparently serviced by the
|
||||
// external flash on cache miss. We are ready to run code from flash.
|
||||
|
||||
// Pull in standard exit routine
|
||||
#include "boot2_helpers/exit_from_boot2.S"
|
||||
|
||||
// Common functions
|
||||
#include "boot2_helpers/wait_ssi_ready.S"
|
||||
#ifdef PROGRAM_STATUS_REG
|
||||
#include "boot2_helpers/read_flash_sreg.S"
|
||||
#endif
|
||||
|
||||
.global literals
|
||||
literals:
|
||||
.ltorg
|
||||
|
||||
.end
|
196
cpu/rpx0xx/vendor/boot_stage2/boot2_w25x10cl.S
vendored
Normal file
196
cpu/rpx0xx/vendor/boot_stage2/boot2_w25x10cl.S
vendored
Normal file
@ -0,0 +1,196 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Second stage boot code
|
||||
// Copyright (c) 2019-2021 Raspberry Pi (Trading) Ltd.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
//
|
||||
// Device: Winbond W25X10CL
|
||||
//
|
||||
// Description: Configures W25X10CL to run in Dual I/O continuous read XIP mode
|
||||
//
|
||||
// Details: * Disable SSI
|
||||
// * Configure SSI to generate 8b command + 28b address + 2 wait,
|
||||
// with address and data using dual SPI mode
|
||||
// * Enable SSI
|
||||
// * Generate dummy read with command = 0xBB, top 24b of address
|
||||
// of 0x000000 followed by M[7:0]=0010zzzz (with the HiZ being
|
||||
// generated by 2 wait cycles). This leaves the W25X10CL in
|
||||
// continuous read mode
|
||||
// * Disable SSI
|
||||
// * Configure SSI to generate 0b command + 28b address + 2 wait,
|
||||
// with the extra 4 bits of address LSB being 0x2 to keep the
|
||||
// W25X10CL in continuous read mode forever
|
||||
// * Enable SSI
|
||||
// * Set VTOR = 0x10000100
|
||||
// * Read MSP reset vector from 0x10000100 and write to MSP (this
|
||||
// will also enable XIP mode in the SSI wrapper)
|
||||
// * Read PC reset vector from 0x10000104 and jump to it
|
||||
//
|
||||
// Building: * This code must be linked to run at 0x20000000
|
||||
// * The code will be padded to a size of 256 bytes, including a
|
||||
// 4-byte checksum. Therefore code size cannot exceed 252 bytes.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "pico/asm_helper.S"
|
||||
#include "hardware/regs/addressmap.h"
|
||||
#include "hardware/regs/ssi.h"
|
||||
|
||||
// The serial flash interface will run at clk_sys/PICO_FLASH_SPI_CLKDIV.
|
||||
// This must be an even number.
|
||||
#ifndef PICO_FLASH_SPI_CLKDIV
|
||||
#define PICO_FLASH_SPI_CLKDIV 4
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// The "System Control Block" is a set of internal Cortex-M0+ control registers
|
||||
// that are memory mapped and accessed like any other H/W register. They have
|
||||
// fixed addresses in the address map of every Cortex-M0+ system.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.equ SCB_VTOR, 0xE000ED08 // RW Vector Table Offset Register
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Winbond W25X10CL Supported Commands
|
||||
// Taken from "w25x10cl_reg_021714.pdf"
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.equ W25X10CL_CMD_READ_DATA_FAST_DUAL_IO, 0xbb
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Winbond W25X10CL "Mode bits" are 8 special bits sent immediately after
|
||||
// the address bits in a "Read Data Fast Dual I/O" command sequence.
|
||||
// Of M[7:4], they say M[7:6] are reserved (set to zero), and bits M[3:0]
|
||||
// are don't care (we HiZ). Only M[5:4] are used, and they must be set
|
||||
// to M[5:4] = 2'b10 to enable continuous read mode.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.equ W25X10CL_MODE_CONTINUOUS_READ, 0x20
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Start of 2nd Stage Boot Code
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.cpu cortex-m0
|
||||
.thumb
|
||||
|
||||
.org 0
|
||||
|
||||
.section .text
|
||||
|
||||
// This code will get copied to 0x20000000 and then executed
|
||||
|
||||
.global _stage2_boot
|
||||
.type _stage2_boot,%function
|
||||
.thumb_func
|
||||
_stage2_boot:
|
||||
push {lr}
|
||||
ldr r3, =XIP_SSI_BASE // Use as base address where possible
|
||||
|
||||
// We are primarily interested in setting up Flash for DSPI XIP w/ continuous read
|
||||
|
||||
mov r1, #0
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET] // Disable SSI to allow further config
|
||||
|
||||
// The Boot ROM sets a very conservative SPI clock frequency to be sure it can
|
||||
// read the initial 256 bytes from any device. Here we can be more aggressive.
|
||||
|
||||
mov r1, #PICO_FLASH_SPI_CLKDIV
|
||||
str r1, [r3, #SSI_BAUDR_OFFSET] // Set SSI Clock
|
||||
|
||||
// First we need to send the initial command to get us in to Fast Read Dual I/O
|
||||
// mode. As this transaction requires a command, we can't send it in XIP mode.
|
||||
// To enter Continuous Read mode as well we need to append 4'b0010 to the address
|
||||
// bits and then add a further 4 don't care bits. We will construct this by
|
||||
// specifying a 28-bit address, with the least significant bits being 4'b0010.
|
||||
// This is just a dummy transaction so we'll perform a read from address zero
|
||||
// and then discard what comes back. All we really care about is that at the
|
||||
// end of the transaction, the Winbond W25X10CL device is in Continuous Read mode
|
||||
// and from then on will only expect to receive addresses.
|
||||
|
||||
#define CTRLR0_ENTER_XIP \
|
||||
(SSI_CTRLR0_SPI_FRF_VALUE_DUAL /* Dual I/O mode */ \
|
||||
<< SSI_CTRLR0_SPI_FRF_LSB) | \
|
||||
(31 << SSI_CTRLR0_DFS_32_LSB) | /* 32 data bits */ \
|
||||
(SSI_CTRLR0_TMOD_VALUE_EEPROM_READ /* Send INST/ADDR, Receive Data */ \
|
||||
<< SSI_CTRLR0_TMOD_LSB)
|
||||
|
||||
ldr r1, =(CTRLR0_ENTER_XIP)
|
||||
str r1, [r3, #SSI_CTRLR0_OFFSET]
|
||||
|
||||
mov r1, #0x0 // NDF=0 (single 32b read)
|
||||
str r1, [r3, #SSI_CTRLR1_OFFSET]
|
||||
|
||||
#define SPI_CTRLR0_ENTER_XIP \
|
||||
(7 << SSI_SPI_CTRLR0_ADDR_L_LSB) | /* Send 28 bits (24 address + 4 mode) */ \
|
||||
(2 << SSI_SPI_CTRLR0_WAIT_CYCLES_LSB) | /* Hi-Z the other 4 mode bits (2 cycles @ dual I/O = 4 bits) */ \
|
||||
(SSI_SPI_CTRLR0_INST_L_VALUE_8B \
|
||||
<< SSI_SPI_CTRLR0_INST_L_LSB) | /* 8-bit instruction */ \
|
||||
(SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C2A /* Send Command in serial mode then address in Dual I/O mode */ \
|
||||
<< SSI_SPI_CTRLR0_TRANS_TYPE_LSB)
|
||||
|
||||
ldr r1, =(SPI_CTRLR0_ENTER_XIP)
|
||||
ldr r0, =(XIP_SSI_BASE + SSI_SPI_CTRLR0_OFFSET) // SPI_CTRL0 Register
|
||||
str r1, [r0]
|
||||
|
||||
mov r1, #1 // Re-enable SSI
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
|
||||
mov r1, #W25X10CL_CMD_READ_DATA_FAST_DUAL_IO // 8b command = 0xBB
|
||||
str r1, [r3, #SSI_DR0_OFFSET] // Push SPI command into TX FIFO
|
||||
mov r1, #0x0000002 // 28-bit Address for dummy read = 0x000000 + 0x2 Mode bits to set M[5:4]=10
|
||||
str r1, [r3, #SSI_DR0_OFFSET] // Push Address into TX FIFO - this will trigger the transaction
|
||||
|
||||
// Now we wait for the read transaction to complete by monitoring the SSI
|
||||
// status register and checking for the "RX FIFO Not Empty" flag to assert.
|
||||
|
||||
mov r1, #SSI_SR_RFNE_BITS
|
||||
00:
|
||||
ldr r0, [r3, #SSI_SR_OFFSET] // Read status register
|
||||
tst r0, r1 // RFNE status flag set?
|
||||
beq 00b // If not then wait
|
||||
|
||||
// At this point CN# will be deasserted and the SPI clock will not be running.
|
||||
// The Winbond WX25X10CL device will be in continuous read, dual I/O mode and
|
||||
// only expecting address bits after the next CN# assertion. So long as we
|
||||
// send 4'b0010 (and 4 more dummy HiZ bits) after every subsequent 24b address
|
||||
// then the Winbond device will remain in continuous read mode. This is the
|
||||
// ideal mode for Execute-In-Place.
|
||||
// (If we want to exit continuous read mode then we will need to switch back
|
||||
// to APM mode and generate a 28-bit address phase with the extra nibble set
|
||||
// to 4'b0000).
|
||||
|
||||
mov r1, #0
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET] // Disable SSI (and clear FIFO) to allow further config
|
||||
|
||||
// Note that the INST_L field is used to select what XIP data gets pushed into
|
||||
// the TX FIFO:
|
||||
// INST_L_0_BITS {ADDR[23:0],XIP_CMD[7:0]} Load "mode bits" into XIP_CMD
|
||||
// Anything else {XIP_CMD[7:0],ADDR[23:0]} Load SPI command into XIP_CMD
|
||||
|
||||
#define SPI_CTRLR0_XIP \
|
||||
(W25X10CL_MODE_CONTINUOUS_READ /* Mode bits to keep Winbond in continuous read mode */ \
|
||||
<< SSI_SPI_CTRLR0_XIP_CMD_LSB) | \
|
||||
(7 << SSI_SPI_CTRLR0_ADDR_L_LSB) | /* Send 28 bits (24 address + 4 mode) */ \
|
||||
(2 << SSI_SPI_CTRLR0_WAIT_CYCLES_LSB) | /* Hi-Z the other 4 mode bits (2 cycles @ dual I/O = 4 bits) */ \
|
||||
(SSI_SPI_CTRLR0_INST_L_VALUE_NONE /* Do not send a command, instead send XIP_CMD as mode bits after address */ \
|
||||
<< SSI_SPI_CTRLR0_INST_L_LSB) | \
|
||||
(SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_2C2A /* Send Address in Dual I/O mode (and Command but that is zero bits long) */ \
|
||||
<< SSI_SPI_CTRLR0_TRANS_TYPE_LSB)
|
||||
|
||||
ldr r1, =(SPI_CTRLR0_XIP)
|
||||
ldr r0, =(XIP_SSI_BASE + SSI_SPI_CTRLR0_OFFSET)
|
||||
str r1, [r0]
|
||||
|
||||
mov r1, #1
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET] // Re-enable SSI
|
||||
|
||||
// We are now in XIP mode, with all transactions using Dual I/O and only
|
||||
// needing to send 24-bit addresses (plus mode bits) for each read transaction.
|
||||
|
||||
// Pull in standard exit routine
|
||||
#include "boot2_helpers/exit_from_boot2.S"
|
||||
|
||||
.global literals
|
||||
literals:
|
||||
.ltorg
|
||||
|
||||
.end
|
13
cpu/rpx0xx/vendor/boot_stage2/boot_stage2.ld
vendored
Normal file
13
cpu/rpx0xx/vendor/boot_stage2/boot_stage2.ld
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
MEMORY {
|
||||
/* We are loaded to the top 256 bytes of SRAM, which is above the bootrom
|
||||
stack. Note 4 bytes occupied by checksum. */
|
||||
SRAM(rx) : ORIGIN = 0x20041f00, LENGTH = 252
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
. = ORIGIN(SRAM);
|
||||
.text : {
|
||||
*(.entry)
|
||||
*(.text)
|
||||
} >SRAM
|
||||
}
|
19
cpu/rpx0xx/vendor/boot_stage2/compile_time_choice.S
vendored
Normal file
19
cpu/rpx0xx/vendor/boot_stage2/compile_time_choice.S
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Second stage boot code
|
||||
// Copyright (c) 2019-2021 Raspberry Pi (Trading) Ltd.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// This implementation uses the PICO_BOOT_STAGE2_CHOOSE_ preprocessor defines to pick
|
||||
// amongst a menu of known boot stage 2 implementations, allowing the board
|
||||
// configuration header to be able to specify the boot stage 2
|
||||
|
||||
#include "boot_stage2/config.h"
|
||||
|
||||
#ifdef PICO_BUILD_BOOT_STAGE2_NAME
|
||||
// boot stage 2 is configured by cmake, so use the name specified there
|
||||
#error PICO_BUILD_BOOT_STAGE2_NAME should not be defined for compile_time_choice builds
|
||||
#else
|
||||
// boot stage 2 is selected by board config header, and PICO_BOOT_STAGE2_ASM is set in boot_stage2/config.h
|
||||
#include PICO_BOOT_STAGE2_ASM
|
||||
#endif
|
92
cpu/rpx0xx/vendor/boot_stage2/config.h
vendored
Normal file
92
cpu/rpx0xx/vendor/boot_stage2/config.h
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _BOOT_STAGE2_CONFIG_H_
|
||||
#define _BOOT_STAGE2_CONFIG_H_
|
||||
|
||||
// NOTE THIS HEADER IS INCLUDED FROM ASSEMBLY
|
||||
|
||||
// PICO_CONFIG: PICO_BUILD_BOOT_STAGE2_NAME, The name of the boot stage 2 if selected by the build, group=boot_stage2
|
||||
#ifdef PICO_BUILD_BOOT_STAGE2_NAME
|
||||
#define _BOOT_STAGE2_SELECTED
|
||||
#else
|
||||
// check that multiple boot stage 2 options haven't been set...
|
||||
|
||||
// PICO_CONFIG: PICO_BOOT_STAGE2_CHOOSE_IS25LP080, Select boot2_is25lp080 as the boot stage 2 when no boot stage 2 selection is made by the CMake build, type=bool, default=0, group=boot_stage2
|
||||
#ifndef PICO_BOOT_STAGE2_CHOOSE_IS25LP080
|
||||
#define PICO_BOOT_STAGE2_CHOOSE_IS25LP080 0
|
||||
#elif PICO_BOOT_STAGE2_CHOOSE_IS25LP080
|
||||
#ifdef _BOOT_STAGE2_SELECTED
|
||||
#error multiple boot stage 2 options chosen
|
||||
#endif
|
||||
#define _BOOT_STAGE2_SELECTED
|
||||
#endif
|
||||
// PICO_CONFIG: PICO_BOOT_STAGE2_CHOOSE_W25Q080, Select boot2_w25q080 as the boot stage 2 when no boot stage 2 selection is made by the CMake build, type=bool, default=0, group=boot_stage2
|
||||
#ifndef PICO_BOOT_STAGE2_CHOOSE_W25Q080
|
||||
#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 0
|
||||
#elif PICO_BOOT_STAGE2_CHOOSE_W25Q080
|
||||
#ifdef _BOOT_STAGE2_SELECTED
|
||||
#error multiple boot stage 2 options chosen
|
||||
#endif
|
||||
#define _BOOT_STAGE2_SELECTED
|
||||
#endif
|
||||
// PICO_CONFIG: PICO_BOOT_STAGE2_CHOOSE_W25X10CL, Select boot2_w25x10cl as the boot stage 2 when no boot stage 2 selection is made by the CMake build, type=bool, default=0, group=boot_stage2
|
||||
#ifndef PICO_BOOT_STAGE2_CHOOSE_W25X10CL
|
||||
#define PICO_BOOT_STAGE2_CHOOSE_W25X10CL 0
|
||||
#elif PICO_BOOT_STAGE2_CHOOSE_W25X10CL
|
||||
#ifdef _BOOT_STAGE2_SELECTED
|
||||
#error multiple boot stage 2 options chosen
|
||||
#endif
|
||||
#define _BOOT_STAGE2_SELECTED
|
||||
#endif
|
||||
// PICO_CONFIG: PICO_BOOT_STAGE2_CHOOSE_AT25SF128A, Select boot2_at25sf128a as the boot stage 2 when no boot stage 2 selection is made by the CMake build, type=bool, default=0, group=boot_stage2
|
||||
#ifndef PICO_BOOT_STAGE2_CHOOSE_AT25SF128A
|
||||
#define PICO_BOOT_STAGE2_CHOOSE_AT25SF128A 0
|
||||
#elif PICO_BOOT_STAGE2_CHOOSE_AT25SF128A
|
||||
#ifdef _BOOT_STAGE2_SELECTED
|
||||
#error multiple boot stage 2 options chosen
|
||||
#endif
|
||||
#define _BOOT_STAGE2_SELECTED
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H, Select boot2_generic_03h as the boot stage 2 when no boot stage 2 selection is made by the CMake build, type=bool, default=1, group=boot_stage2
|
||||
#if defined(PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H) && PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H
|
||||
#ifdef _BOOT_STAGE2_SELECTED
|
||||
#error multiple boot stage 2 options chosen
|
||||
#endif
|
||||
#define _BOOT_STAGE2_SELECTED
|
||||
#endif
|
||||
|
||||
#endif // PICO_BUILD_BOOT_STAGE2_NAME
|
||||
|
||||
#ifdef PICO_BUILD_BOOT_STAGE2_NAME
|
||||
// boot stage 2 is configured by cmake, so use the name specified there
|
||||
#define PICO_BOOT_STAGE2_NAME PICO_BUILD_BOOT_STAGE2_NAME
|
||||
#else
|
||||
// boot stage 2 is selected by board config header, so we have to do some work
|
||||
#if PICO_BOOT_STAGE2_CHOOSE_IS25LP080
|
||||
#define _BOOT_STAGE2 boot2_is25lp080
|
||||
#elif PICO_BOOT_STAGE2_CHOOSE_W25Q080
|
||||
#define _BOOT_STAGE2 boot2_w25q080
|
||||
#elif PICO_BOOT_STAGE2_CHOOSE_W25X10CL
|
||||
#define _BOOT_STAGE2 boot2_w25x10cl
|
||||
#elif PICO_BOOT_STAGE2_CHOOSE_AT25SF128A
|
||||
#define _BOOT_STAGE2 boot2_at25sf128a
|
||||
#elif !defined(PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H) || PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H
|
||||
#undef PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H
|
||||
#define PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H 1
|
||||
#define _BOOT_STAGE2 boot2_generic_03h
|
||||
#else
|
||||
#error no boot stage 2 is defined by PICO_BOOT_STAGE2_CHOOSE_ macro
|
||||
#endif
|
||||
// we can't include cdefs in assembly, so define our own, but avoid conflict with real ones for c inclusion
|
||||
#define _PICO__STRING(x) #x
|
||||
#define _PICO__XSTRING(x) _PICO__STRING(x)
|
||||
#define _PICO__CONCAT1(x, y) x ## y
|
||||
#define PICO_BOOT_STAGE2_NAME _PICO__XSTRING(_BOOT_STAGE2)
|
||||
#define PICO_BOOT_STAGE2_ASM _PICO__XSTRING(_PICO__CONCAT1(_BOOT_STAGE2,.S))
|
||||
#endif
|
||||
#endif
|
28
cpu/rpx0xx/vendor/boot_stage2/include/boot2_helpers/exit_from_boot2.S
vendored
Normal file
28
cpu/rpx0xx/vendor/boot_stage2/include/boot2_helpers/exit_from_boot2.S
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _BOOT2_HELPER_EXIT_FROM_BOOT2
|
||||
#define _BOOT2_HELPER_EXIT_FROM_BOOT2
|
||||
|
||||
#include "hardware/regs/m0plus.h"
|
||||
|
||||
// If entered from the bootrom, lr (which we earlier pushed) will be 0,
|
||||
// and we vector through the table at the start of the main flash image.
|
||||
// Any regular function call will have a nonzero value for lr.
|
||||
check_return:
|
||||
pop {r0}
|
||||
cmp r0, #0
|
||||
beq vector_into_flash
|
||||
bx r0
|
||||
vector_into_flash:
|
||||
ldr r0, =(XIP_BASE + 0x100)
|
||||
ldr r1, =(PPB_BASE + M0PLUS_VTOR_OFFSET)
|
||||
str r0, [r1]
|
||||
ldmia r0, {r0, r1}
|
||||
msr msp, r0
|
||||
bx r1
|
||||
|
||||
#endif
|
30
cpu/rpx0xx/vendor/boot_stage2/include/boot2_helpers/read_flash_sreg.S
vendored
Normal file
30
cpu/rpx0xx/vendor/boot_stage2/include/boot2_helpers/read_flash_sreg.S
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _BOOT2_HELPER_READ_FLASH_SREG
|
||||
#define _BOOT2_HELPER_READ_FLASH_SREG
|
||||
|
||||
#include "boot2_helpers/wait_ssi_ready.S"
|
||||
|
||||
// Pass status read cmd into r0.
|
||||
// Returns status value in r0.
|
||||
.global read_flash_sreg
|
||||
.type read_flash_sreg,%function
|
||||
.thumb_func
|
||||
read_flash_sreg:
|
||||
push {r1, lr}
|
||||
str r0, [r3, #SSI_DR0_OFFSET]
|
||||
// Dummy byte:
|
||||
str r0, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
bl wait_ssi_ready
|
||||
// Discard first byte and combine the next two
|
||||
ldr r0, [r3, #SSI_DR0_OFFSET]
|
||||
ldr r0, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
pop {r1, pc}
|
||||
|
||||
#endif
|
26
cpu/rpx0xx/vendor/boot_stage2/include/boot2_helpers/wait_ssi_ready.S
vendored
Normal file
26
cpu/rpx0xx/vendor/boot_stage2/include/boot2_helpers/wait_ssi_ready.S
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _BOOT2_HELPER_WAIT_SSI_READY
|
||||
#define _BOOT2_HELPER_WAIT_SSI_READY
|
||||
|
||||
wait_ssi_ready:
|
||||
push {r0, r1, lr}
|
||||
|
||||
// Command is complete when there is nothing left to send
|
||||
// (TX FIFO empty) and SSI is no longer busy (CSn deasserted)
|
||||
1:
|
||||
ldr r1, [r3, #SSI_SR_OFFSET]
|
||||
movs r0, #SSI_SR_TFE_BITS
|
||||
tst r1, r0
|
||||
beq 1b
|
||||
movs r0, #SSI_SR_BUSY_BITS
|
||||
tst r1, r0
|
||||
bne 1b
|
||||
|
||||
pop {r0, r1, pc}
|
||||
|
||||
#endif
|
55
cpu/rpx0xx/vendor/boot_stage2/include/hardware/platform_defs.h
vendored
Normal file
55
cpu/rpx0xx/vendor/boot_stage2/include/hardware/platform_defs.h
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _HARDWARE_PLATFORM_DEFS_H
|
||||
#define _HARDWARE_PLATFORM_DEFS_H
|
||||
|
||||
// This header is included from C and assembler - only define macros
|
||||
|
||||
#ifndef _u
|
||||
#ifdef __ASSEMBLER__
|
||||
#define _u(x) x
|
||||
#else
|
||||
#define _u(x) x ## u
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define NUM_CORES _u(2)
|
||||
#define NUM_DMA_CHANNELS _u(12)
|
||||
#define NUM_IRQS _u(32)
|
||||
#define NUM_PIOS _u(2)
|
||||
#define NUM_PIO_STATE_MACHINES _u(4)
|
||||
#define NUM_PWM_SLICES _u(8)
|
||||
#define NUM_SPIN_LOCKS _u(32)
|
||||
#define NUM_UARTS _u(2)
|
||||
#define NUM_I2CS _u(2)
|
||||
#define NUM_SPIS _u(2)
|
||||
|
||||
#define NUM_ADC_CHANNELS _u(5)
|
||||
|
||||
#define NUM_BANK0_GPIOS _u(30)
|
||||
|
||||
#define PIO_INSTRUCTION_COUNT _u(32)
|
||||
|
||||
#define XOSC_MHZ _u(12)
|
||||
|
||||
// PICO_CONFIG: PICO_STACK_SIZE, Stack Size, min=0x100, default=0x800, advanced=true, group=pico_standard_link
|
||||
#ifndef PICO_STACK_SIZE
|
||||
#define PICO_STACK_SIZE _u(0x800)
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_HEAP_SIZE, Heap size to reserve, min=0x100, default=0x800, advanced=true, group=pico_standard_link
|
||||
#ifndef PICO_HEAP_SIZE
|
||||
#define PICO_HEAP_SIZE _u(0x800)
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_NO_RAM_VECTOR_TABLE, Enable/disable the RAM vector table, type=bool, default=0, advanced=true, group=pico_runtime
|
||||
#ifndef PICO_NO_RAM_VECTOR_TABLE
|
||||
#define PICO_NO_RAM_VECTOR_TABLE 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
74
cpu/rpx0xx/vendor/boot_stage2/include/hardware/regs/addressmap.h
vendored
Normal file
74
cpu/rpx0xx/vendor/boot_stage2/include/hardware/regs/addressmap.h
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _ADDRESSMAP_H_
|
||||
#define _ADDRESSMAP_H_
|
||||
|
||||
#include "hardware/platform_defs.h"
|
||||
|
||||
// Register address offsets for atomic RMW aliases
|
||||
#define REG_ALIAS_RW_BITS (0x0u << 12u)
|
||||
#define REG_ALIAS_XOR_BITS (0x1u << 12u)
|
||||
#define REG_ALIAS_SET_BITS (0x2u << 12u)
|
||||
#define REG_ALIAS_CLR_BITS (0x3u << 12u)
|
||||
|
||||
#define ROM_BASE _u(0x00000000)
|
||||
#define XIP_BASE _u(0x10000000)
|
||||
#define XIP_MAIN_BASE _u(0x10000000)
|
||||
#define XIP_NOALLOC_BASE _u(0x11000000)
|
||||
#define XIP_NOCACHE_BASE _u(0x12000000)
|
||||
#define XIP_NOCACHE_NOALLOC_BASE _u(0x13000000)
|
||||
#define XIP_CTRL_BASE _u(0x14000000)
|
||||
#define XIP_SRAM_BASE _u(0x15000000)
|
||||
#define XIP_SRAM_END _u(0x15004000)
|
||||
#define XIP_SSI_BASE _u(0x18000000)
|
||||
#define SRAM_BASE _u(0x20000000)
|
||||
#define SRAM_STRIPED_BASE _u(0x20000000)
|
||||
#define SRAM_STRIPED_END _u(0x20040000)
|
||||
#define SRAM4_BASE _u(0x20040000)
|
||||
#define SRAM5_BASE _u(0x20041000)
|
||||
#define SRAM_END _u(0x20042000)
|
||||
#define SRAM0_BASE _u(0x21000000)
|
||||
#define SRAM1_BASE _u(0x21010000)
|
||||
#define SRAM2_BASE _u(0x21020000)
|
||||
#define SRAM3_BASE _u(0x21030000)
|
||||
#define SYSINFO_BASE _u(0x40000000)
|
||||
#define SYSCFG_BASE _u(0x40004000)
|
||||
#define CLOCKS_BASE _u(0x40008000)
|
||||
#define RESETS_BASE _u(0x4000c000)
|
||||
#define PSM_BASE _u(0x40010000)
|
||||
#define IO_BANK0_BASE _u(0x40014000)
|
||||
#define IO_QSPI_BASE _u(0x40018000)
|
||||
#define PADS_BANK0_BASE _u(0x4001c000)
|
||||
#define PADS_QSPI_BASE _u(0x40020000)
|
||||
#define XOSC_BASE _u(0x40024000)
|
||||
#define PLL_SYS_BASE _u(0x40028000)
|
||||
#define PLL_USB_BASE _u(0x4002c000)
|
||||
#define BUSCTRL_BASE _u(0x40030000)
|
||||
#define UART0_BASE _u(0x40034000)
|
||||
#define UART1_BASE _u(0x40038000)
|
||||
#define SPI0_BASE _u(0x4003c000)
|
||||
#define SPI1_BASE _u(0x40040000)
|
||||
#define I2C0_BASE _u(0x40044000)
|
||||
#define I2C1_BASE _u(0x40048000)
|
||||
#define ADC_BASE _u(0x4004c000)
|
||||
#define PWM_BASE _u(0x40050000)
|
||||
#define TIMER_BASE _u(0x40054000)
|
||||
#define WATCHDOG_BASE _u(0x40058000)
|
||||
#define RTC_BASE _u(0x4005c000)
|
||||
#define ROSC_BASE _u(0x40060000)
|
||||
#define VREG_AND_CHIP_RESET_BASE _u(0x40064000)
|
||||
#define TBMAN_BASE _u(0x4006c000)
|
||||
#define DMA_BASE _u(0x50000000)
|
||||
#define USBCTRL_DPRAM_BASE _u(0x50100000)
|
||||
#define USBCTRL_BASE _u(0x50100000)
|
||||
#define USBCTRL_REGS_BASE _u(0x50110000)
|
||||
#define PIO0_BASE _u(0x50200000)
|
||||
#define PIO1_BASE _u(0x50300000)
|
||||
#define XIP_AUX_BASE _u(0x50400000)
|
||||
#define SIO_BASE _u(0xd0000000)
|
||||
#define PPB_BASE _u(0xe0000000)
|
||||
|
||||
#endif // _ADDRESSMAP_H_
|
1149
cpu/rpx0xx/vendor/boot_stage2/include/hardware/regs/m0plus.h
vendored
Normal file
1149
cpu/rpx0xx/vendor/boot_stage2/include/hardware/regs/m0plus.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
454
cpu/rpx0xx/vendor/boot_stage2/include/hardware/regs/pads_qspi.h
vendored
Normal file
454
cpu/rpx0xx/vendor/boot_stage2/include/hardware/regs/pads_qspi.h
vendored
Normal file
@ -0,0 +1,454 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
// =============================================================================
|
||||
// Register block : PADS_QSPI
|
||||
// Version : 1
|
||||
// Bus type : apb
|
||||
// Description : None
|
||||
// =============================================================================
|
||||
#ifndef HARDWARE_REGS_PADS_QSPI_DEFINED
|
||||
#define HARDWARE_REGS_PADS_QSPI_DEFINED
|
||||
// =============================================================================
|
||||
// Register : PADS_QSPI_VOLTAGE_SELECT
|
||||
// Description : Voltage select. Per bank control
|
||||
// 0x0 -> Set voltage to 3.3V (DVDD >= 2V5)
|
||||
// 0x1 -> Set voltage to 1.8V (DVDD <= 1V8)
|
||||
#define PADS_QSPI_VOLTAGE_SELECT_OFFSET _u(0x00000000)
|
||||
#define PADS_QSPI_VOLTAGE_SELECT_BITS _u(0x00000001)
|
||||
#define PADS_QSPI_VOLTAGE_SELECT_RESET _u(0x00000000)
|
||||
#define PADS_QSPI_VOLTAGE_SELECT_MSB _u(0)
|
||||
#define PADS_QSPI_VOLTAGE_SELECT_LSB _u(0)
|
||||
#define PADS_QSPI_VOLTAGE_SELECT_ACCESS "RW"
|
||||
#define PADS_QSPI_VOLTAGE_SELECT_VALUE_3V3 _u(0x0)
|
||||
#define PADS_QSPI_VOLTAGE_SELECT_VALUE_1V8 _u(0x1)
|
||||
// =============================================================================
|
||||
// Register : PADS_QSPI_GPIO_QSPI_SCLK
|
||||
// Description : Pad control register
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_OFFSET _u(0x00000004)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_BITS _u(0x000000ff)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_RESET _u(0x00000056)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SCLK_OD
|
||||
// Description : Output disable. Has priority over output enable from
|
||||
// peripherals
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_OD_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_OD_BITS _u(0x00000080)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_OD_MSB _u(7)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_OD_LSB _u(7)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_OD_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SCLK_IE
|
||||
// Description : Input enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_IE_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_IE_BITS _u(0x00000040)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_IE_MSB _u(6)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_IE_LSB _u(6)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_IE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SCLK_DRIVE
|
||||
// Description : Drive strength.
|
||||
// 0x0 -> 2mA
|
||||
// 0x1 -> 4mA
|
||||
// 0x2 -> 8mA
|
||||
// 0x3 -> 12mA
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_DRIVE_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_DRIVE_BITS _u(0x00000030)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_DRIVE_MSB _u(5)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_DRIVE_LSB _u(4)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_DRIVE_ACCESS "RW"
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_DRIVE_VALUE_2MA _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_DRIVE_VALUE_4MA _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_DRIVE_VALUE_8MA _u(0x2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_DRIVE_VALUE_12MA _u(0x3)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SCLK_PUE
|
||||
// Description : Pull up enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_PUE_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_PUE_BITS _u(0x00000008)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_PUE_MSB _u(3)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_PUE_LSB _u(3)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_PUE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SCLK_PDE
|
||||
// Description : Pull down enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_PDE_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_PDE_BITS _u(0x00000004)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_PDE_MSB _u(2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_PDE_LSB _u(2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_PDE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SCLK_SCHMITT
|
||||
// Description : Enable schmitt trigger
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_SCHMITT_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_SCHMITT_BITS _u(0x00000002)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_SCHMITT_MSB _u(1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_SCHMITT_LSB _u(1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_SCHMITT_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SCLK_SLEWFAST
|
||||
// Description : Slew rate control. 1 = Fast, 0 = Slow
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_SLEWFAST_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_SLEWFAST_BITS _u(0x00000001)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_SLEWFAST_MSB _u(0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_SLEWFAST_LSB _u(0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SCLK_SLEWFAST_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : PADS_QSPI_GPIO_QSPI_SD0
|
||||
// Description : Pad control register
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_OFFSET _u(0x00000008)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_BITS _u(0x000000ff)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_RESET _u(0x00000052)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD0_OD
|
||||
// Description : Output disable. Has priority over output enable from
|
||||
// peripherals
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_OD_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_OD_BITS _u(0x00000080)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_OD_MSB _u(7)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_OD_LSB _u(7)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_OD_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD0_IE
|
||||
// Description : Input enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_IE_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_IE_BITS _u(0x00000040)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_IE_MSB _u(6)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_IE_LSB _u(6)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_IE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD0_DRIVE
|
||||
// Description : Drive strength.
|
||||
// 0x0 -> 2mA
|
||||
// 0x1 -> 4mA
|
||||
// 0x2 -> 8mA
|
||||
// 0x3 -> 12mA
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_DRIVE_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_DRIVE_BITS _u(0x00000030)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_DRIVE_MSB _u(5)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_DRIVE_LSB _u(4)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_DRIVE_ACCESS "RW"
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_DRIVE_VALUE_2MA _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_DRIVE_VALUE_4MA _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_DRIVE_VALUE_8MA _u(0x2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_DRIVE_VALUE_12MA _u(0x3)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD0_PUE
|
||||
// Description : Pull up enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_PUE_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_PUE_BITS _u(0x00000008)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_PUE_MSB _u(3)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_PUE_LSB _u(3)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_PUE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD0_PDE
|
||||
// Description : Pull down enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_PDE_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_PDE_BITS _u(0x00000004)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_PDE_MSB _u(2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_PDE_LSB _u(2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_PDE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD0_SCHMITT
|
||||
// Description : Enable schmitt trigger
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_SCHMITT_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_SCHMITT_BITS _u(0x00000002)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_SCHMITT_MSB _u(1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_SCHMITT_LSB _u(1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_SCHMITT_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD0_SLEWFAST
|
||||
// Description : Slew rate control. 1 = Fast, 0 = Slow
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_SLEWFAST_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_SLEWFAST_BITS _u(0x00000001)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_SLEWFAST_MSB _u(0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_SLEWFAST_LSB _u(0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD0_SLEWFAST_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : PADS_QSPI_GPIO_QSPI_SD1
|
||||
// Description : Pad control register
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_OFFSET _u(0x0000000c)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_BITS _u(0x000000ff)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_RESET _u(0x00000052)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD1_OD
|
||||
// Description : Output disable. Has priority over output enable from
|
||||
// peripherals
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_OD_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_OD_BITS _u(0x00000080)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_OD_MSB _u(7)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_OD_LSB _u(7)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_OD_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD1_IE
|
||||
// Description : Input enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_IE_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_IE_BITS _u(0x00000040)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_IE_MSB _u(6)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_IE_LSB _u(6)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_IE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD1_DRIVE
|
||||
// Description : Drive strength.
|
||||
// 0x0 -> 2mA
|
||||
// 0x1 -> 4mA
|
||||
// 0x2 -> 8mA
|
||||
// 0x3 -> 12mA
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_DRIVE_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_DRIVE_BITS _u(0x00000030)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_DRIVE_MSB _u(5)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_DRIVE_LSB _u(4)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_DRIVE_ACCESS "RW"
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_DRIVE_VALUE_2MA _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_DRIVE_VALUE_4MA _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_DRIVE_VALUE_8MA _u(0x2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_DRIVE_VALUE_12MA _u(0x3)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD1_PUE
|
||||
// Description : Pull up enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_PUE_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_PUE_BITS _u(0x00000008)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_PUE_MSB _u(3)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_PUE_LSB _u(3)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_PUE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD1_PDE
|
||||
// Description : Pull down enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_PDE_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_PDE_BITS _u(0x00000004)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_PDE_MSB _u(2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_PDE_LSB _u(2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_PDE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD1_SCHMITT
|
||||
// Description : Enable schmitt trigger
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_SCHMITT_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_SCHMITT_BITS _u(0x00000002)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_SCHMITT_MSB _u(1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_SCHMITT_LSB _u(1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_SCHMITT_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD1_SLEWFAST
|
||||
// Description : Slew rate control. 1 = Fast, 0 = Slow
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_SLEWFAST_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_SLEWFAST_BITS _u(0x00000001)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_SLEWFAST_MSB _u(0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_SLEWFAST_LSB _u(0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD1_SLEWFAST_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : PADS_QSPI_GPIO_QSPI_SD2
|
||||
// Description : Pad control register
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_OFFSET _u(0x00000010)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_BITS _u(0x000000ff)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_RESET _u(0x00000052)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD2_OD
|
||||
// Description : Output disable. Has priority over output enable from
|
||||
// peripherals
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_OD_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_OD_BITS _u(0x00000080)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_OD_MSB _u(7)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_OD_LSB _u(7)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_OD_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD2_IE
|
||||
// Description : Input enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_IE_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_IE_BITS _u(0x00000040)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_IE_MSB _u(6)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_IE_LSB _u(6)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_IE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD2_DRIVE
|
||||
// Description : Drive strength.
|
||||
// 0x0 -> 2mA
|
||||
// 0x1 -> 4mA
|
||||
// 0x2 -> 8mA
|
||||
// 0x3 -> 12mA
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_DRIVE_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_DRIVE_BITS _u(0x00000030)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_DRIVE_MSB _u(5)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_DRIVE_LSB _u(4)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_DRIVE_ACCESS "RW"
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_DRIVE_VALUE_2MA _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_DRIVE_VALUE_4MA _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_DRIVE_VALUE_8MA _u(0x2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_DRIVE_VALUE_12MA _u(0x3)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD2_PUE
|
||||
// Description : Pull up enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_PUE_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_PUE_BITS _u(0x00000008)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_PUE_MSB _u(3)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_PUE_LSB _u(3)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_PUE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD2_PDE
|
||||
// Description : Pull down enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_PDE_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_PDE_BITS _u(0x00000004)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_PDE_MSB _u(2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_PDE_LSB _u(2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_PDE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD2_SCHMITT
|
||||
// Description : Enable schmitt trigger
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_SCHMITT_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_SCHMITT_BITS _u(0x00000002)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_SCHMITT_MSB _u(1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_SCHMITT_LSB _u(1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_SCHMITT_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD2_SLEWFAST
|
||||
// Description : Slew rate control. 1 = Fast, 0 = Slow
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_SLEWFAST_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_SLEWFAST_BITS _u(0x00000001)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_SLEWFAST_MSB _u(0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_SLEWFAST_LSB _u(0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD2_SLEWFAST_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : PADS_QSPI_GPIO_QSPI_SD3
|
||||
// Description : Pad control register
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_OFFSET _u(0x00000014)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_BITS _u(0x000000ff)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_RESET _u(0x00000052)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD3_OD
|
||||
// Description : Output disable. Has priority over output enable from
|
||||
// peripherals
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_OD_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_OD_BITS _u(0x00000080)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_OD_MSB _u(7)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_OD_LSB _u(7)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_OD_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD3_IE
|
||||
// Description : Input enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_IE_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_IE_BITS _u(0x00000040)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_IE_MSB _u(6)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_IE_LSB _u(6)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_IE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD3_DRIVE
|
||||
// Description : Drive strength.
|
||||
// 0x0 -> 2mA
|
||||
// 0x1 -> 4mA
|
||||
// 0x2 -> 8mA
|
||||
// 0x3 -> 12mA
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_DRIVE_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_DRIVE_BITS _u(0x00000030)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_DRIVE_MSB _u(5)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_DRIVE_LSB _u(4)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_DRIVE_ACCESS "RW"
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_DRIVE_VALUE_2MA _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_DRIVE_VALUE_4MA _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_DRIVE_VALUE_8MA _u(0x2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_DRIVE_VALUE_12MA _u(0x3)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD3_PUE
|
||||
// Description : Pull up enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_PUE_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_PUE_BITS _u(0x00000008)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_PUE_MSB _u(3)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_PUE_LSB _u(3)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_PUE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD3_PDE
|
||||
// Description : Pull down enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_PDE_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_PDE_BITS _u(0x00000004)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_PDE_MSB _u(2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_PDE_LSB _u(2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_PDE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD3_SCHMITT
|
||||
// Description : Enable schmitt trigger
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_SCHMITT_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_SCHMITT_BITS _u(0x00000002)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_SCHMITT_MSB _u(1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_SCHMITT_LSB _u(1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_SCHMITT_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SD3_SLEWFAST
|
||||
// Description : Slew rate control. 1 = Fast, 0 = Slow
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_SLEWFAST_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_SLEWFAST_BITS _u(0x00000001)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_SLEWFAST_MSB _u(0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_SLEWFAST_LSB _u(0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SD3_SLEWFAST_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : PADS_QSPI_GPIO_QSPI_SS
|
||||
// Description : Pad control register
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_OFFSET _u(0x00000018)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_BITS _u(0x000000ff)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_RESET _u(0x0000005a)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SS_OD
|
||||
// Description : Output disable. Has priority over output enable from
|
||||
// peripherals
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_OD_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_OD_BITS _u(0x00000080)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_OD_MSB _u(7)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_OD_LSB _u(7)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_OD_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SS_IE
|
||||
// Description : Input enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_IE_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_IE_BITS _u(0x00000040)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_IE_MSB _u(6)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_IE_LSB _u(6)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_IE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SS_DRIVE
|
||||
// Description : Drive strength.
|
||||
// 0x0 -> 2mA
|
||||
// 0x1 -> 4mA
|
||||
// 0x2 -> 8mA
|
||||
// 0x3 -> 12mA
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_DRIVE_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_DRIVE_BITS _u(0x00000030)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_DRIVE_MSB _u(5)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_DRIVE_LSB _u(4)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_DRIVE_ACCESS "RW"
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_DRIVE_VALUE_2MA _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_DRIVE_VALUE_4MA _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_DRIVE_VALUE_8MA _u(0x2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_DRIVE_VALUE_12MA _u(0x3)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SS_PUE
|
||||
// Description : Pull up enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_PUE_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_PUE_BITS _u(0x00000008)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_PUE_MSB _u(3)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_PUE_LSB _u(3)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_PUE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SS_PDE
|
||||
// Description : Pull down enable
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_PDE_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_PDE_BITS _u(0x00000004)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_PDE_MSB _u(2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_PDE_LSB _u(2)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_PDE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SS_SCHMITT
|
||||
// Description : Enable schmitt trigger
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_SCHMITT_RESET _u(0x1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_SCHMITT_BITS _u(0x00000002)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_SCHMITT_MSB _u(1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_SCHMITT_LSB _u(1)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_SCHMITT_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : PADS_QSPI_GPIO_QSPI_SS_SLEWFAST
|
||||
// Description : Slew rate control. 1 = Fast, 0 = Slow
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_SLEWFAST_RESET _u(0x0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_SLEWFAST_BITS _u(0x00000001)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_SLEWFAST_MSB _u(0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_SLEWFAST_LSB _u(0)
|
||||
#define PADS_QSPI_GPIO_QSPI_SS_SLEWFAST_ACCESS "RW"
|
||||
// =============================================================================
|
||||
#endif // HARDWARE_REGS_PADS_QSPI_DEFINED
|
809
cpu/rpx0xx/vendor/boot_stage2/include/hardware/regs/ssi.h
vendored
Normal file
809
cpu/rpx0xx/vendor/boot_stage2/include/hardware/regs/ssi.h
vendored
Normal file
@ -0,0 +1,809 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
// =============================================================================
|
||||
// Register block : SSI
|
||||
// Version : 1
|
||||
// Bus type : apb
|
||||
// Description : DW_apb_ssi has the following features:
|
||||
// * APB interface – Allows for easy integration into a
|
||||
// DesignWare Synthesizable Components for AMBA 2
|
||||
// implementation.
|
||||
// * APB3 and APB4 protocol support.
|
||||
// * Scalable APB data bus width – Supports APB data bus widths
|
||||
// of 8, 16, and 32 bits.
|
||||
// * Serial-master or serial-slave operation – Enables serial
|
||||
// communication with serial-master or serial-slave peripheral
|
||||
// devices.
|
||||
// * Programmable Dual/Quad/Octal SPI support in Master Mode.
|
||||
// * Dual Data Rate (DDR) and Read Data Strobe (RDS) Support -
|
||||
// Enables the DW_apb_ssi master to perform operations with the
|
||||
// device in DDR and RDS modes when working in Dual/Quad/Octal
|
||||
// mode of operation.
|
||||
// * Data Mask Support - Enables the DW_apb_ssi to selectively
|
||||
// update the bytes in the device. This feature is applicable
|
||||
// only in enhanced SPI modes.
|
||||
// * eXecute-In-Place (XIP) support - Enables the DW_apb_ssi
|
||||
// master to behave as a memory mapped I/O and fetches the data
|
||||
// from the device based on the APB read request. This feature
|
||||
// is applicable only in enhanced SPI modes.
|
||||
// * DMA Controller Interface – Enables the DW_apb_ssi to
|
||||
// interface to a DMA controller over the bus using a
|
||||
// handshaking interface for transfer requests.
|
||||
// * Independent masking of interrupts – Master collision,
|
||||
// transmit FIFO overflow, transmit FIFO empty, receive FIFO
|
||||
// full, receive FIFO underflow, and receive FIFO overflow
|
||||
// interrupts can all be masked independently.
|
||||
// * Multi-master contention detection – Informs the processor
|
||||
// of multiple serial-master accesses on the serial bus.
|
||||
// * Bypass of meta-stability flip-flops for synchronous clocks
|
||||
// – When the APB clock (pclk) and the DW_apb_ssi serial clock
|
||||
// (ssi_clk) are synchronous, meta-stable flip-flops are not
|
||||
// used when transferring control signals across these clock
|
||||
// domains.
|
||||
// * Programmable delay on the sample time of the received
|
||||
// serial data bit (rxd); enables programmable control of
|
||||
// routing delays resulting in higher serial data-bit rates.
|
||||
// * Programmable features:
|
||||
// - Serial interface operation – Choice of Motorola SPI, Texas
|
||||
// Instruments Synchronous Serial Protocol or National
|
||||
// Semiconductor Microwire.
|
||||
// - Clock bit-rate – Dynamic control of the serial bit rate of
|
||||
// the data transfer; used in only serial-master mode of
|
||||
// operation.
|
||||
// - Data Item size (4 to 32 bits) – Item size of each data
|
||||
// transfer under the control of the programmer.
|
||||
// * Configured features:
|
||||
// - FIFO depth – 16 words deep. The FIFO width is fixed at 32
|
||||
// bits.
|
||||
// - 1 slave select output.
|
||||
// - Hardware slave-select – Dedicated hardware slave-select
|
||||
// line.
|
||||
// - Combined interrupt line - one combined interrupt line from
|
||||
// the DW_apb_ssi to the interrupt controller.
|
||||
// - Interrupt polarity – active high interrupt lines.
|
||||
// - Serial clock polarity – low serial-clock polarity directly
|
||||
// after reset.
|
||||
// - Serial clock phase – capture on first edge of serial-clock
|
||||
// directly after reset.
|
||||
// =============================================================================
|
||||
#ifndef HARDWARE_REGS_SSI_DEFINED
|
||||
#define HARDWARE_REGS_SSI_DEFINED
|
||||
// =============================================================================
|
||||
// Register : SSI_CTRLR0
|
||||
// Description : Control register 0
|
||||
#define SSI_CTRLR0_OFFSET _u(0x00000000)
|
||||
#define SSI_CTRLR0_BITS _u(0x017fffff)
|
||||
#define SSI_CTRLR0_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_CTRLR0_SSTE
|
||||
// Description : Slave select toggle enable
|
||||
#define SSI_CTRLR0_SSTE_RESET _u(0x0)
|
||||
#define SSI_CTRLR0_SSTE_BITS _u(0x01000000)
|
||||
#define SSI_CTRLR0_SSTE_MSB _u(24)
|
||||
#define SSI_CTRLR0_SSTE_LSB _u(24)
|
||||
#define SSI_CTRLR0_SSTE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_CTRLR0_SPI_FRF
|
||||
// Description : SPI frame format
|
||||
// 0x0 -> Standard 1-bit SPI frame format; 1 bit per SCK,
|
||||
// full-duplex
|
||||
// 0x1 -> Dual-SPI frame format; two bits per SCK, half-duplex
|
||||
// 0x2 -> Quad-SPI frame format; four bits per SCK, half-duplex
|
||||
#define SSI_CTRLR0_SPI_FRF_RESET _u(0x0)
|
||||
#define SSI_CTRLR0_SPI_FRF_BITS _u(0x00600000)
|
||||
#define SSI_CTRLR0_SPI_FRF_MSB _u(22)
|
||||
#define SSI_CTRLR0_SPI_FRF_LSB _u(21)
|
||||
#define SSI_CTRLR0_SPI_FRF_ACCESS "RW"
|
||||
#define SSI_CTRLR0_SPI_FRF_VALUE_STD _u(0x0)
|
||||
#define SSI_CTRLR0_SPI_FRF_VALUE_DUAL _u(0x1)
|
||||
#define SSI_CTRLR0_SPI_FRF_VALUE_QUAD _u(0x2)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_CTRLR0_DFS_32
|
||||
// Description : Data frame size in 32b transfer mode
|
||||
// Value of n -> n+1 clocks per frame.
|
||||
#define SSI_CTRLR0_DFS_32_RESET _u(0x00)
|
||||
#define SSI_CTRLR0_DFS_32_BITS _u(0x001f0000)
|
||||
#define SSI_CTRLR0_DFS_32_MSB _u(20)
|
||||
#define SSI_CTRLR0_DFS_32_LSB _u(16)
|
||||
#define SSI_CTRLR0_DFS_32_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_CTRLR0_CFS
|
||||
// Description : Control frame size
|
||||
// Value of n -> n+1 clocks per frame.
|
||||
#define SSI_CTRLR0_CFS_RESET _u(0x0)
|
||||
#define SSI_CTRLR0_CFS_BITS _u(0x0000f000)
|
||||
#define SSI_CTRLR0_CFS_MSB _u(15)
|
||||
#define SSI_CTRLR0_CFS_LSB _u(12)
|
||||
#define SSI_CTRLR0_CFS_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_CTRLR0_SRL
|
||||
// Description : Shift register loop (test mode)
|
||||
#define SSI_CTRLR0_SRL_RESET _u(0x0)
|
||||
#define SSI_CTRLR0_SRL_BITS _u(0x00000800)
|
||||
#define SSI_CTRLR0_SRL_MSB _u(11)
|
||||
#define SSI_CTRLR0_SRL_LSB _u(11)
|
||||
#define SSI_CTRLR0_SRL_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_CTRLR0_SLV_OE
|
||||
// Description : Slave output enable
|
||||
#define SSI_CTRLR0_SLV_OE_RESET _u(0x0)
|
||||
#define SSI_CTRLR0_SLV_OE_BITS _u(0x00000400)
|
||||
#define SSI_CTRLR0_SLV_OE_MSB _u(10)
|
||||
#define SSI_CTRLR0_SLV_OE_LSB _u(10)
|
||||
#define SSI_CTRLR0_SLV_OE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_CTRLR0_TMOD
|
||||
// Description : Transfer mode
|
||||
// 0x0 -> Both transmit and receive
|
||||
// 0x1 -> Transmit only (not for FRF == 0, standard SPI mode)
|
||||
// 0x2 -> Receive only (not for FRF == 0, standard SPI mode)
|
||||
// 0x3 -> EEPROM read mode (TX then RX; RX starts after control
|
||||
// data TX'd)
|
||||
#define SSI_CTRLR0_TMOD_RESET _u(0x0)
|
||||
#define SSI_CTRLR0_TMOD_BITS _u(0x00000300)
|
||||
#define SSI_CTRLR0_TMOD_MSB _u(9)
|
||||
#define SSI_CTRLR0_TMOD_LSB _u(8)
|
||||
#define SSI_CTRLR0_TMOD_ACCESS "RW"
|
||||
#define SSI_CTRLR0_TMOD_VALUE_TX_AND_RX _u(0x0)
|
||||
#define SSI_CTRLR0_TMOD_VALUE_TX_ONLY _u(0x1)
|
||||
#define SSI_CTRLR0_TMOD_VALUE_RX_ONLY _u(0x2)
|
||||
#define SSI_CTRLR0_TMOD_VALUE_EEPROM_READ _u(0x3)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_CTRLR0_SCPOL
|
||||
// Description : Serial clock polarity
|
||||
#define SSI_CTRLR0_SCPOL_RESET _u(0x0)
|
||||
#define SSI_CTRLR0_SCPOL_BITS _u(0x00000080)
|
||||
#define SSI_CTRLR0_SCPOL_MSB _u(7)
|
||||
#define SSI_CTRLR0_SCPOL_LSB _u(7)
|
||||
#define SSI_CTRLR0_SCPOL_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_CTRLR0_SCPH
|
||||
// Description : Serial clock phase
|
||||
#define SSI_CTRLR0_SCPH_RESET _u(0x0)
|
||||
#define SSI_CTRLR0_SCPH_BITS _u(0x00000040)
|
||||
#define SSI_CTRLR0_SCPH_MSB _u(6)
|
||||
#define SSI_CTRLR0_SCPH_LSB _u(6)
|
||||
#define SSI_CTRLR0_SCPH_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_CTRLR0_FRF
|
||||
// Description : Frame format
|
||||
#define SSI_CTRLR0_FRF_RESET _u(0x0)
|
||||
#define SSI_CTRLR0_FRF_BITS _u(0x00000030)
|
||||
#define SSI_CTRLR0_FRF_MSB _u(5)
|
||||
#define SSI_CTRLR0_FRF_LSB _u(4)
|
||||
#define SSI_CTRLR0_FRF_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_CTRLR0_DFS
|
||||
// Description : Data frame size
|
||||
#define SSI_CTRLR0_DFS_RESET _u(0x0)
|
||||
#define SSI_CTRLR0_DFS_BITS _u(0x0000000f)
|
||||
#define SSI_CTRLR0_DFS_MSB _u(3)
|
||||
#define SSI_CTRLR0_DFS_LSB _u(0)
|
||||
#define SSI_CTRLR0_DFS_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : SSI_CTRLR1
|
||||
// Description : Master Control register 1
|
||||
#define SSI_CTRLR1_OFFSET _u(0x00000004)
|
||||
#define SSI_CTRLR1_BITS _u(0x0000ffff)
|
||||
#define SSI_CTRLR1_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_CTRLR1_NDF
|
||||
// Description : Number of data frames
|
||||
#define SSI_CTRLR1_NDF_RESET _u(0x0000)
|
||||
#define SSI_CTRLR1_NDF_BITS _u(0x0000ffff)
|
||||
#define SSI_CTRLR1_NDF_MSB _u(15)
|
||||
#define SSI_CTRLR1_NDF_LSB _u(0)
|
||||
#define SSI_CTRLR1_NDF_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : SSI_SSIENR
|
||||
// Description : SSI Enable
|
||||
#define SSI_SSIENR_OFFSET _u(0x00000008)
|
||||
#define SSI_SSIENR_BITS _u(0x00000001)
|
||||
#define SSI_SSIENR_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SSIENR_SSI_EN
|
||||
// Description : SSI enable
|
||||
#define SSI_SSIENR_SSI_EN_RESET _u(0x0)
|
||||
#define SSI_SSIENR_SSI_EN_BITS _u(0x00000001)
|
||||
#define SSI_SSIENR_SSI_EN_MSB _u(0)
|
||||
#define SSI_SSIENR_SSI_EN_LSB _u(0)
|
||||
#define SSI_SSIENR_SSI_EN_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : SSI_MWCR
|
||||
// Description : Microwire Control
|
||||
#define SSI_MWCR_OFFSET _u(0x0000000c)
|
||||
#define SSI_MWCR_BITS _u(0x00000007)
|
||||
#define SSI_MWCR_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_MWCR_MHS
|
||||
// Description : Microwire handshaking
|
||||
#define SSI_MWCR_MHS_RESET _u(0x0)
|
||||
#define SSI_MWCR_MHS_BITS _u(0x00000004)
|
||||
#define SSI_MWCR_MHS_MSB _u(2)
|
||||
#define SSI_MWCR_MHS_LSB _u(2)
|
||||
#define SSI_MWCR_MHS_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_MWCR_MDD
|
||||
// Description : Microwire control
|
||||
#define SSI_MWCR_MDD_RESET _u(0x0)
|
||||
#define SSI_MWCR_MDD_BITS _u(0x00000002)
|
||||
#define SSI_MWCR_MDD_MSB _u(1)
|
||||
#define SSI_MWCR_MDD_LSB _u(1)
|
||||
#define SSI_MWCR_MDD_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_MWCR_MWMOD
|
||||
// Description : Microwire transfer mode
|
||||
#define SSI_MWCR_MWMOD_RESET _u(0x0)
|
||||
#define SSI_MWCR_MWMOD_BITS _u(0x00000001)
|
||||
#define SSI_MWCR_MWMOD_MSB _u(0)
|
||||
#define SSI_MWCR_MWMOD_LSB _u(0)
|
||||
#define SSI_MWCR_MWMOD_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : SSI_SER
|
||||
// Description : Slave enable
|
||||
// For each bit:
|
||||
// 0 -> slave not selected
|
||||
// 1 -> slave selected
|
||||
#define SSI_SER_OFFSET _u(0x00000010)
|
||||
#define SSI_SER_BITS _u(0x00000001)
|
||||
#define SSI_SER_RESET _u(0x00000000)
|
||||
#define SSI_SER_MSB _u(0)
|
||||
#define SSI_SER_LSB _u(0)
|
||||
#define SSI_SER_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : SSI_BAUDR
|
||||
// Description : Baud rate
|
||||
#define SSI_BAUDR_OFFSET _u(0x00000014)
|
||||
#define SSI_BAUDR_BITS _u(0x0000ffff)
|
||||
#define SSI_BAUDR_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_BAUDR_SCKDV
|
||||
// Description : SSI clock divider
|
||||
#define SSI_BAUDR_SCKDV_RESET _u(0x0000)
|
||||
#define SSI_BAUDR_SCKDV_BITS _u(0x0000ffff)
|
||||
#define SSI_BAUDR_SCKDV_MSB _u(15)
|
||||
#define SSI_BAUDR_SCKDV_LSB _u(0)
|
||||
#define SSI_BAUDR_SCKDV_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : SSI_TXFTLR
|
||||
// Description : TX FIFO threshold level
|
||||
#define SSI_TXFTLR_OFFSET _u(0x00000018)
|
||||
#define SSI_TXFTLR_BITS _u(0x000000ff)
|
||||
#define SSI_TXFTLR_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_TXFTLR_TFT
|
||||
// Description : Transmit FIFO threshold
|
||||
#define SSI_TXFTLR_TFT_RESET _u(0x00)
|
||||
#define SSI_TXFTLR_TFT_BITS _u(0x000000ff)
|
||||
#define SSI_TXFTLR_TFT_MSB _u(7)
|
||||
#define SSI_TXFTLR_TFT_LSB _u(0)
|
||||
#define SSI_TXFTLR_TFT_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : SSI_RXFTLR
|
||||
// Description : RX FIFO threshold level
|
||||
#define SSI_RXFTLR_OFFSET _u(0x0000001c)
|
||||
#define SSI_RXFTLR_BITS _u(0x000000ff)
|
||||
#define SSI_RXFTLR_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_RXFTLR_RFT
|
||||
// Description : Receive FIFO threshold
|
||||
#define SSI_RXFTLR_RFT_RESET _u(0x00)
|
||||
#define SSI_RXFTLR_RFT_BITS _u(0x000000ff)
|
||||
#define SSI_RXFTLR_RFT_MSB _u(7)
|
||||
#define SSI_RXFTLR_RFT_LSB _u(0)
|
||||
#define SSI_RXFTLR_RFT_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : SSI_TXFLR
|
||||
// Description : TX FIFO level
|
||||
#define SSI_TXFLR_OFFSET _u(0x00000020)
|
||||
#define SSI_TXFLR_BITS _u(0x000000ff)
|
||||
#define SSI_TXFLR_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_TXFLR_TFTFL
|
||||
// Description : Transmit FIFO level
|
||||
#define SSI_TXFLR_TFTFL_RESET _u(0x00)
|
||||
#define SSI_TXFLR_TFTFL_BITS _u(0x000000ff)
|
||||
#define SSI_TXFLR_TFTFL_MSB _u(7)
|
||||
#define SSI_TXFLR_TFTFL_LSB _u(0)
|
||||
#define SSI_TXFLR_TFTFL_ACCESS "RO"
|
||||
// =============================================================================
|
||||
// Register : SSI_RXFLR
|
||||
// Description : RX FIFO level
|
||||
#define SSI_RXFLR_OFFSET _u(0x00000024)
|
||||
#define SSI_RXFLR_BITS _u(0x000000ff)
|
||||
#define SSI_RXFLR_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_RXFLR_RXTFL
|
||||
// Description : Receive FIFO level
|
||||
#define SSI_RXFLR_RXTFL_RESET _u(0x00)
|
||||
#define SSI_RXFLR_RXTFL_BITS _u(0x000000ff)
|
||||
#define SSI_RXFLR_RXTFL_MSB _u(7)
|
||||
#define SSI_RXFLR_RXTFL_LSB _u(0)
|
||||
#define SSI_RXFLR_RXTFL_ACCESS "RO"
|
||||
// =============================================================================
|
||||
// Register : SSI_SR
|
||||
// Description : Status register
|
||||
#define SSI_SR_OFFSET _u(0x00000028)
|
||||
#define SSI_SR_BITS _u(0x0000007f)
|
||||
#define SSI_SR_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SR_DCOL
|
||||
// Description : Data collision error
|
||||
#define SSI_SR_DCOL_RESET _u(0x0)
|
||||
#define SSI_SR_DCOL_BITS _u(0x00000040)
|
||||
#define SSI_SR_DCOL_MSB _u(6)
|
||||
#define SSI_SR_DCOL_LSB _u(6)
|
||||
#define SSI_SR_DCOL_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SR_TXE
|
||||
// Description : Transmission error
|
||||
#define SSI_SR_TXE_RESET _u(0x0)
|
||||
#define SSI_SR_TXE_BITS _u(0x00000020)
|
||||
#define SSI_SR_TXE_MSB _u(5)
|
||||
#define SSI_SR_TXE_LSB _u(5)
|
||||
#define SSI_SR_TXE_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SR_RFF
|
||||
// Description : Receive FIFO full
|
||||
#define SSI_SR_RFF_RESET _u(0x0)
|
||||
#define SSI_SR_RFF_BITS _u(0x00000010)
|
||||
#define SSI_SR_RFF_MSB _u(4)
|
||||
#define SSI_SR_RFF_LSB _u(4)
|
||||
#define SSI_SR_RFF_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SR_RFNE
|
||||
// Description : Receive FIFO not empty
|
||||
#define SSI_SR_RFNE_RESET _u(0x0)
|
||||
#define SSI_SR_RFNE_BITS _u(0x00000008)
|
||||
#define SSI_SR_RFNE_MSB _u(3)
|
||||
#define SSI_SR_RFNE_LSB _u(3)
|
||||
#define SSI_SR_RFNE_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SR_TFE
|
||||
// Description : Transmit FIFO empty
|
||||
#define SSI_SR_TFE_RESET _u(0x0)
|
||||
#define SSI_SR_TFE_BITS _u(0x00000004)
|
||||
#define SSI_SR_TFE_MSB _u(2)
|
||||
#define SSI_SR_TFE_LSB _u(2)
|
||||
#define SSI_SR_TFE_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SR_TFNF
|
||||
// Description : Transmit FIFO not full
|
||||
#define SSI_SR_TFNF_RESET _u(0x0)
|
||||
#define SSI_SR_TFNF_BITS _u(0x00000002)
|
||||
#define SSI_SR_TFNF_MSB _u(1)
|
||||
#define SSI_SR_TFNF_LSB _u(1)
|
||||
#define SSI_SR_TFNF_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SR_BUSY
|
||||
// Description : SSI busy flag
|
||||
#define SSI_SR_BUSY_RESET _u(0x0)
|
||||
#define SSI_SR_BUSY_BITS _u(0x00000001)
|
||||
#define SSI_SR_BUSY_MSB _u(0)
|
||||
#define SSI_SR_BUSY_LSB _u(0)
|
||||
#define SSI_SR_BUSY_ACCESS "RO"
|
||||
// =============================================================================
|
||||
// Register : SSI_IMR
|
||||
// Description : Interrupt mask
|
||||
#define SSI_IMR_OFFSET _u(0x0000002c)
|
||||
#define SSI_IMR_BITS _u(0x0000003f)
|
||||
#define SSI_IMR_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_IMR_MSTIM
|
||||
// Description : Multi-master contention interrupt mask
|
||||
#define SSI_IMR_MSTIM_RESET _u(0x0)
|
||||
#define SSI_IMR_MSTIM_BITS _u(0x00000020)
|
||||
#define SSI_IMR_MSTIM_MSB _u(5)
|
||||
#define SSI_IMR_MSTIM_LSB _u(5)
|
||||
#define SSI_IMR_MSTIM_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_IMR_RXFIM
|
||||
// Description : Receive FIFO full interrupt mask
|
||||
#define SSI_IMR_RXFIM_RESET _u(0x0)
|
||||
#define SSI_IMR_RXFIM_BITS _u(0x00000010)
|
||||
#define SSI_IMR_RXFIM_MSB _u(4)
|
||||
#define SSI_IMR_RXFIM_LSB _u(4)
|
||||
#define SSI_IMR_RXFIM_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_IMR_RXOIM
|
||||
// Description : Receive FIFO overflow interrupt mask
|
||||
#define SSI_IMR_RXOIM_RESET _u(0x0)
|
||||
#define SSI_IMR_RXOIM_BITS _u(0x00000008)
|
||||
#define SSI_IMR_RXOIM_MSB _u(3)
|
||||
#define SSI_IMR_RXOIM_LSB _u(3)
|
||||
#define SSI_IMR_RXOIM_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_IMR_RXUIM
|
||||
// Description : Receive FIFO underflow interrupt mask
|
||||
#define SSI_IMR_RXUIM_RESET _u(0x0)
|
||||
#define SSI_IMR_RXUIM_BITS _u(0x00000004)
|
||||
#define SSI_IMR_RXUIM_MSB _u(2)
|
||||
#define SSI_IMR_RXUIM_LSB _u(2)
|
||||
#define SSI_IMR_RXUIM_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_IMR_TXOIM
|
||||
// Description : Transmit FIFO overflow interrupt mask
|
||||
#define SSI_IMR_TXOIM_RESET _u(0x0)
|
||||
#define SSI_IMR_TXOIM_BITS _u(0x00000002)
|
||||
#define SSI_IMR_TXOIM_MSB _u(1)
|
||||
#define SSI_IMR_TXOIM_LSB _u(1)
|
||||
#define SSI_IMR_TXOIM_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_IMR_TXEIM
|
||||
// Description : Transmit FIFO empty interrupt mask
|
||||
#define SSI_IMR_TXEIM_RESET _u(0x0)
|
||||
#define SSI_IMR_TXEIM_BITS _u(0x00000001)
|
||||
#define SSI_IMR_TXEIM_MSB _u(0)
|
||||
#define SSI_IMR_TXEIM_LSB _u(0)
|
||||
#define SSI_IMR_TXEIM_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : SSI_ISR
|
||||
// Description : Interrupt status
|
||||
#define SSI_ISR_OFFSET _u(0x00000030)
|
||||
#define SSI_ISR_BITS _u(0x0000003f)
|
||||
#define SSI_ISR_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_ISR_MSTIS
|
||||
// Description : Multi-master contention interrupt status
|
||||
#define SSI_ISR_MSTIS_RESET _u(0x0)
|
||||
#define SSI_ISR_MSTIS_BITS _u(0x00000020)
|
||||
#define SSI_ISR_MSTIS_MSB _u(5)
|
||||
#define SSI_ISR_MSTIS_LSB _u(5)
|
||||
#define SSI_ISR_MSTIS_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_ISR_RXFIS
|
||||
// Description : Receive FIFO full interrupt status
|
||||
#define SSI_ISR_RXFIS_RESET _u(0x0)
|
||||
#define SSI_ISR_RXFIS_BITS _u(0x00000010)
|
||||
#define SSI_ISR_RXFIS_MSB _u(4)
|
||||
#define SSI_ISR_RXFIS_LSB _u(4)
|
||||
#define SSI_ISR_RXFIS_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_ISR_RXOIS
|
||||
// Description : Receive FIFO overflow interrupt status
|
||||
#define SSI_ISR_RXOIS_RESET _u(0x0)
|
||||
#define SSI_ISR_RXOIS_BITS _u(0x00000008)
|
||||
#define SSI_ISR_RXOIS_MSB _u(3)
|
||||
#define SSI_ISR_RXOIS_LSB _u(3)
|
||||
#define SSI_ISR_RXOIS_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_ISR_RXUIS
|
||||
// Description : Receive FIFO underflow interrupt status
|
||||
#define SSI_ISR_RXUIS_RESET _u(0x0)
|
||||
#define SSI_ISR_RXUIS_BITS _u(0x00000004)
|
||||
#define SSI_ISR_RXUIS_MSB _u(2)
|
||||
#define SSI_ISR_RXUIS_LSB _u(2)
|
||||
#define SSI_ISR_RXUIS_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_ISR_TXOIS
|
||||
// Description : Transmit FIFO overflow interrupt status
|
||||
#define SSI_ISR_TXOIS_RESET _u(0x0)
|
||||
#define SSI_ISR_TXOIS_BITS _u(0x00000002)
|
||||
#define SSI_ISR_TXOIS_MSB _u(1)
|
||||
#define SSI_ISR_TXOIS_LSB _u(1)
|
||||
#define SSI_ISR_TXOIS_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_ISR_TXEIS
|
||||
// Description : Transmit FIFO empty interrupt status
|
||||
#define SSI_ISR_TXEIS_RESET _u(0x0)
|
||||
#define SSI_ISR_TXEIS_BITS _u(0x00000001)
|
||||
#define SSI_ISR_TXEIS_MSB _u(0)
|
||||
#define SSI_ISR_TXEIS_LSB _u(0)
|
||||
#define SSI_ISR_TXEIS_ACCESS "RO"
|
||||
// =============================================================================
|
||||
// Register : SSI_RISR
|
||||
// Description : Raw interrupt status
|
||||
#define SSI_RISR_OFFSET _u(0x00000034)
|
||||
#define SSI_RISR_BITS _u(0x0000003f)
|
||||
#define SSI_RISR_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_RISR_MSTIR
|
||||
// Description : Multi-master contention raw interrupt status
|
||||
#define SSI_RISR_MSTIR_RESET _u(0x0)
|
||||
#define SSI_RISR_MSTIR_BITS _u(0x00000020)
|
||||
#define SSI_RISR_MSTIR_MSB _u(5)
|
||||
#define SSI_RISR_MSTIR_LSB _u(5)
|
||||
#define SSI_RISR_MSTIR_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_RISR_RXFIR
|
||||
// Description : Receive FIFO full raw interrupt status
|
||||
#define SSI_RISR_RXFIR_RESET _u(0x0)
|
||||
#define SSI_RISR_RXFIR_BITS _u(0x00000010)
|
||||
#define SSI_RISR_RXFIR_MSB _u(4)
|
||||
#define SSI_RISR_RXFIR_LSB _u(4)
|
||||
#define SSI_RISR_RXFIR_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_RISR_RXOIR
|
||||
// Description : Receive FIFO overflow raw interrupt status
|
||||
#define SSI_RISR_RXOIR_RESET _u(0x0)
|
||||
#define SSI_RISR_RXOIR_BITS _u(0x00000008)
|
||||
#define SSI_RISR_RXOIR_MSB _u(3)
|
||||
#define SSI_RISR_RXOIR_LSB _u(3)
|
||||
#define SSI_RISR_RXOIR_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_RISR_RXUIR
|
||||
// Description : Receive FIFO underflow raw interrupt status
|
||||
#define SSI_RISR_RXUIR_RESET _u(0x0)
|
||||
#define SSI_RISR_RXUIR_BITS _u(0x00000004)
|
||||
#define SSI_RISR_RXUIR_MSB _u(2)
|
||||
#define SSI_RISR_RXUIR_LSB _u(2)
|
||||
#define SSI_RISR_RXUIR_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_RISR_TXOIR
|
||||
// Description : Transmit FIFO overflow raw interrupt status
|
||||
#define SSI_RISR_TXOIR_RESET _u(0x0)
|
||||
#define SSI_RISR_TXOIR_BITS _u(0x00000002)
|
||||
#define SSI_RISR_TXOIR_MSB _u(1)
|
||||
#define SSI_RISR_TXOIR_LSB _u(1)
|
||||
#define SSI_RISR_TXOIR_ACCESS "RO"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_RISR_TXEIR
|
||||
// Description : Transmit FIFO empty raw interrupt status
|
||||
#define SSI_RISR_TXEIR_RESET _u(0x0)
|
||||
#define SSI_RISR_TXEIR_BITS _u(0x00000001)
|
||||
#define SSI_RISR_TXEIR_MSB _u(0)
|
||||
#define SSI_RISR_TXEIR_LSB _u(0)
|
||||
#define SSI_RISR_TXEIR_ACCESS "RO"
|
||||
// =============================================================================
|
||||
// Register : SSI_TXOICR
|
||||
// Description : TX FIFO overflow interrupt clear
|
||||
// Clear-on-read transmit FIFO overflow interrupt
|
||||
#define SSI_TXOICR_OFFSET _u(0x00000038)
|
||||
#define SSI_TXOICR_BITS _u(0x00000001)
|
||||
#define SSI_TXOICR_RESET _u(0x00000000)
|
||||
#define SSI_TXOICR_MSB _u(0)
|
||||
#define SSI_TXOICR_LSB _u(0)
|
||||
#define SSI_TXOICR_ACCESS "RO"
|
||||
// =============================================================================
|
||||
// Register : SSI_RXOICR
|
||||
// Description : RX FIFO overflow interrupt clear
|
||||
// Clear-on-read receive FIFO overflow interrupt
|
||||
#define SSI_RXOICR_OFFSET _u(0x0000003c)
|
||||
#define SSI_RXOICR_BITS _u(0x00000001)
|
||||
#define SSI_RXOICR_RESET _u(0x00000000)
|
||||
#define SSI_RXOICR_MSB _u(0)
|
||||
#define SSI_RXOICR_LSB _u(0)
|
||||
#define SSI_RXOICR_ACCESS "RO"
|
||||
// =============================================================================
|
||||
// Register : SSI_RXUICR
|
||||
// Description : RX FIFO underflow interrupt clear
|
||||
// Clear-on-read receive FIFO underflow interrupt
|
||||
#define SSI_RXUICR_OFFSET _u(0x00000040)
|
||||
#define SSI_RXUICR_BITS _u(0x00000001)
|
||||
#define SSI_RXUICR_RESET _u(0x00000000)
|
||||
#define SSI_RXUICR_MSB _u(0)
|
||||
#define SSI_RXUICR_LSB _u(0)
|
||||
#define SSI_RXUICR_ACCESS "RO"
|
||||
// =============================================================================
|
||||
// Register : SSI_MSTICR
|
||||
// Description : Multi-master interrupt clear
|
||||
// Clear-on-read multi-master contention interrupt
|
||||
#define SSI_MSTICR_OFFSET _u(0x00000044)
|
||||
#define SSI_MSTICR_BITS _u(0x00000001)
|
||||
#define SSI_MSTICR_RESET _u(0x00000000)
|
||||
#define SSI_MSTICR_MSB _u(0)
|
||||
#define SSI_MSTICR_LSB _u(0)
|
||||
#define SSI_MSTICR_ACCESS "RO"
|
||||
// =============================================================================
|
||||
// Register : SSI_ICR
|
||||
// Description : Interrupt clear
|
||||
// Clear-on-read all active interrupts
|
||||
#define SSI_ICR_OFFSET _u(0x00000048)
|
||||
#define SSI_ICR_BITS _u(0x00000001)
|
||||
#define SSI_ICR_RESET _u(0x00000000)
|
||||
#define SSI_ICR_MSB _u(0)
|
||||
#define SSI_ICR_LSB _u(0)
|
||||
#define SSI_ICR_ACCESS "RO"
|
||||
// =============================================================================
|
||||
// Register : SSI_DMACR
|
||||
// Description : DMA control
|
||||
#define SSI_DMACR_OFFSET _u(0x0000004c)
|
||||
#define SSI_DMACR_BITS _u(0x00000003)
|
||||
#define SSI_DMACR_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_DMACR_TDMAE
|
||||
// Description : Transmit DMA enable
|
||||
#define SSI_DMACR_TDMAE_RESET _u(0x0)
|
||||
#define SSI_DMACR_TDMAE_BITS _u(0x00000002)
|
||||
#define SSI_DMACR_TDMAE_MSB _u(1)
|
||||
#define SSI_DMACR_TDMAE_LSB _u(1)
|
||||
#define SSI_DMACR_TDMAE_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_DMACR_RDMAE
|
||||
// Description : Receive DMA enable
|
||||
#define SSI_DMACR_RDMAE_RESET _u(0x0)
|
||||
#define SSI_DMACR_RDMAE_BITS _u(0x00000001)
|
||||
#define SSI_DMACR_RDMAE_MSB _u(0)
|
||||
#define SSI_DMACR_RDMAE_LSB _u(0)
|
||||
#define SSI_DMACR_RDMAE_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : SSI_DMATDLR
|
||||
// Description : DMA TX data level
|
||||
#define SSI_DMATDLR_OFFSET _u(0x00000050)
|
||||
#define SSI_DMATDLR_BITS _u(0x000000ff)
|
||||
#define SSI_DMATDLR_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_DMATDLR_DMATDL
|
||||
// Description : Transmit data watermark level
|
||||
#define SSI_DMATDLR_DMATDL_RESET _u(0x00)
|
||||
#define SSI_DMATDLR_DMATDL_BITS _u(0x000000ff)
|
||||
#define SSI_DMATDLR_DMATDL_MSB _u(7)
|
||||
#define SSI_DMATDLR_DMATDL_LSB _u(0)
|
||||
#define SSI_DMATDLR_DMATDL_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : SSI_DMARDLR
|
||||
// Description : DMA RX data level
|
||||
#define SSI_DMARDLR_OFFSET _u(0x00000054)
|
||||
#define SSI_DMARDLR_BITS _u(0x000000ff)
|
||||
#define SSI_DMARDLR_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_DMARDLR_DMARDL
|
||||
// Description : Receive data watermark level (DMARDLR+1)
|
||||
#define SSI_DMARDLR_DMARDL_RESET _u(0x00)
|
||||
#define SSI_DMARDLR_DMARDL_BITS _u(0x000000ff)
|
||||
#define SSI_DMARDLR_DMARDL_MSB _u(7)
|
||||
#define SSI_DMARDLR_DMARDL_LSB _u(0)
|
||||
#define SSI_DMARDLR_DMARDL_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : SSI_IDR
|
||||
// Description : Identification register
|
||||
#define SSI_IDR_OFFSET _u(0x00000058)
|
||||
#define SSI_IDR_BITS _u(0xffffffff)
|
||||
#define SSI_IDR_RESET _u(0x51535049)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_IDR_IDCODE
|
||||
// Description : Peripheral dentification code
|
||||
#define SSI_IDR_IDCODE_RESET _u(0x51535049)
|
||||
#define SSI_IDR_IDCODE_BITS _u(0xffffffff)
|
||||
#define SSI_IDR_IDCODE_MSB _u(31)
|
||||
#define SSI_IDR_IDCODE_LSB _u(0)
|
||||
#define SSI_IDR_IDCODE_ACCESS "RO"
|
||||
// =============================================================================
|
||||
// Register : SSI_SSI_VERSION_ID
|
||||
// Description : Version ID
|
||||
#define SSI_SSI_VERSION_ID_OFFSET _u(0x0000005c)
|
||||
#define SSI_SSI_VERSION_ID_BITS _u(0xffffffff)
|
||||
#define SSI_SSI_VERSION_ID_RESET _u(0x3430312a)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SSI_VERSION_ID_SSI_COMP_VERSION
|
||||
// Description : SNPS component version (format X.YY)
|
||||
#define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_RESET _u(0x3430312a)
|
||||
#define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_BITS _u(0xffffffff)
|
||||
#define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_MSB _u(31)
|
||||
#define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_LSB _u(0)
|
||||
#define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_ACCESS "RO"
|
||||
// =============================================================================
|
||||
// Register : SSI_DR0
|
||||
// Description : Data Register 0 (of 36)
|
||||
#define SSI_DR0_OFFSET _u(0x00000060)
|
||||
#define SSI_DR0_BITS _u(0xffffffff)
|
||||
#define SSI_DR0_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_DR0_DR
|
||||
// Description : First data register of 36
|
||||
#define SSI_DR0_DR_RESET _u(0x00000000)
|
||||
#define SSI_DR0_DR_BITS _u(0xffffffff)
|
||||
#define SSI_DR0_DR_MSB _u(31)
|
||||
#define SSI_DR0_DR_LSB _u(0)
|
||||
#define SSI_DR0_DR_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : SSI_RX_SAMPLE_DLY
|
||||
// Description : RX sample delay
|
||||
#define SSI_RX_SAMPLE_DLY_OFFSET _u(0x000000f0)
|
||||
#define SSI_RX_SAMPLE_DLY_BITS _u(0x000000ff)
|
||||
#define SSI_RX_SAMPLE_DLY_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_RX_SAMPLE_DLY_RSD
|
||||
// Description : RXD sample delay (in SCLK cycles)
|
||||
#define SSI_RX_SAMPLE_DLY_RSD_RESET _u(0x00)
|
||||
#define SSI_RX_SAMPLE_DLY_RSD_BITS _u(0x000000ff)
|
||||
#define SSI_RX_SAMPLE_DLY_RSD_MSB _u(7)
|
||||
#define SSI_RX_SAMPLE_DLY_RSD_LSB _u(0)
|
||||
#define SSI_RX_SAMPLE_DLY_RSD_ACCESS "RW"
|
||||
// =============================================================================
|
||||
// Register : SSI_SPI_CTRLR0
|
||||
// Description : SPI control
|
||||
#define SSI_SPI_CTRLR0_OFFSET _u(0x000000f4)
|
||||
#define SSI_SPI_CTRLR0_BITS _u(0xff07fb3f)
|
||||
#define SSI_SPI_CTRLR0_RESET _u(0x03000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SPI_CTRLR0_XIP_CMD
|
||||
// Description : SPI Command to send in XIP mode (INST_L = 8-bit) or to append
|
||||
// to Address (INST_L = 0-bit)
|
||||
#define SSI_SPI_CTRLR0_XIP_CMD_RESET _u(0x03)
|
||||
#define SSI_SPI_CTRLR0_XIP_CMD_BITS _u(0xff000000)
|
||||
#define SSI_SPI_CTRLR0_XIP_CMD_MSB _u(31)
|
||||
#define SSI_SPI_CTRLR0_XIP_CMD_LSB _u(24)
|
||||
#define SSI_SPI_CTRLR0_XIP_CMD_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SPI_CTRLR0_SPI_RXDS_EN
|
||||
// Description : Read data strobe enable
|
||||
#define SSI_SPI_CTRLR0_SPI_RXDS_EN_RESET _u(0x0)
|
||||
#define SSI_SPI_CTRLR0_SPI_RXDS_EN_BITS _u(0x00040000)
|
||||
#define SSI_SPI_CTRLR0_SPI_RXDS_EN_MSB _u(18)
|
||||
#define SSI_SPI_CTRLR0_SPI_RXDS_EN_LSB _u(18)
|
||||
#define SSI_SPI_CTRLR0_SPI_RXDS_EN_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SPI_CTRLR0_INST_DDR_EN
|
||||
// Description : Instruction DDR transfer enable
|
||||
#define SSI_SPI_CTRLR0_INST_DDR_EN_RESET _u(0x0)
|
||||
#define SSI_SPI_CTRLR0_INST_DDR_EN_BITS _u(0x00020000)
|
||||
#define SSI_SPI_CTRLR0_INST_DDR_EN_MSB _u(17)
|
||||
#define SSI_SPI_CTRLR0_INST_DDR_EN_LSB _u(17)
|
||||
#define SSI_SPI_CTRLR0_INST_DDR_EN_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SPI_CTRLR0_SPI_DDR_EN
|
||||
// Description : SPI DDR transfer enable
|
||||
#define SSI_SPI_CTRLR0_SPI_DDR_EN_RESET _u(0x0)
|
||||
#define SSI_SPI_CTRLR0_SPI_DDR_EN_BITS _u(0x00010000)
|
||||
#define SSI_SPI_CTRLR0_SPI_DDR_EN_MSB _u(16)
|
||||
#define SSI_SPI_CTRLR0_SPI_DDR_EN_LSB _u(16)
|
||||
#define SSI_SPI_CTRLR0_SPI_DDR_EN_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SPI_CTRLR0_WAIT_CYCLES
|
||||
// Description : Wait cycles between control frame transmit and data reception
|
||||
// (in SCLK cycles)
|
||||
#define SSI_SPI_CTRLR0_WAIT_CYCLES_RESET _u(0x00)
|
||||
#define SSI_SPI_CTRLR0_WAIT_CYCLES_BITS _u(0x0000f800)
|
||||
#define SSI_SPI_CTRLR0_WAIT_CYCLES_MSB _u(15)
|
||||
#define SSI_SPI_CTRLR0_WAIT_CYCLES_LSB _u(11)
|
||||
#define SSI_SPI_CTRLR0_WAIT_CYCLES_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SPI_CTRLR0_INST_L
|
||||
// Description : Instruction length (0/4/8/16b)
|
||||
// 0x0 -> No instruction
|
||||
// 0x1 -> 4-bit instruction
|
||||
// 0x2 -> 8-bit instruction
|
||||
// 0x3 -> 16-bit instruction
|
||||
#define SSI_SPI_CTRLR0_INST_L_RESET _u(0x0)
|
||||
#define SSI_SPI_CTRLR0_INST_L_BITS _u(0x00000300)
|
||||
#define SSI_SPI_CTRLR0_INST_L_MSB _u(9)
|
||||
#define SSI_SPI_CTRLR0_INST_L_LSB _u(8)
|
||||
#define SSI_SPI_CTRLR0_INST_L_ACCESS "RW"
|
||||
#define SSI_SPI_CTRLR0_INST_L_VALUE_NONE _u(0x0)
|
||||
#define SSI_SPI_CTRLR0_INST_L_VALUE_4B _u(0x1)
|
||||
#define SSI_SPI_CTRLR0_INST_L_VALUE_8B _u(0x2)
|
||||
#define SSI_SPI_CTRLR0_INST_L_VALUE_16B _u(0x3)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SPI_CTRLR0_ADDR_L
|
||||
// Description : Address length (0b-60b in 4b increments)
|
||||
#define SSI_SPI_CTRLR0_ADDR_L_RESET _u(0x0)
|
||||
#define SSI_SPI_CTRLR0_ADDR_L_BITS _u(0x0000003c)
|
||||
#define SSI_SPI_CTRLR0_ADDR_L_MSB _u(5)
|
||||
#define SSI_SPI_CTRLR0_ADDR_L_LSB _u(2)
|
||||
#define SSI_SPI_CTRLR0_ADDR_L_ACCESS "RW"
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_SPI_CTRLR0_TRANS_TYPE
|
||||
// Description : Address and instruction transfer format
|
||||
// 0x0 -> Command and address both in standard SPI frame format
|
||||
// 0x1 -> Command in standard SPI format, address in format
|
||||
// specified by FRF
|
||||
// 0x2 -> Command and address both in format specified by FRF
|
||||
// (e.g. Dual-SPI)
|
||||
#define SSI_SPI_CTRLR0_TRANS_TYPE_RESET _u(0x0)
|
||||
#define SSI_SPI_CTRLR0_TRANS_TYPE_BITS _u(0x00000003)
|
||||
#define SSI_SPI_CTRLR0_TRANS_TYPE_MSB _u(1)
|
||||
#define SSI_SPI_CTRLR0_TRANS_TYPE_LSB _u(0)
|
||||
#define SSI_SPI_CTRLR0_TRANS_TYPE_ACCESS "RW"
|
||||
#define SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C1A _u(0x0)
|
||||
#define SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C2A _u(0x1)
|
||||
#define SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_2C2A _u(0x2)
|
||||
// =============================================================================
|
||||
// Register : SSI_TXD_DRIVE_EDGE
|
||||
// Description : TX drive edge
|
||||
#define SSI_TXD_DRIVE_EDGE_OFFSET _u(0x000000f8)
|
||||
#define SSI_TXD_DRIVE_EDGE_BITS _u(0x000000ff)
|
||||
#define SSI_TXD_DRIVE_EDGE_RESET _u(0x00000000)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Field : SSI_TXD_DRIVE_EDGE_TDE
|
||||
// Description : TXD drive edge
|
||||
#define SSI_TXD_DRIVE_EDGE_TDE_RESET _u(0x00)
|
||||
#define SSI_TXD_DRIVE_EDGE_TDE_BITS _u(0x000000ff)
|
||||
#define SSI_TXD_DRIVE_EDGE_TDE_MSB _u(7)
|
||||
#define SSI_TXD_DRIVE_EDGE_TDE_LSB _u(0)
|
||||
#define SSI_TXD_DRIVE_EDGE_TDE_ACCESS "RW"
|
||||
// =============================================================================
|
||||
#endif // HARDWARE_REGS_SSI_DEFINED
|
38
cpu/rpx0xx/vendor/boot_stage2/include/pico/asm_helper.S
vendored
Normal file
38
cpu/rpx0xx/vendor/boot_stage2/include/pico/asm_helper.S
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "hardware/platform_defs.h"
|
||||
#include "pico/config.h"
|
||||
|
||||
#define WRAPPER_FUNC_NAME(x) __wrap_##x
|
||||
#define SECTION_NAME(x) .text.##x
|
||||
#define RAM_SECTION_NAME(x) .time_critical.##x
|
||||
#define rom_table_code(c1, c2) ((c1) | ((c2) << 8))
|
||||
|
||||
// do not put align in here as it is used mid function sometimes
|
||||
.macro regular_func x
|
||||
.global \x
|
||||
.type \x,%function
|
||||
.thumb_func
|
||||
\x:
|
||||
.endm
|
||||
|
||||
.macro regular_func_with_section x
|
||||
.section .text.\x
|
||||
regular_func \x
|
||||
.endm
|
||||
|
||||
// do not put align in here as it is used mid function sometimes
|
||||
.macro wrapper_func x
|
||||
regular_func WRAPPER_FUNC_NAME(\x)
|
||||
.endm
|
||||
|
||||
.macro __pre_init func, priority_string
|
||||
.section .preinit_array.\priority_string
|
||||
.align 2
|
||||
.word \func
|
||||
.endm
|
||||
|
85
cpu/rpx0xx/vendor/boot_stage2/include/pico/config.h
vendored
Normal file
85
cpu/rpx0xx/vendor/boot_stage2/include/pico/config.h
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
// -----------------------------------------------------
|
||||
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO
|
||||
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
||||
// -----------------------------------------------------
|
||||
|
||||
// This header may be included by other board headers as "boards/pico.h"
|
||||
|
||||
#ifndef _BOARDS_PICO_H
|
||||
#define _BOARDS_PICO_H
|
||||
|
||||
// --- UART ---
|
||||
#ifndef PICO_DEFAULT_UART
|
||||
#define PICO_DEFAULT_UART 0
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_UART_TX_PIN
|
||||
#define PICO_DEFAULT_UART_TX_PIN 0
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_UART_RX_PIN
|
||||
#define PICO_DEFAULT_UART_RX_PIN 1
|
||||
#endif
|
||||
|
||||
// --- LED ---
|
||||
#ifndef PICO_DEFAULT_LED_PIN
|
||||
#define PICO_DEFAULT_LED_PIN 25
|
||||
#endif
|
||||
// no PICO_DEFAULT_WS2812_PIN
|
||||
|
||||
// --- I2C ---
|
||||
#ifndef PICO_DEFAULT_I2C
|
||||
#define PICO_DEFAULT_I2C 0
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_I2C_SDA_PIN
|
||||
#define PICO_DEFAULT_I2C_SDA_PIN 4
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_I2C_SCL_PIN
|
||||
#define PICO_DEFAULT_I2C_SCL_PIN 5
|
||||
#endif
|
||||
|
||||
// --- SPI ---
|
||||
#ifndef PICO_DEFAULT_SPI
|
||||
#define PICO_DEFAULT_SPI 0
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_SPI_SCK_PIN
|
||||
#define PICO_DEFAULT_SPI_SCK_PIN 18
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_SPI_TX_PIN
|
||||
#define PICO_DEFAULT_SPI_TX_PIN 19
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_SPI_RX_PIN
|
||||
#define PICO_DEFAULT_SPI_RX_PIN 16
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_SPI_CSN_PIN
|
||||
#define PICO_DEFAULT_SPI_CSN_PIN 17
|
||||
#endif
|
||||
|
||||
// --- FLASH ---
|
||||
|
||||
#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
|
||||
|
||||
#ifndef PICO_FLASH_SPI_CLKDIV
|
||||
#define PICO_FLASH_SPI_CLKDIV 2
|
||||
#endif
|
||||
|
||||
#ifndef PICO_FLASH_SIZE_BYTES
|
||||
#define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads)
|
||||
#define PICO_SMPS_MODE_PIN 23
|
||||
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 1
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 1
|
||||
#endif
|
||||
|
||||
#endif
|
180
cpu/rpx0xx/vendor/boot_stage2/include/pico/platform.h
vendored
Normal file
180
cpu/rpx0xx/vendor/boot_stage2/include/pico/platform.h
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _PICO_PLATFORM_H_
|
||||
#define _PICO_PLATFORM_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include "pico/types.h"
|
||||
#include "hardware/platform_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \file platform.h
|
||||
* \defgroup pico_platform pico_platform
|
||||
* Compiler definitions for the selected PICO_PLATFORM
|
||||
*/
|
||||
|
||||
#define __isr
|
||||
|
||||
// Section naming macros
|
||||
#define __after_data(group) __attribute__((section(".after_data." group)))
|
||||
#define __not_in_flash(group) __attribute__((section(".time_critical." group)))
|
||||
#define __scratch_x(group) __attribute__((section(".scratch_x." group)))
|
||||
#define __scratch_y(group) __attribute__((section(".scratch_y." group)))
|
||||
#define __uninitialized_ram(group) __attribute__((section(".uninitialized_ram." #group))) group
|
||||
// For use with PICO_COPY_TO_RAM:
|
||||
#define __in_flash(group) __attribute__((section(".flashdata" group)))
|
||||
|
||||
/**
|
||||
* Decorates a function name, such that the function will execute from RAM (assuming it is not inlined
|
||||
* into a flash function by the compiler)
|
||||
*/
|
||||
#define __not_in_flash_func(func_name) __not_in_flash(__STRING(func_name)) func_name
|
||||
/**
|
||||
* Historical synonym for __not_in_flash_func()
|
||||
*/
|
||||
#define __time_critical_func(func_name) __not_in_flash_func(func_name)
|
||||
|
||||
/**
|
||||
* Decorates a function name, such that the function will execute from RAM, explicitly marking it as
|
||||
* noinline to prevent it being inlined into a flash function by the compiler
|
||||
*/
|
||||
#define __no_inline_not_in_flash_func(func_name) __noinline __not_in_flash_func(func_name)
|
||||
|
||||
#define __packed_aligned __packed __aligned(4)
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ < 7
|
||||
#define __force_inline inline __always_inline
|
||||
#else
|
||||
#define __force_inline __always_inline
|
||||
#endif
|
||||
#ifndef count_of
|
||||
#define count_of(a) (sizeof(a)/sizeof((a)[0]))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) ((a)>(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((b)>(a)?(a):(b))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Execute a breakpoint instruction
|
||||
*/
|
||||
static inline void __breakpoint(void) {
|
||||
__asm__("bkpt #0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the compiler does not move memory access across this method call
|
||||
*/
|
||||
__force_inline static void __compiler_memory_barrier(void) {
|
||||
__asm__ volatile ("" : : : "memory");
|
||||
}
|
||||
|
||||
// return a 32 bit handle for a raw ptr; DMA chaining for example embeds pointers in 32 bit values
|
||||
// which of course does not work if we're running the code natively on a 64 bit platforms. Therefore
|
||||
// we provide this macro which allows that code to provide a 64->32 bit mapping in host mode
|
||||
#define host_safe_hw_ptr(x) ((uintptr_t)(x))
|
||||
|
||||
/**
|
||||
* Panic (see panic()) with the message "Unsupported".
|
||||
*/
|
||||
void __attribute__((noreturn)) panic_unsupported(void);
|
||||
|
||||
/**
|
||||
* Panic with a message. An attempt is made to output the message to all registered STDOUT drivers
|
||||
* after which this method executes a BKPT instruction.
|
||||
*
|
||||
* @param fmt format string (printf-like)
|
||||
* @param ... printf-like arguments
|
||||
*/
|
||||
void __attribute__((noreturn)) panic(const char *fmt, ...);
|
||||
|
||||
// PICO_CONFIG: PICO_NO_FPGA_CHECK, Remove the FPGA platform check for small code size reduction, type=bool, default=0, advanced=true, group=pico_runtime
|
||||
#ifndef PICO_NO_FPGA_CHECK
|
||||
#define PICO_NO_FPGA_CHECK 0
|
||||
#endif
|
||||
|
||||
#if PICO_NO_FPGA_CHECK
|
||||
static inline bool running_on_fpga(void) {return false;}
|
||||
#else
|
||||
bool running_on_fpga(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @return the RP2040 chip revision number
|
||||
*/
|
||||
uint8_t rp2040_chip_version(void);
|
||||
|
||||
/**
|
||||
* @return the RP2040 rom version number
|
||||
*/
|
||||
static inline uint8_t rp2040_rom_version(void) {
|
||||
return *(uint8_t*)0x13;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty function intended to be called by any tight hardware polling loop. using this ubiquitously
|
||||
* makes it much easier to find tight loops, but also in the future \#ifdef-ed support for lockup
|
||||
* debugging might be added
|
||||
*/
|
||||
static inline void tight_loop_contents(void) {}
|
||||
|
||||
/**
|
||||
* Helper macro for making chain DMA code portable to PICO_PLATFORM=host. The problem here is
|
||||
* that embedded pointers in the data are only 32 bit, which is a problem if the host
|
||||
* system is 64 bit. This macro is zero cost on the actual device, but in host mode
|
||||
* it provides a 64->32 bit mapping
|
||||
*/
|
||||
#define native_safe_hw_ptr(x) ((uintptr_t)(x))
|
||||
|
||||
/**
|
||||
* Multiplies a by b using multiply instruction using the ARM mul instruction regardless of values;
|
||||
* i.e. this is a 1 cycle operation.
|
||||
*
|
||||
* \param a the first operand
|
||||
* \param b the second operand
|
||||
* \return a * b
|
||||
*/
|
||||
__force_inline static int32_t __mul_instruction(int32_t a, int32_t b) {
|
||||
asm ("mul %0, %1" : "+l" (a) : "l" (b) : );
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Efficiently Multiplies value a by possibly constant value b.
|
||||
* If b is known to be constant and not zero or a power of 2, then a mul instruction is used rather than gcc's default
|
||||
* which is often a slow combination of shifts and adds
|
||||
*
|
||||
* \param a the first operand
|
||||
* \param b the second operand
|
||||
* \return a * b
|
||||
*/
|
||||
#define __fast_mul(a, b) __builtin_choose_expr(__builtin_constant_p(b) && !__builtin_constant_p(a), \
|
||||
(__builtin_popcount(b) >= 2 ? __mul_instruction(a,b) : (a)*(b)), \
|
||||
(a)*(b))
|
||||
|
||||
#define WRAPPER_FUNC(x) __wrap_ ## x
|
||||
#define REAL_FUNC(x) __real_ ## x
|
||||
|
||||
#define __check_type_compatible(type_a, type_b) static_assert(__builtin_types_compatible_p(type_a, type_b), __STRING(type_a) " is not compatible with " __STRING(type_b));
|
||||
|
||||
/**
|
||||
* Get the current exception level on this core
|
||||
* \return the exception number if the CPU is handling an exception, or 0 otherwise
|
||||
*/
|
||||
uint __get_current_exception(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
55
cpu/rpx0xx/vendor/boot_stage2/pad_checksum
vendored
Executable file
55
cpu/rpx0xx/vendor/boot_stage2/pad_checksum
vendored
Executable file
@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import binascii
|
||||
import struct
|
||||
import sys
|
||||
|
||||
|
||||
def any_int(x):
|
||||
try:
|
||||
return int(x, 0)
|
||||
except:
|
||||
raise argparse.ArgumentTypeError("expected an integer, not '{!r}'".format(x))
|
||||
|
||||
|
||||
def bitrev(x, width):
|
||||
return int("{:0{w}b}".format(x, w=width)[::-1], 2)
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("ifile", help="Input file (binary)")
|
||||
parser.add_argument("ofile", help="Output file (assembly)")
|
||||
parser.add_argument("-p", "--pad", help="Padded size (bytes), including 4-byte checksum, default 256",
|
||||
type=any_int, default=256)
|
||||
parser.add_argument("-s", "--seed", help="Checksum seed value, default 0",
|
||||
type=any_int, default=0)
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
idata = open(args.ifile, "rb").read()
|
||||
except:
|
||||
sys.exit("Could not open input file '{}'".format(args.ifile))
|
||||
|
||||
if len(idata) >= args.pad - 4:
|
||||
sys.exit("Input file size ({} bytes) too large for final size ({} bytes)".format(len(idata), args.pad))
|
||||
|
||||
idata_padded = idata + bytes(args.pad - 4 - len(idata))
|
||||
|
||||
# Our bootrom CRC32 is slightly bass-ackward but it's best to work around for now (FIXME)
|
||||
# 100% worth it to save two Thumb instructions
|
||||
checksum = bitrev(
|
||||
(binascii.crc32(bytes(bitrev(b, 8) for b in idata_padded), args.seed ^ 0xffffffff) ^ 0xffffffff) & 0xffffffff, 32)
|
||||
odata = idata_padded + struct.pack("<L", checksum)
|
||||
|
||||
try:
|
||||
with open(args.ofile, "w") as ofile:
|
||||
ofile.write("// Padded and checksummed version of: {}\n\n".format(args.ifile))
|
||||
ofile.write(".cpu cortex-m0plus\n")
|
||||
ofile.write(".thumb\n\n")
|
||||
ofile.write(".section .boot2, \"ax\"\n\n")
|
||||
for offs in range(0, len(odata), 16):
|
||||
chunk = odata[offs:min(offs + 16, len(odata))]
|
||||
ofile.write(".byte {}\n".format(", ".join("0x{:02x}".format(b) for b in chunk)))
|
||||
except:
|
||||
sys.exit("Could not open output file '{}'".format(args.ofile))
|
30
cpu/rpx0xx/vendor/boot_stage2/read_flash_sreg.S
vendored
Normal file
30
cpu/rpx0xx/vendor/boot_stage2/read_flash_sreg.S
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _BOOT2_HELPER_READ_FLASH_SREG
|
||||
#define _BOOT2_HELPER_READ_FLASH_SREG
|
||||
|
||||
#include "boot2_helpers/wait_ssi_ready.S"
|
||||
|
||||
// Pass status read cmd into r0.
|
||||
// Returns status value in r0.
|
||||
.global read_flash_sreg
|
||||
.type read_flash_sreg,%function
|
||||
.thumb_func
|
||||
read_flash_sreg:
|
||||
push {r1, lr}
|
||||
str r0, [r3, #SSI_DR0_OFFSET]
|
||||
// Dummy byte:
|
||||
str r0, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
bl wait_ssi_ready
|
||||
// Discard first byte and combine the next two
|
||||
ldr r0, [r3, #SSI_DR0_OFFSET]
|
||||
ldr r0, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
pop {r1, pc}
|
||||
|
||||
#endif
|
48
cpu/rpx0xx/xosc.c
Normal file
48
cpu/rpx0xx/xosc.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Otto-von-Guericke Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_rpx0xx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the crystal oscillator (XOSC)
|
||||
*
|
||||
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
||||
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "macros/units.h"
|
||||
#include "vendor/RP2040.h"
|
||||
#include "io_reg.h"
|
||||
|
||||
static inline uint32_t _xosc_conf_sartup_delay(uint32_t f_crystal_mhz, uint32_t t_stable_ms)
|
||||
{
|
||||
return (((f_crystal_mhz / 1000) * t_stable_ms) + 128) / 256;
|
||||
}
|
||||
|
||||
void xosc_start(uint32_t f_ref)
|
||||
{
|
||||
assert(f_ref == MHZ(12));
|
||||
uint32_t delay = _xosc_conf_sartup_delay(f_ref, 1);
|
||||
io_reg_write_dont_corrupt(&XOSC->STARTUP.reg, delay << XOSC_STARTUP_DELAY_Pos,
|
||||
XOSC_STARTUP_DELAY_Msk);
|
||||
io_reg_write_dont_corrupt(&XOSC->CTRL.reg, XOSC_CTRL_ENABLE_ENABLE << XOSC_CTRL_ENABLE_Pos,
|
||||
XOSC_CTRL_ENABLE_Msk);
|
||||
while (!XOSC->STATUS.bit.STABLE) { }
|
||||
}
|
||||
|
||||
void xosc_stop(void)
|
||||
{
|
||||
io_reg_write_dont_corrupt(&XOSC->CTRL.reg, XOSC_CTRL_ENABLE_DISABLE << XOSC_CTRL_ENABLE_Pos,
|
||||
XOSC_CTRL_ENABLE_Msk);
|
||||
}
|
Loading…
Reference in New Issue
Block a user