[Core] Add Raspberry Pi RP2040 support (#14877)
* Disable RESET keycode because of naming conflicts * Add Pico SDK as submodule * Add RP2040 build support to QMK * Adjust USB endpoint structs for RP2040 * Add RP2040 bootloader and double-tap reset routine * Add generic and pro micro RP2040 boards * Add RP2040 onekey keyboard * Add WS2812 PIO DMA enabled driver and documentation Supports regular and open-drain output configuration. RP2040 GPIOs are sadly not 5V tolerant, so this is a bit use-less or needs extra hardware or you take the risk to fry your hardware. * Adjust SIO Driver for RP2040 * Adjust I2C Driver for RP2040 * Adjust SPI Driver for RP2040 * Add PIO serial driver and documentation * Add general RP2040 documentation * Apply suggestions from code review Co-authored-by: Nick Brassel <nick@tzarc.org> Co-authored-by: Nick Brassel <nick@tzarc.org>
This commit is contained in:
parent
d206c1791e
commit
d717396708
43 changed files with 2026 additions and 96 deletions
|
@ -21,6 +21,11 @@
|
|||
# include <hal.h>
|
||||
#endif
|
||||
|
||||
/* Include the vendor specific pin defs */
|
||||
#if __has_include_next("_pin_defs.h")
|
||||
# include_next "_pin_defs.h"
|
||||
#endif
|
||||
|
||||
#define A0 PAL_LINE(GPIOA, 0)
|
||||
#define A1 PAL_LINE(GPIOA, 1)
|
||||
#define A2 PAL_LINE(GPIOA, 2)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# List of all the board related files.
|
||||
BOARDSRC = $(CHIBIOS)/os/hal/boards/RP_PICO_RP2040/board.c
|
||||
|
||||
# Required include directories
|
||||
BOARDINC = $(CHIBIOS)/os/hal/boards/RP_PICO_RP2040
|
||||
|
||||
# Shared variables
|
||||
ALLCSRC += $(BOARDSRC)
|
||||
ALLINC += $(BOARDINC)
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright 2022 Stefan Kerkmann
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include_next "board.h"
|
||||
|
||||
#undef BOARD_RP_PICO_RP2040
|
||||
#define BOARD_GENERIC_PROMICRO_RP2040
|
||||
|
||||
#undef BOARD_NAME
|
||||
#define BOARD_NAME "Pro Micro RP2040"
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2022 Stefan Kerkmann
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#define CH_CFG_SMP_MODE TRUE
|
||||
#define CH_CFG_ST_RESOLUTION 32
|
||||
#define CH_CFG_ST_FREQUENCY 1000000
|
||||
#define CH_CFG_INTERVALS_SIZE 32
|
||||
#define CH_CFG_TIME_TYPES_SIZE 32
|
||||
#define CH_CFG_ST_TIMEDELTA 20
|
||||
|
||||
#include_next <chconf.h>
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2022 Stefan Kerkmann
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
/**======================
|
||||
** I2C Driver
|
||||
*========================**/
|
||||
|
||||
#if !defined(I2C_DRIVER)
|
||||
# define I2C_DRIVER I2CD2
|
||||
#endif
|
||||
|
||||
#if !defined(I2C1_SDA_PIN)
|
||||
# define I2C1_SDA_PIN GP2
|
||||
#endif
|
||||
|
||||
#if !defined(I2C1_SCL_PIN)
|
||||
# define I2C1_SCL_PIN GP3
|
||||
#endif
|
||||
|
||||
/**======================
|
||||
** SPI Driver
|
||||
*========================**/
|
||||
|
||||
#if !defined(SPI_DRIVER)
|
||||
# define SPI_DRIVER SPID0
|
||||
#endif
|
||||
|
||||
#if !defined(SPI_SCK_PIN)
|
||||
# define SPI_SCK_PIN GP18
|
||||
#endif
|
||||
|
||||
#if !defined(SPI_MISO_PIN)
|
||||
# define SPI_MISO_PIN GP20
|
||||
#endif
|
||||
|
||||
#if !defined(SPI_MOSI_PIN)
|
||||
# define SPI_MOSI_PIN GP19
|
||||
#endif
|
||||
|
||||
/**======================
|
||||
** SERIAL Driver
|
||||
*========================**/
|
||||
|
||||
#if !defined(SERIAL_USART_DRIVER)
|
||||
# define SERIAL_USART_DRIVER SIOD0
|
||||
#endif
|
||||
|
||||
#if !defined(SERIAL_USART_TX_PIN) && !defined(SOFT_SERIAL_PIN)
|
||||
# define SERIAL_USART_TX_PIN GP0
|
||||
#endif
|
||||
|
||||
#if !defined(SERIAL_USART_RX_PIN)
|
||||
# define SERIAL_USART_RX_PIN GP1
|
||||
#endif
|
||||
|
||||
/**======================
|
||||
** Double-tap
|
||||
*========================**/
|
||||
|
||||
#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2021 Giovanni Di Sirio
|
||||
|
||||
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
|
||||
|
||||
http://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.
|
||||
*/
|
||||
|
||||
#ifndef MCUCONF_H
|
||||
#define MCUCONF_H
|
||||
|
||||
/*
|
||||
* RP2040_MCUCONF drivers configuration.
|
||||
*
|
||||
* IRQ priorities:
|
||||
* 3...0 Lowest...Highest.
|
||||
*
|
||||
* DMA priorities:
|
||||
* 0...1 Lowest...Highest.
|
||||
*/
|
||||
|
||||
#define RP2040_MCUCONF
|
||||
|
||||
/*
|
||||
* HAL driver system settings.
|
||||
*/
|
||||
#define RP_NO_INIT FALSE
|
||||
#define RP_CORE1_START FALSE
|
||||
#define RP_CORE1_VECTORS_TABLE _vectors
|
||||
#define RP_CORE1_ENTRY_POINT _crt0_c1_entry
|
||||
#define RP_CORE1_STACK_END __c1_main_stack_end__
|
||||
|
||||
/*
|
||||
* IRQ system settings.
|
||||
*/
|
||||
#define RP_IRQ_SYSTICK_PRIORITY 2
|
||||
#define RP_IRQ_TIMER_ALARM0_PRIORITY 2
|
||||
#define RP_IRQ_TIMER_ALARM1_PRIORITY 2
|
||||
#define RP_IRQ_TIMER_ALARM2_PRIORITY 2
|
||||
#define RP_IRQ_TIMER_ALARM3_PRIORITY 2
|
||||
#define RP_IRQ_UART0_PRIORITY 3
|
||||
#define RP_IRQ_UART1_PRIORITY 3
|
||||
#define RP_IRQ_SPI0_PRIORITY 2
|
||||
#define RP_IRQ_SPI1_PRIORITY 2
|
||||
#define RP_IRQ_USB0_PRIORITY 3
|
||||
#define RP_IRQ_I2C0_PRIORITY 2
|
||||
#define RP_IRQ_I2C1_PRIORITY 2
|
||||
|
||||
/*
|
||||
* ADC driver system settings.
|
||||
*/
|
||||
#define RP_ADC_USE_ADC1 FALSE
|
||||
|
||||
/*
|
||||
* SIO driver system settings.
|
||||
*/
|
||||
#define RP_SIO_USE_UART0 TRUE
|
||||
#define RP_SIO_USE_UART1 FALSE
|
||||
|
||||
/*
|
||||
* SPI driver system settings.
|
||||
*/
|
||||
#define RP_SPI_USE_SPI0 TRUE
|
||||
#define RP_SPI_USE_SPI1 FALSE
|
||||
#define RP_SPI_SPI0_RX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
|
||||
#define RP_SPI_SPI0_TX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
|
||||
#define RP_SPI_SPI1_RX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
|
||||
#define RP_SPI_SPI1_TX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
|
||||
#define RP_SPI_SPI0_DMA_PRIORITY 1
|
||||
#define RP_SPI_SPI1_DMA_PRIORITY 1
|
||||
#define RP_SPI_DMA_ERROR_HOOK(spip)
|
||||
|
||||
/*
|
||||
* I2C driver system settings.
|
||||
*/
|
||||
#define RP_I2C_USE_I2C0 FALSE
|
||||
#define RP_I2C_USE_I2C1 TRUE
|
||||
#define RP_I2C_BUSY_TIMEOUT 50
|
||||
#define RP_I2C_ADDRESS_MODE_10BIT FALSE
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
*/
|
||||
#define RP_USB_USE_USBD0 TRUE
|
||||
#define RP_USB_FORCE_VBUS_DETECT TRUE
|
||||
#define RP_USE_EXTERNAL_VBUS_DETECT FALSE
|
||||
#define RP_USB_USE_SOF_INTR TRUE
|
||||
#define RP_USB_USE_ERROR_DATA_SEQ_INTR FALSE
|
||||
|
||||
#endif /* MCUCONF_H */
|
|
@ -0,0 +1,9 @@
|
|||
# List of all the board related files.
|
||||
BOARDSRC = $(CHIBIOS)/os/hal/boards/RP_PICO_RP2040/board.c
|
||||
|
||||
# Required include directories
|
||||
BOARDINC = $(CHIBIOS)/os/hal/boards/RP_PICO_RP2040
|
||||
|
||||
# Shared variables
|
||||
ALLCSRC += $(BOARDSRC)
|
||||
ALLINC += $(BOARDINC)
|
12
platforms/chibios/boards/GENERIC_RP_RP2040/configs/board.h
Normal file
12
platforms/chibios/boards/GENERIC_RP_RP2040/configs/board.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Copyright 2022 Stefan Kerkmann
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include_next "board.h"
|
||||
|
||||
#undef BOARD_RP_PICO_RP2040
|
||||
#define BOARD_GENERIC_RP2040
|
||||
|
||||
#undef BOARD_NAME
|
||||
#define BOARD_NAME "Generic Raspberry Pi RP2040"
|
13
platforms/chibios/boards/GENERIC_RP_RP2040/configs/chconf.h
Normal file
13
platforms/chibios/boards/GENERIC_RP_RP2040/configs/chconf.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2022 Stefan Kerkmann
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#define CH_CFG_SMP_MODE TRUE
|
||||
#define CH_CFG_ST_RESOLUTION 32
|
||||
#define CH_CFG_ST_FREQUENCY 1000000
|
||||
#define CH_CFG_INTERVALS_SIZE 32
|
||||
#define CH_CFG_TIME_TYPES_SIZE 32
|
||||
#define CH_CFG_ST_TIMEDELTA 20
|
||||
|
||||
#include_next <chconf.h>
|
98
platforms/chibios/boards/GENERIC_RP_RP2040/configs/mcuconf.h
Normal file
98
platforms/chibios/boards/GENERIC_RP_RP2040/configs/mcuconf.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2021 Giovanni Di Sirio
|
||||
|
||||
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
|
||||
|
||||
http://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.
|
||||
*/
|
||||
|
||||
#ifndef MCUCONF_H
|
||||
#define MCUCONF_H
|
||||
|
||||
/*
|
||||
* RP2040_MCUCONF drivers configuration.
|
||||
*
|
||||
* IRQ priorities:
|
||||
* 3...0 Lowest...Highest.
|
||||
*
|
||||
* DMA priorities:
|
||||
* 0...1 Lowest...Highest.
|
||||
*/
|
||||
|
||||
#define RP2040_MCUCONF
|
||||
|
||||
/*
|
||||
* HAL driver system settings.
|
||||
*/
|
||||
#define RP_NO_INIT FALSE
|
||||
#define RP_CORE1_START FALSE
|
||||
#define RP_CORE1_VECTORS_TABLE _vectors
|
||||
#define RP_CORE1_ENTRY_POINT _crt0_c1_entry
|
||||
#define RP_CORE1_STACK_END __c1_main_stack_end__
|
||||
|
||||
/*
|
||||
* IRQ system settings.
|
||||
*/
|
||||
#define RP_IRQ_SYSTICK_PRIORITY 2
|
||||
#define RP_IRQ_TIMER_ALARM0_PRIORITY 2
|
||||
#define RP_IRQ_TIMER_ALARM1_PRIORITY 2
|
||||
#define RP_IRQ_TIMER_ALARM2_PRIORITY 2
|
||||
#define RP_IRQ_TIMER_ALARM3_PRIORITY 2
|
||||
#define RP_IRQ_UART0_PRIORITY 3
|
||||
#define RP_IRQ_UART1_PRIORITY 3
|
||||
#define RP_IRQ_SPI0_PRIORITY 2
|
||||
#define RP_IRQ_SPI1_PRIORITY 2
|
||||
#define RP_IRQ_USB0_PRIORITY 3
|
||||
#define RP_IRQ_I2C0_PRIORITY 2
|
||||
#define RP_IRQ_I2C1_PRIORITY 2
|
||||
|
||||
/*
|
||||
* ADC driver system settings.
|
||||
*/
|
||||
#define RP_ADC_USE_ADC1 FALSE
|
||||
|
||||
/*
|
||||
* SIO driver system settings.
|
||||
*/
|
||||
#define RP_SIO_USE_UART0 FALSE
|
||||
#define RP_SIO_USE_UART1 FALSE
|
||||
|
||||
/*
|
||||
* SPI driver system settings.
|
||||
*/
|
||||
#define RP_SPI_USE_SPI0 FALSE
|
||||
#define RP_SPI_USE_SPI1 FALSE
|
||||
#define RP_SPI_SPI0_RX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
|
||||
#define RP_SPI_SPI0_TX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
|
||||
#define RP_SPI_SPI1_RX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
|
||||
#define RP_SPI_SPI1_TX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
|
||||
#define RP_SPI_SPI0_DMA_PRIORITY 1
|
||||
#define RP_SPI_SPI1_DMA_PRIORITY 1
|
||||
#define RP_SPI_DMA_ERROR_HOOK(spip)
|
||||
|
||||
/*
|
||||
* I2C driver system settings.
|
||||
*/
|
||||
#define RP_I2C_USE_I2C0 FALSE
|
||||
#define RP_I2C_USE_I2C1 FALSE
|
||||
#define RP_I2C_BUSY_TIMEOUT 50
|
||||
#define RP_I2C_ADDRESS_MODE_10BIT FALSE
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
*/
|
||||
#define RP_USB_USE_USBD0 TRUE
|
||||
#define RP_USB_FORCE_VBUS_DETECT TRUE
|
||||
#define RP_USE_EXTERNAL_VBUS_DETECT FALSE
|
||||
#define RP_USB_USE_SOF_INTR TRUE
|
||||
#define RP_USB_USE_ERROR_DATA_SEQ_INTR FALSE
|
||||
|
||||
#endif /* MCUCONF_H */
|
57
platforms/chibios/bootloaders/rp2040.c
Normal file
57
platforms/chibios/bootloaders/rp2040.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
// Copyright 2022 Stefan Kerkmann
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "quantum.h"
|
||||
#include "hal.h"
|
||||
#include "bootloader.h"
|
||||
#include "pico/bootrom.h"
|
||||
|
||||
#if !defined(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED)
|
||||
# define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK 0U
|
||||
#else
|
||||
# define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK (1U << RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED)
|
||||
#endif
|
||||
|
||||
__attribute__((weak)) void mcu_reset(void) {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
void bootloader_jump(void) {
|
||||
reset_usb_boot(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK, 0U);
|
||||
}
|
||||
|
||||
void enter_bootloader_mode_if_requested(void) {}
|
||||
|
||||
#if defined(RP2040_BOOTLOADER_DOUBLE_TAP_RESET)
|
||||
# if !defined(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT)
|
||||
# define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 200U
|
||||
# endif
|
||||
|
||||
// Needs to be located in a RAM section that is never initialized on boot to
|
||||
// preserve its value on reset
|
||||
static volatile uint32_t __attribute__((section(".ram0.bootloader_magic"))) magic_location;
|
||||
const uint32_t magic_token = 0xCAFEB0BA;
|
||||
|
||||
// We can not use the __early_init / enter_bootloader_mode_if_requested hook as
|
||||
// we depend on an already initialized system with usable memory regions and
|
||||
// populated function pointer tables to the optimized math functions in the
|
||||
// bootrom. This function is called just prior to main.
|
||||
void __late_init(void) {
|
||||
// All clocks have to be enabled before jumping to the bootloader function,
|
||||
// otherwise the bootrom will be stuck infinitely.
|
||||
clocks_init();
|
||||
|
||||
if (magic_location != magic_token) {
|
||||
magic_location = magic_token;
|
||||
// ChibiOS is not initialized at this point, so sleeping is only
|
||||
// possible via busy waiting. The internal timer peripheral is running
|
||||
// at this point with a precision of 1us.
|
||||
chSysPolledDelayX(MS2RTC(1 * MHZ, RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT));
|
||||
magic_location = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
magic_location = 0;
|
||||
reset_usb_boot(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK, 0U);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -19,6 +19,27 @@
|
|||
# define SPLIT_USB_DETECT // Force this on when dedicated pin is not used
|
||||
#endif
|
||||
|
||||
#if defined(MCU_RP)
|
||||
# define CPU_CLOCK RP_CORE_CLK
|
||||
|
||||
# define USE_GPIOV1
|
||||
# define PAL_OUTPUT_TYPE_OPENDRAIN _Static_assert(0, "RP2040 has no Open Drain GPIO configuration, setting this is not possible");
|
||||
|
||||
# define usb_lld_endpoint_fields
|
||||
|
||||
# define I2C1_SCL_PAL_MODE (PAL_MODE_ALTERNATE_I2C | PAL_RP_PAD_SLEWFAST | PAL_RP_PAD_PUE | PAL_RP_PAD_DRIVE4)
|
||||
# define I2C1_SDA_PAL_MODE I2C1_SCL_PAL_MODE
|
||||
|
||||
# define USE_I2CV1_CONTRIB
|
||||
# if !defined(I2C1_CLOCK_SPEED)
|
||||
# define I2C1_CLOCK_SPEED 400000
|
||||
# endif
|
||||
|
||||
# define SPI_SCK_PAL_MODE (PAL_MODE_ALTERNATE_SPI | PAL_RP_PAD_SLEWFAST | PAL_RP_PAD_DRIVE4)
|
||||
# define SPI_MOSI_PAL_MODE SPI_SCK_PAL_MODE
|
||||
# define SPI_MISO_PAL_MODE SPI_SCK_PAL_MODE
|
||||
#endif
|
||||
|
||||
// STM32 compatibility
|
||||
#if defined(MCU_STM32)
|
||||
# define CPU_CLOCK STM32_SYSCLK
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
|
||||
#if defined(SERIAL_USART_CONFIG)
|
||||
static QMKSerialConfig serial_config = SERIAL_USART_CONFIG;
|
||||
#else
|
||||
#elif defined(MCU_STM32) /* STM32 MCUs */
|
||||
static QMKSerialConfig serial_config = {
|
||||
# if HAL_USE_SERIAL
|
||||
.speed = (SERIAL_USART_SPEED), /* baudrate - mandatory */
|
||||
.speed = (SERIAL_USART_SPEED),
|
||||
# else
|
||||
.baud = (SERIAL_USART_SPEED), /* baudrate - mandatory */
|
||||
.baud = (SERIAL_USART_SPEED),
|
||||
# endif
|
||||
.cr1 = (SERIAL_USART_CR1),
|
||||
.cr2 = (SERIAL_USART_CR2),
|
||||
|
@ -23,6 +23,19 @@ static QMKSerialConfig serial_config = {
|
|||
.cr3 = (SERIAL_USART_CR3)
|
||||
# endif
|
||||
};
|
||||
#elif defined(MCU_RP) /* Raspberry Pi MCUs */
|
||||
/* USART in 8E2 config with RX and TX FIFOs enabled. */
|
||||
// clang-format off
|
||||
static QMKSerialConfig serial_config = {
|
||||
.baud = (SERIAL_USART_SPEED),
|
||||
.UARTLCR_H = UART_UARTLCR_H_WLEN_8BITS | UART_UARTLCR_H_PEN | UART_UARTLCR_H_STP2 | UART_UARTLCR_H_FEN,
|
||||
.UARTCR = 0U,
|
||||
.UARTIFLS = UART_UARTIFLS_RXIFLSEL_1_8F | UART_UARTIFLS_TXIFLSEL_1_8E,
|
||||
.UARTDMACR = 0U
|
||||
};
|
||||
// clang-format on
|
||||
#else
|
||||
# error MCU Familiy not supported by default, supply your own serial_config by defining SERIAL_USART_CONFIG in your keyboard files.
|
||||
#endif
|
||||
|
||||
static QMKSerialDriver* serial_driver = (QMKSerialDriver*)&SERIAL_USART_DRIVER;
|
||||
|
@ -156,7 +169,7 @@ inline bool serial_transport_receive_blocking(uint8_t* destination, const size_t
|
|||
* @brief Initiate pins for USART peripheral. Half-duplex configuration.
|
||||
*/
|
||||
__attribute__((weak)) void usart_init(void) {
|
||||
# if defined(MCU_STM32)
|
||||
# if defined(MCU_STM32) /* STM32 MCUs */
|
||||
# if defined(USE_GPIOV1)
|
||||
palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_ALTERNATE_OPENDRAIN);
|
||||
# else
|
||||
|
@ -166,6 +179,8 @@ __attribute__((weak)) void usart_init(void) {
|
|||
# if defined(USART_REMAP)
|
||||
USART_REMAP;
|
||||
# endif
|
||||
# elif defined(MCU_RP) /* Raspberry Pi MCUs */
|
||||
# error Half-duplex with the SIO driver is not supported due to hardware limitations on the RP2040, switch to the PIO driver which has half-duplex support.
|
||||
# else
|
||||
# pragma message "usart_init: MCU Familiy not supported by default, please supply your own init code by implementing usart_init() in your keyboard files."
|
||||
# endif
|
||||
|
@ -177,7 +192,7 @@ __attribute__((weak)) void usart_init(void) {
|
|||
* @brief Initiate pins for USART peripheral. Full-duplex configuration.
|
||||
*/
|
||||
__attribute__((weak)) void usart_init(void) {
|
||||
# if defined(MCU_STM32)
|
||||
# if defined(MCU_STM32) /* STM32 MCUs */
|
||||
# if defined(USE_GPIOV1)
|
||||
palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_ALTERNATE_PUSHPULL);
|
||||
palSetLineMode(SERIAL_USART_RX_PIN, PAL_MODE_INPUT);
|
||||
|
@ -189,6 +204,9 @@ __attribute__((weak)) void usart_init(void) {
|
|||
# if defined(USART_REMAP)
|
||||
USART_REMAP;
|
||||
# endif
|
||||
# elif defined(MCU_RP) /* Raspberry Pi MCUs */
|
||||
palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_ALTERNATE_UART);
|
||||
palSetLineMode(SERIAL_USART_RX_PIN, PAL_MODE_ALTERNATE_UART);
|
||||
# else
|
||||
# pragma message "usart_init: MCU Familiy not supported by default, please supply your own init code by implementing usart_init() in your keyboard files."
|
||||
# endif
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
static pin_t currentSlavePin = NO_PIN;
|
||||
|
||||
#if defined(K20x) || defined(KL2x)
|
||||
#if defined(K20x) || defined(KL2x) || defined(RP2040)
|
||||
static SPIConfig spiConfig = {NULL, 0, 0, 0};
|
||||
#else
|
||||
static SPIConfig spiConfig = {false, NULL, 0, 0, 0, 0};
|
||||
|
@ -167,7 +167,36 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
|
|||
spiConfig.SPI_CPOL = SPI_CPOL_High;
|
||||
break;
|
||||
}
|
||||
#elif defined(MCU_RP)
|
||||
if (lsbFirst) {
|
||||
osalDbgAssert(lsbFirst == false, "RP2040s PrimeCell SPI implementation does not support sending LSB first.");
|
||||
}
|
||||
|
||||
// Motorola frame format and 8bit transfer data size.
|
||||
spiConfig.SSPCR0 = SPI_SSPCR0_FRF_MOTOROLA | SPI_SSPCR0_DSS_8BIT;
|
||||
// Serial output clock = (ck_sys or ck_peri) / (SSPCPSR->CPSDVSR * (1 +
|
||||
// SSPCR0->SCR)). SCR is always set to zero, as QMK SPI API expects the
|
||||
// passed divisor to be the only value to divide the input clock by.
|
||||
spiConfig.SSPCPSR = roundedDivisor; // Even number from 2 to 254
|
||||
|
||||
switch (mode) {
|
||||
case 0:
|
||||
spiConfig.SSPCR0 &= ~SPI_SSPCR0_SPO; // Clock polarity: low
|
||||
spiConfig.SSPCR0 &= ~SPI_SSPCR0_SPH; // Clock phase: sample on first edge
|
||||
break;
|
||||
case 1:
|
||||
spiConfig.SSPCR0 &= ~SPI_SSPCR0_SPO; // Clock polarity: low
|
||||
spiConfig.SSPCR0 |= SPI_SSPCR0_SPH; // Clock phase: sample on second edge transition
|
||||
break;
|
||||
case 2:
|
||||
spiConfig.SSPCR0 |= SPI_SSPCR0_SPO; // Clock polarity: high
|
||||
spiConfig.SSPCR0 &= ~SPI_SSPCR0_SPH; // Clock phase: sample on first edge
|
||||
break;
|
||||
case 3:
|
||||
spiConfig.SSPCR0 |= SPI_SSPCR0_SPO; // Clock polarity: high
|
||||
spiConfig.SSPCR0 |= SPI_SSPCR0_SPH; // Clock phase: sample on second edge transition
|
||||
break;
|
||||
}
|
||||
#else
|
||||
spiConfig.cr1 = 0;
|
||||
|
||||
|
|
457
platforms/chibios/drivers/vendor/RP/RP2040/serial_vendor.c
vendored
Normal file
457
platforms/chibios/drivers/vendor/RP/RP2040/serial_vendor.c
vendored
Normal file
|
@ -0,0 +1,457 @@
|
|||
// Copyright 2022 Stefan Kerkmann
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "quantum.h"
|
||||
#include "serial_usart.h"
|
||||
#include "serial_protocol.h"
|
||||
#include "hardware/pio.h"
|
||||
#include "hardware/clocks.h"
|
||||
|
||||
#if !defined(MCU_RP)
|
||||
# error PIO Driver is only available for Raspberry Pi 2040 MCUs!
|
||||
#endif
|
||||
|
||||
static inline bool receive_impl(uint8_t* destination, const size_t size, sysinterval_t timeout);
|
||||
static inline bool send_impl(const uint8_t* source, const size_t size);
|
||||
static inline void pio_serve_interrupt(void);
|
||||
|
||||
#define MSG_PIO_ERROR ((msg_t)(-3))
|
||||
|
||||
#if defined(SERIAL_PIO_USE_PIO1)
|
||||
static const PIO pio = pio1;
|
||||
|
||||
OSAL_IRQ_HANDLER(RP_PIO1_IRQ_0_HANDLER) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
pio_serve_interrupt();
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#else
|
||||
static const PIO pio = pio0;
|
||||
|
||||
OSAL_IRQ_HANDLER(RP_PIO0_IRQ_0_HANDLER) {
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
pio_serve_interrupt();
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#define UART_TX_WRAP_TARGET 0
|
||||
#define UART_TX_WRAP 3
|
||||
|
||||
// clang-format off
|
||||
#if defined(SERIAL_USART_FULL_DUPLEX)
|
||||
static const uint16_t uart_tx_program_instructions[] = {
|
||||
// .wrap_target
|
||||
0x9fa0, // 0: pull block side 1 [7]
|
||||
0xf727, // 1: set x, 7 side 0 [7]
|
||||
0x6001, // 2: out pins, 1
|
||||
0x0642, // 3: jmp x--, 2 [6]
|
||||
// .wrap
|
||||
};
|
||||
#else
|
||||
static const uint16_t uart_tx_program_instructions[] = {
|
||||
// .wrap_target
|
||||
0x9fa0, // 0: pull block side 1 [7]
|
||||
0xf727, // 1: set x, 7 side 0 [7]
|
||||
0x6081, // 2: out pindirs, 1
|
||||
0x0642, // 3: jmp x--, 2 [6]
|
||||
// .wrap
|
||||
};
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
static const pio_program_t uart_tx_program = {
|
||||
.instructions = uart_tx_program_instructions,
|
||||
.length = 4,
|
||||
.origin = -1,
|
||||
};
|
||||
|
||||
#define UART_RX_WRAP_TARGET 0
|
||||
#define UART_RX_WRAP 8
|
||||
|
||||
// clang-format off
|
||||
static const uint16_t uart_rx_program_instructions[] = {
|
||||
// .wrap_target
|
||||
0x2020, // 0: wait 0 pin, 0
|
||||
0xea27, // 1: set x, 7 [10]
|
||||
0x4001, // 2: in pins, 1
|
||||
0x0642, // 3: jmp x--, 2 [6]
|
||||
0x00c8, // 4: jmp pin, 8
|
||||
0xc020, // 5: irq wait 0
|
||||
0x20a0, // 6: wait 1 pin, 0
|
||||
0x0000, // 7: jmp 0
|
||||
0x8020, // 8: push block
|
||||
// .wrap
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static const pio_program_t uart_rx_program = {
|
||||
.instructions = uart_rx_program_instructions,
|
||||
.length = 9,
|
||||
.origin = -1,
|
||||
};
|
||||
|
||||
thread_reference_t rx_thread = NULL;
|
||||
static int rx_state_machine = -1;
|
||||
|
||||
thread_reference_t tx_thread = NULL;
|
||||
static int tx_state_machine = -1;
|
||||
|
||||
void pio_serve_interrupt(void) {
|
||||
uint32_t irqs = pio->ints0;
|
||||
|
||||
// The RX FIFO is not empty any more, therefore wake any sleeping rx thread
|
||||
if (irqs & (PIO_IRQ0_INTF_SM0_RXNEMPTY_BITS << rx_state_machine)) {
|
||||
// Disable rx not empty interrupt
|
||||
pio_set_irq0_source_enabled(pio, pis_sm0_rx_fifo_not_empty + rx_state_machine, false);
|
||||
|
||||
osalSysLockFromISR();
|
||||
osalThreadResumeI(&rx_thread, MSG_OK);
|
||||
osalSysUnlockFromISR();
|
||||
}
|
||||
|
||||
// The TX FIFO is not full any more, therefore wake any sleeping tx thread
|
||||
if (irqs & (PIO_IRQ0_INTF_SM0_TXNFULL_BITS << tx_state_machine)) {
|
||||
// Disable tx not full interrupt
|
||||
pio_set_irq0_source_enabled(pio, pis_sm0_tx_fifo_not_full + tx_state_machine, false);
|
||||
osalSysLockFromISR();
|
||||
osalThreadResumeI(&tx_thread, MSG_OK);
|
||||
osalSysUnlockFromISR();
|
||||
}
|
||||
|
||||
// IRQ 0 is set on framing or break errors by the rx state machine
|
||||
if (pio_interrupt_get(pio, 0UL)) {
|
||||
pio_interrupt_clear(pio, 0UL);
|
||||
|
||||
osalSysLockFromISR();
|
||||
osalThreadResumeI(&rx_thread, MSG_PIO_ERROR);
|
||||
osalSysUnlockFromISR();
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(SERIAL_USART_FULL_DUPLEX)
|
||||
// The internal pull-ups of the RP2040 are rather weakish with a range of 50k to
|
||||
// 80k, which in turn do not provide enough current to guarantee fast signal rise
|
||||
// times with a parasitic capacitance of greater than 100pf. In real world
|
||||
// applications, like split keyboards which might have vias in the signal path
|
||||
// or long PCB traces, this prevents a successful communication. The solution
|
||||
// is to temporarily augment the weak pull ups from the receiving side by
|
||||
// driving the tx pin high. On the receiving side the lowest possible drive
|
||||
// strength is chosen because the transmitting side must still be able to drive
|
||||
// the signal low. With this configuration the rise times are fast enough and
|
||||
// the generated low level with 360mV will generate a logical zero.
|
||||
static inline void enter_rx_state(void) {
|
||||
osalSysLock();
|
||||
// Wait for the transmitting state machines FIFO to run empty. At this point
|
||||
// the last byte has been pulled from the transmitting state machines FIFO
|
||||
// into the output shift register. We have to wait a tiny bit more until
|
||||
// this byte is transmitted, before we can turn on the receiving state
|
||||
// machine again.
|
||||
while (!pio_sm_is_tx_fifo_empty(pio, tx_state_machine)) {
|
||||
}
|
||||
// Wait for ~11 bits, 1 start bit + 8 data bits + 1 stop bit + 1 bit
|
||||
// headroom.
|
||||
chSysPolledDelayX(US2RTC(1 * MHZ, (1000000U * 11 / SERIAL_USART_SPEED)));
|
||||
// Disable tx state machine to not interfere with our tx pin manipulation
|
||||
pio_sm_set_enabled(pio, tx_state_machine, false);
|
||||
gpio_set_drive_strength(SERIAL_USART_TX_PIN, GPIO_DRIVE_STRENGTH_2MA);
|
||||
pio_sm_set_pins_with_mask(pio, tx_state_machine, 1U << SERIAL_USART_TX_PIN, 1U << SERIAL_USART_TX_PIN);
|
||||
pio_sm_set_consecutive_pindirs(pio, tx_state_machine, SERIAL_USART_TX_PIN, 1U, false);
|
||||
pio_sm_set_enabled(pio, rx_state_machine, true);
|
||||
osalSysUnlock();
|
||||
}
|
||||
|
||||
static inline void leave_rx_state(void) {
|
||||
osalSysLock();
|
||||
// In Half-duplex operation the tx pin dual-functions as sender and
|
||||
// receiver. To not receive the data we will send, we disable the receiving
|
||||
// state machine.
|
||||
pio_sm_set_enabled(pio, rx_state_machine, false);
|
||||
pio_sm_set_consecutive_pindirs(pio, tx_state_machine, SERIAL_USART_TX_PIN, 1U, true);
|
||||
pio_sm_set_pins_with_mask(pio, tx_state_machine, 0U, 1U << SERIAL_USART_TX_PIN);
|
||||
gpio_set_drive_strength(SERIAL_USART_TX_PIN, GPIO_DRIVE_STRENGTH_12MA);
|
||||
pio_sm_restart(pio, tx_state_machine);
|
||||
pio_sm_set_enabled(pio, tx_state_machine, true);
|
||||
osalSysUnlock();
|
||||
}
|
||||
#else
|
||||
// All this trickery is gladly not necessary for full-duplex.
|
||||
static inline void enter_rx_state(void) {}
|
||||
static inline void leave_rx_state(void) {}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Clear the RX and TX hardware FIFOs of the state machines.
|
||||
*/
|
||||
inline void serial_transport_driver_clear(void) {
|
||||
osalSysLock();
|
||||
pio_sm_clear_fifos(pio, rx_state_machine);
|
||||
pio_sm_clear_fifos(pio, tx_state_machine);
|
||||
osalSysUnlock();
|
||||
}
|
||||
|
||||
static inline msg_t sync_tx(sysinterval_t timeout) {
|
||||
msg_t msg = MSG_OK;
|
||||
osalSysLock();
|
||||
while (pio_sm_is_tx_fifo_full(pio, tx_state_machine)) {
|
||||
pio_set_irq0_source_enabled(pio, pis_sm0_tx_fifo_not_full + tx_state_machine, true);
|
||||
msg = osalThreadSuspendTimeoutS(&tx_thread, timeout);
|
||||
if (msg < MSG_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
osalSysUnlock();
|
||||
return msg;
|
||||
}
|
||||
|
||||
static inline bool send_impl(const uint8_t* source, const size_t size) {
|
||||
size_t send = 0;
|
||||
msg_t msg;
|
||||
while (send < size) {
|
||||
msg = sync_tx(TIME_MS2I(SERIAL_USART_TIMEOUT));
|
||||
if (msg < MSG_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
osalSysLock();
|
||||
while (send < size) {
|
||||
if (pio_sm_is_tx_fifo_full(pio, tx_state_machine)) {
|
||||
break;
|
||||
}
|
||||
if (send >= size) {
|
||||
break;
|
||||
}
|
||||
pio_sm_put(pio, tx_state_machine, (uint32_t)(*source));
|
||||
source++;
|
||||
send++;
|
||||
}
|
||||
osalSysUnlock();
|
||||
}
|
||||
|
||||
return send == size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Blocking send of buffer with timeout.
|
||||
*
|
||||
* @return true Send success.
|
||||
* @return false Send failed.
|
||||
*/
|
||||
inline bool serial_transport_send(const uint8_t* source, const size_t size) {
|
||||
leave_rx_state();
|
||||
bool result = send_impl(source, size);
|
||||
enter_rx_state();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline msg_t sync_rx(sysinterval_t timeout) {
|
||||
msg_t msg = MSG_OK;
|
||||
osalSysLock();
|
||||
while (pio_sm_is_rx_fifo_empty(pio, rx_state_machine)) {
|
||||
pio_set_irq0_source_enabled(pio, pis_sm0_rx_fifo_not_empty + rx_state_machine, true);
|
||||
msg = osalThreadSuspendTimeoutS(&rx_thread, timeout);
|
||||
if (msg < MSG_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
osalSysUnlock();
|
||||
return msg;
|
||||
}
|
||||
|
||||
static inline bool receive_impl(uint8_t* destination, const size_t size, sysinterval_t timeout) {
|
||||
size_t read = 0U;
|
||||
|
||||
while (read < size) {
|
||||
msg_t msg = sync_rx(timeout);
|
||||
if (msg < MSG_OK) {
|
||||
return false;
|
||||
}
|
||||
osalSysLock();
|
||||
while (true) {
|
||||
if (pio_sm_is_rx_fifo_empty(pio, rx_state_machine)) {
|
||||
break;
|
||||
}
|
||||
if (read >= size) {
|
||||
break;
|
||||
}
|
||||
*destination++ = *((uint8_t*)&pio->rxf[rx_state_machine] + 3U);
|
||||
read++;
|
||||
}
|
||||
osalSysUnlock();
|
||||
}
|
||||
|
||||
return read == size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Blocking receive of size * bytes with timeout.
|
||||
*
|
||||
* @return true Receive success.
|
||||
* @return false Receive failed, e.g. by timeout.
|
||||
*/
|
||||
inline bool serial_transport_receive(uint8_t* destination, const size_t size) {
|
||||
return receive_impl(destination, size, TIME_MS2I(SERIAL_USART_TIMEOUT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Blocking receive of size * bytes.
|
||||
*
|
||||
* @return true Receive success.
|
||||
* @return false Receive failed.
|
||||
*/
|
||||
inline bool serial_transport_receive_blocking(uint8_t* destination, const size_t size) {
|
||||
return receive_impl(destination, size, TIME_INFINITE);
|
||||
}
|
||||
|
||||
static inline void pio_tx_init(pin_t tx_pin) {
|
||||
uint pio_idx = pio_get_index(pio);
|
||||
uint offset = pio_add_program(pio, &uart_tx_program);
|
||||
|
||||
#if defined(SERIAL_USART_FULL_DUPLEX)
|
||||
// clang-format off
|
||||
iomode_t tx_pin_mode = PAL_RP_GPIO_OE |
|
||||
PAL_RP_PAD_SLEWFAST |
|
||||
PAL_RP_PAD_DRIVE4 |
|
||||
(pio_idx == 0 ? PAL_MODE_ALTERNATE_PIO0 : PAL_MODE_ALTERNATE_PIO1);
|
||||
// clang-format on
|
||||
pio_sm_set_pins_with_mask(pio, tx_state_machine, 1U << tx_pin, 1U << tx_pin);
|
||||
pio_sm_set_consecutive_pindirs(pio, tx_state_machine, tx_pin, 1U, true);
|
||||
#else
|
||||
// clang-format off
|
||||
iomode_t tx_pin_mode = PAL_RP_PAD_IE |
|
||||
PAL_RP_GPIO_OE |
|
||||
PAL_RP_PAD_SCHMITT |
|
||||
PAL_RP_PAD_PUE |
|
||||
PAL_RP_PAD_SLEWFAST |
|
||||
PAL_RP_PAD_DRIVE12 |
|
||||
PAL_RP_IOCTRL_OEOVER_DRVINVPERI |
|
||||
(pio_idx == 0 ? PAL_MODE_ALTERNATE_PIO0 : PAL_MODE_ALTERNATE_PIO1);
|
||||
// clang-format on
|
||||
pio_sm_set_pins_with_mask(pio, tx_state_machine, 0U << tx_pin, 1U << tx_pin);
|
||||
pio_sm_set_consecutive_pindirs(pio, tx_state_machine, tx_pin, 1U, true);
|
||||
#endif
|
||||
|
||||
palSetLineMode(tx_pin, tx_pin_mode);
|
||||
|
||||
pio_sm_config config = pio_get_default_sm_config();
|
||||
sm_config_set_wrap(&config, offset + UART_TX_WRAP_TARGET, offset + UART_TX_WRAP);
|
||||
#if defined(SERIAL_USART_FULL_DUPLEX)
|
||||
sm_config_set_sideset(&config, 2, true, false);
|
||||
#else
|
||||
sm_config_set_sideset(&config, 2, true, true);
|
||||
#endif
|
||||
// OUT shifts to right, no autopull
|
||||
sm_config_set_out_shift(&config, true, false, 32);
|
||||
// We are mapping both OUT and side-set to the same pin, because sometimes
|
||||
// we need to assert user data onto the pin (with OUT) and sometimes
|
||||
// assert constant values (start/stop bit)
|
||||
sm_config_set_out_pins(&config, tx_pin, 1);
|
||||
sm_config_set_sideset_pins(&config, tx_pin);
|
||||
// We only need TX, so get an 8-deep FIFO!
|
||||
sm_config_set_fifo_join(&config, PIO_FIFO_JOIN_TX);
|
||||
// SM transmits 1 bit per 8 execution cycles.
|
||||
float div = (float)clock_get_hz(clk_sys) / (8 * SERIAL_USART_SPEED);
|
||||
sm_config_set_clkdiv(&config, div);
|
||||
pio_sm_init(pio, tx_state_machine, offset, &config);
|
||||
pio_sm_set_enabled(pio, tx_state_machine, true);
|
||||
}
|
||||
|
||||
static inline void pio_rx_init(pin_t rx_pin) {
|
||||
uint offset = pio_add_program(pio, &uart_rx_program);
|
||||
|
||||
#if defined(SERIAL_USART_FULL_DUPLEX)
|
||||
uint pio_idx = pio_get_index(pio);
|
||||
pio_sm_set_consecutive_pindirs(pio, rx_state_machine, rx_pin, 1, false);
|
||||
// clang-format off
|
||||
iomode_t rx_pin_mode = PAL_RP_PAD_IE |
|
||||
PAL_RP_PAD_SCHMITT |
|
||||
PAL_RP_PAD_PUE |
|
||||
(pio_idx == 0 ? PAL_MODE_ALTERNATE_PIO0 : PAL_MODE_ALTERNATE_PIO1);
|
||||
// clang-format on
|
||||
palSetLineMode(rx_pin, rx_pin_mode);
|
||||
#endif
|
||||
|
||||
pio_sm_config config = pio_get_default_sm_config();
|
||||
sm_config_set_wrap(&config, offset + UART_RX_WRAP_TARGET, offset + UART_RX_WRAP);
|
||||
sm_config_set_in_pins(&config, rx_pin); // for WAIT, IN
|
||||
sm_config_set_jmp_pin(&config, rx_pin); // for JMP
|
||||
// Shift to right, autopush disabled
|
||||
sm_config_set_in_shift(&config, true, false, 32);
|
||||
// Deeper FIFO as we're not doing any TX
|
||||
sm_config_set_fifo_join(&config, PIO_FIFO_JOIN_RX);
|
||||
// SM transmits 1 bit per 8 execution cycles.
|
||||
float div = (float)clock_get_hz(clk_sys) / (8 * SERIAL_USART_SPEED);
|
||||
sm_config_set_clkdiv(&config, div);
|
||||
pio_sm_init(pio, rx_state_machine, offset, &config);
|
||||
pio_sm_set_enabled(pio, rx_state_machine, true);
|
||||
}
|
||||
|
||||
static inline void pio_init(pin_t tx_pin, pin_t rx_pin) {
|
||||
uint pio_idx = pio_get_index(pio);
|
||||
|
||||
/* Get PIOx peripheral out of reset state. */
|
||||
hal_lld_peripheral_unreset(pio_idx == 0 ? RESETS_ALLREG_PIO0 : RESETS_ALLREG_PIO1);
|
||||
|
||||
tx_state_machine = pio_claim_unused_sm(pio, true);
|
||||
if (tx_state_machine < 0) {
|
||||
dprintln("ERROR: Failed to acquire state machine for serial transmission!");
|
||||
return;
|
||||
}
|
||||
pio_tx_init(tx_pin);
|
||||
|
||||
rx_state_machine = pio_claim_unused_sm(pio, true);
|
||||
if (rx_state_machine < 0) {
|
||||
dprintln("ERROR: Failed to acquire state machine for serial reception!");
|
||||
return;
|
||||
}
|
||||
pio_rx_init(rx_pin);
|
||||
|
||||
// Enable error flag IRQ source for rx state machine
|
||||
pio_set_irq0_source_enabled(pio, pis_sm0_rx_fifo_not_empty + rx_state_machine, true);
|
||||
pio_set_irq0_source_enabled(pio, pis_sm0_tx_fifo_not_full + tx_state_machine, true);
|
||||
pio_set_irq0_source_enabled(pio, pis_interrupt0, true);
|
||||
|
||||
// Enable PIO specific interrupt vector
|
||||
#if defined(SERIAL_PIO_USE_PIO1)
|
||||
nvicEnableVector(RP_PIO1_IRQ_0_NUMBER, RP_IRQ_UART0_PRIORITY);
|
||||
#else
|
||||
nvicEnableVector(RP_PIO0_IRQ_0_NUMBER, RP_IRQ_UART0_PRIORITY);
|
||||
#endif
|
||||
|
||||
enter_rx_state();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PIO driver specific initialization function for the master side.
|
||||
*/
|
||||
void serial_transport_driver_master_init(void) {
|
||||
#if defined(SERIAL_USART_FULL_DUPLEX)
|
||||
pin_t tx_pin = SERIAL_USART_TX_PIN;
|
||||
pin_t rx_pin = SERIAL_USART_RX_PIN;
|
||||
#else
|
||||
pin_t tx_pin = SERIAL_USART_TX_PIN;
|
||||
pin_t rx_pin = SERIAL_USART_TX_PIN;
|
||||
#endif
|
||||
|
||||
#if defined(SERIAL_USART_PIN_SWAP)
|
||||
pio_init(rx_pin, tx_pin);
|
||||
#else
|
||||
pio_init(tx_pin, rx_pin);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PIO driver specific initialization function for the slave side.
|
||||
*/
|
||||
void serial_transport_driver_slave_init(void) {
|
||||
#if defined(SERIAL_USART_FULL_DUPLEX)
|
||||
pin_t tx_pin = SERIAL_USART_TX_PIN;
|
||||
pin_t rx_pin = SERIAL_USART_RX_PIN;
|
||||
#else
|
||||
pin_t tx_pin = SERIAL_USART_TX_PIN;
|
||||
pin_t rx_pin = SERIAL_USART_TX_PIN;
|
||||
#endif
|
||||
|
||||
pio_init(tx_pin, rx_pin);
|
||||
}
|
189
platforms/chibios/drivers/vendor/RP/RP2040/ws2812_vendor.c
vendored
Normal file
189
platforms/chibios/drivers/vendor/RP/RP2040/ws2812_vendor.c
vendored
Normal file
|
@ -0,0 +1,189 @@
|
|||
// Copyright 2022 Stefan Kerkmann
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "quantum.h"
|
||||
#include "ws2812.h"
|
||||
#include "hardware/pio.h"
|
||||
#include "hardware/clocks.h"
|
||||
|
||||
#if !defined(MCU_RP)
|
||||
# error PIO Driver is only available for Raspberry Pi 2040 MCUs!
|
||||
#endif
|
||||
|
||||
#if defined(WS2812_PIO_USE_PIO1)
|
||||
static const PIO pio = pio1;
|
||||
#else
|
||||
static const PIO pio = pio0;
|
||||
#endif
|
||||
|
||||
#if !defined(RP_DMA_PRIORITY_WS2812)
|
||||
# define RP_DMA_PRIORITY_WS2812 12
|
||||
#endif
|
||||
|
||||
static int state_machine = -1;
|
||||
|
||||
#define WS2812_WRAP_TARGET 0
|
||||
#define WS2812_WRAP 3
|
||||
|
||||
#define WS2812_T1 2
|
||||
#define WS2812_T2 5
|
||||
#define WS2812_T3 3
|
||||
|
||||
#if defined(WS2812_EXTERNAL_PULLUP)
|
||||
|
||||
# pragma message "The GPIOs of the RP2040 are NOT 5V tolerant! Make sure to NOT apply any voltage over 3.3V to the RGB data pin."
|
||||
|
||||
// clang-format off
|
||||
static const uint16_t ws2812_program_instructions[] = {
|
||||
// .wrap_target
|
||||
0x7221, // 0: out x, 1 side 1 [2]
|
||||
0x0123, // 1: jmp !x, 3 side 0 [1]
|
||||
0x0400, // 2: jmp 0 side 0 [4]
|
||||
0xb442, // 3: nop side 1 [4]
|
||||
// .wrap
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
static const uint16_t ws2812_program_instructions[] = {
|
||||
// .wrap_target
|
||||
0x6221, // 0: out x, 1 side 0 [2]
|
||||
0x1123, // 1: jmp !x, 3 side 1 [1]
|
||||
0x1400, // 2: jmp 0 side 1 [4]
|
||||
0xa442, // 3: nop side 0 [4]
|
||||
// .wrap
|
||||
};
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
static const pio_program_t ws2812_program = {
|
||||
.instructions = ws2812_program_instructions,
|
||||
.length = 4,
|
||||
.origin = -1,
|
||||
};
|
||||
|
||||
static uint32_t WS2812_BUFFER[RGBLED_NUM];
|
||||
static const rp_dma_channel_t* WS2812_DMA_CHANNEL;
|
||||
|
||||
bool ws2812_init(void) {
|
||||
uint pio_idx = pio_get_index(pio);
|
||||
/* Get PIOx peripheral out of reset state. */
|
||||
hal_lld_peripheral_unreset(pio_idx == 0 ? RESETS_ALLREG_PIO0 : RESETS_ALLREG_PIO1);
|
||||
|
||||
// clang-format off
|
||||
iomode_t rgb_pin_mode = PAL_RP_PAD_SLEWFAST |
|
||||
PAL_RP_GPIO_OE |
|
||||
(pio_idx == 0 ? PAL_MODE_ALTERNATE_PIO0 : PAL_MODE_ALTERNATE_PIO1);
|
||||
// clang-format on
|
||||
|
||||
palSetLineMode(RGB_DI_PIN, rgb_pin_mode);
|
||||
|
||||
state_machine = pio_claim_unused_sm(pio, true);
|
||||
if (state_machine < 0) {
|
||||
dprintln("ERROR: Failed to acquire state machine for WS2812 output!");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint offset = pio_add_program(pio, &ws2812_program);
|
||||
|
||||
pio_sm_set_consecutive_pindirs(pio, state_machine, RGB_DI_PIN, 1, true);
|
||||
|
||||
pio_sm_config config = pio_get_default_sm_config();
|
||||
sm_config_set_wrap(&config, offset + WS2812_WRAP_TARGET, offset + WS2812_WRAP);
|
||||
sm_config_set_sideset_pins(&config, RGB_DI_PIN);
|
||||
sm_config_set_fifo_join(&config, PIO_FIFO_JOIN_TX);
|
||||
|
||||
#if defined(WS2812_EXTERNAL_PULLUP)
|
||||
/* Instruct side-set to change the pin-directions instead of outputting
|
||||
* a logic level. We generate our levels the following way:
|
||||
*
|
||||
* 1: Set RGB data pin to high impedance input and let the pull-up drive the
|
||||
* signal high.
|
||||
*
|
||||
* 0: Set RGB data pin to low impedance output and drive the pin low.
|
||||
*/
|
||||
sm_config_set_sideset(&config, 1, false, true);
|
||||
#else
|
||||
sm_config_set_sideset(&config, 1, false, false);
|
||||
#endif
|
||||
|
||||
#if defined(RGBW)
|
||||
sm_config_set_out_shift(&config, false, true, 32);
|
||||
#else
|
||||
sm_config_set_out_shift(&config, false, true, 24);
|
||||
#endif
|
||||
|
||||
int cycles_per_bit = WS2812_T1 + WS2812_T2 + WS2812_T3;
|
||||
float div = clock_get_hz(clk_sys) / (800.0f * KHZ * cycles_per_bit);
|
||||
sm_config_set_clkdiv(&config, div);
|
||||
|
||||
pio_sm_init(pio, state_machine, offset, &config);
|
||||
pio_sm_set_enabled(pio, state_machine, true);
|
||||
|
||||
WS2812_DMA_CHANNEL = dmaChannelAlloc(RP_DMA_CHANNEL_ID_ANY, RP_DMA_PRIORITY_WS2812, NULL, NULL);
|
||||
|
||||
// clang-format off
|
||||
uint32_t mode = DMA_CTRL_TRIG_INCR_READ |
|
||||
DMA_CTRL_TRIG_DATA_SIZE_WORD |
|
||||
DMA_CTRL_TRIG_IRQ_QUIET |
|
||||
DMA_CTRL_TRIG_TREQ_SEL(pio_idx == 0 ? state_machine : state_machine + 8);
|
||||
// clang-format on
|
||||
|
||||
dmaChannelSetModeX(WS2812_DMA_CHANNEL, mode);
|
||||
dmaChannelSetDestinationX(WS2812_DMA_CHANNEL, (uint32_t)&pio->txf[state_machine]);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert RGBW value into WS2812 compatible 32-bit data word.
|
||||
*/
|
||||
__always_inline static uint32_t rgbw8888_to_u32(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) {
|
||||
#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
|
||||
return ((uint32_t)green << 24) | ((uint32_t)red << 16) | ((uint32_t)blue << 8) | ((uint32_t)white);
|
||||
#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
|
||||
return ((uint32_t)red << 24) | ((uint32_t)green << 16) | ((uint32_t)blue << 8) | ((uint32_t)white);
|
||||
#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
|
||||
return ((uint32_t)blue << 24) | ((uint32_t)green << 16) | ((uint32_t)red << 8) | ((uint32_t)white);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void sync_ws2812_transfer(void) {
|
||||
if (unlikely(dmaChannelIsBusyX(WS2812_DMA_CHANNEL) || !pio_sm_is_tx_fifo_empty(pio, state_machine))) {
|
||||
fast_timer_t start = timer_read_fast();
|
||||
do {
|
||||
// Abort the synchronization if we have to wait longer than the total
|
||||
// count of LEDs in millisecounds. This is safely much longer than it
|
||||
// would take to push all the data out.
|
||||
if (unlikely(timer_elapsed_fast(start) > RGBLED_NUM)) {
|
||||
dprintln("ERROR: WS2812 DMA transfer has stalled, aborting!");
|
||||
dmaChannelDisableX(WS2812_DMA_CHANNEL);
|
||||
return;
|
||||
}
|
||||
|
||||
} while (dmaChannelIsBusyX(WS2812_DMA_CHANNEL) || !pio_sm_is_tx_fifo_empty(pio, state_machine));
|
||||
// We wait for the WS2812 chain to reset after all data has been pushed
|
||||
// out.
|
||||
wait_us(WS2812_TRST_US);
|
||||
}
|
||||
}
|
||||
|
||||
void ws2812_setleds(LED_TYPE* ledarray, uint16_t leds) {
|
||||
static bool is_initialized = false;
|
||||
if (unlikely(!is_initialized)) {
|
||||
is_initialized = ws2812_init();
|
||||
}
|
||||
|
||||
sync_ws2812_transfer();
|
||||
|
||||
for (int i = 0; i < leds; i++) {
|
||||
#if defined(RGBW)
|
||||
WS2812_BUFFER[i] = rgbw8888_to_u32(ledarray[i].r, ledarray[i].g, ledarray[i].b, ledarray[i].w);
|
||||
#else
|
||||
WS2812_BUFFER[i] = rgbw8888_to_u32(ledarray[i].r, ledarray[i].g, ledarray[i].b, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
dmaChannelSetSourceX(WS2812_DMA_CHANNEL, (uint32_t)WS2812_BUFFER);
|
||||
dmaChannelSetCounterX(WS2812_DMA_CHANNEL, leds);
|
||||
dmaChannelEnableX(WS2812_DMA_CHANNEL);
|
||||
}
|
|
@ -108,6 +108,8 @@ else ifeq ($(strip $(BOOTLOADER)),kiibohd)
|
|||
$(UNSYNC_OUTPUT_CMD) && $(call EXEC_DFU_UTIL)
|
||||
else ifeq ($(strip $(BOOTLOADER)),tinyuf2)
|
||||
$(UNSYNC_OUTPUT_CMD) && $(call EXEC_UF2_UTIL_DEPLOY)
|
||||
else ifeq ($(strip $(BOOTLOADER)),rp2040)
|
||||
$(UNSYNC_OUTPUT_CMD) && $(call EXEC_UF2_UTIL_DEPLOY)
|
||||
else ifeq ($(strip $(MCU_FAMILY)),KINETIS)
|
||||
$(UNSYNC_OUTPUT_CMD) && $(call EXEC_TEENSY)
|
||||
else ifeq ($(strip $(MCU_FAMILY)),MIMXRT1062)
|
||||
|
|
|
@ -88,9 +88,9 @@ ifeq ("$(MCU_PORT_NAME)","")
|
|||
endif
|
||||
|
||||
ifeq ("$(wildcard $(PLATFORM_MK))","")
|
||||
PLATFORM_MK = $(CHIBIOS)/os/hal/ports/$(MCU_PORT_NAME)/$(MCU_SERIES)/$(PLATFORM_NAME).mk
|
||||
PLATFORM_MK = $(CHIBIOS_CONTRIB)/os/hal/ports/$(MCU_PORT_NAME)/$(MCU_SERIES)/$(PLATFORM_NAME).mk
|
||||
ifeq ("$(wildcard $(PLATFORM_MK))","")
|
||||
PLATFORM_MK = $(CHIBIOS_CONTRIB)/os/hal/ports/$(MCU_PORT_NAME)/$(MCU_SERIES)/$(PLATFORM_NAME).mk
|
||||
PLATFORM_MK = $(CHIBIOS)/os/hal/ports/$(MCU_PORT_NAME)/$(MCU_SERIES)/$(PLATFORM_NAME).mk
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -287,6 +287,17 @@ EXTRAINCDIRS += $(CHIBIOS)/os/license $(CHIBIOS)/os/oslib/include \
|
|||
$(HALINC) $(PLATFORMINC) $(BOARDINC) $(TESTINC) \
|
||||
$(STREAMSINC) $(CHIBIOS)/os/various $(COMMON_VPATH)
|
||||
|
||||
#
|
||||
# QMK specific MCU family support selection.
|
||||
##############################################################################
|
||||
ifneq ("$(wildcard $(PLATFORM_PATH)/$(PLATFORM_KEY)/vendors/$(MCU_FAMILY)/$(MCU_SERIES).mk)","")
|
||||
# Either by MCU series e.g. STM32/STM32F1xx.mk or...
|
||||
include $(PLATFORM_PATH)/$(PLATFORM_KEY)/vendors/$(MCU_FAMILY)/$(MCU_SERIES).mk
|
||||
else ifneq ("$(wildcard $(PLATFORM_PATH)/$(PLATFORM_KEY)/vendors/$(MCU_FAMILY)/$(MCU_FAMILY).mk)","")
|
||||
# By MCU family e.g. STM32/STM32.mk
|
||||
include $(PLATFORM_PATH)/$(PLATFORM_KEY)/vendors/$(MCU_FAMILY)/$(MCU_FAMILY).mk
|
||||
endif
|
||||
|
||||
#
|
||||
# ChibiOS-Contrib
|
||||
##############################################################################
|
||||
|
|
285
platforms/chibios/vendors/RP/RP2040.mk
vendored
Normal file
285
platforms/chibios/vendors/RP/RP2040.mk
vendored
Normal file
|
@ -0,0 +1,285 @@
|
|||
#
|
||||
# Raspberry Pi RP2040 specific drivers
|
||||
##############################################################################
|
||||
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/vendor/$(MCU_FAMILY)/$(MCU_SERIES)
|
||||
|
||||
ifeq ($(strip $(WS2812_DRIVER)), vendor)
|
||||
OPT_DEFS += -DRP_DMA_REQUIRED=TRUE
|
||||
endif
|
||||
|
||||
#
|
||||
# Raspberry Pi Pico SDK Support
|
||||
##############################################################################
|
||||
ADEFS += -DCRT0_VTOR_INIT=1 \
|
||||
-DCRT0_EXTRA_CORES_NUMBER=0
|
||||
|
||||
CFLAGS += -DPICO_NO_FPGA_CHECK \
|
||||
-DNDEBUG
|
||||
|
||||
#
|
||||
# Pico SDK source and header files needed by QMK and ChibiOS
|
||||
##############################################################################
|
||||
PICOSDKROOT := $(TOP_DIR)/lib/pico-sdk
|
||||
|
||||
PICOSDKSRC = $(PICOSDKROOT)/src/rp2_common/hardware_clocks/clocks.c \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_pll/pll.c \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_pio/pio.c \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_gpio/gpio.c \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_claim/claim.c \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_watchdog/watchdog.c \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_xosc/xosc.c \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_bootrom/bootrom.c
|
||||
|
||||
PICOSDKINC = $(CHIBIOS)//os/various/pico_bindings/dumb/include \
|
||||
$(PICOSDKROOT)/src/common/pico_base/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_platform/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_base/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_clocks/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_claim/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_gpio/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_irq/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_pll/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_pio/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_sync/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_resets/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_watchdog/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_xosc/include \
|
||||
$(PICOSDKROOT)/src/rp2040/hardware_regs/include \
|
||||
$(PICOSDKROOT)/src/rp2040/hardware_structs/include \
|
||||
$(PICOSDKROOT)/src/boards/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_bootrom/include
|
||||
|
||||
PLATFORM_SRC += $(PICOSDKSRC)
|
||||
EXTRAINCDIRS += $(PICOSDKINC)
|
||||
|
||||
PLATFORM_RP2040_PATH := $(PLATFORM_PATH)/$(PLATFORM_KEY)/vendors/$(MCU_FAMILY)
|
||||
|
||||
PLATFORM_SRC += $(PLATFORM_RP2040_PATH)/stage2_bootloaders.c \
|
||||
$(PLATFORM_RP2040_PATH)/pico_sdk_shims.c
|
||||
|
||||
EXTRAINCDIRS += $(PLATFORM_RP2040_PATH)
|
||||
|
||||
#
|
||||
# RP2040 optimized compiler intrinsics
|
||||
##############################################################################
|
||||
|
||||
# Enables optimized Compiler intrinsics which are located in the RP2040
|
||||
# bootrom. This needs startup code and linker script support from ChibiOS,
|
||||
# which is WIP. Therefore disabled by default for now.
|
||||
RP2040_INTRINSICS_ENABLED ?= no
|
||||
ifeq ($(strip $(RP2040_INTRINSICS_ENABLED)), yes)
|
||||
PICOSDKINTRINSICSSRC = $(PICOSDKROOT)/src/rp2_common/pico_float/float_aeabi.S \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_float/float_math.c \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_float/float_init_rom.c \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_float/float_v1_rom_shim.S \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_double/double_aeabi.S \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_double/double_math.c \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_double/double_init_rom.c \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_double/double_v1_rom_shim.S \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_divider/divider.S \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_int64_ops/pico_int64_ops_aeabi.S \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_malloc/pico_malloc.c \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S
|
||||
|
||||
PICOSDKINTRINSICSINC = $(PICOSDKROOT)/src/common/pico_base/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_platfrom/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_bootrom/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/hardware_divider/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_float/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_double/include \
|
||||
$(PICOSDKROOT)/src/rp2_common/pico_malloc/include
|
||||
|
||||
OPT_DEFS += -DPICO_FLOAT_SUPPORT_ROM_V1=0 -DPICO_DOUBLE_SUPPORT_ROM_V1=0
|
||||
|
||||
CFLAGS += -Wl,--defsym=__StackLimit=__heap_end__
|
||||
CFLAGS += -Wl,--defsym=__unhandled_user_irq=_unhandled_exception
|
||||
CFLAGS += -Wl,--build-id=none
|
||||
|
||||
# single precision floating point intrinsics
|
||||
OPT_DEFS += -DPICO_FLOAT_IN_RAM=1
|
||||
OPT_DEFS += -DPICO_FLOAT_PROPAGATE_NANS=0
|
||||
|
||||
CFLAGS += -Wl,--wrap=__aeabi_fdiv
|
||||
CFLAGS += -Wl,--wrap=__aeabi_fmul
|
||||
CFLAGS += -Wl,--wrap=__aeabi_frsub
|
||||
CFLAGS += -Wl,--wrap=__aeabi_fsub
|
||||
CFLAGS += -Wl,--wrap=__aeabi_cfcmpeq
|
||||
CFLAGS += -Wl,--wrap=__aeabi_cfrcmple
|
||||
CFLAGS += -Wl,--wrap=__aeabi_cfcmple
|
||||
CFLAGS += -Wl,--wrap=__aeabi_fcmpeq
|
||||
CFLAGS += -Wl,--wrap=__aeabi_fcmplt
|
||||
CFLAGS += -Wl,--wrap=__aeabi_fcmple
|
||||
CFLAGS += -Wl,--wrap=__aeabi_fcmpge
|
||||
CFLAGS += -Wl,--wrap=__aeabi_fcmpgt
|
||||
CFLAGS += -Wl,--wrap=__aeabi_fcmpun
|
||||
CFLAGS += -Wl,--wrap=__aeabi_i2f
|
||||
CFLAGS += -Wl,--wrap=__aeabi_l2f
|
||||
CFLAGS += -Wl,--wrap=__aeabi_ui2f
|
||||
CFLAGS += -Wl,--wrap=__aeabi_ul2f
|
||||
CFLAGS += -Wl,--wrap=__aeabi_i2f
|
||||
CFLAGS += -Wl,--wrap=__aeabi_f2iz
|
||||
CFLAGS += -Wl,--wrap=__aeabi_f2lz
|
||||
CFLAGS += -Wl,--wrap=__aeabi_f2uiz
|
||||
CFLAGS += -Wl,--wrap=__aeabi_f2ulz
|
||||
CFLAGS += -Wl,--wrap=__aeabi_f2d
|
||||
CFLAGS += -Wl,--wrap=sqrtf
|
||||
CFLAGS += -Wl,--wrap=cosf
|
||||
CFLAGS += -Wl,--wrap=sinf
|
||||
CFLAGS += -Wl,--wrap=tanf
|
||||
CFLAGS += -Wl,--wrap=atan2f
|
||||
CFLAGS += -Wl,--wrap=expf
|
||||
CFLAGS += -Wl,--wrap=logf
|
||||
CFLAGS += -Wl,--wrap=ldexpf
|
||||
CFLAGS += -Wl,--wrap=copysignf
|
||||
CFLAGS += -Wl,--wrap=truncf
|
||||
CFLAGS += -Wl,--wrap=floorf
|
||||
CFLAGS += -Wl,--wrap=ceilf
|
||||
CFLAGS += -Wl,--wrap=roundf
|
||||
CFLAGS += -Wl,--wrap=sincosf
|
||||
CFLAGS += -Wl,--wrap=asinf
|
||||
CFLAGS += -Wl,--wrap=acosf
|
||||
CFLAGS += -Wl,--wrap=atanf
|
||||
CFLAGS += -Wl,--wrap=sinhf
|
||||
CFLAGS += -Wl,--wrap=coshf
|
||||
CFLAGS += -Wl,--wrap=tanhf
|
||||
CFLAGS += -Wl,--wrap=asinhf
|
||||
CFLAGS += -Wl,--wrap=acoshf
|
||||
CFLAGS += -Wl,--wrap=atanhf
|
||||
CFLAGS += -Wl,--wrap=exp2f
|
||||
CFLAGS += -Wl,--wrap=log2f
|
||||
CFLAGS += -Wl,--wrap=exp10f
|
||||
CFLAGS += -Wl,--wrap=log10f
|
||||
CFLAGS += -Wl,--wrap=powf
|
||||
CFLAGS += -Wl,--wrap=powintf
|
||||
CFLAGS += -Wl,--wrap=hypotf
|
||||
CFLAGS += -Wl,--wrap=cbrtf
|
||||
CFLAGS += -Wl,--wrap=fmodf
|
||||
CFLAGS += -Wl,--wrap=dremf
|
||||
CFLAGS += -Wl,--wrap=remainderf
|
||||
CFLAGS += -Wl,--wrap=remquof
|
||||
CFLAGS += -Wl,--wrap=expm1f
|
||||
CFLAGS += -Wl,--wrap=log1pf
|
||||
CFLAGS += -Wl,--wrap=fmaf
|
||||
|
||||
# double precision floating point intrinsics
|
||||
OPT_DEFS += -DPICO_DOUBLE_IN_RAM=1
|
||||
OPT_DEFS += -DPICO_DOUBLE_PROPAGATE_NANS=0
|
||||
|
||||
CFLAGS += -Wl,--wrap=__aeabi_dadd
|
||||
CFLAGS += -Wl,--wrap=__aeabi_ddiv
|
||||
CFLAGS += -Wl,--wrap=__aeabi_dmul
|
||||
CFLAGS += -Wl,--wrap=__aeabi_drsub
|
||||
CFLAGS += -Wl,--wrap=__aeabi_dsub
|
||||
CFLAGS += -Wl,--wrap=__aeabi_cdcmpeq
|
||||
CFLAGS += -Wl,--wrap=__aeabi_cdrcmple
|
||||
CFLAGS += -Wl,--wrap=__aeabi_cdcmple
|
||||
CFLAGS += -Wl,--wrap=__aeabi_dcmpeq
|
||||
CFLAGS += -Wl,--wrap=__aeabi_dcmplt
|
||||
CFLAGS += -Wl,--wrap=__aeabi_dcmple
|
||||
CFLAGS += -Wl,--wrap=__aeabi_dcmpge
|
||||
CFLAGS += -Wl,--wrap=__aeabi_dcmpgt
|
||||
CFLAGS += -Wl,--wrap=__aeabi_dcmpun
|
||||
CFLAGS += -Wl,--wrap=__aeabi_i2d
|
||||
CFLAGS += -Wl,--wrap=__aeabi_l2d
|
||||
CFLAGS += -Wl,--wrap=__aeabi_ui2d
|
||||
CFLAGS += -Wl,--wrap=__aeabi_ul2d
|
||||
CFLAGS += -Wl,--wrap=__aeabi_d2iz
|
||||
CFLAGS += -Wl,--wrap=__aeabi_d2lz
|
||||
CFLAGS += -Wl,--wrap=__aeabi_d2uiz
|
||||
CFLAGS += -Wl,--wrap=__aeabi_d2ulz
|
||||
CFLAGS += -Wl,--wrap=__aeabi_d2f
|
||||
CFLAGS += -Wl,--wrap=sqrt
|
||||
CFLAGS += -Wl,--wrap=cos
|
||||
CFLAGS += -Wl,--wrap=sin
|
||||
CFLAGS += -Wl,--wrap=tan
|
||||
CFLAGS += -Wl,--wrap=atan2
|
||||
CFLAGS += -Wl,--wrap=exp
|
||||
CFLAGS += -Wl,--wrap=log
|
||||
CFLAGS += -Wl,--wrap=ldexp
|
||||
CFLAGS += -Wl,--wrap=copysign
|
||||
CFLAGS += -Wl,--wrap=trunc
|
||||
CFLAGS += -Wl,--wrap=floor
|
||||
CFLAGS += -Wl,--wrap=ceil
|
||||
CFLAGS += -Wl,--wrap=round
|
||||
CFLAGS += -Wl,--wrap=sincos
|
||||
CFLAGS += -Wl,--wrap=asin
|
||||
CFLAGS += -Wl,--wrap=acos
|
||||
CFLAGS += -Wl,--wrap=atan
|
||||
CFLAGS += -Wl,--wrap=sinh
|
||||
CFLAGS += -Wl,--wrap=cosh
|
||||
CFLAGS += -Wl,--wrap=tanh
|
||||
CFLAGS += -Wl,--wrap=asinh
|
||||
CFLAGS += -Wl,--wrap=acosh
|
||||
CFLAGS += -Wl,--wrap=atanh
|
||||
CFLAGS += -Wl,--wrap=exp2
|
||||
CFLAGS += -Wl,--wrap=log2
|
||||
CFLAGS += -Wl,--wrap=exp10
|
||||
CFLAGS += -Wl,--wrap=log10
|
||||
CFLAGS += -Wl,--wrap=pow
|
||||
CFLAGS += -Wl,--wrap=powint
|
||||
CFLAGS += -Wl,--wrap=hypot
|
||||
CFLAGS += -Wl,--wrap=cbrt
|
||||
CFLAGS += -Wl,--wrap=fmod
|
||||
CFLAGS += -Wl,--wrap=drem
|
||||
CFLAGS += -Wl,--wrap=remainder
|
||||
CFLAGS += -Wl,--wrap=remquo
|
||||
CFLAGS += -Wl,--wrap=expm1
|
||||
CFLAGS += -Wl,--wrap=log1p
|
||||
CFLAGS += -Wl,--wrap=fma
|
||||
|
||||
# bit operation intrinsics
|
||||
OPT_DEFS += -DPICO_BITS_IN_RAM=1
|
||||
|
||||
CFLAGS += -Wl,--wrap=__clzsi2
|
||||
CFLAGS += -Wl,--wrap=__clzsi2
|
||||
CFLAGS += -Wl,--wrap=__clzdi2
|
||||
CFLAGS += -Wl,--wrap=__ctzsi2
|
||||
CFLAGS += -Wl,--wrap=__ctzdi2
|
||||
CFLAGS += -Wl,--wrap=__popcountsi2
|
||||
CFLAGS += -Wl,--wrap=__popcountdi2
|
||||
CFLAGS += -Wl,--wrap=__clz
|
||||
CFLAGS += -Wl,--wrap=__clzl
|
||||
CFLAGS += -Wl,--wrap=__clzsi2
|
||||
CFLAGS += -Wl,--wrap=__clzll
|
||||
|
||||
# integer division intrinsics
|
||||
OPT_DEFS += -DPICO_DIVIDER_IN_RAM=1
|
||||
OPT_DEFS += -DPICO_DIVIDER_DISABLE_INTERRUPTS=1
|
||||
|
||||
CFLAGS += -Wl,--wrap=__aeabi_idiv
|
||||
CFLAGS += -Wl,--wrap=__aeabi_idivmod
|
||||
CFLAGS += -Wl,--wrap=__aeabi_ldivmod
|
||||
CFLAGS += -Wl,--wrap=__aeabi_uidiv
|
||||
CFLAGS += -Wl,--wrap=__aeabi_uidivmod
|
||||
CFLAGS += -Wl,--wrap=__aeabi_uldivmod
|
||||
|
||||
# 64bit integer intrinsics
|
||||
OPT_DEFS += -DPICO_INT64_OPS_IN_RAM=1
|
||||
|
||||
CFLAGS += -Wl,--wrap=__aeabi_lmul
|
||||
|
||||
# malloc and friends functions
|
||||
OPT_DEFS += -DPICO_USE_MALLOC_MUTEX=0
|
||||
OPT_DEFS += -DPICO_DEBUG_MALLOC=0
|
||||
OPT_DEFS ?= -DPICO_MALLOC_PANIC=0
|
||||
|
||||
CFLAGS += -Wl,--wrap=malloc
|
||||
CFLAGS += -Wl,--wrap=calloc
|
||||
CFLAGS += -Wl,--wrap=free
|
||||
|
||||
# memory operation intrinsics
|
||||
OPT_DEFS += -DPICO_MEM_IN_RAM=1
|
||||
|
||||
CFLAGS += -Wl,--wrap=memcpy
|
||||
CFLAGS += -Wl,--wrap=memset
|
||||
CFLAGS += -Wl,--wrap=__aeabi_memcpy
|
||||
CFLAGS += -Wl,--wrap=__aeabi_memset
|
||||
CFLAGS += -Wl,--wrap=__aeabi_memcpy4
|
||||
CFLAGS += -Wl,--wrap=__aeabi_memset4
|
||||
CFLAGS += -Wl,--wrap=__aeabi_memcpy8
|
||||
CFLAGS += -Wl,--wrap=__aeabi_memset8
|
||||
|
||||
PLATFORM_SRC += $(PICOSDKINTRINSICSSRC)
|
||||
EXTRAINCDIRS += $(PICOSDKINTRINSICSINC)
|
||||
endif
|
37
platforms/chibios/vendors/RP/_pin_defs.h
vendored
Normal file
37
platforms/chibios/vendors/RP/_pin_defs.h
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2022 Stefan Kerkmann
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
/* RP2040 GPIO Numbering */
|
||||
#define GP0 0U
|
||||
#define GP1 1U
|
||||
#define GP2 2U
|
||||
#define GP3 3U
|
||||
#define GP4 4U
|
||||
#define GP5 5U
|
||||
#define GP6 6U
|
||||
#define GP7 7U
|
||||
#define GP8 8U
|
||||
#define GP9 9U
|
||||
#define GP10 10U
|
||||
#define GP11 11U
|
||||
#define GP12 12U
|
||||
#define GP13 13U
|
||||
#define GP14 14U
|
||||
#define GP15 15U
|
||||
#define GP16 16U
|
||||
#define GP17 17U
|
||||
#define GP18 18U
|
||||
#define GP19 19U
|
||||
#define GP20 20U
|
||||
#define GP21 21U
|
||||
#define GP22 22U
|
||||
#define GP23 23U
|
||||
#define GP24 24U
|
||||
#define GP25 25U
|
||||
#define GP26 26U
|
||||
#define GP27 27U
|
||||
#define GP28 28U
|
||||
#define GP29 29U
|
||||
#define GP30 30U
|
9
platforms/chibios/vendors/RP/pico_sdk_shims.c
vendored
Normal file
9
platforms/chibios/vendors/RP/pico_sdk_shims.c
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
// Copyright 2022 Stefan Kerkmann
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <ch.h>
|
||||
|
||||
void panic(const char *fmt, ...) {
|
||||
chSysHalt(fmt);
|
||||
}
|
174
platforms/chibios/vendors/RP/stage2_bootloaders.c
vendored
Normal file
174
platforms/chibios/vendors/RP/stage2_bootloaders.c
vendored
Normal file
|
@ -0,0 +1,174 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// Pre-compiled second stage boot code for RP2040.
|
||||
//
|
||||
// Copyright (c) 2019-2021 Raspberry Pi (Trading) Ltd.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define BOOTLOADER_SECTION __attribute__ ((used, section (".boot2")))
|
||||
|
||||
#if defined(RP2040_FLASH_AT25SF128A)
|
||||
|
||||
uint8_t BOOTLOADER_SECTION BOOT2_AT25SF128A[256] = {
|
||||
0x00, 0xb5, 0x31, 0x4b, 0x21, 0x20, 0x58, 0x60, 0x98, 0x68, 0x02, 0x21,
|
||||
0x88, 0x43, 0x98, 0x60, 0xd8, 0x60, 0x18, 0x61, 0x58, 0x61, 0x2d, 0x4b,
|
||||
0x00, 0x21, 0x99, 0x60, 0x04, 0x21, 0x59, 0x61, 0x01, 0x21, 0xf0, 0x22,
|
||||
0x99, 0x50, 0x2a, 0x49, 0x19, 0x60, 0x01, 0x21, 0x99, 0x60, 0x35, 0x20,
|
||||
0x00, 0xf0, 0x42, 0xf8, 0x02, 0x22, 0x90, 0x42, 0x12, 0xd0, 0x06, 0x21,
|
||||
0x19, 0x66, 0x00, 0xf0, 0x32, 0xf8, 0x19, 0x6e, 0x31, 0x21, 0x19, 0x66,
|
||||
0x1a, 0x66, 0x00, 0xf0, 0x2c, 0xf8, 0x19, 0x6e, 0x19, 0x6e, 0x19, 0x6e,
|
||||
0x05, 0x20, 0x00, 0xf0, 0x2f, 0xf8, 0x01, 0x21, 0x08, 0x42, 0xf9, 0xd1,
|
||||
0x00, 0x21, 0x99, 0x60, 0x1b, 0x49, 0x19, 0x60, 0x00, 0x21, 0x59, 0x60,
|
||||
0x1a, 0x49, 0x1b, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60, 0xeb, 0x21,
|
||||
0x19, 0x66, 0x20, 0x21, 0x19, 0x66, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0x21,
|
||||
0x99, 0x60, 0x16, 0x49, 0x14, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60,
|
||||
0x01, 0xbc, 0x00, 0x28, 0x00, 0xd0, 0x00, 0x47, 0x12, 0x48, 0x13, 0x49,
|
||||
0x08, 0x60, 0x03, 0xc8, 0x80, 0xf3, 0x08, 0x88, 0x08, 0x47, 0x03, 0xb5,
|
||||
0x99, 0x6a, 0x04, 0x20, 0x01, 0x42, 0xfb, 0xd0, 0x01, 0x20, 0x01, 0x42,
|
||||
0xf8, 0xd1, 0x03, 0xbd, 0x02, 0xb5, 0x18, 0x66, 0x18, 0x66, 0xff, 0xf7,
|
||||
0xf2, 0xff, 0x18, 0x6e, 0x18, 0x6e, 0x02, 0xbd, 0x00, 0x00, 0x02, 0x40,
|
||||
0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x5f, 0x00,
|
||||
0x21, 0x22, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x18, 0x22, 0x20, 0x00, 0x20,
|
||||
0x00, 0x01, 0x00, 0x10, 0x08, 0xed, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xc0, 0xdd, 0xc0, 0xb5
|
||||
};
|
||||
|
||||
#elif defined(RP2040_FLASH_GD25Q64CS)
|
||||
|
||||
uint8_t BOOTLOADER_SECTION BOOT2_GD25Q64CS[256] = {
|
||||
0x00, 0xb5, 0x31, 0x4b, 0x21, 0x20, 0x58, 0x60, 0x98, 0x68, 0x02, 0x21,
|
||||
0x88, 0x43, 0x98, 0x60, 0xd8, 0x60, 0x18, 0x61, 0x58, 0x61, 0x2d, 0x4b,
|
||||
0x00, 0x21, 0x99, 0x60, 0x04, 0x21, 0x59, 0x61, 0x01, 0x21, 0xf0, 0x22,
|
||||
0x99, 0x50, 0x2a, 0x49, 0x19, 0x60, 0x01, 0x21, 0x99, 0x60, 0x35, 0x20,
|
||||
0x00, 0xf0, 0x42, 0xf8, 0x02, 0x22, 0x90, 0x42, 0x12, 0xd0, 0x06, 0x21,
|
||||
0x19, 0x66, 0x00, 0xf0, 0x32, 0xf8, 0x19, 0x6e, 0x31, 0x21, 0x19, 0x66,
|
||||
0x1a, 0x66, 0x00, 0xf0, 0x2c, 0xf8, 0x19, 0x6e, 0x19, 0x6e, 0x19, 0x6e,
|
||||
0x05, 0x20, 0x00, 0xf0, 0x2f, 0xf8, 0x01, 0x21, 0x08, 0x42, 0xf9, 0xd1,
|
||||
0x00, 0x21, 0x99, 0x60, 0x1b, 0x49, 0x19, 0x60, 0x00, 0x21, 0x59, 0x60,
|
||||
0x1a, 0x49, 0x1b, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60, 0xe7, 0x21,
|
||||
0x19, 0x66, 0xa0, 0x21, 0x19, 0x66, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0x21,
|
||||
0x99, 0x60, 0x16, 0x49, 0x14, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60,
|
||||
0x01, 0xbc, 0x00, 0x28, 0x00, 0xd0, 0x00, 0x47, 0x12, 0x48, 0x13, 0x49,
|
||||
0x08, 0x60, 0x03, 0xc8, 0x80, 0xf3, 0x08, 0x88, 0x08, 0x47, 0x03, 0xb5,
|
||||
0x99, 0x6a, 0x04, 0x20, 0x01, 0x42, 0xfb, 0xd0, 0x01, 0x20, 0x01, 0x42,
|
||||
0xf8, 0xd1, 0x03, 0xbd, 0x02, 0xb5, 0x18, 0x66, 0x18, 0x66, 0xff, 0xf7,
|
||||
0xf2, 0xff, 0x18, 0x6e, 0x18, 0x6e, 0x02, 0xbd, 0x00, 0x00, 0x02, 0x40,
|
||||
0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x5f, 0x00,
|
||||
0x21, 0x12, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x18, 0x22, 0x10, 0x00, 0xa0,
|
||||
0x00, 0x01, 0x00, 0x10, 0x08, 0xed, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xe2, 0xd9, 0xa2, 0xb5
|
||||
};
|
||||
|
||||
#elif defined(RP2040_FLASH_W25X10CL)
|
||||
|
||||
uint8_t BOOTLOADER_SECTION BOOT2_W25X10CL[256] = {
|
||||
0x00, 0xb5, 0x14, 0x4b, 0x00, 0x21, 0x99, 0x60, 0x04, 0x21, 0x59, 0x61,
|
||||
0x12, 0x49, 0x19, 0x60, 0x00, 0x21, 0x59, 0x60, 0x11, 0x49, 0x12, 0x48,
|
||||
0x01, 0x60, 0x01, 0x21, 0x99, 0x60, 0xbb, 0x21, 0x19, 0x66, 0x02, 0x21,
|
||||
0x19, 0x66, 0x08, 0x21, 0x98, 0x6a, 0x08, 0x42, 0xfc, 0xd0, 0x00, 0x21,
|
||||
0x99, 0x60, 0x0c, 0x49, 0x0a, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60,
|
||||
0x01, 0xbc, 0x00, 0x28, 0x00, 0xd0, 0x00, 0x47, 0x08, 0x48, 0x09, 0x49,
|
||||
0x08, 0x60, 0x03, 0xc8, 0x80, 0xf3, 0x08, 0x88, 0x08, 0x47, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x00, 0x03, 0x3f, 0x00, 0x1d, 0x12, 0x00, 0x00,
|
||||
0xf4, 0x00, 0x00, 0x18, 0x1e, 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x10,
|
||||
0x08, 0xed, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7c, 0x81, 0x53, 0x9a
|
||||
};
|
||||
|
||||
#elif defined(RP2040_FLASH_IS25LP080)
|
||||
|
||||
uint8_t BOOTLOADER_SECTION BOOT2_IS25LP080[256] = {
|
||||
0x00, 0xb5, 0x2b, 0x4b, 0x00, 0x21, 0x99, 0x60, 0x04, 0x21, 0x59, 0x61,
|
||||
0x29, 0x49, 0x19, 0x60, 0x01, 0x21, 0x99, 0x60, 0x28, 0x48, 0x00, 0xf0,
|
||||
0x42, 0xf8, 0x28, 0x4a, 0x90, 0x42, 0x12, 0xd0, 0x06, 0x21, 0x19, 0x66,
|
||||
0x00, 0xf0, 0x32, 0xf8, 0x19, 0x6e, 0x01, 0x21, 0x19, 0x66, 0x00, 0x20,
|
||||
0x1a, 0x66, 0x00, 0xf0, 0x2b, 0xf8, 0x19, 0x6e, 0x19, 0x6e, 0x1f, 0x48,
|
||||
0x00, 0xf0, 0x2f, 0xf8, 0x01, 0x21, 0x08, 0x42, 0xf9, 0xd1, 0x00, 0x21,
|
||||
0x99, 0x60, 0x1d, 0x49, 0x19, 0x60, 0x00, 0x21, 0x59, 0x60, 0x1c, 0x49,
|
||||
0x1c, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60, 0xeb, 0x21, 0x19, 0x66,
|
||||
0xa0, 0x21, 0x19, 0x66, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0x21, 0x99, 0x60,
|
||||
0x17, 0x49, 0x16, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60, 0x01, 0xbc,
|
||||
0x00, 0x28, 0x00, 0xd0, 0x00, 0x47, 0x14, 0x48, 0x14, 0x49, 0x08, 0x60,
|
||||
0x03, 0xc8, 0x80, 0xf3, 0x08, 0x88, 0x08, 0x47, 0x03, 0xb5, 0x99, 0x6a,
|
||||
0x04, 0x20, 0x01, 0x42, 0xfb, 0xd0, 0x01, 0x20, 0x01, 0x42, 0xf8, 0xd1,
|
||||
0x03, 0xbd, 0x02, 0xb5, 0x18, 0x66, 0x18, 0x66, 0xff, 0xf7, 0xf2, 0xff,
|
||||
0x18, 0x6e, 0x18, 0x6e, 0x02, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
|
||||
0x00, 0x00, 0x07, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||
0x00, 0x03, 0x5f, 0x00, 0x21, 0x22, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x18,
|
||||
0x22, 0x20, 0x00, 0xa0, 0x00, 0x01, 0x00, 0x10, 0x08, 0xed, 0x00, 0xe0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x28, 0x33, 0x43, 0xb2
|
||||
};
|
||||
|
||||
#elif defined(RP2040_FLASH_GENERIC_03H)
|
||||
|
||||
uint8_t BOOTLOADER_SECTION BOOT2_GENERIC_03H[256] = {
|
||||
0x00, 0xb5, 0x0c, 0x4b, 0x00, 0x21, 0x99, 0x60, 0x04, 0x21, 0x59, 0x61,
|
||||
0x0a, 0x49, 0x19, 0x60, 0x0a, 0x49, 0x0b, 0x48, 0x01, 0x60, 0x00, 0x21,
|
||||
0x59, 0x60, 0x01, 0x21, 0x99, 0x60, 0x01, 0xbc, 0x00, 0x28, 0x00, 0xd0,
|
||||
0x00, 0x47, 0x07, 0x48, 0x07, 0x49, 0x08, 0x60, 0x03, 0xc8, 0x80, 0xf3,
|
||||
0x08, 0x88, 0x08, 0x47, 0x00, 0x00, 0x00, 0x18, 0x00, 0x03, 0x1f, 0x00,
|
||||
0x18, 0x02, 0x00, 0x03, 0xf4, 0x00, 0x00, 0x18, 0x00, 0x01, 0x00, 0x10,
|
||||
0x08, 0xed, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x2c, 0xec, 0x21, 0x0d
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
uint8_t BOOTLOADER_SECTION BOOT2_W25Q080[256] = {
|
||||
0x00, 0xb5, 0x32, 0x4b, 0x21, 0x20, 0x58, 0x60, 0x98, 0x68, 0x02, 0x21,
|
||||
0x88, 0x43, 0x98, 0x60, 0xd8, 0x60, 0x18, 0x61, 0x58, 0x61, 0x2e, 0x4b,
|
||||
0x00, 0x21, 0x99, 0x60, 0x04, 0x21, 0x59, 0x61, 0x01, 0x21, 0xf0, 0x22,
|
||||
0x99, 0x50, 0x2b, 0x49, 0x19, 0x60, 0x01, 0x21, 0x99, 0x60, 0x35, 0x20,
|
||||
0x00, 0xf0, 0x44, 0xf8, 0x02, 0x22, 0x90, 0x42, 0x14, 0xd0, 0x06, 0x21,
|
||||
0x19, 0x66, 0x00, 0xf0, 0x34, 0xf8, 0x19, 0x6e, 0x01, 0x21, 0x19, 0x66,
|
||||
0x00, 0x20, 0x18, 0x66, 0x1a, 0x66, 0x00, 0xf0, 0x2c, 0xf8, 0x19, 0x6e,
|
||||
0x19, 0x6e, 0x19, 0x6e, 0x05, 0x20, 0x00, 0xf0, 0x2f, 0xf8, 0x01, 0x21,
|
||||
0x08, 0x42, 0xf9, 0xd1, 0x00, 0x21, 0x99, 0x60, 0x1b, 0x49, 0x19, 0x60,
|
||||
0x00, 0x21, 0x59, 0x60, 0x1a, 0x49, 0x1b, 0x48, 0x01, 0x60, 0x01, 0x21,
|
||||
0x99, 0x60, 0xeb, 0x21, 0x19, 0x66, 0xa0, 0x21, 0x19, 0x66, 0x00, 0xf0,
|
||||
0x12, 0xf8, 0x00, 0x21, 0x99, 0x60, 0x16, 0x49, 0x14, 0x48, 0x01, 0x60,
|
||||
0x01, 0x21, 0x99, 0x60, 0x01, 0xbc, 0x00, 0x28, 0x00, 0xd0, 0x00, 0x47,
|
||||
0x12, 0x48, 0x13, 0x49, 0x08, 0x60, 0x03, 0xc8, 0x80, 0xf3, 0x08, 0x88,
|
||||
0x08, 0x47, 0x03, 0xb5, 0x99, 0x6a, 0x04, 0x20, 0x01, 0x42, 0xfb, 0xd0,
|
||||
0x01, 0x20, 0x01, 0x42, 0xf8, 0xd1, 0x03, 0xbd, 0x02, 0xb5, 0x18, 0x66,
|
||||
0x18, 0x66, 0xff, 0xf7, 0xf2, 0xff, 0x18, 0x6e, 0x18, 0x6e, 0x02, 0xbd,
|
||||
0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x03, 0x5f, 0x00, 0x21, 0x22, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x18,
|
||||
0x22, 0x20, 0x00, 0xa0, 0x00, 0x01, 0x00, 0x10, 0x08, 0xed, 0x00, 0xe0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0x0b, 0x8f, 0xd5
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue