├── scripts ├── flash_can.py ├── make-version.sh ├── check-gcc.sh ├── uf2_append_boot_signature.py └── buildbinary.py ├── .gitattributes ├── lib ├── .gitignore ├── stm32f0 │ └── include │ │ ├── stm32f0xx.h │ │ ├── stm32f030x6.h │ │ ├── stm32f030x8.h │ │ ├── stm32f030xc.h │ │ ├── stm32f031x6.h │ │ ├── stm32f038xx.h │ │ ├── stm32f042x6.h │ │ ├── stm32f048xx.h │ │ ├── stm32f051x8.h │ │ ├── stm32f058xx.h │ │ ├── stm32f070x6.h │ │ ├── stm32f070xb.h │ │ ├── stm32f071xb.h │ │ ├── stm32f072xb.h │ │ ├── stm32f078xx.h │ │ ├── stm32f091xc.h │ │ └── stm32f098xx.h ├── stm32f1 │ └── include │ │ ├── stm32f1xx.h │ │ ├── stm32f100xb.h │ │ ├── stm32f100xe.h │ │ ├── stm32f101x6.h │ │ ├── stm32f101xb.h │ │ ├── stm32f101xe.h │ │ ├── stm32f101xg.h │ │ ├── stm32f102x6.h │ │ ├── stm32f102xb.h │ │ ├── stm32f103x6.h │ │ ├── stm32f103xb.h │ │ ├── stm32f103xe.h │ │ ├── stm32f103xg.h │ │ ├── stm32f105xc.h │ │ ├── stm32f107xc.h │ │ └── system_stm32f1xx.h ├── stm32f2 │ └── include │ │ ├── stm32f2xx.h │ │ ├── stm32f205xx.h │ │ ├── stm32f207xx.h │ │ ├── stm32f215xx.h │ │ ├── stm32f217xx.h │ │ └── system_stm32f2xx.h ├── stm32f4 │ └── include │ │ └── stm32f4xx.h ├── stm32h7 │ └── include │ │ ├── stm32h7xx.h │ │ └── system_stm32h7xx.h ├── rp2040 │ ├── boot_stage2 │ │ ├── doc.h │ │ ├── boot_stage2.ld │ │ ├── asminclude │ │ │ └── boot2_helpers │ │ │ │ ├── wait_ssi_ready.S │ │ │ │ ├── read_flash_sreg.S │ │ │ │ └── exit_from_boot2.S │ │ ├── compile_time_choice.S │ │ ├── boot2_usb_blinky.S │ │ └── pad_checksum │ ├── hardware │ │ ├── structs │ │ │ ├── padsbank0.h │ │ │ ├── psm.h │ │ │ ├── mpu.h │ │ │ ├── pads_qspi.h │ │ │ ├── resets.h │ │ │ ├── systick.h │ │ │ ├── ioqspi.h │ │ │ ├── scb.h │ │ │ ├── pll.h │ │ │ ├── watchdog.h │ │ │ ├── vreg_and_chip_reset.h │ │ │ ├── xosc.h │ │ │ ├── adc.h │ │ │ ├── spi.h │ │ │ ├── rosc.h │ │ │ ├── syscfg.h │ │ │ ├── rtc.h │ │ │ ├── interp.h │ │ │ ├── xip_ctrl.h │ │ │ ├── pwm.h │ │ │ ├── uart.h │ │ │ ├── timer.h │ │ │ ├── iobank0.h │ │ │ ├── ssi.h │ │ │ ├── pio.h │ │ │ ├── sio.h │ │ │ ├── bus_ctrl.h │ │ │ ├── dma.h │ │ │ └── clocks.h │ │ ├── regs │ │ │ ├── dreq.h │ │ │ ├── intctrl.h │ │ │ ├── tbman.h │ │ │ ├── addressmap.h │ │ │ └── sysinfo.h │ │ └── platform_defs.h │ ├── boot │ │ └── uf2.h │ ├── elf2uf2 │ │ └── elf.h │ ├── rp2040.patch │ ├── cmsis_include │ │ └── system_RP2040.h │ └── pico │ │ └── platform.h ├── rp2040_flash │ └── Makefile ├── kconfiglib │ ├── LICENSE.txt │ └── olddefconfig.py ├── lpc176x │ ├── lpc176x.patch │ └── device │ │ └── system_LPC17xx.h ├── cmsis-core │ └── cmsis_version.h ├── fast-hash │ ├── fasthash.h │ └── fasthash.c ├── can2040 │ └── can2040.h └── stm32g0 │ └── include │ └── system_stm32g0xx.h ├── src ├── bootentry.h ├── flashcmd.h ├── generic │ ├── armcm_reset.h │ ├── armcm_timer.h │ ├── usb_cdc_ep.h │ ├── irq.h │ ├── serial_irq.h │ ├── canserial.h │ ├── pgm.h │ ├── alloc.c │ ├── misc.h │ ├── crc16_ccitt.c │ ├── canbus.h │ ├── armcm_boot.h │ ├── canbus.c │ ├── armcm_reset.c │ ├── io.h │ ├── usb_cdc.h │ ├── armcm_timer.c │ ├── usbstd_cdc.h │ ├── gpio.h │ ├── armcm_irq.c │ ├── armcm_link.lds.S │ ├── armcm_deployer.lds.S │ ├── armcm_boot.c │ └── armcm_canboot.c ├── Makefile ├── stm32 │ ├── flash.h │ ├── dfu_reboot.c │ ├── clockline.c │ ├── chipid.c │ ├── gpioperiph.c │ ├── internal.h │ ├── gpio.h │ ├── serial.c │ ├── stm32f0_timer.c │ └── Makefile ├── lpc176x │ ├── flash.h │ ├── usb_cdc_ep.h │ ├── internal.h │ ├── Makefile │ ├── chipid.c │ ├── gpio.h │ ├── main.c │ ├── serial.c │ └── Kconfig ├── rp2040 │ ├── flash.h │ ├── internal.h │ ├── chipid.c │ ├── timer.c │ ├── gpio.h │ ├── rp2040_link.lds.S │ ├── can.c │ ├── flash.c │ ├── serial.c │ ├── Makefile │ ├── Kconfig │ └── gpio.c ├── deployer.h ├── initial_pins.h ├── canboot.h ├── initial_pins.c ├── sched.h ├── byteorder.h ├── led.c ├── compiler.h ├── sched.c ├── ctr.h ├── bootentry.c ├── command.h ├── deployer.c ├── Kconfig └── flashcmd.c ├── .gitignore └── developer-certificate-of-origin /scripts/flash_can.py: -------------------------------------------------------------------------------- 1 | flashtool.py -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /lib/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | bossac/bin/ 3 | bossac/obj/ 4 | hidflash/hid-flash 5 | hub-ctrl/hub-ctrl 6 | -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f0xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f0xx.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f1xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f1xx.h -------------------------------------------------------------------------------- /lib/stm32f2/include/stm32f2xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f2/include/stm32f2xx.h -------------------------------------------------------------------------------- /lib/stm32f4/include/stm32f4xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f4/include/stm32f4xx.h -------------------------------------------------------------------------------- /lib/stm32h7/include/stm32h7xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32h7/include/stm32h7xx.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f030x6.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f030x6.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f030x8.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f030x8.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f030xc.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f030xc.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f031x6.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f031x6.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f038xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f038xx.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f042x6.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f042x6.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f048xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f048xx.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f051x8.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f051x8.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f058xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f058xx.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f070x6.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f070x6.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f070xb.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f070xb.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f071xb.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f071xb.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f072xb.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f072xb.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f078xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f078xx.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f091xc.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f091xc.h -------------------------------------------------------------------------------- /lib/stm32f0/include/stm32f098xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f0/include/stm32f098xx.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f100xb.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f100xb.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f100xe.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f100xe.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f101x6.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f101x6.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f101xb.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f101xb.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f101xe.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f101xe.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f101xg.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f101xg.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f102x6.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f102x6.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f102xb.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f102xb.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f103x6.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f103x6.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f103xb.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f103xb.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f103xe.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f103xe.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f103xg.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f103xg.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f105xc.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f105xc.h -------------------------------------------------------------------------------- /lib/stm32f1/include/stm32f107xc.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f1/include/stm32f107xc.h -------------------------------------------------------------------------------- /lib/stm32f2/include/stm32f205xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f2/include/stm32f205xx.h -------------------------------------------------------------------------------- /lib/stm32f2/include/stm32f207xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f2/include/stm32f207xx.h -------------------------------------------------------------------------------- /lib/stm32f2/include/stm32f215xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f2/include/stm32f215xx.h -------------------------------------------------------------------------------- /lib/stm32f2/include/stm32f217xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigtreetech/katapult/HEAD/lib/stm32f2/include/stm32f217xx.h -------------------------------------------------------------------------------- /src/bootentry.h: -------------------------------------------------------------------------------- 1 | #ifndef __BOOTENTRY_H 2 | #define __BOOTENTRY_H 3 | 4 | int bootentry_check(void); 5 | 6 | #endif // bootentry.h 7 | -------------------------------------------------------------------------------- /src/flashcmd.h: -------------------------------------------------------------------------------- 1 | #ifndef __FLASHCMD_H 2 | #define __FLASHCMD_H 3 | 4 | int flashcmd_is_in_transfer(void); 5 | 6 | #endif // flashcmd.h 7 | -------------------------------------------------------------------------------- /lib/rp2040/boot_stage2/doc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \defgroup boot_stage2 boot_stage2 3 | * \brief Second stage boot loaders responsible for setting up external flash 4 | */ 5 | -------------------------------------------------------------------------------- /src/generic/armcm_reset.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_ARMCM_RESET_H 2 | #define __GENERIC_ARMCM_RESET_H 3 | 4 | void try_request_canboot(void); 5 | 6 | #endif // armcm_reset.h 7 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | # Main code build rules 2 | 3 | src-y += sched.c bootentry.c command.c flashcmd.c initial_pins.c 4 | src-$(CONFIG_ENABLE_LED) += led.c 5 | 6 | deployer-y += deployer.c 7 | -------------------------------------------------------------------------------- /src/generic/armcm_timer.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_ARMCM_TIMER_H 2 | #define __GENERIC_ARMCM_TIMER_H 3 | 4 | #include // uint32_t 5 | 6 | void udelay(uint32_t usecs); 7 | 8 | #endif // armcm_timer.h 9 | -------------------------------------------------------------------------------- /src/stm32/flash.h: -------------------------------------------------------------------------------- 1 | #ifndef __STM32_FLASH_H 2 | #define __STM32_FLASH_H 3 | 4 | #include 5 | 6 | int flash_write_block(uint32_t block_address, uint32_t *data); 7 | int flash_complete(void); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/lpc176x/flash.h: -------------------------------------------------------------------------------- 1 | #ifndef __LPC176X_FLASH_H 2 | #define __LPC176X_FLASH_H 3 | 4 | #include 5 | 6 | int flash_write_block(uint32_t block_address, uint32_t *data); 7 | int flash_complete(void); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/lpc176x/usb_cdc_ep.h: -------------------------------------------------------------------------------- 1 | #ifndef __LPC176X_USB_CDC_EP_H 2 | #define __LPC176X_USB_CDC_EP_H 3 | 4 | enum { 5 | USB_CDC_EP_ACM = 1, 6 | USB_CDC_EP_BULK_OUT = 2, 7 | USB_CDC_EP_BULK_IN = 5, 8 | }; 9 | 10 | #endif // usb_cdc_ep.h 11 | -------------------------------------------------------------------------------- /src/generic/usb_cdc_ep.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_USB_CDC_EP_H 2 | #define __GENERIC_USB_CDC_EP_H 3 | 4 | // Default USB endpoint ids 5 | enum { 6 | USB_CDC_EP_BULK_IN = 1, 7 | USB_CDC_EP_BULK_OUT = 2, 8 | USB_CDC_EP_ACM = 3, 9 | }; 10 | 11 | #endif // usb_cdc_ep.h 12 | -------------------------------------------------------------------------------- /src/generic/irq.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_IRQ_H 2 | #define __GENERIC_IRQ_H 3 | 4 | typedef unsigned long irqstatus_t; 5 | 6 | void irq_disable(void); 7 | void irq_enable(void); 8 | irqstatus_t irq_save(void); 9 | void irq_restore(irqstatus_t flag); 10 | void irq_wait(void); 11 | void irq_poll(void); 12 | 13 | #endif // irq.h 14 | -------------------------------------------------------------------------------- /src/rp2040/flash.h: -------------------------------------------------------------------------------- 1 | // Flash (IAP) functionality for RP2040 2 | // This file may be distributed under the terms of the GNU GPLv3 license. 3 | #ifndef __RP2040_FLASH_H 4 | #define __RP2040_FLASH_H 5 | 6 | #include 7 | 8 | int flash_write_block(uint32_t block_address, uint32_t *data); 9 | int flash_complete(void); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/deployer.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEPLOYER_H 2 | #define __DEPLOYER_H 3 | 4 | #include // uint8_t 5 | 6 | int deployer_is_active(void); 7 | 8 | // Code in out/canboot_payload.c generated by scripts/buildbinary.py 9 | extern const uint8_t deployer_canboot_binary[]; 10 | extern const uint32_t deployer_canboot_binary_size; 11 | 12 | #endif // deployer.h 13 | -------------------------------------------------------------------------------- /scripts/make-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Detect the version of Katapult 3 | 4 | a="/$0"; a="${a%/*}"; a="${a:-.}"; a="${a##/}/"; SRCDIR=$(cd "$a/.."; pwd) 5 | 6 | if [ -e "${SRCDIR}/.git" ]; then 7 | git describe --tags --long --always --dirty 8 | elif [ -f "${SRCDIR}/.version" ]; then 9 | cat "${SRCDIR}/.version" 10 | else 11 | echo "?" 12 | fi 13 | -------------------------------------------------------------------------------- /src/generic/serial_irq.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_SERIAL_IRQ_H 2 | #define __GENERIC_SERIAL_IRQ_H 3 | 4 | #include // uint32_t 5 | 6 | // callback provided by board specific code 7 | void serial_enable_tx_irq(void); 8 | 9 | // serial_irq.c 10 | void serial_rx_byte(uint_fast8_t data); 11 | int serial_get_tx_byte(uint8_t *pdata); 12 | 13 | #endif // serial_irq.h 14 | -------------------------------------------------------------------------------- /lib/rp2040/boot_stage2/boot_stage2.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | /* We are loaded to the top 256 bytes of SRAM, which is above the bootrom 3 | stack. Note 4 bytes occupied by checksum. */ 4 | SRAM(rx) : ORIGIN = 0x20041f00, LENGTH = 252 5 | } 6 | 7 | SECTIONS { 8 | . = ORIGIN(SRAM); 9 | .text : { 10 | *(.entry) 11 | *(.text) 12 | } >SRAM 13 | } 14 | -------------------------------------------------------------------------------- /src/initial_pins.h: -------------------------------------------------------------------------------- 1 | #ifndef __INITIAl_PINS_H 2 | #define __INITIAl_PINS_H 3 | 4 | struct initial_pin_s { 5 | int pin; 6 | uint8_t flags; 7 | }; 8 | 9 | enum { IP_OUT_HIGH = 1 }; 10 | 11 | // out/compile_time_request.c (auto generated file) 12 | extern const struct initial_pin_s initial_pins[]; 13 | extern const int initial_pins_size; 14 | 15 | #endif // initial_pins.h 16 | -------------------------------------------------------------------------------- /src/rp2040/internal.h: -------------------------------------------------------------------------------- 1 | #ifndef __RP2040_INTERNAL_H 2 | #define __RP2040_INTERNAL_H 3 | // Local definitions for rp2040 4 | 5 | #include "RP2040.h" 6 | 7 | void enable_pclock(uint32_t reset_bit); 8 | int is_enabled_pclock(uint32_t reset_bit); 9 | uint32_t get_pclock_frequency(uint32_t reset_bit); 10 | void gpio_peripheral(uint32_t gpio, int func, int pull_up); 11 | 12 | #endif // internal.h 13 | -------------------------------------------------------------------------------- /src/generic/canserial.h: -------------------------------------------------------------------------------- 1 | #ifndef __CANSERIAL_H__ 2 | #define __CANSERIAL_H__ 3 | 4 | #include // uint32_t 5 | 6 | #define CANBUS_ID_ADMIN 0x3f0 7 | #define CANBUS_ID_ADMIN_RESP 0x3f1 8 | 9 | // canserial.c 10 | void canserial_notify_tx(void); 11 | struct canbus_msg; 12 | int canserial_process_data(struct canbus_msg *msg); 13 | void canserial_set_uuid(uint8_t *raw_uuid, uint32_t raw_uuid_len); 14 | 15 | #endif // canserial.h 16 | -------------------------------------------------------------------------------- /src/generic/pgm.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_PGM_H 2 | #define __GENERIC_PGM_H 3 | // This header provides wrappers for the AVR specific "PROGMEM" 4 | // declarations on non-avr platforms. 5 | 6 | #define NEED_PROGMEM 0 7 | #define PROGMEM 8 | #define PSTR(S) S 9 | #define READP(VAR) VAR 10 | #define vsnprintf_P(D, S, F, A) vsnprintf(D, S, F, A) 11 | #define strcasecmp_P(S1, S2) strcasecmp(S1, S2) 12 | #define memcpy_P(DST, SRC, SIZE) memcpy((DST), (SRC), (SIZE)) 13 | 14 | #endif // pgm.h 15 | -------------------------------------------------------------------------------- /src/stm32/dfu_reboot.c: -------------------------------------------------------------------------------- 1 | // Reboot into stm32 ROM dfu bootloader 2 | // 3 | // Copyright (C) 2019-2022 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "internal.h" // NVIC_SystemReset 8 | 9 | // Flag that bootloader is desired and reboot 10 | void 11 | dfu_reboot(void) 12 | { 13 | } 14 | 15 | // Check if rebooting into system DFU Bootloader 16 | void 17 | dfu_reboot_check(void) 18 | { 19 | } 20 | -------------------------------------------------------------------------------- /lib/rp2040_flash/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-c -Wall -ggdb 3 | LDFALGS= 4 | SOURCES=main.c picoboot_connection.c 5 | OBJECTS=$(SOURCES:.c=.o) 6 | LIBS=`pkg-config libusb-1.0 --libs` 7 | INCLUDE_DIRS+=-I../rp2040/ `pkg-config libusb-1.0 --cflags` 8 | 9 | EXECUTABLE=rp2040_flash 10 | 11 | all: $(EXECUTABLE) 12 | 13 | $(EXECUTABLE): $(OBJECTS) 14 | $(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ 15 | 16 | .c.o: 17 | $(CC) $(CFLAGS) $(INCLUDE_DIRS) $< -o $@ 18 | 19 | clean: 20 | rm -f $(OBJECTS) $(EXECUTABLE) 21 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/padsbank0.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_PADSBANK0_H 8 | #define _HARDWARE_STRUCTS_PADSBANK0_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/pads_bank0.h" 13 | 14 | typedef struct { 15 | io_rw_32 voltage_select; 16 | io_rw_32 io[30]; 17 | } padsbank0_hw_t; 18 | 19 | #define padsbank0_hw ((padsbank0_hw_t *)PADS_BANK0_BASE) 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/psm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_PSM_H 8 | #define _HARDWARE_STRUCTS_PSM_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/psm.h" 13 | 14 | typedef struct { 15 | io_rw_32 frce_on; 16 | io_rw_32 frce_off; 17 | io_rw_32 wdsel; 18 | io_rw_32 done; 19 | } psm_hw_t; 20 | 21 | #define psm_hw ((psm_hw_t *const)PSM_BASE) 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/mpu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_MPU_H 8 | #define _HARDWARE_STRUCTS_MPU_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/regs/m0plus.h" 12 | 13 | typedef struct { 14 | io_ro_32 type; 15 | io_rw_32 ctrl; 16 | io_rw_32 rnr; 17 | io_rw_32 rbar; 18 | io_rw_32 rasr; 19 | } mpu_hw_t; 20 | 21 | #define mpu_hw ((mpu_hw_t *const)(PPB_BASE + M0PLUS_MPU_TYPE_OFFSET)) 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/pads_qspi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_PADS_QSPI_H 8 | #define _HARDWARE_STRUCTS_PADS_QSPI_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/pads_qspi.h" 13 | 14 | typedef struct { 15 | io_rw_32 voltage_select; 16 | io_rw_32 io[6]; 17 | } pads_qspi_hw_t; 18 | 19 | #define pads_qspi_hw ((pads_qspi_hw_t *const)PADS_QSPI_BASE) 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/resets.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | #ifndef _HARDWARE_STRUCTS_RESETS_H 7 | #define _HARDWARE_STRUCTS_RESETS_H 8 | 9 | #include "hardware/address_mapped.h" 10 | #include "hardware/regs/resets.h" 11 | 12 | /// \tag::resets_hw[] 13 | typedef struct { 14 | io_rw_32 reset; 15 | io_rw_32 wdsel; 16 | io_rw_32 reset_done; 17 | } resets_hw_t; 18 | 19 | #define resets_hw ((resets_hw_t *const)RESETS_BASE) 20 | /// \end::resets_hw[] 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/systick.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_SYSTICK_H 8 | #define _HARDWARE_STRUCTS_SYSTICK_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/regs/m0plus.h" 12 | 13 | typedef struct { 14 | io_rw_32 csr; 15 | io_rw_32 rvr; 16 | io_rw_32 cvr; 17 | io_ro_32 calib; 18 | } systick_hw_t; 19 | 20 | #define systick_hw ((systick_hw_t *const)(PPB_BASE + M0PLUS_SYST_CSR_OFFSET)) 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /scripts/check-gcc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This script checks for a broken Ubuntu 18.04 arm-none-eabi-gcc compile 3 | 4 | f1="$1" 5 | f2="$2" 6 | 7 | s1=`readelf -A "$f1" | grep "Tag_ARM_ISA_use"` 8 | s2=`readelf -A "$f2" | grep "Tag_ARM_ISA_use"` 9 | 10 | if [ "$s1" != "$s2" ]; then 11 | echo "" 12 | echo "ERROR: The compiler failed to correctly compile Klipper" 13 | echo "It will be necessary to upgrade the compiler" 14 | echo "See: https://bugs.launchpad.net/ubuntu/+source/newlib/+bug/1767223" 15 | echo "" 16 | rm -f "$f1" 17 | exit 99 18 | fi 19 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/ioqspi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_IOQSPI_H 8 | #define _HARDWARE_STRUCTS_IOQSPI_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/io_qspi.h" 13 | 14 | typedef struct { 15 | struct { 16 | io_rw_32 status; 17 | io_rw_32 ctrl; 18 | } io[6]; 19 | } ioqspi_hw_t; 20 | 21 | #define ioqspi_hw ((ioqspi_hw_t *const)IO_QSPI_BASE) 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/canboot.h: -------------------------------------------------------------------------------- 1 | #ifndef __CANBOOT_H 2 | #define __CANBOOT_H 3 | 4 | #include // uint32_t 5 | 6 | #define CANBOOT_SIGNATURE 0x21746f6f426e6143 // CanBoot! 7 | #define REQUEST_CANBOOT 0x5984E3FA6CA1589B 8 | #define REQUEST_START_APP 0x7b06ec45a9a8243d 9 | 10 | uint64_t get_bootup_code(void); 11 | void set_bootup_code(uint64_t code); 12 | void application_read_flash(uint32_t address, uint32_t *dest); 13 | int application_check_valid(void); 14 | void application_jump(void); 15 | 16 | void udelay(uint32_t usecs); 17 | void timer_setup(void); 18 | 19 | #endif // canboot.h 20 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/scb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | #ifndef _HARDWARE_STRUCTS_SCB_H 7 | #define _HARDWARE_STRUCTS_SCB_H 8 | 9 | #include "hardware/address_mapped.h" 10 | #include "hardware/regs/m0plus.h" 11 | 12 | // SCB == System Control Block 13 | typedef struct { 14 | io_ro_32 cpuid; 15 | io_rw_32 icsr; 16 | io_rw_32 vtor; 17 | io_rw_32 aircr; 18 | io_rw_32 scr; 19 | // ... 20 | } armv6m_scb_t; 21 | 22 | #define scb_hw ((armv6m_scb_t *const)(PPB_BASE + M0PLUS_CPUID_OFFSET)) 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/pll.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_PLL_H 8 | #define _HARDWARE_STRUCTS_PLL_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/regs/pll.h" 12 | 13 | /// \tag::pll_hw[] 14 | typedef struct { 15 | io_rw_32 cs; 16 | io_rw_32 pwr; 17 | io_rw_32 fbdiv_int; 18 | io_rw_32 prim; 19 | } pll_hw_t; 20 | 21 | #define pll_sys_hw ((pll_hw_t *const)PLL_SYS_BASE) 22 | #define pll_usb_hw ((pll_hw_t *const)PLL_USB_BASE) 23 | /// \end::pll_hw[] 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/watchdog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_WATCHDOG_H 8 | #define _HARDWARE_STRUCTS_WATCHDOG_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/watchdog.h" 13 | 14 | typedef struct { 15 | io_rw_32 ctrl; 16 | io_wo_32 load; 17 | io_ro_32 reason; 18 | io_rw_32 scratch[8]; 19 | io_rw_32 tick; 20 | } watchdog_hw_t; 21 | 22 | #define watchdog_hw ((watchdog_hw_t *const)WATCHDOG_BASE) 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/generic/alloc.c: -------------------------------------------------------------------------------- 1 | // Generic implementation of dynamic memory pool 2 | // 3 | // Copyright (C) 2016,2017 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "misc.h" // dynmem_start 8 | 9 | static char dynmem_pool[20 * 1024]; 10 | 11 | // Return the start of memory available for dynamic allocations 12 | void * 13 | dynmem_start(void) 14 | { 15 | return dynmem_pool; 16 | } 17 | 18 | // Return the end of memory available for dynamic allocations 19 | void * 20 | dynmem_end(void) 21 | { 22 | return &dynmem_pool[sizeof(dynmem_pool)]; 23 | } 24 | -------------------------------------------------------------------------------- /src/generic/misc.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_MISC_H 2 | #define __GENERIC_MISC_H 3 | 4 | #include // va_list 5 | #include // uint8_t 6 | 7 | struct command_encoder; 8 | void console_sendf(const struct command_encoder *ce, va_list args); 9 | void *console_receive_buffer(void); 10 | 11 | uint32_t timer_from_us(uint32_t us); 12 | uint8_t timer_is_before(uint32_t time1, uint32_t time2); 13 | uint32_t timer_read_time(void); 14 | void timer_kick(void); 15 | 16 | void *dynmem_start(void); 17 | void *dynmem_end(void); 18 | 19 | uint16_t crc16_ccitt(uint8_t *buf, uint_fast8_t len); 20 | 21 | void bootloader_request(void); 22 | 23 | #endif // misc.h 24 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/vreg_and_chip_reset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_VREG_AND_CHIP_RESET_H 8 | #define _HARDWARE_STRUCTS_VREG_AND_CHIP_RESET_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/vreg_and_chip_reset.h" 13 | 14 | typedef struct { 15 | io_rw_32 vreg; 16 | io_rw_32 bod; 17 | io_rw_32 chip_reset; 18 | } vreg_and_chip_reset_hw_t; 19 | 20 | #define vreg_and_chip_reset_hw ((vreg_and_chip_reset_hw_t *const)VREG_AND_CHIP_RESET_BASE) 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/xosc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_XOSC_H 8 | #define _HARDWARE_STRUCTS_XOSC_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/xosc.h" 13 | 14 | /// \tag::xosc_hw[] 15 | typedef struct { 16 | io_rw_32 ctrl; 17 | io_rw_32 status; 18 | io_rw_32 dormant; 19 | io_rw_32 startup; 20 | io_rw_32 _reserved[3]; 21 | io_rw_32 count; 22 | } xosc_hw_t; 23 | 24 | #define xosc_hw ((xosc_hw_t *const)XOSC_BASE) 25 | /// \end::xosc_hw[] 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/adc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | #ifndef _HARDWARE_STRUCTS_ADC_H 7 | #define _HARDWARE_STRUCTS_ADC_H 8 | 9 | #include "hardware/address_mapped.h" 10 | #include "hardware/regs/adc.h" 11 | 12 | typedef struct { 13 | io_rw_32 cs; 14 | io_rw_32 result; 15 | io_rw_32 fcs; 16 | io_rw_32 fifo; 17 | io_rw_32 div; 18 | io_rw_32 intr; 19 | io_rw_32 inte; 20 | io_rw_32 intf; 21 | io_rw_32 ints; 22 | } adc_hw_t; 23 | 24 | check_hw_layout(adc_hw_t, ints, ADC_INTS_OFFSET); 25 | 26 | #define adc_hw ((adc_hw_t *const)ADC_BASE) 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /lib/rp2040/boot_stage2/asminclude/boot2_helpers/wait_ssi_ready.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _BOOT2_HELPER_WAIT_SSI_READY 8 | #define _BOOT2_HELPER_WAIT_SSI_READY 9 | 10 | wait_ssi_ready: 11 | push {r0, r1, lr} 12 | 13 | // Command is complete when there is nothing left to send 14 | // (TX FIFO empty) and SSI is no longer busy (CSn deasserted) 15 | 1: 16 | ldr r1, [r3, #SSI_SR_OFFSET] 17 | movs r0, #SSI_SR_TFE_BITS 18 | tst r1, r0 19 | beq 1b 20 | movs r0, #SSI_SR_BUSY_BITS 21 | tst r1, r0 22 | bne 1b 23 | 24 | pop {r0, r1, pc} 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_SPI_H 8 | #define _HARDWARE_STRUCTS_SPI_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/regs/spi.h" 12 | 13 | typedef struct { 14 | io_rw_32 cr0; 15 | io_rw_32 cr1; 16 | io_rw_32 dr; 17 | io_rw_32 sr; 18 | io_rw_32 cpsr; 19 | io_rw_32 imsc; 20 | io_rw_32 ris; 21 | io_rw_32 mis; 22 | io_rw_32 icr; 23 | io_rw_32 dmacr; 24 | } spi_hw_t; 25 | 26 | #define spi0_hw ((spi_hw_t *const)SPI0_BASE) 27 | #define spi1_hw ((spi_hw_t *const)SPI1_BASE) 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/generic/crc16_ccitt.c: -------------------------------------------------------------------------------- 1 | // Code for crc16_ccitt 2 | // 3 | // Copyright (C) 2016 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "misc.h" // crc16_ccitt 8 | 9 | // Implement the standard crc "ccitt" algorithm on the given buffer 10 | uint16_t 11 | crc16_ccitt(uint8_t *buf, uint_fast8_t len) 12 | { 13 | uint16_t crc = 0xffff; 14 | while (len--) { 15 | uint8_t data = *buf++; 16 | data ^= crc & 0xff; 17 | data ^= data << 4; 18 | crc = ((((uint16_t)data << 8) | (crc >> 8)) ^ (uint8_t)(data >> 4) 19 | ^ ((uint16_t)data << 3)); 20 | } 21 | return crc; 22 | } 23 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/rosc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_ROSC_H 8 | #define _HARDWARE_STRUCTS_ROSC_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/rosc.h" 13 | 14 | typedef struct { 15 | io_rw_32 ctrl; 16 | io_rw_32 freqa; 17 | io_rw_32 freqb; 18 | io_rw_32 dormant; 19 | io_rw_32 div; 20 | io_rw_32 phase; 21 | io_rw_32 status; 22 | io_rw_32 randombit; 23 | io_rw_32 count; 24 | io_rw_32 dftx; 25 | } rosc_hw_t; 26 | 27 | #define rosc_hw ((rosc_hw_t *const)ROSC_BASE) 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/syscfg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_SYSCFG_H 8 | #define _HARDWARE_STRUCTS_SYSCFG_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/syscfg.h" 13 | 14 | typedef struct { 15 | io_rw_32 proc0_nmi_mask; 16 | io_rw_32 proc1_nmi_mask; 17 | io_rw_32 proc_config; 18 | io_rw_32 proc_in_sync_bypass; 19 | io_rw_32 proc_in_sync_bypass_hi; 20 | io_rw_32 dbgforce; 21 | io_rw_32 mempowerdown; 22 | } syscfg_hw_t; 23 | 24 | #define syscfg_hw ((syscfg_hw_t *const)SYSCFG_BASE) 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | .config 55 | .config.old 56 | *.pyc 57 | out/ -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/rtc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_RTC_H 8 | #define _HARDWARE_STRUCTS_RTC_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/rtc.h" 13 | 14 | typedef struct { 15 | io_rw_32 clkdiv_m1; 16 | io_rw_32 setup_0; 17 | io_rw_32 setup_1; 18 | io_rw_32 ctrl; 19 | io_rw_32 irq_setup_0; 20 | io_rw_32 irq_setup_1; 21 | io_rw_32 rtc_1; 22 | io_rw_32 rtc_0; 23 | io_rw_32 intr; 24 | io_rw_32 inte; 25 | io_rw_32 intf; 26 | io_rw_32 ints; 27 | } rtc_hw_t; 28 | 29 | #define rtc_hw ((rtc_hw_t *const)RTC_BASE) 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /lib/kconfiglib/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2019, Ulf Magnusson 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 6 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/interp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_INTERP_H 8 | #define _HARDWARE_STRUCTS_INTERP_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/sio.h" 13 | 14 | typedef struct { 15 | io_rw_32 accum[2]; 16 | io_rw_32 base[3]; 17 | io_ro_32 pop[3]; 18 | io_ro_32 peek[3]; 19 | io_rw_32 ctrl[2]; 20 | io_rw_32 add_raw[2]; 21 | io_wo_32 base01; 22 | } interp_hw_t; 23 | 24 | #define interp_hw_array ((interp_hw_t *)(SIO_BASE + SIO_INTERP0_ACCUM0_OFFSET)) 25 | #define interp0_hw (&interp_hw_array[0]) 26 | #define interp1_hw (&interp_hw_array[1]) 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/xip_ctrl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | #ifndef _HARDWARE_STRUCTS_XIP_CTRL_H 7 | #define _HARDWARE_STRUCTS_XIP_CTRL_H 8 | 9 | #include "hardware/address_mapped.h" 10 | #include "hardware/regs/xip.h" 11 | 12 | typedef struct { 13 | io_rw_32 ctrl; 14 | io_rw_32 flush; 15 | io_rw_32 stat; 16 | io_rw_32 ctr_hit; 17 | io_rw_32 ctr_acc; 18 | io_rw_32 stream_addr; 19 | io_rw_32 stream_ctr; 20 | io_rw_32 stream_fifo; 21 | } xip_ctrl_hw_t; 22 | 23 | #define XIP_STAT_FIFO_FULL 0x4u 24 | #define XIP_STAT_FIFO_EMPTY 0x2u 25 | #define XIP_STAT_FLUSH_RDY 0x1u 26 | 27 | #define xip_ctrl_hw ((xip_ctrl_hw_t *const)XIP_CTRL_BASE) 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/generic/canbus.h: -------------------------------------------------------------------------------- 1 | #ifndef __CANBUS_H__ 2 | #define __CANBUS_H__ 3 | 4 | #include // uint32_t 5 | 6 | struct canbus_msg { 7 | uint32_t id; 8 | uint32_t dlc; 9 | union { 10 | uint8_t data[8]; 11 | uint32_t data32[2]; 12 | }; 13 | }; 14 | 15 | #define CANMSG_ID_RTR (1<<30) 16 | #define CANMSG_ID_EFF (1<<31) 17 | 18 | #define CANMSG_DATA_LEN(msg) ((msg)->dlc > 8 ? 8 : (msg)->dlc) 19 | 20 | // callbacks provided by board specific code 21 | int canhw_send(struct canbus_msg *msg); 22 | void canhw_set_filter(uint32_t id); 23 | 24 | // canbus.c 25 | int canbus_send(struct canbus_msg *msg); 26 | void canbus_set_filter(uint32_t id); 27 | void canbus_notify_tx(void); 28 | void canbus_process_data(struct canbus_msg *msg); 29 | 30 | #endif // canbus.h 31 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/pwm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_PWM_H 8 | #define _HARDWARE_STRUCTS_PWM_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/pwm.h" 13 | 14 | typedef struct pwm_slice_hw { 15 | io_rw_32 csr; 16 | io_rw_32 div; 17 | io_rw_32 ctr; 18 | io_rw_32 cc; 19 | io_rw_32 top; 20 | } pwm_slice_hw_t; 21 | 22 | typedef struct { 23 | pwm_slice_hw_t slice[NUM_PWM_SLICES]; 24 | io_rw_32 en; 25 | io_rw_32 intr; 26 | io_rw_32 inte; 27 | io_rw_32 intf; 28 | io_rw_32 ints; 29 | } pwm_hw_t; 30 | 31 | #define pwm_hw ((pwm_hw_t *const)PWM_BASE) 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/lpc176x/internal.h: -------------------------------------------------------------------------------- 1 | #ifndef __LPC176X_INTERNAL_H 2 | #define __LPC176X_INTERNAL_H 3 | // Local definitions for lpc176x code 4 | 5 | #include "LPC17xx.h" 6 | 7 | #define GPIO(PORT, NUM) ((PORT) * 32 + (NUM)) 8 | #define GPIO2PORT(PIN) ((PIN) / 32) 9 | #define GPIO2BIT(PIN) (1<<((PIN) % 32)) 10 | 11 | #define PCLK_TIMER0 1 12 | #define PCLK_UART0 3 13 | #define PCLK_PWM1 6 14 | #define PCLK_I2C0 7 15 | #define PCLK_SSP1 10 16 | #define PCLK_ADC 12 17 | #define PCLK_I2C1 19 18 | #define PCLK_SSP0 21 19 | #define PCLK_UART3 25 20 | #define PCLK_I2C2 26 21 | #define PCLK_USB 31 22 | int is_enabled_pclock(uint32_t pclk); 23 | void enable_pclock(uint32_t pclk); 24 | uint32_t get_pclock_frequency(uint32_t pclk); 25 | void gpio_peripheral(uint32_t gpio, int func, int pullup); 26 | void usb_disconnect(void); 27 | 28 | #endif // internal.h 29 | -------------------------------------------------------------------------------- /lib/rp2040/boot_stage2/asminclude/boot2_helpers/read_flash_sreg.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _BOOT2_HELPER_READ_FLASH_SREG 8 | #define _BOOT2_HELPER_READ_FLASH_SREG 9 | 10 | #include "boot2_helpers/wait_ssi_ready.S" 11 | 12 | // Pass status read cmd into r0. 13 | // Returns status value in r0. 14 | .global read_flash_sreg 15 | .type read_flash_sreg,%function 16 | .thumb_func 17 | read_flash_sreg: 18 | push {r1, lr} 19 | str r0, [r3, #SSI_DR0_OFFSET] 20 | // Dummy byte: 21 | str r0, [r3, #SSI_DR0_OFFSET] 22 | 23 | bl wait_ssi_ready 24 | // Discard first byte and combine the next two 25 | ldr r0, [r3, #SSI_DR0_OFFSET] 26 | ldr r0, [r3, #SSI_DR0_OFFSET] 27 | 28 | pop {r1, pc} 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /lib/rp2040/boot_stage2/asminclude/boot2_helpers/exit_from_boot2.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _BOOT2_HELPER_EXIT_FROM_BOOT2 8 | #define _BOOT2_HELPER_EXIT_FROM_BOOT2 9 | 10 | #include "hardware/regs/m0plus.h" 11 | 12 | // If entered from the bootrom, lr (which we earlier pushed) will be 0, 13 | // and we vector through the table at the start of the main flash image. 14 | // Any regular function call will have a nonzero value for lr. 15 | check_return: 16 | pop {r0} 17 | cmp r0, #0 18 | beq vector_into_flash 19 | bx r0 20 | vector_into_flash: 21 | ldr r0, =(XIP_BASE + 0x100) 22 | ldr r1, =(PPB_BASE + M0PLUS_VTOR_OFFSET) 23 | str r0, [r1] 24 | ldmia r0, {r0, r1} 25 | msr msp, r0 26 | bx r1 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/generic/armcm_boot.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_ARMCM_BOOT_H 2 | #define __GENERIC_ARMCM_BOOT_H 3 | 4 | #include "ctr.h" // DECL_CTR_INT 5 | 6 | void armcm_main(void); 7 | 8 | // Declare an IRQ handler 9 | #define DECL_ARMCM_IRQ(FUNC, NUM) \ 10 | DECL_CTR_INT("DECL_ARMCM_IRQ " __stringify(FUNC), 1, CTR_INT(NUM)) 11 | 12 | // Statically declare an IRQ handler and run-time enable it 13 | #define armcm_enable_irq(FUNC, NUM, PRIORITY) do { \ 14 | DECL_ARMCM_IRQ(FUNC, (NUM)); \ 15 | NVIC_SetPriority((NUM), (PRIORITY)); \ 16 | NVIC_EnableIRQ((NUM)); \ 17 | } while (0) 18 | 19 | // Vectors created by scripts/buildcommands.py from DECL_ARMCM_IRQ commands 20 | extern const void * const VectorTable[]; 21 | 22 | #endif // armcm_boot.h 23 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/uart.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_UART_H 8 | #define _HARDWARE_STRUCTS_UART_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/regs/uart.h" 12 | 13 | typedef struct { 14 | io_rw_32 dr; 15 | io_rw_32 rsr; 16 | uint32_t _pad0[4]; 17 | io_rw_32 fr; 18 | uint32_t _pad1; 19 | io_rw_32 ilpr; 20 | io_rw_32 ibrd; 21 | io_rw_32 fbrd; 22 | io_rw_32 lcr_h; 23 | io_rw_32 cr; 24 | io_rw_32 ifls; 25 | io_rw_32 imsc; 26 | io_rw_32 ris; 27 | io_rw_32 mis; 28 | io_rw_32 icr; 29 | io_rw_32 dmacr; 30 | } uart_hw_t; 31 | 32 | #define uart0_hw ((uart_hw_t *const)UART0_BASE) 33 | #define uart1_hw ((uart_hw_t *const)UART1_BASE) 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_TIMER_H 8 | #define _HARDWARE_STRUCTS_TIMER_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/timer.h" 13 | 14 | #define NUM_TIMERS 4 15 | 16 | typedef struct { 17 | io_wo_32 timehw; 18 | io_wo_32 timelw; 19 | io_ro_32 timehr; 20 | io_ro_32 timelr; 21 | io_rw_32 alarm[NUM_TIMERS]; 22 | io_rw_32 armed; 23 | io_ro_32 timerawh; 24 | io_ro_32 timerawl; 25 | io_rw_32 dbgpause; 26 | io_rw_32 pause; 27 | io_rw_32 intr; 28 | io_rw_32 inte; 29 | io_rw_32 intf; 30 | io_ro_32 ints; 31 | } timer_hw_t; 32 | 33 | #define timer_hw ((timer_hw_t *const)TIMER_BASE) 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/generic/canbus.c: -------------------------------------------------------------------------------- 1 | // Wrapper functions connecting canserial.c to low-level can hardware 2 | // 3 | // Copyright (C) 2022 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "autoconf.h" // CONFIG_CANBUS_FREQUENCY 8 | #include "canbus.h" // canhw_send 9 | #include "canserial.h" // canserial_notify_tx 10 | #include "command.h" // DECL_CONSTANT 11 | 12 | DECL_CONSTANT("CANBUS_FREQUENCY", CONFIG_CANBUS_FREQUENCY); 13 | 14 | int 15 | canbus_send(struct canbus_msg *msg) 16 | { 17 | return canhw_send(msg); 18 | } 19 | 20 | void 21 | canbus_set_filter(uint32_t id) 22 | { 23 | canhw_set_filter(id); 24 | } 25 | 26 | void 27 | canbus_notify_tx(void) 28 | { 29 | canserial_notify_tx(); 30 | } 31 | 32 | void 33 | canbus_process_data(struct canbus_msg *msg) 34 | { 35 | canserial_process_data(msg); 36 | } 37 | -------------------------------------------------------------------------------- /lib/kconfiglib/olddefconfig.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018-2019, Ulf Magnusson 4 | # SPDX-License-Identifier: ISC 5 | 6 | """ 7 | Updates an old .config file or creates a new one, by filling in default values 8 | for all new symbols. This is the same as picking the default selection for all 9 | symbols in oldconfig, or entering the menuconfig interface and immediately 10 | saving. 11 | 12 | The default input/output filename is '.config'. A different filename can be 13 | passed in the KCONFIG_CONFIG environment variable. 14 | 15 | When overwriting a configuration file, the old version is saved to 16 | .old (e.g. .config.old). 17 | """ 18 | import kconfiglib 19 | 20 | 21 | def main(): 22 | kconf = kconfiglib.standard_kconfig(__doc__) 23 | print(kconf.load_config()) 24 | print(kconf.write_config()) 25 | 26 | 27 | if __name__ == "__main__": 28 | main() 29 | -------------------------------------------------------------------------------- /src/initial_pins.c: -------------------------------------------------------------------------------- 1 | // Support setting gpio pins at mcu start 2 | // 3 | // Copyright (C) 2019 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "autoconf.h" // CONFIG_INITIAL_PINS 8 | #include "board/gpio.h" // gpio_out_setup 9 | #include "board/pgm.h" // READP 10 | #include "ctr.h" // DECL_CTR 11 | #include "initial_pins.h" // initial_pins 12 | #include "sched.h" // DECL_INIT 13 | 14 | DECL_CTR("DECL_INITIAL_PINS " __stringify(CONFIG_INITIAL_PINS)); 15 | 16 | void 17 | initial_pins_setup(void) 18 | { 19 | if (sizeof(CONFIG_INITIAL_PINS) <= 1) 20 | return; 21 | int i; 22 | for (i=0; ipin), READP(ip->flags) & IP_OUT_HIGH); 25 | } 26 | } 27 | DECL_INIT(initial_pins_setup); 28 | -------------------------------------------------------------------------------- /src/generic/armcm_reset.c: -------------------------------------------------------------------------------- 1 | // Generic reset command handler for ARM Cortex-M boards 2 | // 3 | // Copyright (C) 2019 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "autoconf.h" // CONFIG_FLASH_BOOT_ADDRESS 8 | #include "armcm_reset.h" // try_request_canboot 9 | #include "board/internal.h" // NVIC_SystemReset 10 | #include "board/irq.h" // irq_disable 11 | #include "board/misc.h" // try_request_canboot 12 | #include "canboot.h" // REQUEST_CANBOOT 13 | 14 | void 15 | try_request_canboot(void) 16 | { 17 | uint32_t *bl_vectors = (uint32_t *)(CONFIG_FLASH_BOOT_ADDRESS); 18 | uint64_t *req_sig = (uint64_t *)bl_vectors[0]; 19 | irq_disable(); 20 | *req_sig = REQUEST_CANBOOT; 21 | #if __CORTEX_M >= 7 22 | SCB_CleanDCache_by_Addr((void*)req_sig, sizeof(*req_sig)); 23 | #endif 24 | NVIC_SystemReset(); 25 | } 26 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/iobank0.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_IOBANK0_H 8 | #define _HARDWARE_STRUCTS_IOBANK0_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/io_bank0.h" 13 | 14 | typedef struct { 15 | io_rw_32 inte[4]; 16 | io_rw_32 intf[4]; 17 | io_rw_32 ints[4]; 18 | } io_irq_ctrl_hw_t; 19 | 20 | /// \tag::iobank0_hw[] 21 | typedef struct { 22 | struct { 23 | io_rw_32 status; 24 | io_rw_32 ctrl; 25 | } io[30]; 26 | io_rw_32 intr[4]; 27 | io_irq_ctrl_hw_t proc0_irq_ctrl; 28 | io_irq_ctrl_hw_t proc1_irq_ctrl; 29 | io_irq_ctrl_hw_t dormant_wake_irq_ctrl; 30 | } iobank0_hw_t; 31 | /// \end::iobank0_hw[] 32 | 33 | #define iobank0_hw ((iobank0_hw_t *const)IO_BANK0_BASE) 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/stm32/clockline.c: -------------------------------------------------------------------------------- 1 | // Code to enable clock lines on stm32 2 | // 3 | // Copyright (C) 2021 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "board/irq.h" // irq_save 8 | #include "internal.h" // struct cline 9 | 10 | // Enable a peripheral clock 11 | void 12 | enable_pclock(uint32_t periph_base) 13 | { 14 | struct cline cl = lookup_clock_line(periph_base); 15 | irqstatus_t flag = irq_save(); 16 | *cl.en |= cl.bit; 17 | *cl.en; // Pause 2 cycles to ensure peripheral is enabled 18 | if (cl.rst) { 19 | // Reset peripheral 20 | *cl.rst = cl.bit; 21 | *cl.rst = 0; 22 | } 23 | irq_restore(flag); 24 | } 25 | 26 | // Check if a peripheral clock has been enabled 27 | int 28 | is_enabled_pclock(uint32_t periph_base) 29 | { 30 | struct cline cl = lookup_clock_line(periph_base); 31 | return *cl.en & cl.bit; 32 | } 33 | -------------------------------------------------------------------------------- /lib/rp2040/boot_stage2/compile_time_choice.S: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Second stage boot code 3 | // Copyright (c) 2019-2021 Raspberry Pi (Trading) Ltd. 4 | // SPDX-License-Identifier: BSD-3-Clause 5 | // ---------------------------------------------------------------------------- 6 | // 7 | // This implementation uses the PICO_BOOT_STAGE2_CHOOSE_ preprocessor defines to pick 8 | // amongst a menu of known boot stage 2 implementations, allowing the board 9 | // configuration header to be able to specify the boot stage 2 10 | 11 | #include "boot_stage2/config.h" 12 | 13 | #ifdef PICO_BUILD_BOOT_STAGE2_NAME 14 | // boot stage 2 is configured by cmake, so use the name specified there 15 | #error PICO_BUILD_BOOT_STAGE2_NAME should not be defined for compile_time_choice builds 16 | #else 17 | // boot stage 2 is selected by board config header, and PICO_BOOT_STAGE2_ASM is set in boot_stage2/config.h 18 | #include PICO_BOOT_STAGE2_ASM 19 | #endif 20 | -------------------------------------------------------------------------------- /src/generic/io.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_IO_H 2 | #define __GENERIC_IO_H 3 | 4 | #include // uint32_t 5 | #include "compiler.h" // barrier 6 | 7 | static inline void writel(void *addr, uint32_t val) { 8 | barrier(); 9 | *(volatile uint32_t *)addr = val; 10 | } 11 | static inline void writew(void *addr, uint16_t val) { 12 | barrier(); 13 | *(volatile uint16_t *)addr = val; 14 | } 15 | static inline void writeb(void *addr, uint8_t val) { 16 | barrier(); 17 | *(volatile uint8_t *)addr = val; 18 | } 19 | static inline uint32_t readl(const void *addr) { 20 | uint32_t val = *(volatile const uint32_t *)addr; 21 | barrier(); 22 | return val; 23 | } 24 | static inline uint16_t readw(const void *addr) { 25 | uint16_t val = *(volatile const uint16_t *)addr; 26 | barrier(); 27 | return val; 28 | } 29 | static inline uint8_t readb(const void *addr) { 30 | uint8_t val = *(volatile const uint8_t *)addr; 31 | barrier(); 32 | return val; 33 | } 34 | 35 | #endif // io.h 36 | -------------------------------------------------------------------------------- /src/sched.h: -------------------------------------------------------------------------------- 1 | #ifndef __SCHED_H 2 | #define __SCHED_H 3 | 4 | #include // uint32_t 5 | #include "ctr.h" // DECL_CTR 6 | 7 | // Declare an init function (called at firmware startup) 8 | #define DECL_INIT(FUNC) _DECL_CALLLIST(ctr_run_initfuncs, FUNC) 9 | // Declare a task function (called periodically during normal runtime) 10 | #define DECL_TASK(FUNC) _DECL_CALLLIST(ctr_run_taskfuncs, FUNC) 11 | // Declare a shutdown function (called on an emergency stop) 12 | #define DECL_SHUTDOWN(FUNC) _DECL_CALLLIST(ctr_run_shutdownfuncs, FUNC) 13 | 14 | // Task waking struct 15 | struct task_wake { 16 | uint8_t wake; 17 | }; 18 | 19 | // sched.c 20 | void sched_wake_tasks(void); 21 | void sched_wake_task(struct task_wake *w); 22 | uint8_t sched_check_wake(struct task_wake *w); 23 | void sched_main(void); 24 | 25 | // Compiler glue for DECL_X macros above. 26 | #define _DECL_CALLLIST(NAME, FUNC) \ 27 | DECL_CTR("_DECL_CALLLIST " __stringify(NAME) " " __stringify(FUNC)) 28 | 29 | #endif // sched.h 30 | -------------------------------------------------------------------------------- /src/stm32/chipid.c: -------------------------------------------------------------------------------- 1 | // Support for extracting the hardware chip id on stm32 2 | // 3 | // Copyright (C) 2019 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "generic/canserial.h" // canserial_set_uuid 8 | #include "generic/usb_cdc.h" // usb_fill_serial 9 | #include "generic/usbstd.h" // usb_string_descriptor 10 | #include "internal.h" // UID_BASE 11 | #include "sched.h" // DECL_INIT 12 | 13 | #define CHIP_UID_LEN 12 14 | 15 | static struct { 16 | struct usb_string_descriptor desc; 17 | uint16_t data[CHIP_UID_LEN * 2]; 18 | } cdc_chipid; 19 | 20 | struct usb_string_descriptor * 21 | usbserial_get_serialid(void) 22 | { 23 | return &cdc_chipid.desc; 24 | } 25 | 26 | void 27 | chipid_init(void) 28 | { 29 | if (CONFIG_USB_SERIAL_NUMBER_CHIPID) 30 | usb_fill_serial(&cdc_chipid.desc, ARRAY_SIZE(cdc_chipid.data) 31 | , (void*)UID_BASE); 32 | if (CONFIG_CANBUS) 33 | canserial_set_uuid((void*)UID_BASE, CHIP_UID_LEN); 34 | } 35 | DECL_INIT(chipid_init); 36 | -------------------------------------------------------------------------------- /src/generic/usb_cdc.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_USB_CDC_H 2 | #define __GENERIC_USB_CDC_H 3 | 4 | #include // uint_fast8_t 5 | 6 | // endpoint sizes 7 | enum { 8 | USB_CDC_EP0_SIZE = 16, 9 | USB_CDC_EP_ACM_SIZE = 8, 10 | USB_CDC_EP_BULK_OUT_SIZE = 64, 11 | USB_CDC_EP_BULK_IN_SIZE = 64, 12 | }; 13 | 14 | // callbacks provided by board specific code 15 | int_fast8_t usb_read_bulk_out(void *data, uint_fast8_t max_len); 16 | int_fast8_t usb_send_bulk_in(void *data, uint_fast8_t len); 17 | int_fast8_t usb_read_ep0(void *data, uint_fast8_t max_len); 18 | int_fast8_t usb_read_ep0_setup(void *data, uint_fast8_t max_len); 19 | int_fast8_t usb_send_ep0(const void *data, uint_fast8_t len); 20 | int_fast8_t usb_send_ep0_progmem(const void *data, uint_fast8_t len); 21 | void usb_stall_ep0(void); 22 | void usb_set_address(uint_fast8_t addr); 23 | void usb_set_configure(void); 24 | struct usb_string_descriptor *usbserial_get_serialid(void); 25 | 26 | // usb_cdc.c 27 | void usb_fill_serial(struct usb_string_descriptor *desc, int strlen, void *id); 28 | void usb_notify_bulk_in(void); 29 | void usb_notify_bulk_out(void); 30 | void usb_notify_ep0(void); 31 | 32 | #endif // usb_cdc.h 33 | -------------------------------------------------------------------------------- /src/lpc176x/Makefile: -------------------------------------------------------------------------------- 1 | # lpc176x build rules 2 | 3 | # Setup the toolchain 4 | CROSS_PREFIX=arm-none-eabi- 5 | 6 | dirs-y += src/lpc176x src/generic lib/lpc176x/device 7 | 8 | CFLAGS += -mthumb -mcpu=cortex-m3 -Ilib/lpc176x/device -Ilib/cmsis-core 9 | CFLAGS += -Wno-nonnull 10 | 11 | CFLAGS_katapult.elf += -nostdlib -lgcc -lc_nano 12 | CFLAGS_katapult.elf += -T $(OUT)src/generic/armcm_link.ld 13 | $(OUT)katapult.elf: $(OUT)src/generic/armcm_link.ld 14 | 15 | # Add source files 16 | mcu-y = lpc176x/main.c lpc176x/gpio.c lpc176x/flash.c 17 | mcu-y += generic/armcm_irq.c generic/armcm_timer.c generic/crc16_ccitt.c 18 | mcu-y += ../lib/lpc176x/device/system_LPC17xx.c 19 | 20 | src-y += generic/armcm_canboot.c $(mcu-y) 21 | src-$(CONFIG_USBSERIAL) += lpc176x/usbserial.c lpc176x/chipid.c 22 | src-$(CONFIG_USBSERIAL) += generic/usb_cdc.c 23 | src-$(CONFIG_SERIAL) += lpc176x/serial.c generic/serial_irq.c 24 | 25 | BUILDBINARY_FLAGS = -l 26 | 27 | # Deployer build 28 | deployer-y += generic/armcm_boot.c generic/armcm_reset.c $(mcu-y) 29 | CFLAGS_deployer.elf += -nostdlib -lgcc -lc_nano 30 | CFLAGS_deployer.elf += -T $(OUT)src/generic/armcm_deployer.ld 31 | $(OUT)deployer.elf: $(OUT)src/generic/armcm_deployer.ld 32 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/ssi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_SSI_H 8 | #define _HARDWARE_STRUCTS_SSI_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/ssi.h" 13 | 14 | typedef struct { 15 | io_rw_32 ctrlr0; 16 | io_rw_32 ctrlr1; 17 | io_rw_32 ssienr; 18 | io_rw_32 mwcr; 19 | io_rw_32 ser; 20 | io_rw_32 baudr; 21 | io_rw_32 txftlr; 22 | io_rw_32 rxftlr; 23 | io_rw_32 txflr; 24 | io_rw_32 rxflr; 25 | io_rw_32 sr; 26 | io_rw_32 imr; 27 | io_rw_32 isr; 28 | io_rw_32 risr; 29 | io_rw_32 txoicr; 30 | io_rw_32 rxoicr; 31 | io_rw_32 rxuicr; 32 | io_rw_32 msticr; 33 | io_rw_32 icr; 34 | io_rw_32 dmacr; 35 | io_rw_32 dmatdlr; 36 | io_rw_32 dmardlr; 37 | io_rw_32 idr; 38 | io_rw_32 ssi_version_id; 39 | io_rw_32 dr0; 40 | uint32_t _pad[(0xf0 - 0x60) / 4 - 1]; 41 | io_rw_32 rx_sample_dly; 42 | io_rw_32 spi_ctrlr0; 43 | io_rw_32 txd_drive_edge; 44 | } ssi_hw_t; 45 | 46 | #define ssi_hw ((ssi_hw_t *const)XIP_SSI_BASE) 47 | #endif 48 | -------------------------------------------------------------------------------- /lib/rp2040/boot/uf2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _BOOT_UF2_H 8 | #define _BOOT_UF2_H 9 | 10 | #include 11 | #include 12 | 13 | /** \file uf2.h 14 | * \defgroup boot_uf2 boot_uf2 15 | * 16 | * Header file for the UF2 format supported by an RP2040 in BOOTSEL mode. 17 | */ 18 | 19 | #define UF2_MAGIC_START0 0x0A324655u 20 | #define UF2_MAGIC_START1 0x9E5D5157u 21 | #define UF2_MAGIC_END 0x0AB16F30u 22 | 23 | #define UF2_FLAG_NOT_MAIN_FLASH 0x00000001u 24 | #define UF2_FLAG_FILE_CONTAINER 0x00001000u 25 | #define UF2_FLAG_FAMILY_ID_PRESENT 0x00002000u 26 | #define UF2_FLAG_MD5_PRESENT 0x00004000u 27 | 28 | #define RP2040_FAMILY_ID 0xe48bff56 29 | 30 | struct uf2_block { 31 | // 32 byte header 32 | uint32_t magic_start0; 33 | uint32_t magic_start1; 34 | uint32_t flags; 35 | uint32_t target_addr; 36 | uint32_t payload_size; 37 | uint32_t block_no; 38 | uint32_t num_blocks; 39 | uint32_t file_size; // or familyID; 40 | uint8_t data[476]; 41 | uint32_t magic_end; 42 | }; 43 | 44 | static_assert(sizeof(struct uf2_block) == 512, "uf2_block not sector sized"); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/generic/armcm_timer.c: -------------------------------------------------------------------------------- 1 | // Timer based on ARM Cortex-M3/M4 SysTick and DWT logic 2 | // 3 | // Copyright (C) 2017-2019 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "autoconf.h" // CONFIG_CLOCK_FREQ 8 | #include "armcm_boot.h" // DECL_ARMCM_IRQ 9 | #include "board/internal.h" // SysTick 10 | #include "board/irq.h" // irq_disable 11 | #include "board/misc.h" // timer_from_us 12 | #include "canboot.h" // timer_setup 13 | 14 | // Return the number of clock ticks for a given number of microseconds 15 | uint32_t 16 | timer_from_us(uint32_t us) 17 | { 18 | return us * (CONFIG_CLOCK_FREQ / 1000000); 19 | } 20 | 21 | // Return true if time1 is before time2. Always use this function to 22 | // compare times as regular C comparisons can fail if the counter 23 | // rolls over. 24 | uint8_t 25 | timer_is_before(uint32_t time1, uint32_t time2) 26 | { 27 | return (int32_t)(time1 - time2) < 0; 28 | } 29 | 30 | 31 | // Return the current time (in absolute clock ticks). 32 | uint32_t 33 | timer_read_time(void) 34 | { 35 | return DWT->CYCCNT; 36 | } 37 | 38 | // Initialize the timer 39 | void 40 | timer_setup(void) 41 | { 42 | CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; 43 | DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; 44 | } 45 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/pio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_PIO_H 8 | #define _HARDWARE_STRUCTS_PIO_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/pio.h" 13 | 14 | typedef struct { 15 | io_rw_32 ctrl; 16 | io_ro_32 fstat; 17 | io_rw_32 fdebug; 18 | io_ro_32 flevel; 19 | io_wo_32 txf[NUM_PIO_STATE_MACHINES]; 20 | io_ro_32 rxf[NUM_PIO_STATE_MACHINES]; 21 | io_rw_32 irq; 22 | io_wo_32 irq_force; 23 | io_rw_32 input_sync_bypass; 24 | io_rw_32 dbg_padout; 25 | io_rw_32 dbg_padoe; 26 | io_rw_32 dbg_cfginfo; 27 | io_wo_32 instr_mem[32]; 28 | struct pio_sm_hw { 29 | io_rw_32 clkdiv; 30 | io_rw_32 execctrl; 31 | io_rw_32 shiftctrl; 32 | io_ro_32 addr; 33 | io_rw_32 instr; 34 | io_rw_32 pinctrl; 35 | } sm[NUM_PIO_STATE_MACHINES]; 36 | io_rw_32 intr; 37 | io_rw_32 inte0; 38 | io_rw_32 intf0; 39 | io_ro_32 ints0; 40 | io_rw_32 inte1; 41 | io_rw_32 intf1; 42 | io_ro_32 ints1; 43 | } pio_hw_t; 44 | 45 | #define pio0_hw ((pio_hw_t *const)PIO0_BASE) 46 | #define pio1_hw ((pio_hw_t *const)PIO1_BASE) 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/rp2040/chipid.c: -------------------------------------------------------------------------------- 1 | // Support for extracting the hardware chip id on rp2040 2 | // 3 | // Copyright (C) 2021 Lasse Dalegaard 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include // memcpy 8 | #include "autoconf.h" // CONFIG_USB_SERIAL_NUMBER_CHIPID 9 | #include "hw_flash.h" 10 | #include "board/irq.h" // irq_disable, irq_enable 11 | #include "board/canserial.h" // canserial_set_uuid 12 | #include "generic/usb_cdc.h" // usb_fill_serial 13 | #include "generic/usbstd.h" // usb_string_descriptor 14 | #include "sched.h" // DECL_INIT 15 | 16 | #define CHIP_UID_LEN 8 17 | 18 | static struct { 19 | struct usb_string_descriptor desc; 20 | uint16_t data[CHIP_UID_LEN * 2]; 21 | } cdc_chipid; 22 | 23 | struct usb_string_descriptor * 24 | usbserial_get_serialid(void) 25 | { 26 | return &cdc_chipid.desc; 27 | } 28 | 29 | void 30 | chipid_init(void) 31 | { 32 | if (!(CONFIG_USB_SERIAL_NUMBER_CHIPID || CONFIG_CANBUS)) 33 | return; 34 | 35 | uint8_t data[8] = {0}; 36 | flash_get_unique_id(data); 37 | 38 | if (CONFIG_USB_SERIAL_NUMBER_CHIPID) 39 | usb_fill_serial(&cdc_chipid.desc, ARRAY_SIZE(cdc_chipid.data), data); 40 | if (CONFIG_CANBUS) 41 | canserial_set_uuid(data, CHIP_UID_LEN); 42 | } 43 | DECL_INIT(chipid_init); 44 | -------------------------------------------------------------------------------- /src/byteorder.h: -------------------------------------------------------------------------------- 1 | #ifndef __BYTEORDER_H 2 | #define __BYTEORDER_H 3 | 4 | #include // uint32_t 5 | 6 | #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 7 | 8 | #define cpu_to_le16(x) ((uint16_t)(x)) 9 | #define cpu_to_le32(x) ((uint32_t)(x)) 10 | #define cpu_to_le64(x) ((uint64_t)(x)) 11 | #define le16_to_cpu(x) ((uint16_t)(x)) 12 | #define le32_to_cpu(x) ((uint32_t)(x)) 13 | #define le64_to_cpu(x) ((uint64_t)(x)) 14 | 15 | #define cpu_to_be16(x) __builtin_bswap16(x) 16 | #define cpu_to_be32(x) __builtin_bswap32(x) 17 | #define cpu_to_be64(x) __builtin_bswap64(x) 18 | #define be16_to_cpu(x) __builtin_bswap16(x) 19 | #define be32_to_cpu(x) __builtin_bswap32(x) 20 | #define be64_to_cpu(x) __builtin_bswap64(x) 21 | 22 | #else // big endian 23 | 24 | #define cpu_to_le16(x) __builtin_bswap16(x) 25 | #define cpu_to_le32(x) __builtin_bswap32(x) 26 | #define cpu_to_le64(x) __builtin_bswap64(x) 27 | #define le16_to_cpu(x) __builtin_bswap16(x) 28 | #define le32_to_cpu(x) __builtin_bswap32(x) 29 | #define le64_to_cpu(x) __builtin_bswap64(x) 30 | 31 | #define cpu_to_be16(x) ((uint16_t)(x)) 32 | #define cpu_to_be32(x) ((uint32_t)(x)) 33 | #define cpu_to_be64(x) ((uint64_t)(x)) 34 | #define be16_to_cpu(x) ((uint16_t)(x)) 35 | #define be32_to_cpu(x) ((uint32_t)(x)) 36 | #define be64_to_cpu(x) ((uint64_t)(x)) 37 | 38 | #endif 39 | 40 | #endif // byteorder.h 41 | -------------------------------------------------------------------------------- /src/generic/usbstd_cdc.h: -------------------------------------------------------------------------------- 1 | // Standard definitions for USB CDC devices 2 | #ifndef __GENERIC_USBSTD_CDC_H 3 | #define __GENERIC_USBSTD_CDC_H 4 | 5 | #define USB_CDC_SUBCLASS_ACM 0x02 6 | 7 | #define USB_CDC_ACM_PROTO_AT_V25TER 1 8 | 9 | struct usb_cdc_header_descriptor { 10 | uint8_t bLength; 11 | uint8_t bDescriptorType; 12 | uint8_t bDescriptorSubType; 13 | uint16_t bcdCDC; 14 | } PACKED; 15 | 16 | #define USB_CDC_HEADER_TYPE 0x00 17 | #define USB_CDC_ACM_TYPE 0x02 18 | #define USB_CDC_UNION_TYPE 0x06 19 | 20 | #define USB_CDC_CS_INTERFACE 0x24 21 | #define USB_CDC_CS_ENDPOINT 0x25 22 | 23 | struct usb_cdc_acm_descriptor { 24 | uint8_t bLength; 25 | uint8_t bDescriptorType; 26 | uint8_t bDescriptorSubType; 27 | uint8_t bmCapabilities; 28 | } PACKED; 29 | 30 | struct usb_cdc_union_descriptor { 31 | uint8_t bLength; 32 | uint8_t bDescriptorType; 33 | uint8_t bDescriptorSubType; 34 | uint8_t bMasterInterface0; 35 | uint8_t bSlaveInterface0; 36 | } PACKED; 37 | 38 | #define USB_CDC_REQ_SET_LINE_CODING 0x20 39 | #define USB_CDC_REQ_GET_LINE_CODING 0x21 40 | #define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22 41 | 42 | struct usb_cdc_line_coding { 43 | uint32_t dwDTERate; 44 | uint8_t bCharFormat; 45 | uint8_t bParityType; 46 | uint8_t bDataBits; 47 | } PACKED; 48 | 49 | #endif // usbstd_cdc.h 50 | -------------------------------------------------------------------------------- /lib/rp2040/elf2uf2/elf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _ELF_H 8 | #define _ELF_H 9 | 10 | #include 11 | 12 | #define ELF_MAGIC 0x464c457fu 13 | 14 | #define EM_ARM 0x28u 15 | 16 | #define EF_ARM_ABI_FLOAT_HARD 0x00000400u 17 | 18 | #define PT_LOAD 0x00000001u 19 | 20 | #pragma pack(push, 1) 21 | struct elf_header { 22 | uint32_t magic; 23 | uint8_t arch_class; 24 | uint8_t endianness; 25 | uint8_t version; 26 | uint8_t abi; 27 | uint8_t abi_version; 28 | uint8_t _pad[7]; 29 | uint16_t type; 30 | uint16_t machine; 31 | uint32_t version2; 32 | }; 33 | 34 | struct elf32_header { 35 | struct elf_header common; 36 | uint32_t entry; 37 | uint32_t ph_offset; 38 | uint32_t sh_offset; 39 | uint32_t flags; 40 | uint16_t eh_size; 41 | uint16_t ph_entry_size; 42 | uint16_t ph_num; 43 | uint16_t sh_entry_size; 44 | uint16_t sh_num; 45 | uint16_t sh_str_index; 46 | }; 47 | 48 | struct elf32_ph_entry { 49 | uint32_t type; 50 | uint32_t offset; 51 | uint32_t vaddr; 52 | uint32_t paddr; 53 | uint32_t filez; 54 | uint32_t memsz; 55 | uint32_t flags; 56 | uint32_t align; 57 | }; 58 | #pragma pack(pop) 59 | 60 | #endif -------------------------------------------------------------------------------- /src/led.c: -------------------------------------------------------------------------------- 1 | // LED status updates 2 | // 3 | // Copyright (C) 2021 Eric Callahan 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "autoconf.h" // CONFIG_ENABLE_LED 8 | #include "board/gpio.h" // gpio_out_setup 9 | #include "board/misc.h" // timer_read_time 10 | #include "ctr.h" // DECL_CTR 11 | #include "flashcmd.h" // flashcmd_is_in_transfer 12 | #include "sched.h" // DECL_INIT 13 | 14 | #define WAIT_BLINK_TIME 1000000 15 | #define XFER_BLINK_TIME 20000 16 | 17 | DECL_CTR("DECL_LED_PIN " __stringify(CONFIG_STATUS_LED_PIN)); 18 | extern uint32_t led_gpio, led_gpio_high; // Generated by buildcommands.py 19 | 20 | static struct gpio_out led; 21 | static uint32_t last_blink_time; 22 | 23 | void 24 | led_init(void) 25 | { 26 | led = gpio_out_setup(led_gpio, led_gpio_high); 27 | last_blink_time = timer_read_time(); 28 | } 29 | DECL_INIT(led_init); 30 | 31 | void 32 | led_blink_task(void) 33 | { 34 | int in_transfer = flashcmd_is_in_transfer(); 35 | uint32_t usec = in_transfer ? XFER_BLINK_TIME : WAIT_BLINK_TIME; 36 | uint32_t curtime = timer_read_time(); 37 | uint32_t endtime = last_blink_time + timer_from_us(usec); 38 | if (timer_is_before(endtime, curtime)) { 39 | gpio_out_toggle(led); 40 | last_blink_time = timer_read_time(); 41 | } 42 | } 43 | DECL_TASK(led_blink_task); 44 | -------------------------------------------------------------------------------- /src/lpc176x/chipid.c: -------------------------------------------------------------------------------- 1 | // Support for extracting the hardware chip id on lpc176x 2 | // 3 | // Copyright (C) 2019 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "autoconf.h" // CONFIG_USB_SERIAL_NUMBER_CHIPID 8 | #include "generic/irq.h" // irq_disable 9 | #include "generic/usb_cdc.h" // usb_fill_serial 10 | #include "generic/usbstd.h" // usb_string_descriptor 11 | #include "sched.h" // DECL_INIT 12 | 13 | // IAP interface 14 | #define IAP_LOCATION 0x1fff1ff1 15 | #define IAP_CMD_READ_UID 58 16 | #define IAP_UID_LEN 16 17 | typedef void (*IAP)(uint32_t *, uint32_t *); 18 | 19 | static struct { 20 | struct usb_string_descriptor desc; 21 | uint16_t data[IAP_UID_LEN * 2]; 22 | } cdc_chipid; 23 | 24 | struct usb_string_descriptor * 25 | usbserial_get_serialid(void) 26 | { 27 | return &cdc_chipid.desc; 28 | } 29 | 30 | void 31 | chipid_init(void) 32 | { 33 | if (!CONFIG_USB_SERIAL_NUMBER_CHIPID) 34 | return; 35 | 36 | uint32_t iap_cmd_uid[5] = {IAP_CMD_READ_UID, 0, 0, 0, 0}; 37 | uint32_t iap_resp[5]; 38 | IAP iap_entry = (IAP)IAP_LOCATION; 39 | irq_disable(); 40 | iap_entry(iap_cmd_uid, iap_resp); 41 | irq_enable(); 42 | 43 | usb_fill_serial(&cdc_chipid.desc, ARRAY_SIZE(cdc_chipid.data) 44 | , &iap_resp[1]); 45 | } 46 | DECL_INIT(chipid_init); 47 | -------------------------------------------------------------------------------- /lib/lpc176x/lpc176x.patch: -------------------------------------------------------------------------------- 1 | --- device/system_LPC17xx.c 2018-05-02 12:23:57.292132454 -0400 2 | +++ device/system_LPC17xx.c 2021-05-04 10:08:17.637502030 -0400 3 | @@ -297,22 +297,19 @@ 4 | #define CLKSRCSEL_Val 0x00000001 5 | #define PLL0_SETUP 1 6 | 7 | -#ifdef MCB1700 8 | -# define PLL0CFG_Val 0x00050063 9 | -# define PLL1_SETUP 1 10 | -# define PLL1CFG_Val 0x00000023 11 | -# define CCLKCFG_Val 0x00000003 12 | -# define USBCLKCFG_Val 0x00000000 13 | +#include "autoconf.h" // CONFIG_MACH_LPC1769 14 | +#if CONFIG_MACH_LPC1769 15 | +# define PLL0CFG_Val 0x0000000E 16 | #else 17 | -# define PLL0CFG_Val 0x0000000B 18 | -# define PLL1_SETUP 0 19 | -# define PLL1CFG_Val 0x00000000 20 | -# define CCLKCFG_Val 0x00000002 21 | -# define USBCLKCFG_Val 0x00000005 22 | +# define PLL0CFG_Val 0x00010018 23 | #endif 24 | +#define PLL1_SETUP 1 25 | +#define PLL1CFG_Val 0x00000023 26 | +#define CCLKCFG_Val 0x00000002 27 | +#define USBCLKCFG_Val 0x00000000 28 | 29 | -#define PCLKSEL0_Val 0x00000000 30 | -#define PCLKSEL1_Val 0x00000000 31 | +#define PCLKSEL0_Val 0x55515155 32 | +#define PCLKSEL1_Val 0x54555455 33 | #define PCONP_Val 0x042887DE 34 | #define CLKOUTCFG_Val 0x00000000 35 | 36 | -------------------------------------------------------------------------------- /src/generic/gpio.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_GPIO_H 2 | #define __GENERIC_GPIO_H 3 | 4 | #include // uint8_t 5 | 6 | struct gpio_out { 7 | uint8_t pin; 8 | }; 9 | struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val); 10 | void gpio_out_reset(struct gpio_out g, uint8_t val); 11 | void gpio_out_toggle_noirq(struct gpio_out g); 12 | void gpio_out_toggle(struct gpio_out g); 13 | void gpio_out_write(struct gpio_out g, uint8_t val); 14 | 15 | struct gpio_in { 16 | uint8_t pin; 17 | }; 18 | struct gpio_in gpio_in_setup(uint8_t pin, int8_t pull_up); 19 | void gpio_in_reset(struct gpio_in g, int8_t pull_up); 20 | uint8_t gpio_in_read(struct gpio_in g); 21 | 22 | struct gpio_pwm { 23 | uint8_t pin; 24 | }; 25 | struct gpio_pwm gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint8_t val); 26 | void gpio_pwm_write(struct gpio_pwm g, uint8_t val); 27 | 28 | struct gpio_adc { 29 | uint8_t pin; 30 | }; 31 | struct gpio_adc gpio_adc_setup(uint8_t pin); 32 | uint32_t gpio_adc_sample(struct gpio_adc g); 33 | uint16_t gpio_adc_read(struct gpio_adc g); 34 | void gpio_adc_cancel_sample(struct gpio_adc g); 35 | 36 | struct spi_config { 37 | uint32_t cfg; 38 | }; 39 | struct spi_config spi_setup(uint32_t bus, uint8_t mode, uint32_t rate); 40 | void spi_prepare(struct spi_config config); 41 | void spi_transfer(struct spi_config config, uint8_t receive_data 42 | , uint8_t len, uint8_t *data); 43 | 44 | #endif // gpio.h 45 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/regs/dreq.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | #ifndef _DREQ_H_ 7 | #define _DREQ_H_ 8 | 9 | #define DREQ_PIO0_TX0 0x0 10 | #define DREQ_PIO0_TX1 0x1 11 | #define DREQ_PIO0_TX2 0x2 12 | #define DREQ_PIO0_TX3 0x3 13 | #define DREQ_PIO0_RX0 0x4 14 | #define DREQ_PIO0_RX1 0x5 15 | #define DREQ_PIO0_RX2 0x6 16 | #define DREQ_PIO0_RX3 0x7 17 | #define DREQ_PIO1_TX0 0x8 18 | #define DREQ_PIO1_TX1 0x9 19 | #define DREQ_PIO1_TX2 0xa 20 | #define DREQ_PIO1_TX3 0xb 21 | #define DREQ_PIO1_RX0 0xc 22 | #define DREQ_PIO1_RX1 0xd 23 | #define DREQ_PIO1_RX2 0xe 24 | #define DREQ_PIO1_RX3 0xf 25 | #define DREQ_SPI0_TX 0x10 26 | #define DREQ_SPI0_RX 0x11 27 | #define DREQ_SPI1_TX 0x12 28 | #define DREQ_SPI1_RX 0x13 29 | #define DREQ_UART0_TX 0x14 30 | #define DREQ_UART0_RX 0x15 31 | #define DREQ_UART1_TX 0x16 32 | #define DREQ_UART1_RX 0x17 33 | #define DREQ_PWM_WRAP0 0x18 34 | #define DREQ_PWM_WRAP1 0x19 35 | #define DREQ_PWM_WRAP2 0x1a 36 | #define DREQ_PWM_WRAP3 0x1b 37 | #define DREQ_PWM_WRAP4 0x1c 38 | #define DREQ_PWM_WRAP5 0x1d 39 | #define DREQ_PWM_WRAP6 0x1e 40 | #define DREQ_PWM_WRAP7 0x1f 41 | #define DREQ_I2C0_TX 0x20 42 | #define DREQ_I2C0_RX 0x21 43 | #define DREQ_I2C1_TX 0x22 44 | #define DREQ_I2C1_RX 0x23 45 | #define DREQ_ADC 0x24 46 | #define DREQ_XIP_STREAM 0x25 47 | #define DREQ_XIP_SSITX 0x26 48 | #define DREQ_XIP_SSIRX 0x27 49 | 50 | #endif // _DREQ_H_ 51 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/sio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_SIO_H 8 | #define _HARDWARE_STRUCTS_SIO_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/regs/sio.h" 12 | #include "hardware/structs/interp.h" 13 | 14 | typedef struct { 15 | io_ro_32 cpuid; 16 | io_ro_32 gpio_in; 17 | io_ro_32 gpio_hi_in; 18 | uint32_t _pad; 19 | 20 | io_rw_32 gpio_out; 21 | io_wo_32 gpio_set; 22 | io_wo_32 gpio_clr; 23 | io_wo_32 gpio_togl; 24 | 25 | io_wo_32 gpio_oe; 26 | io_wo_32 gpio_oe_set; 27 | io_wo_32 gpio_oe_clr; 28 | io_wo_32 gpio_oe_togl; 29 | 30 | io_rw_32 gpio_hi_out; 31 | io_wo_32 gpio_hi_set; 32 | io_wo_32 gpio_hi_clr; 33 | io_wo_32 gpio_hi_togl; 34 | 35 | io_wo_32 gpio_hi_oe; 36 | io_wo_32 gpio_hi_oe_set; 37 | io_wo_32 gpio_hi_oe_clr; 38 | io_wo_32 gpio_hi_oe_togl; 39 | 40 | io_rw_32 fifo_st; 41 | io_wo_32 fifo_wr; 42 | io_ro_32 fifo_rd; 43 | io_ro_32 spinlock_st; 44 | 45 | io_rw_32 div_udividend; 46 | io_rw_32 div_udivisor; 47 | io_rw_32 div_sdividend; 48 | io_rw_32 div_sdivisor; 49 | 50 | io_rw_32 div_quotient; 51 | io_rw_32 div_remainder; 52 | io_rw_32 div_csr; 53 | 54 | uint32_t _pad2; 55 | 56 | interp_hw_t interp[2]; 57 | } sio_hw_t; 58 | 59 | #define sio_hw ((sio_hw_t *)SIO_BASE) 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/stm32/gpioperiph.c: -------------------------------------------------------------------------------- 1 | // Code to setup gpio on stm32 chip (except for stm32f1) 2 | // 3 | // Copyright (C) 2019-2021 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "internal.h" // gpio_peripheral 8 | 9 | // Set the mode and extended function of a pin 10 | void 11 | gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup) 12 | { 13 | GPIO_TypeDef *regs = digital_regs[GPIO2PORT(gpio)]; 14 | 15 | // Enable GPIO clock 16 | gpio_clock_enable(regs); 17 | 18 | // Configure GPIO 19 | uint32_t mode_bits = mode & 0xf, func = (mode >> 4) & 0xf, od = mode >> 8; 20 | uint32_t pup = pullup ? (pullup > 0 ? 1 : 2) : 0; 21 | uint32_t pos = gpio % 16, af_reg = pos / 8; 22 | uint32_t af_shift = (pos % 8) * 4, af_msk = 0x0f << af_shift; 23 | uint32_t m_shift = pos * 2, m_msk = 0x03 << m_shift; 24 | 25 | regs->AFR[af_reg] = (regs->AFR[af_reg] & ~af_msk) | (func << af_shift); 26 | regs->MODER = (regs->MODER & ~m_msk) | (mode_bits << m_shift); 27 | regs->PUPDR = (regs->PUPDR & ~m_msk) | (pup << m_shift); 28 | regs->OTYPER = (regs->OTYPER & ~(1 << pos)) | (od << pos); 29 | 30 | // Setup OSPEEDR: 31 | // stm32f0 is ~10Mhz at 50pF 32 | // stm32f2 is ~25Mhz at 40pF 33 | // stm32f4 is ~50Mhz at 40pF 34 | // stm32g0 is ~30Mhz at 50pF 35 | // stm32h7 is ~85Mhz at 50pF 36 | uint32_t ospeed = CONFIG_MACH_STM32F0 ? 0x01 : 0x02; 37 | regs->OSPEEDR = (regs->OSPEEDR & ~m_msk) | (ospeed << m_shift); 38 | } 39 | -------------------------------------------------------------------------------- /lib/rp2040/boot_stage2/boot2_usb_blinky.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | // Stub second stage which calls into USB bootcode, with parameters. 8 | // USB boot takes two parameters: 9 | // - A GPIO mask for activity LED -- if mask is 0, don't touch GPIOs at all 10 | // - A mask of interfaces to disable. Bit 0 disables MSC, bit 1 disables PICOBoot 11 | // The bootrom passes 0 for both of these parameters, but user code (or this 12 | // second stage) can pass anything. 13 | 14 | #define USB_BOOT_MSD_AND_PICOBOOT 0x0 15 | #define USB_BOOT_MSD_ONLY 0x2 16 | #define USB_BOOT_PICOBOOT_ONLY 0x1 17 | 18 | // Config 19 | #define ACTIVITY_LED 0 20 | #define BOOT_MODE USB_BOOT_MSD_AND_PICOBOOT 21 | 22 | .cpu cortex-m0 23 | .thumb 24 | 25 | .section .text 26 | 27 | .global _stage2_boot 28 | .type _stage2_boot,%function 29 | 30 | .thumb_func 31 | _stage2_boot: 32 | mov r7, #0x14 // Pointer to _well_known pointer table in ROM 33 | ldrh r0, [r7, #0] // Offset 0 is 16 bit pointer to function table 34 | ldrh r7, [r7, #4] // Offset 4 is 16 bit pointer to table lookup routine 35 | ldr r1, =('U' | ('B' << 8)) // Symbol for USB Boot 36 | blx r7 37 | cmp r0, #0 38 | beq dead 39 | 40 | mov r7, r0 41 | ldr r0, =(1u << ACTIVITY_LED) // Mask of which GPIO (or GPIOs) to use 42 | mov r1, #BOOT_MODE 43 | blx r7 44 | 45 | dead: 46 | wfi 47 | b dead 48 | 49 | .global literals 50 | literals: 51 | .ltorg 52 | 53 | .end 54 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/platform_defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_PLATFORM_DEFS_H 8 | #define _HARDWARE_PLATFORM_DEFS_H 9 | 10 | // This header is included from C and assembler - only define macros 11 | 12 | #ifndef _u 13 | #ifdef __ASSEMBLER__ 14 | #define _u(x) x 15 | #else 16 | #define _u(x) x ## u 17 | #endif 18 | #endif 19 | 20 | #define NUM_CORES _u(2) 21 | #define NUM_DMA_CHANNELS _u(12) 22 | #define NUM_IRQS _u(32) 23 | #define NUM_PIOS _u(2) 24 | #define NUM_PIO_STATE_MACHINES _u(4) 25 | #define NUM_PWM_SLICES _u(8) 26 | #define NUM_SPIN_LOCKS _u(32) 27 | #define NUM_UARTS _u(2) 28 | #define NUM_I2CS _u(2) 29 | #define NUM_SPIS _u(2) 30 | 31 | #define NUM_ADC_CHANNELS _u(5) 32 | 33 | #define NUM_BANK0_GPIOS _u(30) 34 | 35 | #define PIO_INSTRUCTION_COUNT _u(32) 36 | 37 | #define XOSC_MHZ _u(12) 38 | 39 | // PICO_CONFIG: PICO_STACK_SIZE, Stack Size, min=0x100, default=0x800, advanced=true, group=pico_standard_link 40 | #ifndef PICO_STACK_SIZE 41 | #define PICO_STACK_SIZE _u(0x800) 42 | #endif 43 | 44 | // PICO_CONFIG: PICO_HEAP_SIZE, Heap size to reserve, min=0x100, default=0x800, advanced=true, group=pico_standard_link 45 | #ifndef PICO_HEAP_SIZE 46 | #define PICO_HEAP_SIZE _u(0x800) 47 | #endif 48 | 49 | // PICO_CONFIG: PICO_NO_RAM_VECTOR_TABLE, Enable/disable the RAM vector table, type=bool, default=0, advanced=true, group=pico_runtime 50 | #ifndef PICO_NO_RAM_VECTOR_TABLE 51 | #define PICO_NO_RAM_VECTOR_TABLE 0 52 | #endif 53 | 54 | #endif 55 | 56 | -------------------------------------------------------------------------------- /developer-certificate-of-origin: -------------------------------------------------------------------------------- 1 | Developer Certificate of Origin 2 | Version 1.1 3 | 4 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 5 | 1 Letterman Drive 6 | Suite D4700 7 | San Francisco, CA, 94129 8 | 9 | Everyone is permitted to copy and distribute verbatim copies of this 10 | license document, but changing it is not allowed. 11 | 12 | 13 | Developer's Certificate of Origin 1.1 14 | 15 | By making a contribution to this project, I certify that: 16 | 17 | (a) The contribution was created in whole or in part by me and I 18 | have the right to submit it under the open source license 19 | indicated in the file; or 20 | 21 | (b) The contribution is based upon previous work that, to the best 22 | of my knowledge, is covered under an appropriate open source 23 | license and I have the right under that license to submit that 24 | work with modifications, whether created in whole or in part 25 | by me, under the same open source license (unless I am 26 | permitted to submit under a different license), as indicated 27 | in the file; or 28 | 29 | (c) The contribution was provided directly to me by some other 30 | person who certified (a), (b) or (c) and I have not modified 31 | it. 32 | 33 | (d) I understand and agree that this project and the contribution 34 | are public and that a record of the contribution (including all 35 | personal information I submit with it, including my sign-off) is 36 | maintained indefinitely and may be redistributed consistent with 37 | this project or the open source license(s) involved. 38 | -------------------------------------------------------------------------------- /src/stm32/internal.h: -------------------------------------------------------------------------------- 1 | #ifndef __STM32_INTERNAL_H 2 | #define __STM32_INTERNAL_H 3 | // Local definitions for STM32 code 4 | 5 | #include "autoconf.h" // CONFIG_MACH_STM32F1 6 | 7 | #if CONFIG_MACH_STM32F0 8 | #include "stm32f0xx.h" 9 | #elif CONFIG_MACH_STM32F1 10 | #include "stm32f1xx.h" 11 | #elif CONFIG_MACH_STM32F2 12 | #include "stm32f2xx.h" 13 | #elif CONFIG_MACH_STM32F4 14 | #include "stm32f4xx.h" 15 | #elif CONFIG_MACH_STM32G0 16 | #include "stm32g0xx.h" 17 | #elif CONFIG_MACH_STM32G4 18 | #include "stm32g4xx.h" 19 | #elif CONFIG_MACH_STM32H7 20 | #include "stm32h7xx.h" 21 | #elif CONFIG_MACH_STM32L4 22 | #include "stm32l4xx.h" 23 | #endif 24 | 25 | // gpio.c 26 | extern GPIO_TypeDef * const digital_regs[]; 27 | #define GPIO(PORT, NUM) (((PORT)-'A') * 16 + (NUM)) 28 | #define GPIO2PORT(PIN) ((PIN) / 16) 29 | #define GPIO2BIT(PIN) (1<<((PIN) % 16)) 30 | 31 | // gpioperiph.c 32 | #define GPIO_INPUT 0 33 | #define GPIO_OUTPUT 1 34 | #define GPIO_OPEN_DRAIN 0x100 35 | #define GPIO_FUNCTION(fn) (2 | ((fn) << 4)) 36 | #define GPIO_ANALOG 3 37 | void gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup); 38 | 39 | // clockline.c 40 | void enable_pclock(uint32_t periph_base); 41 | int is_enabled_pclock(uint32_t periph_base); 42 | 43 | // dfu_reboot.c 44 | void dfu_reboot(void); 45 | void dfu_reboot_check(void); 46 | 47 | // stm32??.c 48 | struct cline { volatile uint32_t *en, *rst; uint32_t bit; }; 49 | struct cline lookup_clock_line(uint32_t periph_base); 50 | uint32_t get_pclock_frequency(uint32_t periph_base); 51 | void gpio_clock_enable(GPIO_TypeDef *regs); 52 | 53 | #endif // internal.h 54 | -------------------------------------------------------------------------------- /src/compiler.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPILER_H 2 | #define __COMPILER_H 3 | // Low level definitions for C languange and gcc compiler. 4 | 5 | #define barrier() __asm__ __volatile__("": : :"memory") 6 | 7 | #define likely(x) __builtin_expect(!!(x), 1) 8 | #define unlikely(x) __builtin_expect(!!(x), 0) 9 | 10 | #define noinline __attribute__((noinline)) 11 | #ifndef __always_inline 12 | #define __always_inline inline __attribute__((always_inline)) 13 | #endif 14 | #define __visible __attribute__((externally_visible)) 15 | #define __noreturn __attribute__((noreturn)) 16 | 17 | #define PACKED __attribute__((packed)) 18 | #ifndef __aligned 19 | #define __aligned(x) __attribute__((aligned(x))) 20 | #endif 21 | #ifndef __section 22 | #define __section(S) __attribute__((section(S))) 23 | #endif 24 | 25 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 26 | #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) 27 | #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) 28 | #define ALIGN_DOWN(x,a) ((x) & ~((typeof(x))(a)-1)) 29 | 30 | #define container_of(ptr, type, member) ({ \ 31 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 32 | (type *)( (char *)__mptr - offsetof(type,member) );}) 33 | 34 | #define __stringify_1(x) #x 35 | #define __stringify(x) __stringify_1(x) 36 | 37 | #define ___PASTE(a,b) a##b 38 | #define __PASTE(a,b) ___PASTE(a,b) 39 | 40 | #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) 41 | #define DIV_ROUND_CLOSEST(x, divisor)({ \ 42 | typeof(divisor) __divisor = divisor; \ 43 | (((x) + ((__divisor) / 2)) / (__divisor)); \ 44 | }) 45 | 46 | #endif // compiler.h 47 | -------------------------------------------------------------------------------- /scripts/uf2_append_boot_signature.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Add boot signature (one page of zeros) at gived address. 3 | # 4 | # This file may be distributed under the terms of the GNU GPLv3 license. 5 | import sys, argparse, struct 6 | 7 | def renumerate(content): 8 | result = bytearray() 9 | total = len(content) // 512 10 | for current in range(total): 11 | block = content[current * 512 : (current + 1) * 512] 12 | result.extend(block[ : 20]) 13 | result.extend(struct.pack(" 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "autoconf.h" // CONFIG_CLOCK_FREQ 8 | #include "board/armcm_boot.h" // armcm_enable_irq 9 | #include "board/irq.h" // irq_disable 10 | #include "board/misc.h" // timer_read_time 11 | #include "canboot.h" // timer_setup 12 | #include "hardware/structs/resets.h" // RESETS_RESET_UART0_BITS 13 | #include "hardware/structs/timer.h" // RESETS_RESET_UART0_BITS 14 | #include "internal.h" // enable_pclock 15 | #include "sched.h" // DECL_INIT 16 | 17 | 18 | /**************************************************************** 19 | * Low level timer code 20 | ****************************************************************/ 21 | 22 | // Return the number of clock ticks for a given number of microseconds 23 | uint32_t 24 | timer_from_us(uint32_t us) 25 | { 26 | return us * (CONFIG_CLOCK_FREQ / 1000000); 27 | } 28 | 29 | // Return true if time1 is before time2. Always use this function to 30 | // compare times as regular C comparisons can fail if the counter 31 | // rolls over. 32 | uint8_t 33 | timer_is_before(uint32_t time1, uint32_t time2) 34 | { 35 | return (int32_t)(time1 - time2) < 0; 36 | } 37 | 38 | // Return the current time (in absolute clock ticks). 39 | uint32_t 40 | timer_read_time(void) 41 | { 42 | return timer_hw->timerawl; 43 | } 44 | 45 | /**************************************************************** 46 | * Setup and irqs 47 | ****************************************************************/ 48 | 49 | void 50 | timer_setup(void) 51 | { 52 | irq_disable(); 53 | enable_pclock(RESETS_RESET_TIMER_BITS); 54 | timer_hw->timelw = 0; 55 | timer_hw->timehw = 0; 56 | irq_enable(); 57 | } 58 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/dma.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_DMA_H 8 | #define _HARDWARE_STRUCTS_DMA_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/dma.h" 13 | 14 | typedef struct { 15 | io_rw_32 read_addr; 16 | io_rw_32 write_addr; 17 | io_rw_32 transfer_count; 18 | io_rw_32 ctrl_trig; 19 | io_rw_32 al1_ctrl; 20 | io_rw_32 al1_read_addr; 21 | io_rw_32 al1_write_addr; 22 | io_rw_32 al1_transfer_count_trig; 23 | io_rw_32 al2_ctrl; 24 | io_rw_32 al2_transfer_count; 25 | io_rw_32 al2_read_addr; 26 | io_rw_32 al2_write_addr_trig; 27 | io_rw_32 al3_ctrl; 28 | io_rw_32 al3_write_addr; 29 | io_rw_32 al3_transfer_count; 30 | io_rw_32 al3_read_addr_trig; 31 | } dma_channel_hw_t; 32 | 33 | typedef struct { 34 | dma_channel_hw_t ch[NUM_DMA_CHANNELS]; 35 | uint32_t _pad0[16 * (16 - NUM_DMA_CHANNELS)]; 36 | io_ro_32 intr; 37 | io_rw_32 inte0; 38 | io_rw_32 intf0; 39 | io_rw_32 ints0; 40 | uint32_t _pad1[1]; 41 | io_rw_32 inte1; 42 | io_rw_32 intf1; 43 | io_rw_32 ints1; 44 | io_rw_32 timer[4]; 45 | io_wo_32 multi_channel_trigger; 46 | io_rw_32 sniff_ctrl; 47 | io_rw_32 sniff_data; 48 | uint32_t _pad2[1]; 49 | io_ro_32 fifo_levels; 50 | io_wo_32 abort; 51 | } dma_hw_t; 52 | 53 | typedef struct { 54 | struct dma_debug_hw_channel { 55 | io_ro_32 ctrdeq; 56 | io_ro_32 tcr; 57 | uint32_t pad[14]; 58 | } ch[NUM_DMA_CHANNELS]; 59 | } dma_debug_hw_t; 60 | 61 | #define dma_hw ((dma_hw_t *const)DMA_BASE) 62 | #define dma_debug_hw ((dma_debug_hw_t *const)(DMA_BASE + DMA_CH0_DBG_CTDREQ_OFFSET)) 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /lib/cmsis-core/cmsis_version.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************//** 2 | * @file cmsis_version.h 3 | * @brief CMSIS Core(M) Version definitions 4 | * @version V5.0.4 5 | * @date 23. July 2019 6 | ******************************************************************************/ 7 | /* 8 | * Copyright (c) 2009-2019 ARM Limited. All rights reserved. 9 | * 10 | * SPDX-License-Identifier: Apache-2.0 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the License); you may 13 | * not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 20 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | */ 24 | 25 | #if defined ( __ICCARM__ ) 26 | #pragma system_include /* treat file as system include file for MISRA check */ 27 | #elif defined (__clang__) 28 | #pragma clang system_header /* treat file as system include file */ 29 | #endif 30 | 31 | #ifndef __CMSIS_VERSION_H 32 | #define __CMSIS_VERSION_H 33 | 34 | /* CMSIS Version definitions */ 35 | #define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ 36 | #define __CM_CMSIS_VERSION_SUB ( 4U) /*!< [15:0] CMSIS Core(M) sub version */ 37 | #define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ 38 | __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ 39 | #endif 40 | -------------------------------------------------------------------------------- /src/sched.c: -------------------------------------------------------------------------------- 1 | // Basic scheduling functions and startup code 2 | // 3 | // Copyright (C) 2016-2022 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "board/io.h" // readb 8 | #include "board/misc.h" // jump_to_application 9 | #include "bootentry.h" // bootentry_check 10 | #include "canboot.h" // timer_setup 11 | #include "deployer.h" // deployer_is_active 12 | #include "sched.h" // sched_check_periodic 13 | 14 | // The main CanBoot code is running (not the deployer application) 15 | int 16 | deployer_is_active(void) 17 | { 18 | return 0; 19 | } 20 | 21 | // Implement simple delay mechanism 22 | void 23 | udelay(uint32_t usecs) 24 | { 25 | uint32_t end = timer_read_time() + timer_from_us(usecs); 26 | while (timer_is_before(timer_read_time(), end)) 27 | ; 28 | } 29 | 30 | // Wrapper for Klipper compatibility 31 | void 32 | sched_wake_tasks(void) 33 | { 34 | } 35 | 36 | // Note that a task is ready to run 37 | void 38 | sched_wake_task(struct task_wake *w) 39 | { 40 | writeb(&w->wake, 1); 41 | } 42 | 43 | // Check if a task is ready to run (as indicated by sched_wake_task) 44 | uint8_t 45 | sched_check_wake(struct task_wake *w) 46 | { 47 | if (!readb(&w->wake)) 48 | return 0; 49 | writeb(&w->wake, 0); 50 | return 1; 51 | } 52 | 53 | // Init followed by main task dispatch loop 54 | void 55 | sched_main(void) 56 | { 57 | timer_setup(); 58 | if (!bootentry_check()) 59 | application_jump(); 60 | 61 | // Run all init functions marked with DECL_INIT() 62 | extern void ctr_run_initfuncs(void); 63 | ctr_run_initfuncs(); 64 | 65 | for (;;) { 66 | // Run all task functions marked with DECL_TASK() 67 | extern void ctr_run_taskfuncs(void); 68 | ctr_run_taskfuncs(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/rp2040/gpio.h: -------------------------------------------------------------------------------- 1 | #ifndef __RP2040_GPIO_H 2 | #define __RP2040_GPIO_H 3 | 4 | #include // uint32_t 5 | 6 | struct gpio_out { 7 | uint32_t bit; 8 | }; 9 | struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val); 10 | void gpio_out_reset(struct gpio_out g, uint8_t val); 11 | void gpio_out_toggle_noirq(struct gpio_out g); 12 | void gpio_out_toggle(struct gpio_out g); 13 | void gpio_out_write(struct gpio_out g, uint8_t val); 14 | 15 | struct gpio_in { 16 | uint32_t bit; 17 | }; 18 | struct gpio_in gpio_in_setup(uint8_t pin, int8_t pull_up); 19 | void gpio_in_reset(struct gpio_in g, int8_t pull_up); 20 | uint8_t gpio_in_read(struct gpio_in g); 21 | 22 | struct gpio_pwm { 23 | void *reg; 24 | uint8_t shift; 25 | uint32_t mask; 26 | }; 27 | struct gpio_pwm gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint8_t val); 28 | void gpio_pwm_write(struct gpio_pwm g, uint32_t val); 29 | 30 | struct gpio_adc { 31 | uint8_t chan; 32 | }; 33 | struct gpio_adc gpio_adc_setup(uint32_t pin); 34 | uint32_t gpio_adc_sample(struct gpio_adc g); 35 | uint16_t gpio_adc_read(struct gpio_adc g); 36 | void gpio_adc_cancel_sample(struct gpio_adc g); 37 | 38 | struct spi_config { 39 | void *spi; 40 | uint32_t cr0, cpsr; 41 | }; 42 | struct spi_config spi_setup(uint32_t bus, uint8_t mode, uint32_t rate); 43 | void spi_prepare(struct spi_config config); 44 | void spi_transfer(struct spi_config config, uint8_t receive_data 45 | , uint8_t len, uint8_t *data); 46 | 47 | struct i2c_config { 48 | void *i2c; 49 | uint8_t addr; 50 | }; 51 | 52 | struct i2c_config i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr); 53 | void i2c_write(struct i2c_config config, uint8_t write_len, uint8_t *write); 54 | void i2c_read(struct i2c_config config, uint8_t reg_len, uint8_t *reg 55 | , uint8_t read_len, uint8_t *read); 56 | 57 | #endif // gpio.h 58 | -------------------------------------------------------------------------------- /src/lpc176x/gpio.h: -------------------------------------------------------------------------------- 1 | #ifndef __LPC176X_GPIO_H 2 | #define __LPC176X_GPIO_H 3 | 4 | #include 5 | 6 | struct gpio_out { 7 | void *regs; 8 | uint32_t bit; 9 | }; 10 | struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val); 11 | void gpio_out_reset(struct gpio_out g, uint8_t val); 12 | void gpio_out_toggle_noirq(struct gpio_out g); 13 | void gpio_out_toggle(struct gpio_out g); 14 | void gpio_out_write(struct gpio_out g, uint8_t val); 15 | 16 | struct gpio_in { 17 | void *regs; 18 | uint32_t bit; 19 | }; 20 | struct gpio_in gpio_in_setup(uint8_t pin, int8_t pull_up); 21 | void gpio_in_reset(struct gpio_in g, int8_t pull_up); 22 | uint8_t gpio_in_read(struct gpio_in g); 23 | 24 | struct gpio_pwm { 25 | void *reg; 26 | uint8_t channel; 27 | }; 28 | struct gpio_pwm gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint8_t val); 29 | void gpio_pwm_write(struct gpio_pwm g, uint32_t val); 30 | 31 | struct gpio_adc { 32 | uint32_t chan; 33 | }; 34 | struct gpio_adc gpio_adc_setup(uint8_t pin); 35 | uint32_t gpio_adc_sample(struct gpio_adc g); 36 | uint16_t gpio_adc_read(struct gpio_adc g); 37 | void gpio_adc_cancel_sample(struct gpio_adc g); 38 | 39 | struct spi_config { 40 | void *spi; 41 | uint32_t cr0, cpsr; 42 | }; 43 | struct spi_config spi_setup(uint32_t bus, uint8_t mode, uint32_t rate); 44 | void spi_prepare(struct spi_config config); 45 | void spi_transfer(struct spi_config config, uint8_t receive_data 46 | , uint8_t len, uint8_t *data); 47 | 48 | struct i2c_config { 49 | void *i2c; 50 | uint8_t addr; 51 | }; 52 | 53 | struct i2c_config i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr); 54 | void i2c_write(struct i2c_config config, uint8_t write_len, uint8_t *write); 55 | void i2c_read(struct i2c_config config, uint8_t reg_len, uint8_t *reg 56 | , uint8_t read_len, uint8_t *read); 57 | 58 | #endif // gpio.h 59 | -------------------------------------------------------------------------------- /src/stm32/gpio.h: -------------------------------------------------------------------------------- 1 | #ifndef __STM32_GPIO_H 2 | #define __STM32_GPIO_H 3 | 4 | #include // uint32_t 5 | 6 | struct gpio_out { 7 | void *regs; 8 | uint32_t bit; 9 | }; 10 | struct gpio_out gpio_out_setup(uint32_t pin, uint32_t val); 11 | void gpio_out_reset(struct gpio_out g, uint32_t val); 12 | void gpio_out_toggle_noirq(struct gpio_out g); 13 | void gpio_out_toggle(struct gpio_out g); 14 | void gpio_out_write(struct gpio_out g, uint32_t val); 15 | 16 | struct gpio_in { 17 | void *regs; 18 | uint32_t bit; 19 | }; 20 | struct gpio_in gpio_in_setup(uint32_t pin, int32_t pull_up); 21 | void gpio_in_reset(struct gpio_in g, int32_t pull_up); 22 | uint8_t gpio_in_read(struct gpio_in g); 23 | 24 | struct gpio_pwm { 25 | void *reg; 26 | }; 27 | struct gpio_pwm gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint8_t val); 28 | void gpio_pwm_write(struct gpio_pwm g, uint32_t val); 29 | 30 | struct gpio_adc { 31 | void *adc; 32 | uint32_t chan; 33 | }; 34 | struct gpio_adc gpio_adc_setup(uint32_t pin); 35 | uint32_t gpio_adc_sample(struct gpio_adc g); 36 | uint16_t gpio_adc_read(struct gpio_adc g); 37 | void gpio_adc_cancel_sample(struct gpio_adc g); 38 | 39 | struct spi_config { 40 | void *spi; 41 | uint32_t spi_cr1; 42 | }; 43 | struct spi_config spi_setup(uint32_t bus, uint8_t mode, uint32_t rate); 44 | void spi_prepare(struct spi_config config); 45 | void spi_transfer(struct spi_config config, uint8_t receive_data 46 | , uint8_t len, uint8_t *data); 47 | 48 | struct i2c_config { 49 | void *i2c; 50 | uint8_t addr; 51 | }; 52 | 53 | struct i2c_config i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr); 54 | void i2c_write(struct i2c_config config, uint8_t write_len, uint8_t *write); 55 | void i2c_read(struct i2c_config config, uint8_t reg_len, uint8_t *reg 56 | , uint8_t read_len, uint8_t *read); 57 | 58 | #endif // gpio.h 59 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/regs/tbman.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | // ============================================================================= 7 | // Register block : TBMAN 8 | // Version : 1 9 | // Bus type : apb 10 | // Description : Testbench manager. Allows the programmer to know what 11 | // platform their software is running on. 12 | // ============================================================================= 13 | #ifndef HARDWARE_REGS_TBMAN_DEFINED 14 | #define HARDWARE_REGS_TBMAN_DEFINED 15 | // ============================================================================= 16 | // Register : TBMAN_PLATFORM 17 | // Description : Indicates the type of platform in use 18 | #define TBMAN_PLATFORM_OFFSET _u(0x00000000) 19 | #define TBMAN_PLATFORM_BITS _u(0x00000003) 20 | #define TBMAN_PLATFORM_RESET _u(0x00000005) 21 | // ----------------------------------------------------------------------------- 22 | // Field : TBMAN_PLATFORM_FPGA 23 | // Description : Indicates the platform is an FPGA 24 | #define TBMAN_PLATFORM_FPGA_RESET _u(0x0) 25 | #define TBMAN_PLATFORM_FPGA_BITS _u(0x00000002) 26 | #define TBMAN_PLATFORM_FPGA_MSB _u(1) 27 | #define TBMAN_PLATFORM_FPGA_LSB _u(1) 28 | #define TBMAN_PLATFORM_FPGA_ACCESS "RO" 29 | // ----------------------------------------------------------------------------- 30 | // Field : TBMAN_PLATFORM_ASIC 31 | // Description : Indicates the platform is an ASIC 32 | #define TBMAN_PLATFORM_ASIC_RESET _u(0x1) 33 | #define TBMAN_PLATFORM_ASIC_BITS _u(0x00000001) 34 | #define TBMAN_PLATFORM_ASIC_MSB _u(0) 35 | #define TBMAN_PLATFORM_ASIC_LSB _u(0) 36 | #define TBMAN_PLATFORM_ASIC_ACCESS "RO" 37 | // ============================================================================= 38 | #endif // HARDWARE_REGS_TBMAN_DEFINED 39 | -------------------------------------------------------------------------------- /lib/fast-hash/fasthash.h: -------------------------------------------------------------------------------- 1 | /* The MIT License 2 | 3 | Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com) 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without 8 | restriction, including without limitation the rights to use, copy, 9 | modify, merge, publish, distribute, sublicense, and/or sell copies 10 | of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | */ 25 | 26 | #ifndef _FASTHASH_H 27 | #define _FASTHASH_H 28 | 29 | #include 30 | #include 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | /** 37 | * fasthash32 - 32-bit implementation of fasthash 38 | * @buf: data buffer 39 | * @len: data size 40 | * @seed: the seed 41 | */ 42 | uint32_t fasthash32(const void *buf, size_t len, uint32_t seed); 43 | 44 | /** 45 | * fasthash64 - 64-bit implementation of fasthash 46 | * @buf: data buffer 47 | * @len: data size 48 | * @seed: the seed 49 | */ 50 | uint64_t fasthash64(const void *buf, size_t len, uint64_t seed); 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/ctr.h: -------------------------------------------------------------------------------- 1 | #ifndef __CTR_H 2 | #define __CTR_H 3 | // Definitions for creating compile time requests. The DECL_CTR macro 4 | // produces requests (text strings) that are placed in a special 5 | // section of the intermediate object files (*.o). The build extracts 6 | // these strings and places them in out/compile_time_requests.txt. 7 | // The scripts/buildcommand.py code then generates 8 | // out/compile_time_request.c from these requests. 9 | 10 | #include "compiler.h" // __section 11 | 12 | // Declare a compile time request 13 | #define DECL_CTR(REQUEST) \ 14 | static char __PASTE(_DECLS_, __LINE__)[] __attribute__((used)) \ 15 | __section(".compile_time_request") = (REQUEST) 16 | 17 | // Macro to encode an integer for use with DECL_CTR_INT() 18 | #define _CTR_HEX(H) ((H) > 9 ? (H) - 10 + 'A' : (H) + '0') 19 | #define _CTR_SHIFT(V, S) _CTR_HEX(((uint32_t)(V) >> (S)) & 0x0f) 20 | #define _CTR_INT(V, S) ((V) < 0 ? _CTR_SHIFT(-(V), (S)) : _CTR_SHIFT((V), (S))) 21 | #define CTR_INT(VALUE) { \ 22 | ' ', (VALUE) < 0 ? '-' : '+', '0', 'x', \ 23 | _CTR_INT((VALUE),28), _CTR_INT((VALUE),24), \ 24 | _CTR_INT((VALUE),20), _CTR_INT((VALUE),16), \ 25 | _CTR_INT((VALUE),12), _CTR_INT((VALUE),8), \ 26 | _CTR_INT((VALUE),4), _CTR_INT((VALUE),0) } 27 | 28 | // Declare a compile time request with an integer expression 29 | #define DECL_CTR_INT(REQUEST, PARAM_COUNT, args...) \ 30 | static struct { \ 31 | char _request[sizeof(REQUEST)-1]; \ 32 | char _values[(PARAM_COUNT)][12]; \ 33 | char _end_of_line; \ 34 | } __PASTE(_DECLI_, __LINE__) __attribute__((used)) \ 35 | __section(".compile_time_request") = { \ 36 | (REQUEST), { args }, 0 } 37 | 38 | #endif // ctr.h 39 | -------------------------------------------------------------------------------- /src/generic/armcm_irq.c: -------------------------------------------------------------------------------- 1 | // Definitions for irq enable/disable on ARM Cortex-M processors 2 | // 3 | // Copyright (C) 2017-2018 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "board/internal.h" // __CORTEX_M 8 | #include "irq.h" // irqstatus_t 9 | #include "sched.h" // DECL_SHUTDOWN 10 | 11 | void 12 | irq_disable(void) 13 | { 14 | asm volatile("cpsid i" ::: "memory"); 15 | } 16 | 17 | void 18 | irq_enable(void) 19 | { 20 | asm volatile("cpsie i" ::: "memory"); 21 | } 22 | 23 | irqstatus_t 24 | irq_save(void) 25 | { 26 | irqstatus_t flag; 27 | asm volatile("mrs %0, primask" : "=r" (flag) :: "memory"); 28 | irq_disable(); 29 | return flag; 30 | } 31 | 32 | void 33 | irq_restore(irqstatus_t flag) 34 | { 35 | asm volatile("msr primask, %0" :: "r" (flag) : "memory"); 36 | } 37 | 38 | void 39 | irq_wait(void) 40 | { 41 | if (__CORTEX_M >= 7) 42 | // Cortex-m7 may disable cpu counter on wfi, so use nop 43 | asm volatile("cpsie i\n nop\n cpsid i\n" ::: "memory"); 44 | else 45 | asm volatile("cpsie i\n wfi\n cpsid i\n" ::: "memory"); 46 | } 47 | 48 | void 49 | irq_poll(void) 50 | { 51 | } 52 | 53 | // Clear the active irq if a shutdown happened in an irq handler 54 | void 55 | clear_active_irq(void) 56 | { 57 | uint32_t psr; 58 | asm volatile("mrs %0, psr" : "=r" (psr)); 59 | if (!(psr & 0x1ff)) 60 | // Shutdown did not occur in an irq - nothing to do. 61 | return; 62 | // Clear active irq status 63 | psr = 1<<24; // T-bit 64 | uint32_t temp; 65 | asm volatile( 66 | " push { %1 }\n" 67 | " adr %0, 1f\n" 68 | " push { %0 }\n" 69 | " push { r0, r1, r2, r3, r4, lr }\n" 70 | " bx %2\n" 71 | ".balign 4\n" 72 | "1:\n" 73 | : "=&r"(temp) : "r"(psr), "r"(0xfffffff9) : "r12", "cc"); 74 | } 75 | DECL_SHUTDOWN(clear_active_irq); 76 | -------------------------------------------------------------------------------- /src/rp2040/rp2040_link.lds.S: -------------------------------------------------------------------------------- 1 | // rp2040 linker script (based on armcm_link.lds.S and customized for stage2) 2 | // 3 | // Copyright (C) 2019-2021 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "autoconf.h" // CONFIG_FLASH_START 8 | 9 | OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 10 | OUTPUT_ARCH(arm) 11 | 12 | MEMORY 13 | { 14 | rom (rx) : ORIGIN = CONFIG_FLASH_START , LENGTH = CONFIG_FLASH_SIZE 15 | ram (rwx) : ORIGIN = CONFIG_RAM_START , LENGTH = CONFIG_RAM_SIZE 16 | } 17 | 18 | SECTIONS 19 | { 20 | .text : { 21 | . = ALIGN(4); 22 | KEEP(*(.boot2)) 23 | KEEP(*(.vector_table_flash)) 24 | KEEP(*(.reset_handler_flash)) 25 | KEEP(*(.reset_handler_flash.*)) 26 | } > rom 27 | 28 | . = ALIGN(4); 29 | _data_flash = .; 30 | 31 | .data : AT (_data_flash) 32 | { 33 | . = ALIGN(128); 34 | _data_start = .; 35 | KEEP(*(.vector_table)) 36 | *(.text .text.*) 37 | *(.rodata .rodata*) 38 | *(.ramfunc .ramfunc.*); 39 | *(.data .data.*); 40 | . = ALIGN(4); 41 | _data_end = .; 42 | } > ram 43 | 44 | .bss (NOLOAD) : 45 | { 46 | . = ALIGN(4); 47 | _bss_start = .; 48 | *(.bss .bss.*) 49 | *(COMMON) 50 | . = ALIGN(4); 51 | _bss_end = .; 52 | } > ram 53 | 54 | _stack_start = CONFIG_RAM_START + CONFIG_RAM_SIZE - CONFIG_STACK_SIZE - 1024; 55 | .stack _stack_start (NOLOAD) : 56 | { 57 | . = . + CONFIG_STACK_SIZE; 58 | _stack_end = .; 59 | } > ram 60 | 61 | /DISCARD/ : { 62 | // The .init/.fini sections are used by __libc_init_array(), but 63 | // that isn't needed so no need to include them in the binary. 64 | *(.init) 65 | *(.fini) 66 | // Don't include exception tables 67 | *(.ARM.extab) 68 | *(.ARM.exidx) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/structs/clocks.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _HARDWARE_STRUCTS_CLOCKS_H 8 | #define _HARDWARE_STRUCTS_CLOCKS_H 9 | 10 | #include "hardware/address_mapped.h" 11 | #include "hardware/platform_defs.h" 12 | #include "hardware/regs/clocks.h" 13 | 14 | /*! \brief Enumeration identifying a hardware clock 15 | * \ingroup hardware_clocks 16 | */ 17 | /// \tag::clkenum[] 18 | enum clock_index { 19 | clk_gpout0 = 0, ///< GPIO Muxing 0 20 | clk_gpout1, ///< GPIO Muxing 1 21 | clk_gpout2, ///< GPIO Muxing 2 22 | clk_gpout3, ///< GPIO Muxing 3 23 | clk_ref, ///< Watchdog and timers reference clock 24 | clk_sys, ///< Processors, bus fabric, memory, memory mapped registers 25 | clk_peri, ///< Peripheral clock for UART and SPI 26 | clk_usb, ///< USB clock 27 | clk_adc, ///< ADC clock 28 | clk_rtc, ///< Real time clock 29 | CLK_COUNT 30 | }; 31 | /// \end::clkenum[] 32 | 33 | /// \tag::clock_hw[] 34 | typedef struct { 35 | io_rw_32 ctrl; 36 | io_rw_32 div; 37 | io_rw_32 selected; 38 | } clock_hw_t; 39 | /// \end::clock_hw[] 40 | 41 | typedef struct { 42 | io_rw_32 ref_khz; 43 | io_rw_32 min_khz; 44 | io_rw_32 max_khz; 45 | io_rw_32 delay; 46 | io_rw_32 interval; 47 | io_rw_32 src; 48 | io_ro_32 status; 49 | io_ro_32 result; 50 | } fc_hw_t; 51 | 52 | typedef struct { 53 | clock_hw_t clk[CLK_COUNT]; 54 | struct { 55 | io_rw_32 ctrl; 56 | io_rw_32 status; 57 | } resus; 58 | fc_hw_t fc0; 59 | io_rw_32 wake_en0; 60 | io_rw_32 wake_en1; 61 | io_rw_32 sleep_en0; 62 | io_rw_32 sleep_en1; 63 | io_rw_32 enabled0; 64 | io_rw_32 enabled1; 65 | io_rw_32 intr; 66 | io_rw_32 inte; 67 | io_rw_32 intf; 68 | io_rw_32 ints; 69 | } clocks_hw_t; 70 | 71 | #define clocks_hw ((clocks_hw_t *const)CLOCKS_BASE) 72 | #endif 73 | -------------------------------------------------------------------------------- /lib/lpc176x/device/system_LPC17xx.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file: system_LPC17xx.h 3 | * @purpose: CMSIS Cortex-M3 Device Peripheral Access Layer Header File 4 | * for the NXP LPC17xx Device Series 5 | * @version: V1.02 6 | * @date: 27. July 2009 7 | *---------------------------------------------------------------------------- 8 | * 9 | * Copyright (C) 2009 ARM Limited. All rights reserved. 10 | * 11 | * ARM Limited (ARM) is supplying this software for use with Cortex-M3 12 | * processor based microcontrollers. This file can be freely distributed 13 | * within development tools that are supporting such ARM based processors. 14 | * 15 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 16 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 17 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 18 | * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR 19 | * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 20 | * 21 | ******************************************************************************/ 22 | 23 | 24 | #ifndef __SYSTEM_LPC17xx_H 25 | #define __SYSTEM_LPC17xx_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 32 | 33 | 34 | /** 35 | * Initialize the system 36 | * 37 | * @param none 38 | * @return none 39 | * 40 | * @brief Setup the microcontroller system. 41 | * Initialize the System and update the SystemCoreClock variable. 42 | */ 43 | extern void SystemInit (void); 44 | 45 | /** 46 | * Update SystemCoreClock variable 47 | * 48 | * @param none 49 | * @return none 50 | * 51 | * @brief Updates the SystemCoreClock with current core Clock 52 | * retrieved from cpu registers. 53 | */ 54 | extern void SystemCoreClockUpdate (void); 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif /* __SYSTEM_LPC17xx_H */ 61 | -------------------------------------------------------------------------------- /lib/rp2040/cmsis_include/system_RP2040.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************//** 2 | * @file system_RP2040.h 3 | * @brief CMSIS-Core(M) Device Peripheral Access Layer Header File for 4 | * Device RP2040 5 | * @version V1.0.0 6 | * @date 5. May 2021 7 | *****************************************************************************/ 8 | /* 9 | * Copyright (c) 2009-2021 Arm Limited. All rights reserved. 10 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 11 | * 12 | * SPDX-License-Identifier: Apache-2.0 13 | * 14 | * Licensed under the Apache License, Version 2.0 (the License); you may 15 | * not use this file except in compliance with the License. 16 | * You may obtain a copy of the License at 17 | * 18 | * www.apache.org/licenses/LICENSE-2.0 19 | * 20 | * Unless required by applicable law or agreed to in writing, software 21 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 22 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | * See the License for the specific language governing permissions and 24 | * limitations under the License. 25 | * 26 | * SPDX-License-Identifier: BSD-3-Clause 27 | */ 28 | 29 | #ifndef _CMSIS_SYSTEM_RP2040_H 30 | #define _CMSIS_SYSTEM_RP2040_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | /** 37 | \brief Exception / Interrupt Handler Function Prototype 38 | */ 39 | typedef void(*VECTOR_TABLE_Type)(void); 40 | 41 | /** 42 | \brief System Clock Frequency (Core Clock) 43 | */ 44 | extern uint32_t SystemCoreClock; 45 | 46 | /** 47 | \brief Setup the microcontroller system. 48 | 49 | Initialize the System and update the SystemCoreClock variable. 50 | */ 51 | extern void SystemInit (void); 52 | 53 | 54 | /** 55 | \brief Update SystemCoreClock variable. 56 | 57 | Updates the SystemCoreClock with current core Clock retrieved from cpu registers. 58 | */ 59 | extern void SystemCoreClockUpdate (void); 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif /* _CMSIS_SYSTEM_RP2040_H */ 66 | -------------------------------------------------------------------------------- /lib/rp2040/boot_stage2/pad_checksum: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import binascii 5 | import struct 6 | import sys 7 | 8 | 9 | def any_int(x): 10 | try: 11 | return int(x, 0) 12 | except: 13 | raise argparse.ArgumentTypeError("expected an integer, not '{!r}'".format(x)) 14 | 15 | 16 | def bitrev(x, width): 17 | return int("{:0{w}b}".format(x, w=width)[::-1], 2) 18 | 19 | 20 | parser = argparse.ArgumentParser() 21 | parser.add_argument("ifile", help="Input file (binary)") 22 | parser.add_argument("ofile", help="Output file (assembly)") 23 | parser.add_argument("-p", "--pad", help="Padded size (bytes), including 4-byte checksum, default 256", 24 | type=any_int, default=256) 25 | parser.add_argument("-s", "--seed", help="Checksum seed value, default 0", 26 | type=any_int, default=0) 27 | args = parser.parse_args() 28 | 29 | try: 30 | idata = open(args.ifile, "rb").read() 31 | except: 32 | sys.exit("Could not open input file '{}'".format(args.ifile)) 33 | 34 | if len(idata) >= args.pad - 4: 35 | sys.exit("Input file size ({} bytes) too large for final size ({} bytes)".format(len(idata), args.pad)) 36 | 37 | idata_padded = idata + bytes(args.pad - 4 - len(idata)) 38 | 39 | # Our bootrom CRC32 is slightly bass-ackward but it's best to work around for now (FIXME) 40 | # 100% worth it to save two Thumb instructions 41 | checksum = bitrev( 42 | (binascii.crc32(bytes(bitrev(b, 8) for b in idata_padded), args.seed ^ 0xffffffff) ^ 0xffffffff) & 0xffffffff, 32) 43 | odata = idata_padded + struct.pack(" 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "autoconf.h" // CONFIG_FLASH_START 8 | 9 | OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 10 | OUTPUT_ARCH(arm) 11 | 12 | MEMORY 13 | { 14 | rom (rx) : ORIGIN = CONFIG_FLASH_START , LENGTH = CONFIG_FLASH_SIZE 15 | ram (rwx) : ORIGIN = CONFIG_RAM_START , LENGTH = CONFIG_RAM_SIZE 16 | } 17 | 18 | SECTIONS 19 | { 20 | .text : { 21 | . = ALIGN(4); 22 | _text_vectortable_start = .; 23 | KEEP(*(.vector_table)) 24 | _text_vectortable_end = .; 25 | *(.text .text.*) 26 | *(.rodata .rodata*) 27 | } > rom 28 | 29 | . = ALIGN(4); 30 | _data_flash = .; 31 | 32 | #if CONFIG_ARMCM_RAM_VECTORTABLE 33 | .ram_vectortable (NOLOAD) : { 34 | _ram_vectortable_start = .; 35 | . = . + ( _text_vectortable_end - _text_vectortable_start ) ; 36 | _ram_vectortable_end = .; 37 | } > ram 38 | #endif 39 | 40 | .data : AT (_data_flash) 41 | { 42 | . = ALIGN(4); 43 | _data_start = .; 44 | *(.ramfunc .ramfunc.*); 45 | *(.data .data.*); 46 | . = ALIGN(4); 47 | _data_end = .; 48 | } > ram 49 | 50 | .bss (NOLOAD) : 51 | { 52 | . = ALIGN(4); 53 | _bss_start = .; 54 | *(.bss .bss.*) 55 | *(COMMON) 56 | . = ALIGN(4); 57 | _bss_end = .; 58 | } > ram 59 | 60 | _stack_start = CONFIG_RAM_START + CONFIG_RAM_SIZE - CONFIG_STACK_SIZE - 8; 61 | .stack _stack_start (NOLOAD) : 62 | { 63 | . = . + CONFIG_STACK_SIZE; 64 | _stack_end = .; 65 | } > ram 66 | 67 | .reserved (NOLOAD) : 68 | { 69 | . = . + 8; 70 | } > ram 71 | 72 | /DISCARD/ : { 73 | // The .init/.fini sections are used by __libc_init_array(), but 74 | // that isn't needed so no need to include them in the binary. 75 | *(.init) 76 | *(.fini) 77 | // Don't include exception tables 78 | *(.ARM.extab) 79 | *(.ARM.exidx) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/can2040/can2040.h: -------------------------------------------------------------------------------- 1 | #ifndef _CAN2040_H 2 | #define _CAN2040_H 3 | 4 | #include // uint32_t 5 | 6 | struct can2040_msg { 7 | uint32_t id; 8 | uint32_t dlc; 9 | union { 10 | uint8_t data[8]; 11 | uint32_t data32[2]; 12 | }; 13 | }; 14 | 15 | enum { 16 | CAN2040_ID_RTR = 1<<30, 17 | CAN2040_ID_EFF = 1<<31, 18 | }; 19 | 20 | enum { 21 | CAN2040_NOTIFY_RX = 1<<20, 22 | CAN2040_NOTIFY_TX = 1<<21, 23 | CAN2040_NOTIFY_ERROR = 1<<23, 24 | }; 25 | struct can2040; 26 | typedef void (*can2040_rx_cb)(struct can2040 *cd, uint32_t notify 27 | , struct can2040_msg *msg); 28 | 29 | void can2040_setup(struct can2040 *cd, uint32_t pio_num); 30 | void can2040_callback_config(struct can2040 *cd, can2040_rx_cb rx_cb); 31 | void can2040_start(struct can2040 *cd, uint32_t sys_clock, uint32_t bitrate 32 | , uint32_t gpio_rx, uint32_t gpio_tx); 33 | void can2040_shutdown(struct can2040 *cd); 34 | void can2040_pio_irq_handler(struct can2040 *cd); 35 | int can2040_check_transmit(struct can2040 *cd); 36 | int can2040_transmit(struct can2040 *cd, struct can2040_msg *msg); 37 | 38 | 39 | /**************************************************************** 40 | * Internal definitions 41 | ****************************************************************/ 42 | 43 | struct can2040_bitunstuffer { 44 | uint32_t stuffed_bits, count_stuff; 45 | uint32_t unstuffed_bits, count_unstuff; 46 | }; 47 | 48 | struct can2040_transmit { 49 | struct can2040_msg msg; 50 | uint32_t crc, stuffed_words, stuffed_data[5]; 51 | }; 52 | 53 | struct can2040 { 54 | // Setup 55 | uint32_t pio_num; 56 | void *pio_hw; 57 | uint32_t gpio_rx, gpio_tx; 58 | can2040_rx_cb rx_cb; 59 | 60 | // Bit unstuffing 61 | struct can2040_bitunstuffer unstuf; 62 | uint32_t raw_bit_count; 63 | 64 | // Input data state 65 | uint32_t parse_state; 66 | uint32_t parse_crc, parse_crc_bits, parse_crc_pos; 67 | struct can2040_msg parse_msg; 68 | 69 | // Reporting 70 | uint32_t report_state; 71 | 72 | // Transmits 73 | uint32_t tx_state; 74 | uint32_t tx_pull_pos, tx_push_pos; 75 | struct can2040_transmit tx_queue[4]; 76 | }; 77 | 78 | #endif // can2040.h 79 | -------------------------------------------------------------------------------- /src/generic/armcm_deployer.lds.S: -------------------------------------------------------------------------------- 1 | // CanBoot "deployer" ARM Cortex-M linker script 2 | // 3 | // Copyright (C) 2019-2022 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "autoconf.h" // CONFIG_FLASH_START 8 | 9 | OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 10 | OUTPUT_ARCH(arm) 11 | 12 | MEMORY 13 | { 14 | rom (rx) : ORIGIN = CONFIG_FLASH_APPLICATION_ADDRESS , LENGTH = CONFIG_FLASH_SIZE 15 | ram (rwx) : ORIGIN = CONFIG_RAM_START , LENGTH = CONFIG_RAM_SIZE 16 | } 17 | 18 | SECTIONS 19 | { 20 | .text : { 21 | . = ALIGN(4); 22 | _text_vectortable_start = .; 23 | KEEP(*(.vector_table)) 24 | _text_vectortable_end = .; 25 | #if CONFIG_LAUNCH_APP_ADDRESS > CONFIG_FLASH_APPLICATION_ADDRESS 26 | . = CONFIG_LAUNCH_APP_ADDRESS - CONFIG_FLASH_APPLICATION_ADDRESS ; 27 | #endif 28 | *(.text .text.*) 29 | *(.rodata .rodata*) 30 | } > rom 31 | 32 | . = ALIGN(4); 33 | _data_flash = .; 34 | 35 | #if CONFIG_ARMCM_RAM_VECTORTABLE 36 | .ram_vectortable (NOLOAD) : { 37 | _ram_vectortable_start = .; 38 | . = . + ( _text_vectortable_end - _text_vectortable_start ) ; 39 | _ram_vectortable_end = .; 40 | } > ram 41 | #endif 42 | 43 | .data : AT (_data_flash) 44 | { 45 | . = ALIGN(4); 46 | _data_start = .; 47 | *(.ramfunc .ramfunc.*); 48 | *(.data .data.*); 49 | . = ALIGN(4); 50 | _data_end = .; 51 | } > ram 52 | 53 | .bss (NOLOAD) : 54 | { 55 | . = ALIGN(4); 56 | _bss_start = .; 57 | *(.bss .bss.*) 58 | *(COMMON) 59 | . = ALIGN(4); 60 | _bss_end = .; 61 | } > ram 62 | 63 | _stack_start = CONFIG_RAM_START + CONFIG_RAM_SIZE - CONFIG_STACK_SIZE ; 64 | .stack _stack_start (NOLOAD) : 65 | { 66 | . = . + CONFIG_STACK_SIZE; 67 | _stack_end = .; 68 | } > ram 69 | 70 | /DISCARD/ : { 71 | // The .init/.fini sections are used by __libc_init_array(), but 72 | // that isn't needed so no need to include them in the binary. 73 | *(.init) 74 | *(.fini) 75 | // Don't include exception tables 76 | *(.ARM.extab) 77 | *(.ARM.exidx) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/bootentry.c: -------------------------------------------------------------------------------- 1 | // Determine if the bootloader or application should start 2 | // 3 | // Copyright (C) 2021 Eric Callahan 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include // strlen 8 | #include "autoconf.h" // CONFIG_* 9 | #include "board/flash.h" // flash_read_block 10 | #include "board/gpio.h" // gpio_in_setup 11 | #include "board/misc.h" // set_bootup_code 12 | #include "bootentry.h" // bootentry_check 13 | #include "canboot.h" // udelay 14 | #include "ctr.h" // DECL_CTR 15 | 16 | // Generated by buildcommands.py 17 | DECL_CTR("DECL_BUTTON " __stringify(CONFIG_BUTTON_PIN)); 18 | extern int32_t button_gpio, button_high, button_pullup; 19 | 20 | // Check for a bootloader request via double tap of reset button 21 | static int 22 | check_button_pressed(void) 23 | { 24 | if (!CONFIG_ENABLE_BUTTON) 25 | return 0; 26 | struct gpio_in button = gpio_in_setup(button_gpio, button_pullup); 27 | udelay(10); 28 | return gpio_in_read(button) == button_high; 29 | } 30 | 31 | #define DOUBLE_CLICK_MIN_US 10000 32 | #define DOUBLE_CLICK_MAX_US 500000 33 | 34 | // Check for a bootloader request via double tap of reset button 35 | static void 36 | check_double_reset(void) 37 | { 38 | if (!CONFIG_ENABLE_DOUBLE_RESET) 39 | return; 40 | // Set request signature and delay - this enters the bootloader if 41 | // the reset button is double clicked 42 | udelay(DOUBLE_CLICK_MIN_US); 43 | set_bootup_code(REQUEST_CANBOOT); 44 | udelay(DOUBLE_CLICK_MAX_US - DOUBLE_CLICK_MIN_US); 45 | // No reset, clear the bootup code 46 | set_bootup_code(0); 47 | } 48 | 49 | // Check if bootloader or application should be started 50 | int 51 | bootentry_check(void) 52 | { 53 | // Enter the bootloader in the following conditions: 54 | // - The request signature is set in memory (request from app) 55 | // - No application code is present 56 | uint64_t bootup_code = get_bootup_code(); 57 | if (bootup_code == REQUEST_CANBOOT || !application_check_valid() 58 | || check_button_pressed()) { 59 | // Start bootloader main loop 60 | set_bootup_code(0); 61 | return 1; 62 | } 63 | check_double_reset(); 64 | 65 | // jump to app 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /lib/stm32f1/include/system_stm32f1xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f10x.h 4 | * @author MCD Application Team 5 | * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2017 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /** @addtogroup CMSIS 21 | * @{ 22 | */ 23 | 24 | /** @addtogroup stm32f10x_system 25 | * @{ 26 | */ 27 | 28 | /** 29 | * @brief Define to prevent recursive inclusion 30 | */ 31 | #ifndef __SYSTEM_STM32F10X_H 32 | #define __SYSTEM_STM32F10X_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | /** @addtogroup STM32F10x_System_Includes 39 | * @{ 40 | */ 41 | 42 | /** 43 | * @} 44 | */ 45 | 46 | 47 | /** @addtogroup STM32F10x_System_Exported_types 48 | * @{ 49 | */ 50 | 51 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 52 | extern const uint8_t AHBPrescTable[16U]; /*!< AHB prescalers table values */ 53 | extern const uint8_t APBPrescTable[8U]; /*!< APB prescalers table values */ 54 | 55 | /** 56 | * @} 57 | */ 58 | 59 | /** @addtogroup STM32F10x_System_Exported_Constants 60 | * @{ 61 | */ 62 | 63 | /** 64 | * @} 65 | */ 66 | 67 | /** @addtogroup STM32F10x_System_Exported_Macros 68 | * @{ 69 | */ 70 | 71 | /** 72 | * @} 73 | */ 74 | 75 | /** @addtogroup STM32F10x_System_Exported_Functions 76 | * @{ 77 | */ 78 | 79 | extern void SystemInit(void); 80 | extern void SystemCoreClockUpdate(void); 81 | /** 82 | * @} 83 | */ 84 | 85 | #ifdef __cplusplus 86 | } 87 | #endif 88 | 89 | #endif /*__SYSTEM_STM32F10X_H */ 90 | 91 | /** 92 | * @} 93 | */ 94 | 95 | /** 96 | * @} 97 | */ 98 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 99 | -------------------------------------------------------------------------------- /src/lpc176x/main.c: -------------------------------------------------------------------------------- 1 | // Main starting point for LPC176x boards. 2 | // 3 | // Copyright (C) 2018-2021 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "autoconf.h" // CONFIG_CLOCK_FREQ 8 | #include "board/armcm_boot.h" // armcm_main 9 | #include "board/armcm_reset.h" // try_request_canboot 10 | #include "board/irq.h" // irq_disable 11 | #include "board/misc.h" // bootloader_request 12 | #include "internal.h" // enable_pclock 13 | #include "sched.h" // sched_main 14 | 15 | 16 | /**************************************************************** 17 | * watchdog handler 18 | ****************************************************************/ 19 | 20 | void 21 | watchdog_reset(void) 22 | { 23 | LPC_WDT->WDFEED = 0xaa; 24 | LPC_WDT->WDFEED = 0x55; 25 | } 26 | DECL_TASK(watchdog_reset); 27 | 28 | void 29 | watchdog_init(void) 30 | { 31 | LPC_WDT->WDTC = 4000000 / 2; // 500ms timeout 32 | LPC_WDT->WDCLKSEL = 1<<31; // Lock to internal RC 33 | LPC_WDT->WDMOD = 0x03; // select reset and enable 34 | watchdog_reset(); 35 | } 36 | DECL_INIT(watchdog_init); 37 | 38 | 39 | /**************************************************************** 40 | * misc functions 41 | ****************************************************************/ 42 | 43 | // Try to reboot into bootloader 44 | void 45 | bootloader_request(void) 46 | { 47 | if (!CONFIG_FLASH_APPLICATION_ADDRESS) 48 | return; 49 | try_request_canboot(); 50 | // Disable USB and pause for 5ms so host recognizes a disconnect 51 | irq_disable(); 52 | if (CONFIG_USB) 53 | usb_disconnect(); 54 | // The "LPC17xx-DFU-Bootloader" will enter the bootloader if the 55 | // watchdog timeout flag is set. 56 | LPC_WDT->WDMOD = 0x07; 57 | NVIC_SystemReset(); 58 | } 59 | 60 | // Check if a peripheral clock has been enabled 61 | int 62 | is_enabled_pclock(uint32_t pclk) 63 | { 64 | return !!(LPC_SC->PCONP & (1<PCONP |= 1< 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include // uint32_t 8 | #include // memcpy 9 | #include "autoconf.h" // CONFIG_CANBUS_FREQUENCY 10 | #include "board/armcm_boot.h" // armcm_enable_irq 11 | #include "board/io.h" // readl 12 | #include "can2040.h" // can2040_setup 13 | #include "command.h" // DECL_CONSTANT_STR 14 | #include "fasthash.h" // fasthash64 15 | #include "generic/canbus.h" // canbus_notify_tx 16 | #include "generic/canserial.h" // CANBUS_ID_ADMIN 17 | #include "hardware/structs/resets.h" // RESETS_RESET_PIO0_BITS 18 | #include "internal.h" // DMA_IRQ_0_IRQn 19 | #include "sched.h" // DECL_INIT 20 | 21 | #define GPIO_STR_CAN_RX "gpio" __stringify(CONFIG_RP2040_CANBUS_GPIO_RX) 22 | #define GPIO_STR_CAN_TX "gpio" __stringify(CONFIG_RP2040_CANBUS_GPIO_TX) 23 | DECL_CONSTANT_STR("RESERVE_PINS_CAN", GPIO_STR_CAN_RX "," GPIO_STR_CAN_TX); 24 | 25 | static struct can2040 cbus; 26 | 27 | // Transmit a packet 28 | int 29 | canhw_send(struct canbus_msg *msg) 30 | { 31 | int ret = can2040_transmit(&cbus, (void*)msg); 32 | if (ret < 0) 33 | return -1; 34 | return CANMSG_DATA_LEN(msg); 35 | } 36 | 37 | // Setup the receive packet filter 38 | void 39 | canhw_set_filter(uint32_t id) 40 | { 41 | // Filter not implemented (and not necessary) 42 | } 43 | 44 | // can2040 callback function - handle rx and tx notifications 45 | static void 46 | can2040_cb(struct can2040 *cd, uint32_t notify, struct can2040_msg *msg) 47 | { 48 | if (notify & CAN2040_NOTIFY_TX) { 49 | canbus_notify_tx(); 50 | return; 51 | } 52 | if (notify & CAN2040_NOTIFY_RX) 53 | canbus_process_data((void*)msg); 54 | } 55 | 56 | // Main PIO irq handler 57 | void 58 | PIOx_IRQHandler(void) 59 | { 60 | can2040_pio_irq_handler(&cbus); 61 | } 62 | 63 | void 64 | can_init(void) 65 | { 66 | // Setup canbus 67 | can2040_setup(&cbus, 0); 68 | can2040_callback_config(&cbus, can2040_cb); 69 | 70 | // Enable irqs 71 | armcm_enable_irq(PIOx_IRQHandler, PIO0_IRQ_0_IRQn, 1); 72 | 73 | // Start canbus 74 | uint32_t pclk = get_pclock_frequency(RESETS_RESET_PIO0_RESET); 75 | can2040_start(&cbus, pclk, CONFIG_CANBUS_FREQUENCY 76 | , CONFIG_RP2040_CANBUS_GPIO_RX, CONFIG_RP2040_CANBUS_GPIO_TX); 77 | } 78 | DECL_INIT(can_init); 79 | -------------------------------------------------------------------------------- /src/rp2040/flash.c: -------------------------------------------------------------------------------- 1 | // Flash (IAP) functionality for RP2040 2 | // This file may be distributed under the terms of the GNU GPLv3 license. 3 | #include "flash.h" 4 | 5 | #include // memcpy 6 | #include "autoconf.h" // CONFIG_BLOCK_SIZE 7 | #include "generic/irq.h" 8 | #include "hw_flash.h" // flash_write_page 9 | 10 | #define MAX(a, b) ((a) > (b))?(a):(b) 11 | #define PAGE_SIZE (MAX(CONFIG_BLOCK_SIZE, 256)) 12 | #define SECTOR_SIZE 4096 13 | 14 | // buffer to consolidate multiple block_size requests into one page size write 15 | static uint32_t buffer_not_empty; // true if buffer hold some data 16 | static uint32_t buffer_start_address; // buffer data should be written at this flash address 17 | static uint8_t buffer[PAGE_SIZE] __aligned(4); // buffer data itseft 18 | 19 | static uint32_t page_write_count; 20 | 21 | static void 22 | flush_buffer(void) 23 | { 24 | if (!buffer_not_empty) { 25 | return; 26 | } 27 | if ((buffer_start_address % SECTOR_SIZE) == 0) { 28 | flash_range_erase(buffer_start_address - CONFIG_FLASH_START, SECTOR_SIZE); 29 | } 30 | flash_range_program(buffer_start_address - CONFIG_FLASH_START, buffer, PAGE_SIZE); 31 | page_write_count += 1; 32 | buffer_not_empty = 0; 33 | } 34 | 35 | static void 36 | ensure_buffer(uint32_t address) 37 | { 38 | if (buffer_not_empty) { 39 | if ((address >= buffer_start_address) && 40 | (address + CONFIG_BLOCK_SIZE <= buffer_start_address + PAGE_SIZE)) { 41 | // current buffer have space for the new data 42 | return; 43 | } else { 44 | // flush existing data 45 | flush_buffer(); 46 | } 47 | } 48 | //prepare buffer 49 | buffer_not_empty = 1; 50 | // address should be multiple of PAGE_SIZE 51 | buffer_start_address = (address / PAGE_SIZE) * PAGE_SIZE; 52 | memset(buffer, 0xFF, PAGE_SIZE); 53 | } 54 | 55 | static int 56 | check_valid_flash_address(uint32_t address) 57 | { 58 | if ((address % CONFIG_BLOCK_SIZE) != 0) { 59 | return -1; 60 | } 61 | if (address < CONFIG_FLASH_START) { 62 | return -2; 63 | } 64 | if (address + CONFIG_BLOCK_SIZE > CONFIG_FLASH_START + CONFIG_FLASH_SIZE) { 65 | return -3; 66 | } 67 | return 0; 68 | } 69 | 70 | int 71 | flash_write_block(uint32_t block_address, uint32_t *data) 72 | { 73 | int ret = check_valid_flash_address(block_address); 74 | if (ret < 0) { 75 | return ret; 76 | } 77 | ensure_buffer(block_address); 78 | memcpy(&buffer[block_address - buffer_start_address], data, CONFIG_BLOCK_SIZE); 79 | return 0; 80 | } 81 | 82 | int 83 | flash_complete(void) 84 | { 85 | flush_buffer(); 86 | return page_write_count; 87 | } 88 | -------------------------------------------------------------------------------- /lib/fast-hash/fasthash.c: -------------------------------------------------------------------------------- 1 | /* The MIT License 2 | 3 | Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com) 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without 8 | restriction, including without limitation the rights to use, copy, 9 | modify, merge, publish, distribute, sublicense, and/or sell copies 10 | of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | */ 25 | 26 | #include "fasthash.h" 27 | 28 | // Compression function for Merkle-Damgard construction. 29 | // This function is generated using the framework provided. 30 | #define mix(h) ({ \ 31 | (h) ^= (h) >> 23; \ 32 | (h) *= 0x2127599bf4325c37ULL; \ 33 | (h) ^= (h) >> 47; }) 34 | 35 | uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) 36 | { 37 | const uint64_t m = 0x880355f21e6d1965ULL; 38 | const uint64_t *pos = (const uint64_t *)buf; 39 | const uint64_t *end = pos + (len / 8); 40 | const unsigned char *pos2; 41 | uint64_t h = seed ^ (len * m); 42 | uint64_t v; 43 | 44 | while (pos != end) { 45 | v = *pos++; 46 | h ^= mix(v); 47 | h *= m; 48 | } 49 | 50 | pos2 = (const unsigned char*)pos; 51 | v = 0; 52 | 53 | switch (len & 7) { 54 | case 7: v ^= (uint64_t)pos2[6] << 48; 55 | case 6: v ^= (uint64_t)pos2[5] << 40; 56 | case 5: v ^= (uint64_t)pos2[4] << 32; 57 | case 4: v ^= (uint64_t)pos2[3] << 24; 58 | case 3: v ^= (uint64_t)pos2[2] << 16; 59 | case 2: v ^= (uint64_t)pos2[1] << 8; 60 | case 1: v ^= (uint64_t)pos2[0]; 61 | h ^= mix(v); 62 | h *= m; 63 | } 64 | 65 | return mix(h); 66 | } 67 | 68 | uint32_t fasthash32(const void *buf, size_t len, uint32_t seed) 69 | { 70 | // the following trick converts the 64-bit hashcode to Fermat 71 | // residue, which shall retain information from both the higher 72 | // and lower parts of hashcode. 73 | uint64_t h = fasthash64(buf, len, seed); 74 | return h - (h >> 32); 75 | } 76 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/regs/addressmap.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | #ifndef _ADDRESSMAP_H_ 7 | #define _ADDRESSMAP_H_ 8 | 9 | #include "hardware/platform_defs.h" 10 | 11 | // Register address offsets for atomic RMW aliases 12 | #define REG_ALIAS_RW_BITS (0x0u << 12u) 13 | #define REG_ALIAS_XOR_BITS (0x1u << 12u) 14 | #define REG_ALIAS_SET_BITS (0x2u << 12u) 15 | #define REG_ALIAS_CLR_BITS (0x3u << 12u) 16 | 17 | #define ROM_BASE _u(0x00000000) 18 | #define XIP_BASE _u(0x10000000) 19 | #define XIP_MAIN_BASE _u(0x10000000) 20 | #define XIP_NOALLOC_BASE _u(0x11000000) 21 | #define XIP_NOCACHE_BASE _u(0x12000000) 22 | #define XIP_NOCACHE_NOALLOC_BASE _u(0x13000000) 23 | #define XIP_CTRL_BASE _u(0x14000000) 24 | #define XIP_SRAM_BASE _u(0x15000000) 25 | #define XIP_SRAM_END _u(0x15004000) 26 | #define XIP_SSI_BASE _u(0x18000000) 27 | #define SRAM_BASE _u(0x20000000) 28 | #define SRAM_STRIPED_BASE _u(0x20000000) 29 | #define SRAM_STRIPED_END _u(0x20040000) 30 | #define SRAM4_BASE _u(0x20040000) 31 | #define SRAM5_BASE _u(0x20041000) 32 | #define SRAM_END _u(0x20042000) 33 | #define SRAM0_BASE _u(0x21000000) 34 | #define SRAM1_BASE _u(0x21010000) 35 | #define SRAM2_BASE _u(0x21020000) 36 | #define SRAM3_BASE _u(0x21030000) 37 | #define SYSINFO_BASE _u(0x40000000) 38 | #define SYSCFG_BASE _u(0x40004000) 39 | #define CLOCKS_BASE _u(0x40008000) 40 | #define RESETS_BASE _u(0x4000c000) 41 | #define PSM_BASE _u(0x40010000) 42 | #define IO_BANK0_BASE _u(0x40014000) 43 | #define IO_QSPI_BASE _u(0x40018000) 44 | #define PADS_BANK0_BASE _u(0x4001c000) 45 | #define PADS_QSPI_BASE _u(0x40020000) 46 | #define XOSC_BASE _u(0x40024000) 47 | #define PLL_SYS_BASE _u(0x40028000) 48 | #define PLL_USB_BASE _u(0x4002c000) 49 | #define BUSCTRL_BASE _u(0x40030000) 50 | #define UART0_BASE _u(0x40034000) 51 | #define UART1_BASE _u(0x40038000) 52 | #define SPI0_BASE _u(0x4003c000) 53 | #define SPI1_BASE _u(0x40040000) 54 | #define I2C0_BASE _u(0x40044000) 55 | #define I2C1_BASE _u(0x40048000) 56 | #define ADC_BASE _u(0x4004c000) 57 | #define PWM_BASE _u(0x40050000) 58 | #define TIMER_BASE _u(0x40054000) 59 | #define WATCHDOG_BASE _u(0x40058000) 60 | #define RTC_BASE _u(0x4005c000) 61 | #define ROSC_BASE _u(0x40060000) 62 | #define VREG_AND_CHIP_RESET_BASE _u(0x40064000) 63 | #define TBMAN_BASE _u(0x4006c000) 64 | #define DMA_BASE _u(0x50000000) 65 | #define USBCTRL_DPRAM_BASE _u(0x50100000) 66 | #define USBCTRL_BASE _u(0x50100000) 67 | #define USBCTRL_REGS_BASE _u(0x50110000) 68 | #define PIO0_BASE _u(0x50200000) 69 | #define PIO1_BASE _u(0x50300000) 70 | #define XIP_AUX_BASE _u(0x50400000) 71 | #define SIO_BASE _u(0xd0000000) 72 | #define PPB_BASE _u(0xe0000000) 73 | 74 | #endif // _ADDRESSMAP_H_ 75 | -------------------------------------------------------------------------------- /scripts/buildbinary.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Tool to check final Katapult binary size 3 | # 4 | # Copyright (C) 2022 Kevin O'Connor 5 | # 6 | # This file may be distributed under the terms of the GNU GPLv3 license. 7 | import sys, argparse, struct 8 | 9 | ERR_MSG = """ 10 | The Katapult binary is too large for the configured LAUNCH_APP_ADDRESS. 11 | 12 | Rerun "make menuconfig" and either increase the LAUNCH_APP_ADDRESS or 13 | disable features to reduce the final binary size. 14 | """ 15 | 16 | C_TEMPLATE = """ 17 | /* DO NOT EDIT! This is an autogenerated file. See scripts/buildbinary.py. */ 18 | 19 | #include 20 | #include "deployer.h" 21 | 22 | const uint8_t deployer_canboot_binary[] = { 23 | %s 24 | }; 25 | 26 | const uint32_t deployer_canboot_binary_size = %d; 27 | """ 28 | 29 | def format_c_code(data): 30 | ldata = len(data) 31 | data = data + (b"\xff" * (8 - (ldata % 8))) 32 | vals = [" "] 33 | for i, d in enumerate(data): 34 | vals.append("0x%02x," % (d,)) 35 | if i % 14 == 13: 36 | vals.append("\n ") 37 | return C_TEMPLATE % ("".join(vals), ldata) 38 | 39 | def update_lpc176x_checksum(data): 40 | data28 = data[:28] 41 | words = struct.unpack(' max_size: 65 | msg = "\nMaximum size %d. Current size %d.\n\n" % (max_size, len(data)) 66 | sys.stderr.write(ERR_MSG + msg) 67 | sys.exit(-1) 68 | 69 | if args.lpc176x: 70 | data = update_lpc176x_checksum(data) 71 | 72 | if args.code: 73 | f = open(args.code, 'w') 74 | f.write(format_c_code(data)) 75 | f.close() 76 | 77 | f = open(args.output_file, 'wb') 78 | f.write(data) 79 | f.close() 80 | 81 | if __name__ == '__main__': 82 | main() 83 | -------------------------------------------------------------------------------- /src/rp2040/serial.c: -------------------------------------------------------------------------------- 1 | // rp2040 serial 2 | // 3 | // Copyright (C) 2021 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include // uint32_t 8 | #include "autoconf.h" // CONFIG_SERIAL 9 | #include "board/armcm_boot.h" // armcm_enable_irq 10 | #include "board/irq.h" // irq_save 11 | #include "board/serial_irq.h" // serial_rx_data 12 | #include "hardware/structs/resets.h" // RESETS_RESET_UART0_BITS 13 | #include "hardware/structs/uart.h" // UART0_BASE 14 | #include "internal.h" // UART0_IRQn 15 | #include "sched.h" // DECL_INIT 16 | 17 | #define UARTx uart0_hw 18 | #define UARTx_IRQn UART0_IRQ_IRQn 19 | #define GPIO_Rx 1 20 | #define GPIO_Tx 0 21 | 22 | // Write tx bytes to the serial port 23 | static void 24 | kick_tx(void) 25 | { 26 | for (;;) { 27 | if (UARTx->fr & UART_UARTFR_TXFF_BITS) { 28 | // Output fifo full - enable tx irq 29 | UARTx->imsc = (UART_UARTIMSC_RXIM_BITS | UART_UARTIMSC_RTIM_BITS 30 | | UART_UARTIMSC_TXIM_BITS); 31 | break; 32 | } 33 | uint8_t data; 34 | int ret = serial_get_tx_byte(&data); 35 | if (ret) { 36 | // No more data to send - disable tx irq 37 | UARTx->imsc = UART_UARTIMSC_RXIM_BITS | UART_UARTIMSC_RTIM_BITS; 38 | break; 39 | } 40 | UARTx->dr = data; 41 | } 42 | } 43 | 44 | void 45 | UARTx_IRQHandler(void) 46 | { 47 | uint32_t mis = UARTx->mis; 48 | if (mis & (UART_UARTMIS_RXMIS_BITS | UART_UARTMIS_RTMIS_BITS)) { 49 | do { 50 | serial_rx_byte(UARTx->dr); 51 | } while (!(UARTx->fr & UART_UARTFR_RXFE_BITS)); 52 | } else if (mis & UART_UARTMIS_TXMIS_BITS) { 53 | kick_tx(); 54 | } 55 | } 56 | 57 | void 58 | serial_enable_tx_irq(void) 59 | { 60 | if (!(UARTx->fr & UART_UARTFR_TXFF_BITS)) { 61 | irqstatus_t flag = irq_save(); 62 | kick_tx(); 63 | irq_restore(flag); 64 | } 65 | } 66 | 67 | void 68 | serial_init(void) 69 | { 70 | enable_pclock(RESETS_RESET_UART0_BITS); 71 | 72 | // Setup baud 73 | uint32_t pclk = get_pclock_frequency(RESETS_RESET_UART0_BITS); 74 | uint32_t div = DIV_ROUND_CLOSEST(pclk * 4, CONFIG_SERIAL_BAUD); 75 | UARTx->ibrd = div >> 6; 76 | UARTx->fbrd = div & 0x3f; 77 | 78 | // Enable fifo, set 8N1 79 | UARTx->lcr_h = UART_UARTLCR_H_FEN_BITS | UART_UARTLCR_H_WLEN_BITS; 80 | UARTx->ifls = 0; 81 | UARTx->cr = (UART_UARTCR_RXE_BITS | UART_UARTCR_TXE_BITS 82 | | UART_UARTCR_UARTEN_BITS); 83 | 84 | // Setup pins 85 | gpio_peripheral(GPIO_Rx, 2, 1); 86 | gpio_peripheral(GPIO_Tx, 2, 0); 87 | 88 | // Enable receive irq 89 | armcm_enable_irq(UARTx_IRQHandler, UARTx_IRQn, 0); 90 | UARTx->imsc = UART_UARTIMSC_RXIM_BITS | UART_UARTIMSC_RTIM_BITS; 91 | } 92 | DECL_INIT(serial_init); 93 | -------------------------------------------------------------------------------- /src/lpc176x/serial.c: -------------------------------------------------------------------------------- 1 | // lpc176x serial port 2 | // 3 | // Copyright (C) 2018-2021 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "board/armcm_boot.h" // armcm_enable_irq 8 | #include "autoconf.h" // CONFIG_SERIAL_BAUD 9 | #include "board/irq.h" // irq_save 10 | #include "board/serial_irq.h" // serial_rx_data 11 | #include "command.h" // DECL_CONSTANT_STR 12 | #include "internal.h" // gpio_peripheral 13 | #include "sched.h" // DECL_INIT 14 | 15 | #if CONFIG_LPC_SERIAL_UART0_P03_P02 16 | DECL_CONSTANT_STR("RESERVE_PINS_serial", "P0.3,P0.2"); 17 | #define GPIO_Rx GPIO(0, 3) 18 | #define GPIO_Tx GPIO(0, 2) 19 | #define GPIO_FUNCTION_UARTx 1 20 | #define LPC_UARTx LPC_UART0 21 | #define UARTx_IRQn UART0_IRQn 22 | #define PCLK_UARTx PCLK_UART0 23 | #elif CONFIG_LPC_SERIAL_UART3_P429_P428 24 | DECL_CONSTANT_STR("RESERVE_PINS_serial", "P4.29,P4.28"); 25 | #define GPIO_Rx GPIO(4, 29) 26 | #define GPIO_Tx GPIO(4, 28) 27 | #define GPIO_FUNCTION_UARTx 3 28 | #define LPC_UARTx LPC_UART3 29 | #define UARTx_IRQn UART3_IRQn 30 | #define PCLK_UARTx PCLK_UART3 31 | #endif 32 | 33 | // Write tx bytes to the serial port 34 | static void 35 | kick_tx(void) 36 | { 37 | for (;;) { 38 | if (!(LPC_UARTx->LSR & (1<<5))) { 39 | // Output fifo full - enable tx irq 40 | LPC_UARTx->IER = 0x03; 41 | break; 42 | } 43 | uint8_t data; 44 | int ret = serial_get_tx_byte(&data); 45 | if (ret) { 46 | // No more data to send - disable tx irq 47 | LPC_UARTx->IER = 0x01; 48 | break; 49 | } 50 | LPC_UARTx->THR = data; 51 | } 52 | } 53 | 54 | void 55 | UARTx_IRQHandler(void) 56 | { 57 | uint32_t iir = LPC_UARTx->IIR, status = iir & 0x0f; 58 | if (status == 0x04) 59 | serial_rx_byte(LPC_UARTx->RBR); 60 | else if (status == 0x02) 61 | kick_tx(); 62 | } 63 | 64 | void 65 | serial_enable_tx_irq(void) 66 | { 67 | if (LPC_UARTx->LSR & (1<<5)) { 68 | irqstatus_t flag = irq_save(); 69 | kick_tx(); 70 | irq_restore(flag); 71 | } 72 | } 73 | 74 | void 75 | serial_init(void) 76 | { 77 | // Setup baud 78 | enable_pclock(PCLK_UARTx); 79 | LPC_UARTx->LCR = (1<<7); // set DLAB bit 80 | uint32_t pclk = get_pclock_frequency(PCLK_UARTx); 81 | uint32_t div = pclk / (CONFIG_SERIAL_BAUD * 16); 82 | LPC_UARTx->DLL = div & 0xff; 83 | LPC_UARTx->DLM = (div >> 8) & 0xff; 84 | LPC_UARTx->FDR = 0x10; 85 | LPC_UARTx->LCR = 3; // 8N1 ; clear DLAB bit 86 | 87 | // Enable fifo 88 | LPC_UARTx->FCR = 0x01; 89 | 90 | // Setup pins 91 | gpio_peripheral(GPIO_Rx, GPIO_FUNCTION_UARTx, 0); 92 | gpio_peripheral(GPIO_Tx, GPIO_FUNCTION_UARTx, 0); 93 | 94 | // Enable receive irq 95 | armcm_enable_irq(UARTx_IRQHandler, UARTx_IRQn, 0); 96 | LPC_UARTx->IER = 0x01; 97 | } 98 | DECL_INIT(serial_init); 99 | -------------------------------------------------------------------------------- /src/lpc176x/Kconfig: -------------------------------------------------------------------------------- 1 | # Kconfig settings for LPC176x processors 2 | 3 | if MACH_LPC176X 4 | 5 | config LPC_SELECT 6 | bool 7 | default y 8 | select HAVE_GPIO 9 | select HAVE_GPIO_ADC 10 | select HAVE_GPIO_I2C 11 | select HAVE_GPIO_SPI 12 | select HAVE_GPIO_BITBANGING 13 | select HAVE_STRICT_TIMING 14 | select HAVE_CHIPID 15 | select HAVE_GPIO_HARD_PWM 16 | select HAVE_STEPPER_BOTH_EDGE 17 | 18 | config BOARD_DIRECTORY 19 | string 20 | default "lpc176x" 21 | 22 | choice 23 | prompt "Processor model" 24 | config MACH_LPC1768 25 | bool "lpc1768 (100 MHz)" 26 | config MACH_LPC1769 27 | bool "lpc1769 (120 MHz)" 28 | endchoice 29 | 30 | config MCU 31 | string 32 | default "lpc1768" if MACH_LPC1768 33 | default "lpc1769" if MACH_LPC1769 34 | 35 | config CLOCK_FREQ 36 | int 37 | default 100000000 if MACH_LPC1768 38 | default 120000000 if MACH_LPC1769 39 | 40 | config FLASH_SIZE 41 | hex 42 | default 0x80000 43 | 44 | config FLASH_BOOT_ADDRESS 45 | hex 46 | default 0x0 47 | 48 | config RAM_START 49 | hex 50 | default 0x10000000 51 | 52 | config RAM_SIZE 53 | hex 54 | default 0x7ee0 # (0x8000 - 256 - 32) 32 bytes for ISP commands, 256 bytes for ISP stack 55 | 56 | config STACK_SIZE 57 | int 58 | default 512 59 | 60 | 61 | ###################################################################### 62 | # Bootloader 63 | ###################################################################### 64 | 65 | choice 66 | prompt "Build Katapult deployment application" 67 | config LPC_FLASH_START_0000 68 | bool "Do not build" 69 | config LPC_FLASH_START_4000 70 | bool "16KiB bootloader (Smoothieware bootloader)" 71 | endchoice 72 | config FLASH_APPLICATION_ADDRESS 73 | hex 74 | default 0x4000 if LPC_FLASH_START_4000 75 | default 0x0000 76 | 77 | 78 | ###################################################################### 79 | # Communication inteface 80 | ###################################################################### 81 | 82 | choice 83 | prompt "Communication interface" 84 | config LPC_USB 85 | bool "USB" 86 | select USBSERIAL 87 | config LPC_SERIAL_UART0_P03_P02 88 | bool "Serial (on UART0 P0.3/P0.2)" 89 | select SERIAL 90 | config LPC_SERIAL_UART3_P429_P428 91 | bool "Serial (on UART3 P4.29/P4.28)" if LOW_LEVEL_OPTIONS 92 | select SERIAL 93 | endchoice 94 | 95 | 96 | ###################################################################### 97 | # Flash settings 98 | ###################################################################### 99 | 100 | config FLASH_START 101 | hex 102 | default 0x0000 103 | 104 | config LAUNCH_APP_ADDRESS 105 | hex 106 | default 0x4000 107 | 108 | config BLOCK_SIZE 109 | int 110 | default 64 111 | 112 | endif 113 | -------------------------------------------------------------------------------- /lib/stm32g0/include/system_stm32g0xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32g0xx.h 4 | * @author MCD Application Team 5 | * @brief CMSIS Cortex-M0+ Device System Source File for STM32G0xx devices. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2018 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under Apache License, Version 2.0, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/Apache-2.0 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /** @addtogroup CMSIS 21 | * @{ 22 | */ 23 | 24 | /** @addtogroup stm32g0xx_system 25 | * @{ 26 | */ 27 | 28 | /** 29 | * @brief Define to prevent recursive inclusion 30 | */ 31 | #ifndef SYSTEM_STM32G0XX_H 32 | #define SYSTEM_STM32G0XX_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | /** @addtogroup STM32G0xx_System_Includes 39 | * @{ 40 | */ 41 | 42 | /** 43 | * @} 44 | */ 45 | 46 | 47 | /** @addtogroup STM32G0xx_System_Exported_types 48 | * @{ 49 | */ 50 | /* This variable is updated in three ways: 51 | 1) by calling CMSIS function SystemCoreClockUpdate() 52 | 2) by calling HAL API function HAL_RCC_GetSysClockFreq() 53 | 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency 54 | Note: If you use this function to configure the system clock; then there 55 | is no need to call the 2 first functions listed above, since SystemCoreClock 56 | variable is updated automatically. 57 | */ 58 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 59 | 60 | extern const uint32_t AHBPrescTable[16]; /*!< AHB prescalers table values */ 61 | extern const uint32_t APBPrescTable[8]; /*!< APB prescalers table values */ 62 | 63 | /** 64 | * @} 65 | */ 66 | 67 | /** @addtogroup STM32G0xx_System_Exported_Constants 68 | * @{ 69 | */ 70 | 71 | /** 72 | * @} 73 | */ 74 | 75 | /** @addtogroup STM32G0xx_System_Exported_Macros 76 | * @{ 77 | */ 78 | 79 | /** 80 | * @} 81 | */ 82 | 83 | /** @addtogroup STM32G0xx_System_Exported_Functions 84 | * @{ 85 | */ 86 | 87 | extern void SystemInit(void); 88 | extern void SystemCoreClockUpdate(void); 89 | /** 90 | * @} 91 | */ 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif /*SYSTEM_STM32G0XX_H */ 98 | 99 | /** 100 | * @} 101 | */ 102 | 103 | /** 104 | * @} 105 | */ 106 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 107 | -------------------------------------------------------------------------------- /lib/stm32f2/include/system_stm32f2xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f2xx.h 4 | * @author MCD Application Team 5 | * @brief CMSIS Cortex-M3 Device System Source File for STM32F2xx devices. 6 | **************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2017 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /** @addtogroup CMSIS 21 | * @{ 22 | */ 23 | 24 | /** @addtogroup stm32f2xx_system 25 | * @{ 26 | */ 27 | 28 | /** 29 | * @brief Define to prevent recursive inclusion 30 | */ 31 | #ifndef __SYSTEM_STM32F2XX_H 32 | #define __SYSTEM_STM32F2XX_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | /** @addtogroup STM32F2xx_System_Includes 39 | * @{ 40 | */ 41 | 42 | /** 43 | * @} 44 | */ 45 | 46 | 47 | /** @addtogroup STM32F2xx_System_Exported_types 48 | * @{ 49 | */ 50 | /* This variable is updated in three ways: 51 | 1) by calling CMSIS function SystemCoreClockUpdate() 52 | 2) by calling HAL API function HAL_RCC_GetSysClockFreq() 53 | 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency 54 | Note: If you use this function to configure the system clock; then there 55 | is no need to call the 2 first functions listed above, since SystemCoreClock 56 | variable is updated automatically. 57 | */ 58 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 59 | 60 | extern const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */ 61 | extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */ 62 | 63 | /** 64 | * @} 65 | */ 66 | 67 | /** @addtogroup STM32F2xx_System_Exported_Constants 68 | * @{ 69 | */ 70 | 71 | /** 72 | * @} 73 | */ 74 | 75 | /** @addtogroup STM32F2xx_System_Exported_Macros 76 | * @{ 77 | */ 78 | 79 | /** 80 | * @} 81 | */ 82 | 83 | /** @addtogroup STM32F2xx_System_Exported_Functions 84 | * @{ 85 | */ 86 | 87 | extern void SystemInit(void); 88 | extern void SystemCoreClockUpdate(void); 89 | /** 90 | * @} 91 | */ 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif /*__SYSTEM_STM32F2XX_H */ 98 | 99 | /** 100 | * @} 101 | */ 102 | 103 | /** 104 | * @} 105 | */ 106 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 107 | -------------------------------------------------------------------------------- /lib/stm32h7/include/system_stm32h7xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32h7xx.h 4 | * @author MCD Application Team 5 | * @brief CMSIS Cortex-Mx Device System Source File for STM32H7xx devices. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2017 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /** @addtogroup CMSIS 21 | * @{ 22 | */ 23 | 24 | /** @addtogroup stm32h7xx_system 25 | * @{ 26 | */ 27 | 28 | /** 29 | * @brief Define to prevent recursive inclusion 30 | */ 31 | #ifndef SYSTEM_STM32H7XX_H 32 | #define SYSTEM_STM32H7XX_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | /** @addtogroup STM32H7xx_System_Includes 39 | * @{ 40 | */ 41 | 42 | /** 43 | * @} 44 | */ 45 | 46 | 47 | /** @addtogroup STM32H7xx_System_Exported_types 48 | * @{ 49 | */ 50 | /* This variable is updated in three ways: 51 | 1) by calling CMSIS function SystemCoreClockUpdate() 52 | 2) by calling HAL API function HAL_RCC_GetSysClockFreq() 53 | 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency 54 | Note: If you use this function to configure the system clock; then there 55 | is no need to call the 2 first functions listed above, since SystemCoreClock 56 | variable is updated automatically. 57 | */ 58 | extern uint32_t SystemCoreClock; /*!< System Domain1 Clock Frequency */ 59 | extern uint32_t SystemD2Clock; /*!< System Domain2 Clock Frequency */ 60 | extern const uint8_t D1CorePrescTable[16] ; /*!< D1CorePrescTable prescalers table values */ 61 | 62 | /** 63 | * @} 64 | */ 65 | 66 | /** @addtogroup STM32H7xx_System_Exported_Constants 67 | * @{ 68 | */ 69 | 70 | /** 71 | * @} 72 | */ 73 | 74 | /** @addtogroup STM32H7xx_System_Exported_Macros 75 | * @{ 76 | */ 77 | 78 | /** 79 | * @} 80 | */ 81 | 82 | /** @addtogroup STM32H7xx_System_Exported_Functions 83 | * @{ 84 | */ 85 | 86 | extern void SystemInit(void); 87 | extern void SystemCoreClockUpdate(void); 88 | /** 89 | * @} 90 | */ 91 | 92 | #ifdef __cplusplus 93 | } 94 | #endif 95 | 96 | #endif /* SYSTEM_STM32H7XX_H */ 97 | 98 | /** 99 | * @} 100 | */ 101 | 102 | /** 103 | * @} 104 | */ 105 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 106 | -------------------------------------------------------------------------------- /src/command.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMAND_H 2 | #define __COMMAND_H 3 | 4 | #include // va_list 5 | #include 6 | #include // uint32_t 7 | #include "ctr.h" // DECL_CTR 8 | 9 | // Declare a constant exported to the host 10 | #define DECL_CONSTANT(NAME, VALUE) \ 11 | DECL_CTR_INT("DECL_CONSTANT " NAME, 1, CTR_INT(VALUE)) 12 | #define DECL_CONSTANT_STR(NAME, VALUE) \ 13 | DECL_CTR("DECL_CONSTANT_STR " NAME " " VALUE) 14 | 15 | // Declare an enumeration 16 | #define DECL_ENUMERATION(ENUM, NAME, VALUE) \ 17 | DECL_CTR_INT("DECL_ENUMERATION " ENUM " " NAME, 1, CTR_INT(VALUE)) 18 | #define DECL_ENUMERATION_RANGE(ENUM, NAME, VALUE, COUNT) \ 19 | DECL_CTR_INT("DECL_ENUMERATION_RANGE " ENUM " " NAME, \ 20 | 2, CTR_INT(VALUE), CTR_INT(COUNT)) 21 | 22 | // Shutdown wrappers for Klipper compatibility 23 | #define shutdown(msg) do { } while (1) 24 | #define try_shutdown(msg) do { } while (0) 25 | 26 | #define PROTO_VERSION 0x00010100 // Version 1.1.0 27 | #define CMD_CONNECT 0x11 28 | #define CMD_RX_BLOCK 0x12 29 | #define CMD_RX_EOF 0x13 30 | #define CMD_REQ_BLOCK 0x14 31 | #define CMD_COMPLETE 0x15 32 | #define CMD_GET_CANBUS_ID 0x16 33 | #define RESPONSE_ACK 0xa0 34 | #define RESPONSE_NACK 0xf1 35 | #define RESPONSE_COMMAND_ERROR 0xf2 36 | 37 | // Command Format: 38 | // <2 byte header> <1 byte cmd> <1 byte data word count> <2 byte crc> <2 byte trailer> 39 | #define MESSAGE_MIN 8 40 | #define MESSAGE_MAX 128 41 | #define MESSAGE_HEADER_SIZE 4 42 | #define MESSAGE_TRAILER_SIZE 4 43 | #define MESSAGE_POS_STX1 0 44 | #define MESSAGE_POS_STX2 1 45 | #define MESSAGE_POS_LEN 3 46 | #define MESSAGE_TRAILER_CRC 4 47 | #define MESSAGE_TRAILER_SYNC2 2 48 | #define MESSAGE_TRAILER_SYNC 1 49 | #define MESSAGE_STX1 0x01 50 | #define MESSAGE_STX2 0x88 51 | #define MESSAGE_SYNC2 0x99 52 | #define MESSAGE_SYNC 0x03 53 | 54 | // command handlers 55 | void command_connect(uint32_t *data); 56 | void command_read_block(uint32_t *data); 57 | void command_write_block(uint32_t *data); 58 | void command_eof(uint32_t *data); 59 | void command_complete(uint32_t *data); 60 | void command_get_canbus_id(uint32_t *data); 61 | 62 | // command.c 63 | void command_respond_ack(uint32_t acked_cmd, uint32_t *out, uint32_t out_len); 64 | void command_respond_command_error(void); 65 | int command_get_arg_count(uint32_t *data); 66 | 67 | struct command_encoder { 68 | uint32_t *data; 69 | uint_fast8_t max_size; 70 | }; 71 | uint_fast8_t command_encode_and_frame( 72 | uint8_t *buf, const struct command_encoder *ce, va_list args); 73 | int_fast8_t command_find_block(uint8_t *buf, uint_fast8_t buf_len 74 | , uint_fast8_t *pop_count); 75 | void command_dispatch(uint8_t *buf, uint_fast8_t msglen); 76 | void command_send_ack(void); 77 | int_fast8_t command_find_and_dispatch(uint8_t *buf, uint_fast8_t buf_len 78 | , uint_fast8_t *pop_count); 79 | 80 | #endif // command.h 81 | -------------------------------------------------------------------------------- /src/deployer.c: -------------------------------------------------------------------------------- 1 | // Main code for canboot deployer application 2 | // 3 | // Copyright (C) 2016-2022 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include // memcmp 8 | #include "autoconf.h" // CONFIG_BLOCK_SIZE 9 | #include "board/armcm_reset.h" // try_request_canboot 10 | #include "board/flash.h" // flash_write_block 11 | #include "board/io.h" // readb 12 | #include "board/misc.h" // timer_read_time 13 | #include "canboot.h" // timer_setup 14 | #include "deployer.h" // deployer_is_active 15 | #include "sched.h" // sched_check_periodic 16 | 17 | // The CanBoot "deployer application" is running 18 | int 19 | deployer_is_active(void) 20 | { 21 | return 1; 22 | } 23 | 24 | // Implement simple delay mechanism 25 | void 26 | udelay(uint32_t usecs) 27 | { 28 | uint32_t end = timer_read_time() + timer_from_us(usecs); 29 | while (timer_is_before(timer_read_time(), end)) 30 | ; 31 | } 32 | 33 | // Wrapper for Klipper compatibility 34 | void 35 | sched_wake_tasks(void) 36 | { 37 | } 38 | 39 | // Note that a task is ready to run 40 | void 41 | sched_wake_task(struct task_wake *w) 42 | { 43 | writeb(&w->wake, 1); 44 | } 45 | 46 | // Check if a task is ready to run (as indicated by sched_wake_task) 47 | uint8_t 48 | sched_check_wake(struct task_wake *w) 49 | { 50 | if (!readb(&w->wake)) 51 | return 0; 52 | writeb(&w->wake, 0); 53 | return 1; 54 | } 55 | 56 | // Halt the processor 57 | static void 58 | halt(void) 59 | { 60 | for (;;) 61 | ; 62 | } 63 | 64 | // Init followed by CanBoot flashing 65 | void 66 | sched_main(void) 67 | { 68 | timer_setup(); 69 | 70 | // Run all init functions marked with DECL_INIT() 71 | extern void ctr_run_initfuncs(void); 72 | ctr_run_initfuncs(); 73 | 74 | // Check if flash has already been written 75 | void *fstart = (void*)CONFIG_FLASH_START; 76 | uint32_t cbsize = deployer_canboot_binary_size; 77 | if (memcmp(fstart, deployer_canboot_binary, cbsize) == 0) { 78 | try_request_canboot(); 79 | halt(); 80 | } 81 | 82 | // Wait 100ms to help ensure power supply is stable before 83 | // overwriting existing bootloader 84 | udelay(100000); 85 | 86 | // Write CanBoot to flash 87 | const uint8_t *p = deployer_canboot_binary, *end = &p[cbsize]; 88 | while (p < end) { 89 | uint32_t data[CONFIG_BLOCK_SIZE / 4]; 90 | memset(data, 0xff, sizeof(data)); 91 | uint32_t c = CONFIG_BLOCK_SIZE; 92 | if (p + c > end) 93 | c = end - p; 94 | memcpy(data, p, c); 95 | int ret = flash_write_block((uint32_t)fstart, data); 96 | if (ret < 0) 97 | // An error occurred - halt to try avoiding endless boot loops 98 | halt(); 99 | p += c; 100 | fstart += c; 101 | } 102 | flash_complete(); 103 | 104 | // Flash completed - reboot into canboot 105 | try_request_canboot(); 106 | } 107 | -------------------------------------------------------------------------------- /src/rp2040/Makefile: -------------------------------------------------------------------------------- 1 | # Additional RP2040 build rules 2 | 3 | # Setup the toolchain 4 | CROSS_PREFIX=arm-none-eabi- 5 | 6 | dirs-y += src/rp2040 src/generic lib/rp2040/elf2uf2 lib/fast-hash lib/can2040 lib/rp2040/pico/flash/ 7 | 8 | CFLAGS += -mcpu=cortex-m0plus -mthumb -Ilib/cmsis-core 9 | CFLAGS += -Ilib/rp2040 -Ilib/rp2040/cmsis_include -Ilib/fast-hash -Ilib/can2040 -Ilib/rp2040/pico/flash/ -Ilib/rp2040/pico/bootrom/ 10 | 11 | CFLAGS_katapult.elf += -nostdlib -lgcc -lc_nano 12 | CFLAGS_katapult.elf += -T $(OUT)src/rp2040/rp2040_link.ld 13 | 14 | # Add source files 15 | mcu-y = rp2040/main.c rp2040/gpio.c rp2040/timer.c rp2040/flash.c ../lib/rp2040/pico/flash/hw_flash.c 16 | mcu-y += generic/armcm_irq.c generic/crc16_ccitt.c 17 | 18 | src-y += rp2040/armcm_canboot.c $(mcu-y) 19 | src-$(CONFIG_USBSERIAL) += rp2040/usbserial.c generic/usb_cdc.c 20 | src-$(CONFIG_USBSERIAL) += rp2040/chipid.c 21 | src-$(CONFIG_SERIAL) += rp2040/serial.c generic/serial_irq.c 22 | src-$(CONFIG_CANSERIAL) += rp2040/can.c rp2040/chipid.c ../lib/can2040/can2040.c 23 | src-$(CONFIG_CANSERIAL) += generic/canserial.c generic/canbus.c 24 | src-$(CONFIG_CANSERIAL) += ../lib/fast-hash/fasthash.c 25 | 26 | $(OUT)katapult.elf: $(OUT)stage2.o $(OUT)src/rp2040/rp2040_link.ld 27 | # rp2040 stage2 building 28 | STAGE2_FILE := $(shell echo $(CONFIG_RP2040_STAGE2_FILE)) 29 | $(OUT)stage2.o: lib/rp2040/boot_stage2/$(STAGE2_FILE) $(OUT)autoconf.h 30 | @echo " Building rp2040 stage2 $@" 31 | $(Q)$(CC) $(CFLAGS) -Ilib/rp2040/boot_stage2 -Ilib/rp2040/boot_stage2/asminclude -DPICO_FLASH_SPI_CLKDIV=$(CONFIG_RP2040_STAGE2_CLKDIV) -c $< -o $(OUT)stage2raw1.o 32 | $(Q)$(LD) $(OUT)stage2raw1.o --script=lib/rp2040/boot_stage2/boot_stage2.ld -o $(OUT)stage2raw.o 33 | $(Q)$(OBJCOPY) -O binary $(OUT)stage2raw.o $(OUT)stage2raw.bin 34 | $(Q)lib/rp2040/boot_stage2/pad_checksum -s 0xffffffff $(OUT)stage2raw.bin $(OUT)stage2.S 35 | $(Q)$(CC) $(CFLAGS) -c $(OUT)stage2.S -o $(OUT)stage2.o 36 | OBJS_katapult.elf += $(OUT)stage2.o 37 | 38 | # Binary output file rules 39 | target-y += $(OUT)katapult.uf2 40 | 41 | $(OUT)lib/rp2040/elf2uf2/elf2uf2: lib/rp2040/elf2uf2/main.cpp 42 | @echo " Building $@" 43 | $(Q)g++ -g -O -Ilib/rp2040 $< -o $@ 44 | 45 | $(OUT)katapult.uf2: $(OUT)katapult.elf $(OUT)lib/rp2040/elf2uf2/elf2uf2 46 | @echo " Creating uf2 file $@" 47 | $(Q)$(OUT)lib/rp2040/elf2uf2/elf2uf2 $(OUT)katapult.elf $(OUT)katapult.uf2 48 | ifeq ($(CONFIG_RP2040_ADD_BOOT_SIGNATURE), y) 49 | $(Q)$(PYTHON) ./scripts/uf2_append_boot_signature.py --address $(CONFIG_LAUNCH_APP_ADDRESS) --input $(OUT)katapult.uf2 --output $(OUT)katapult.uf2 50 | endif 51 | @echo " Creating legacy uf2 file $(OUT)canboot.uf2" 52 | $(Q)cp $@ $(OUT)canboot.uf2 53 | 54 | lib/rp2040_flash/rp2040_flash: 55 | @echo " Building rp2040_flash" 56 | $(Q)make -C lib/rp2040_flash rp2040_flash 57 | 58 | # Flash rules 59 | flash: $(OUT)katapult.uf2 lib/rp2040_flash/rp2040_flash 60 | @echo " Flashing $< " 61 | $(Q) $(if $(NOSUDO),,sudo) ./lib/rp2040_flash/rp2040_flash $(OUT)katapult.uf2 62 | 63 | # Deployer build 64 | deployer-y += generic/armcm_boot.c generic/armcm_reset.c $(mcu-y) 65 | CFLAGS_deployer.elf += -nostdlib -lgcc -lc_nano 66 | CFLAGS_deployer.elf += -T $(OUT)src/generic/armcm_deployer.ld 67 | $(OUT)deployer.elf: $(OUT)src/generic/armcm_deployer.ld 68 | -------------------------------------------------------------------------------- /src/rp2040/Kconfig: -------------------------------------------------------------------------------- 1 | # Kconfig settings for RP2040 processor 2 | 3 | if MACH_RP2040 4 | 5 | config RP2040_SELECT 6 | bool 7 | default y 8 | select HAVE_GPIO 9 | select HAVE_CHIPID 10 | 11 | config BOARD_DIRECTORY 12 | string 13 | default "rp2040" 14 | 15 | config MCU 16 | string 17 | default "rp2040" 18 | 19 | config CLOCK_FREQ 20 | int 21 | default 12000000 22 | 23 | config FLASH_SIZE 24 | hex 25 | default 0x200000 26 | 27 | config RAM_START 28 | hex 29 | default 0x20000000 30 | 31 | config RAM_SIZE 32 | hex 33 | default 0x42000 34 | 35 | config STACK_SIZE 36 | int 37 | default 512 38 | 39 | config FLASH_START 40 | hex 41 | default 0x10000000 42 | 43 | config LAUNCH_APP_ADDRESS 44 | default 0x10004000 45 | hex 46 | 47 | config FLASH_BOOT_ADDRESS 48 | hex 49 | default 0x10000100 50 | 51 | config BLOCK_SIZE 52 | int 53 | default 64 54 | 55 | ###################################################################### 56 | # Bootloader options 57 | ###################################################################### 58 | 59 | config RP2040_ADD_BOOT_SIGNATURE 60 | bool 61 | default y 62 | help 63 | Add boot signature (zero page at application start) 64 | into resulting uf2. 65 | This is used to force bootloader entry 66 | before application is updated. 67 | 68 | choice 69 | prompt "Flash chip" if LOW_LEVEL_OPTIONS 70 | config RP2040_FLASH_W25Q080 71 | bool "W25Q080 with CLKDIV 2" 72 | config RP2040_FLASH_GENERIC_03 73 | bool "GENERIC_03H with CLKDIV 4" 74 | endchoice 75 | 76 | config RP2040_STAGE2_FILE 77 | string 78 | default "boot2_generic_03h.S" if RP2040_FLASH_GENERIC_03 79 | default "boot2_w25q080.S" 80 | 81 | config RP2040_STAGE2_CLKDIV 82 | int 83 | default 4 if RP2040_FLASH_GENERIC_03 84 | default 2 85 | 86 | ###################################################################### 87 | # Deployer 88 | ###################################################################### 89 | 90 | choice 91 | prompt "Build Katapult deployment application" 92 | config RP2040_FLASH_START_0000 93 | bool "Do not build" 94 | config RP2040_FLASH_START_4000 95 | bool "16KiB bootloader" 96 | endchoice 97 | config FLASH_APPLICATION_ADDRESS 98 | hex 99 | default 0x10004000 if RP2040_FLASH_START_4000 100 | default 0x10000100 101 | 102 | ###################################################################### 103 | # Communication inteface 104 | ###################################################################### 105 | 106 | choice 107 | prompt "Communication interface" 108 | config RP2040_USB 109 | bool "USB" 110 | select USBSERIAL 111 | config RP2040_SERIAL_UART0 112 | bool "Serial (on UART0 GPIO1/GPIO0)" 113 | select SERIAL 114 | config RP2040_CANBUS 115 | bool "CAN bus" 116 | select CANSERIAL 117 | endchoice 118 | 119 | config RP2040_CANBUS_GPIO_RX 120 | int "CAN RX gpio number" if CANBUS 121 | default 4 122 | range 0 29 123 | 124 | config RP2040_CANBUS_GPIO_TX 125 | int "CAN TX gpio number" if CANBUS 126 | default 5 127 | range 0 29 128 | 129 | endif 130 | -------------------------------------------------------------------------------- /src/stm32/serial.c: -------------------------------------------------------------------------------- 1 | // STM32 serial 2 | // 3 | // Copyright (C) 2019 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "autoconf.h" // CONFIG_SERIAL_BAUD 8 | #include "board/armcm_boot.h" // armcm_enable_irq 9 | #include "board/serial_irq.h" // serial_rx_byte 10 | #include "command.h" // DECL_CONSTANT_STR 11 | #include "internal.h" // enable_pclock 12 | #include "sched.h" // DECL_INIT 13 | 14 | // Select the configured serial port 15 | #if CONFIG_STM32_SERIAL_USART1 16 | DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA10,PA9"); 17 | #define GPIO_Rx GPIO('A', 10) 18 | #define GPIO_Tx GPIO('A', 9) 19 | #define USARTx USART1 20 | #define USARTx_IRQn USART1_IRQn 21 | #elif CONFIG_STM32_SERIAL_USART1_ALT_PB7_PB6 22 | DECL_CONSTANT_STR("RESERVE_PINS_serial", "PB7,PB6"); 23 | #define GPIO_Rx GPIO('B', 7) 24 | #define GPIO_Tx GPIO('B', 6) 25 | #define USARTx USART1 26 | #define USARTx_IRQn USART1_IRQn 27 | #elif CONFIG_STM32_SERIAL_USART2 28 | DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA3,PA2"); 29 | #define GPIO_Rx GPIO('A', 3) 30 | #define GPIO_Tx GPIO('A', 2) 31 | #define USARTx USART2 32 | #define USARTx_IRQn USART2_IRQn 33 | #elif CONFIG_STM32_SERIAL_USART2_ALT_PD6_PD5 34 | DECL_CONSTANT_STR("RESERVE_PINS_serial", "PD6,PD5"); 35 | #define GPIO_Rx GPIO('D', 6) 36 | #define GPIO_Tx GPIO('D', 5) 37 | #define USARTx USART2 38 | #define USARTx_IRQn USART2_IRQn 39 | #elif CONFIG_STM32_SERIAL_USART3 40 | DECL_CONSTANT_STR("RESERVE_PINS_serial", "PB11,PB10"); 41 | #define GPIO_Rx GPIO('B', 11) 42 | #define GPIO_Tx GPIO('B', 10) 43 | #define USARTx USART3 44 | #define USARTx_IRQn USART3_IRQn 45 | #elif CONFIG_STM32_SERIAL_USART3_ALT_PD9_PD8 46 | DECL_CONSTANT_STR("RESERVE_PINS_serial", "PD9,PD8"); 47 | #define GPIO_Rx GPIO('D', 9) 48 | #define GPIO_Tx GPIO('D', 8) 49 | #define USARTx USART3 50 | #define USARTx_IRQn USART3_IRQn 51 | #endif 52 | 53 | #define CR1_FLAGS (USART_CR1_UE | USART_CR1_RE | USART_CR1_TE \ 54 | | USART_CR1_RXNEIE) 55 | 56 | void 57 | USARTx_IRQHandler(void) 58 | { 59 | uint32_t sr = USARTx->SR; 60 | if (sr & (USART_SR_RXNE | USART_SR_ORE)) { 61 | // The ORE flag is automatically cleared by reading SR, followed 62 | // by reading DR. 63 | serial_rx_byte(USARTx->DR); 64 | } 65 | if (sr & USART_SR_TXE && USARTx->CR1 & USART_CR1_TXEIE) { 66 | uint8_t data; 67 | int ret = serial_get_tx_byte(&data); 68 | if (ret) 69 | USARTx->CR1 = CR1_FLAGS; 70 | else 71 | USARTx->DR = data; 72 | } 73 | } 74 | 75 | void 76 | serial_enable_tx_irq(void) 77 | { 78 | USARTx->CR1 = CR1_FLAGS | USART_CR1_TXEIE; 79 | } 80 | 81 | void 82 | serial_init(void) 83 | { 84 | enable_pclock((uint32_t)USARTx); 85 | 86 | uint32_t pclk = get_pclock_frequency((uint32_t)USARTx); 87 | uint32_t div = DIV_ROUND_CLOSEST(pclk, CONFIG_SERIAL_BAUD); 88 | USARTx->BRR = (((div / 16) << USART_BRR_DIV_Mantissa_Pos) 89 | | ((div % 16) << USART_BRR_DIV_Fraction_Pos)); 90 | USARTx->CR1 = CR1_FLAGS; 91 | armcm_enable_irq(USARTx_IRQHandler, USARTx_IRQn, 0); 92 | 93 | gpio_peripheral(GPIO_Rx, GPIO_FUNCTION(7), 1); 94 | gpio_peripheral(GPIO_Tx, GPIO_FUNCTION(7), 0); 95 | } 96 | DECL_INIT(serial_init); 97 | -------------------------------------------------------------------------------- /src/rp2040/gpio.c: -------------------------------------------------------------------------------- 1 | // GPIO functions on rp2040 2 | // 3 | // Copyright (C) 2021 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include // ffs 8 | #include "board/irq.h" // irq_save 9 | #include "command.h" // shutdown 10 | #include "gpio.h" // gpio_out_setup 11 | #include "hardware/structs/iobank0.h" // iobank0_hw 12 | #include "hardware/structs/padsbank0.h" // padsbank0_hw 13 | #include "hardware/structs/sio.h" // sio_hw 14 | #include "internal.h" // gpio_peripheral 15 | #include "sched.h" // sched_shutdown 16 | 17 | 18 | /**************************************************************** 19 | * Pin mappings 20 | ****************************************************************/ 21 | 22 | DECL_ENUMERATION_RANGE("pin", "gpio0", 0, 30); 23 | 24 | // Set the mode and extended function of a pin 25 | void 26 | gpio_peripheral(uint32_t gpio, int func, int pull_up) 27 | { 28 | padsbank0_hw->io[gpio] = ( 29 | PADS_BANK0_GPIO0_IE_BITS 30 | | (PADS_BANK0_GPIO0_DRIVE_VALUE_4MA << PADS_BANK0_GPIO0_DRIVE_MSB) 31 | | (pull_up > 0 ? PADS_BANK0_GPIO0_PUE_BITS : 0) 32 | | (pull_up < 0 ? PADS_BANK0_GPIO0_PDE_BITS : 0)); 33 | iobank0_hw->io[gpio].ctrl = func << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB; 34 | } 35 | 36 | // Convert a register and bit location back to an integer pin identifier 37 | static int 38 | mask_to_pin(uint32_t mask) 39 | { 40 | return ffs(mask)-1; 41 | } 42 | 43 | 44 | /**************************************************************** 45 | * General Purpose Input Output (GPIO) pins 46 | ****************************************************************/ 47 | 48 | struct gpio_out 49 | gpio_out_setup(uint8_t pin, uint8_t val) 50 | { 51 | if (pin >= 30) 52 | goto fail; 53 | struct gpio_out g = { .bit=1<gpio_oe_set = g.bit; 67 | gpio_peripheral(pin, 5, 0); 68 | irq_restore(flag); 69 | } 70 | 71 | void 72 | gpio_out_toggle_noirq(struct gpio_out g) 73 | { 74 | sio_hw->gpio_togl = g.bit; 75 | } 76 | 77 | void 78 | gpio_out_toggle(struct gpio_out g) 79 | { 80 | gpio_out_toggle_noirq(g); 81 | } 82 | 83 | void 84 | gpio_out_write(struct gpio_out g, uint8_t val) 85 | { 86 | if (val) 87 | sio_hw->gpio_set = g.bit; 88 | else 89 | sio_hw->gpio_clr = g.bit; 90 | } 91 | 92 | 93 | struct gpio_in 94 | gpio_in_setup(uint8_t pin, int8_t pull_up) 95 | { 96 | if (pin >= 30) 97 | goto fail; 98 | struct gpio_in g = { .bit=1<gpio_oe_clr = g.bit; 112 | irq_restore(flag); 113 | } 114 | 115 | uint8_t 116 | gpio_in_read(struct gpio_in g) 117 | { 118 | return !!(sio_hw->gpio_in & g.bit); 119 | } 120 | -------------------------------------------------------------------------------- /src/stm32/stm32f0_timer.c: -------------------------------------------------------------------------------- 1 | // STM32F0 timer support 2 | // 3 | // Copyright (C) 2019 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "board/armcm_boot.h" // armcm_enable_irq 8 | #include "board/armcm_timer.h" // udelay 9 | #include "board/internal.h" // TIM3 10 | #include "board/io.h" // readl 11 | #include "board/irq.h" // irq_disable 12 | #include "board/misc.h" // timer_read_time 13 | #include "canboot.h" // timer_setup 14 | 15 | 16 | /**************************************************************** 17 | * Low level timer code 18 | ****************************************************************/ 19 | 20 | // Use 32bit TIM2 timer if available (otherwise use 16bit TIM3 timer) 21 | #if defined(TIM2) 22 | #define TIMx TIM2 23 | #define TIMx_IRQn TIM2_IRQn 24 | #define HAVE_TIMER_32BIT 1 25 | #elif defined(TIM3) 26 | #define TIMx TIM3 27 | #define TIMx_IRQn TIM3_IRQn 28 | #define HAVE_TIMER_32BIT 0 29 | #endif 30 | 31 | // Some chips have slightly different register names 32 | #if CONFIG_MACH_STM32G0B0 33 | #define TIM3_IRQn TIM3_TIM4_IRQn 34 | #endif 35 | 36 | static inline uint32_t 37 | timer_get(void) 38 | { 39 | return TIMx->CNT; 40 | } 41 | 42 | static inline void 43 | timer_set(uint32_t next) 44 | { 45 | TIMx->CCR1 = next; 46 | TIMx->SR = 0; 47 | } 48 | 49 | 50 | /**************************************************************** 51 | * 16bit hardware timer to 32bit conversion 52 | ****************************************************************/ 53 | 54 | // High bits of timer (top 17 bits) 55 | static uint32_t timer_high; 56 | 57 | // Return the current time (in absolute clock ticks). 58 | uint32_t __always_inline 59 | timer_read_time(void) 60 | { 61 | if (HAVE_TIMER_32BIT) 62 | return timer_get(); 63 | uint32_t th = readl(&timer_high); 64 | uint32_t cur = timer_get(); 65 | // Combine timer_high (high 17 bits) and current time (low 16 66 | // bits) using method that handles rollovers correctly. 67 | return (th ^ cur) + (th & 0xffff); 68 | } 69 | 70 | 71 | /**************************************************************** 72 | * Setup and irqs 73 | ****************************************************************/ 74 | 75 | // Hardware timer IRQ handler - dispatch software timers 76 | void __aligned(16) 77 | TIMx_IRQHandler(void) 78 | { 79 | irq_disable(); 80 | timer_high += 0x8000; 81 | timer_set(timer_high + 0x8000); 82 | irq_enable(); 83 | } 84 | 85 | // Initialize the timer 86 | void 87 | timer_setup(void) 88 | { 89 | irqstatus_t flag = irq_save(); 90 | enable_pclock((uint32_t)TIMx); 91 | TIMx->CNT = 0; 92 | #if !HAVE_TIMER_32BIT 93 | TIMx->DIER = TIM_DIER_CC1IE; 94 | TIMx->CCER = TIM_CCER_CC1E; 95 | armcm_enable_irq(TIMx_IRQHandler, TIMx_IRQn, 2); 96 | timer_set(0x8000); 97 | #endif 98 | TIMx->CR1 = TIM_CR1_CEN; 99 | irq_restore(flag); 100 | } 101 | 102 | // Return the number of clock ticks for a given number of microseconds 103 | uint32_t 104 | timer_from_us(uint32_t us) 105 | { 106 | return us * (CONFIG_CLOCK_FREQ / 1000000); 107 | } 108 | 109 | // Return true if time1 is before time2. Always use this function to 110 | // compare times as regular C comparisons can fail if the counter 111 | // rolls over. 112 | uint8_t 113 | timer_is_before(uint32_t time1, uint32_t time2) 114 | { 115 | return (int32_t)(time1 - time2) < 0; 116 | } 117 | -------------------------------------------------------------------------------- /lib/rp2040/pico/platform.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _PICO_PLATFORM_H_ 8 | #define _PICO_PLATFORM_H_ 9 | 10 | #include "hardware/platform_defs.h" 11 | #include 12 | 13 | #ifdef __unix__ 14 | 15 | #include 16 | 17 | #endif 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | #define __not_in_flash(grup) 24 | #define __not_in_flash_func(func) func 25 | #define __no_inline_not_in_flash_func(func) 26 | #define __in_flash(group) 27 | #define __scratch_x(group) 28 | #define __scratch_y(group) 29 | 30 | #define __packed_aligned 31 | #define __packed 32 | 33 | #define __time_critical_func(x) x 34 | #define __after_data(group) 35 | 36 | //int running_on_fpga() { return false; } 37 | extern void tight_loop_contents(); 38 | 39 | #ifndef __STRING 40 | #define __STRING(x) #x 41 | #endif 42 | 43 | #ifndef _MSC_VER 44 | #ifndef __noreturn 45 | #define __noreturn __attribute((noreturn)) 46 | #endif 47 | 48 | #ifndef __unused 49 | #define __unused __attribute__((unused)) 50 | #endif 51 | 52 | #ifndef __noinline 53 | #define __noinline __attribute__((noinline)) 54 | #endif 55 | 56 | #ifndef __aligned 57 | #define __aligned(x) __attribute__((aligned(x))) 58 | #endif 59 | 60 | #define PICO_WEAK_FUNCTION_DEF(x) _Pragma(__STRING(weak x)) 61 | #define PICO_WEAK_FUNCTION_IMPL_NAME(x) x 62 | 63 | #else 64 | #ifndef __noreturn 65 | #define __noreturn __declspec(noreturn) 66 | #endif 67 | 68 | #ifndef __unused 69 | #define __unused 70 | #endif 71 | 72 | #ifndef __noinline 73 | #define __noinline __declspec(noinline) 74 | #endif 75 | 76 | #ifndef __aligned 77 | #define __aligned(x) __declspec(align(x)) 78 | #endif 79 | 80 | #ifndef __CONCAT 81 | #define __CONCAT(x,y) x ## y 82 | #endif 83 | 84 | #define __thread __declspec( thread ) 85 | 86 | #define PICO_WEAK_FUNCTION_DEF(x) __pragma(comment(linker, __STRING(/alternatename:_##x=_##x##__weak))); 87 | #define PICO_WEAK_FUNCTION_IMPL_NAME(x) x ## __weak 88 | 89 | static __noreturn void __builtin_unreachable() { 90 | } 91 | 92 | #include 93 | #define __builtin_clz __lzcnt 94 | #endif 95 | 96 | #ifndef count_of 97 | #define count_of(a) (sizeof(a)/sizeof((a)[0])) 98 | #endif 99 | 100 | #ifndef MAX 101 | #define MAX(a, b) ((a)>(b)?(a):(b)) 102 | #endif 103 | 104 | #ifndef MIN 105 | #define MIN(a, b) ((b)>(a)?(a):(b)) 106 | #endif 107 | 108 | // abort in our case 109 | void __noreturn __breakpoint(); 110 | 111 | void __noreturn panic_unsupported(); 112 | 113 | void __noreturn panic(const char *fmt, ...); 114 | 115 | // arggggghhhh there is a weak function called sem_init used by SDL 116 | #define sem_init sem_init_alternative 117 | 118 | extern uint32_t host_safe_hw_ptr_impl(uintptr_t x); 119 | // return a 32 bit handle for a raw ptr; DMA chaining for example embeds pointers in 32 bit values 120 | // which of course does not work if we're running the code natively on a 64 bit platforms. Therefore 121 | // we provide this macro which allows that code to provide a 64->32 bit mapping in host mode 122 | #define host_safe_hw_ptr(x) host_safe_hw_ptr_impl((uintptr_t)(x)) 123 | void *decode_host_safe_hw_ptr(uint32_t ptr); 124 | 125 | #define __fast_mul(a,b) ((a)*(b)) 126 | 127 | typedef unsigned int uint; 128 | 129 | static inline int32_t __mul_instruction(int32_t a,int32_t b) 130 | { 131 | return a*b; 132 | } 133 | 134 | static inline void __compiler_memory_barrier(void) { 135 | } 136 | #ifdef __cplusplus 137 | } 138 | #endif 139 | #endif 140 | -------------------------------------------------------------------------------- /src/generic/armcm_boot.c: -------------------------------------------------------------------------------- 1 | // ARM Cortex-M vector table and initial bootup handling 2 | // 3 | // Copyright (C) 2019 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include "armcm_boot.h" // DECL_ARMCM_IRQ 8 | #include "autoconf.h" // CONFIG_MCU 9 | #include "board/internal.h" // SysTick 10 | #include "command.h" // DECL_CONSTANT_STR 11 | #include "misc.h" // dynmem_start 12 | 13 | // Export MCU type 14 | DECL_CONSTANT_STR("MCU", CONFIG_MCU); 15 | 16 | // Symbols created by armcm_link.lds.S linker script 17 | extern uint32_t _data_start, _data_end, _data_flash; 18 | extern uint32_t _bss_start, _bss_end, _stack_start; 19 | extern uint32_t _stack_end; 20 | 21 | /**************************************************************** 22 | * Basic interrupt handlers 23 | ****************************************************************/ 24 | 25 | static void __noreturn 26 | reset_handler_stage_two(void) 27 | { 28 | int i; 29 | 30 | // Clear all enabled user interrupts and user pending interrupts 31 | for (i = 0; i < ARRAY_SIZE(NVIC->ICER); i++) { 32 | NVIC->ICER[i] = 0xFFFFFFFF; 33 | __DSB(); 34 | NVIC->ICPR[i] = 0xFFFFFFFF; 35 | } 36 | 37 | // Reset all user interrupt priorities 38 | for (i = 0; i < ARRAY_SIZE(NVIC->IP); i++) 39 | NVIC->IP[i] = 0; 40 | 41 | // Disable SysTick interrupt 42 | SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk; 43 | __DSB(); 44 | 45 | // Clear pending pendsv and systick interrupts 46 | SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk; 47 | 48 | // Reset all system interrupt priorities 49 | #if __CORTEX_M >= 7 50 | for (i = 0; i < ARRAY_SIZE(SCB->SHPR); i++) 51 | SCB->SHPR[i] = 0; 52 | #else 53 | for (i = 0; i < ARRAY_SIZE(SCB->SHP); i++) 54 | SCB->SHP[i] = 0; 55 | #endif 56 | 57 | __DSB(); 58 | __ISB(); 59 | __enable_irq(); 60 | 61 | // Copy global variables from flash to ram 62 | uint32_t count = (&_data_end - &_data_start) * 4; 63 | __builtin_memcpy(&_data_start, &_data_flash, count); 64 | 65 | // Clear the bss segment 66 | __builtin_memset(&_bss_start, 0, (&_bss_end - &_bss_start) * 4); 67 | 68 | barrier(); 69 | 70 | // Initializing the C library isn't needed... 71 | //__libc_init_array(); 72 | 73 | // Run the main board specific code 74 | armcm_main(); 75 | 76 | // The armcm_main() call should not return 77 | for (;;) 78 | ; 79 | } 80 | 81 | // Initial code entry point - invoked by the processor after a reset 82 | // Reset interrupts and stack to take control from bootloaders 83 | void 84 | ResetHandler(void) 85 | { 86 | __disable_irq(); 87 | 88 | // Explicitly load the stack pointer, jump to stage two 89 | asm volatile("mov sp, %0\n bx %1" 90 | : : "r"(&_stack_end), "r"(reset_handler_stage_two)); 91 | } 92 | DECL_ARMCM_IRQ(ResetHandler, -15); 93 | 94 | // Code called for any undefined interrupts 95 | void 96 | DefaultHandler(void) 97 | { 98 | for (;;) 99 | ; 100 | } 101 | 102 | 103 | /**************************************************************** 104 | * Dynamic memory range 105 | ****************************************************************/ 106 | 107 | // Return the start of memory available for dynamic allocations 108 | void * 109 | dynmem_start(void) 110 | { 111 | return &_bss_end; 112 | } 113 | 114 | // Return the end of memory available for dynamic allocations 115 | void * 116 | dynmem_end(void) 117 | { 118 | return &_stack_start; 119 | } 120 | -------------------------------------------------------------------------------- /src/generic/armcm_canboot.c: -------------------------------------------------------------------------------- 1 | // CanBoot specific entry code for ARM Cortex-M vector table and bootup 2 | // 3 | // Copyright (C) 2019 Kevin O'Connor 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include // memcpy 8 | #include "armcm_boot.h" // DECL_ARMCM_IRQ 9 | #include "autoconf.h" // CONFIG_MCU 10 | #include "board/internal.h" // SysTick 11 | #include "board/irq.h" // irq_disable 12 | #include "canboot.h" // get_bootup_code 13 | #include "command.h" // DECL_CONSTANT_STR 14 | 15 | // Export MCU type 16 | DECL_CONSTANT_STR("MCU", CONFIG_MCU); 17 | 18 | // Symbols created by armcm_link.lds.S linker script 19 | extern uint32_t _data_start, _data_end, _data_flash; 20 | extern uint32_t _bss_start, _bss_end, _stack_start; 21 | extern uint32_t _stack_end; 22 | 23 | #pragma GCC diagnostic push 24 | #pragma GCC diagnostic ignored "-Warray-bounds" 25 | 26 | uint64_t 27 | get_bootup_code(void) 28 | { 29 | uint64_t *req_code = (void*)&_stack_end; 30 | return *req_code; 31 | } 32 | 33 | void 34 | set_bootup_code(uint64_t code) 35 | { 36 | uint64_t *req_code = (void*)&_stack_end; 37 | *req_code = code; 38 | barrier(); 39 | #if __CORTEX_M >= 7 40 | SCB_CleanDCache_by_Addr((void*)req_code, sizeof(*req_code)); 41 | #endif 42 | } 43 | 44 | #pragma GCC diagnostic pop 45 | 46 | // Helper function to read area of flash 47 | void 48 | application_read_flash(uint32_t address, uint32_t *dest) 49 | { 50 | memcpy(dest, (void*)address, CONFIG_BLOCK_SIZE); 51 | } 52 | 53 | // Check if the application flash area looks valid 54 | int 55 | application_check_valid(void) 56 | { 57 | uint32_t *app = (void*)CONFIG_LAUNCH_APP_ADDRESS; 58 | return *app != 0 && *app != 0xffffffff; 59 | } 60 | 61 | // Jump to the main application (exiting the bootloader) 62 | void 63 | application_jump(void) 64 | { 65 | irq_disable(); 66 | set_bootup_code(REQUEST_START_APP); 67 | NVIC_SystemReset(); 68 | } 69 | 70 | static void 71 | start_application(void) 72 | { 73 | set_bootup_code(0); 74 | uint32_t *vtor = (void*)CONFIG_LAUNCH_APP_ADDRESS; 75 | #if __CORTEX_M > 0 || __VTOR_PRESENT 76 | SCB->VTOR = (uint32_t)vtor; 77 | #endif 78 | asm volatile("MSR msp, %0\n bx %1" : : "r"(vtor[0]), "r"(vtor[1])); 79 | } 80 | 81 | void __noreturn __visible 82 | reset_handler_stage_two(void) 83 | { 84 | uint64_t bootup_code = get_bootup_code(); 85 | if (bootup_code == REQUEST_START_APP) 86 | start_application(); 87 | 88 | // Copy global variables from flash to ram 89 | uint32_t count = (&_data_end - &_data_start) * 4; 90 | __builtin_memcpy(&_data_start, &_data_flash, count); 91 | 92 | // Clear the bss segment 93 | __builtin_memset(&_bss_start, 0, (&_bss_end - &_bss_start) * 4); 94 | 95 | barrier(); 96 | 97 | // Initializing the C library isn't needed... 98 | //__libc_init_array(); 99 | 100 | // Run the main board specific code 101 | armcm_main(); 102 | 103 | // The armcm_main() call should not return 104 | for (;;) 105 | ; 106 | } 107 | 108 | // Initial code entry point - invoked by the processor after a reset 109 | asm(".section .text.ResetHandler\n" 110 | ".balign 8\n" 111 | ".8byte " __stringify(CANBOOT_SIGNATURE) "\n" 112 | ".global ResetHandler\n" 113 | ".type ResetHandler, %function\n" 114 | "ResetHandler:\n" 115 | " b reset_handler_stage_two\n" 116 | ); 117 | extern void ResetHandler(); 118 | DECL_ARMCM_IRQ(ResetHandler, -15); 119 | 120 | // Code called for any undefined interrupts 121 | void 122 | DefaultHandler(void) 123 | { 124 | for (;;) 125 | ; 126 | } 127 | -------------------------------------------------------------------------------- /src/stm32/Makefile: -------------------------------------------------------------------------------- 1 | # Additional STM32 build rules 2 | 3 | # Setup the toolchain 4 | CROSS_PREFIX=arm-none-eabi- 5 | 6 | dirs-y += src/stm32 src/generic lib/fast-hash 7 | dirs-$(CONFIG_MACH_STM32F0) += lib/stm32f0 8 | dirs-$(CONFIG_MACH_STM32F1) += lib/stm32f1 9 | dirs-$(CONFIG_MACH_STM32F2) += lib/stm32f2 10 | dirs-$(CONFIG_MACH_STM32F4) += lib/stm32f4 11 | dirs-$(CONFIG_MACH_STM32G0) += lib/stm32g0 12 | dirs-$(CONFIG_MACH_STM32H7) += lib/stm32h7 13 | 14 | MCU := $(shell echo $(CONFIG_MCU)) 15 | MCU_UPPER := $(shell echo $(CONFIG_MCU) | tr a-z A-Z | tr X x) 16 | 17 | CFLAGS-$(CONFIG_MACH_STM32F0) += -mcpu=cortex-m0 -Ilib/stm32f0/include 18 | CFLAGS-$(CONFIG_MACH_STM32F1) += -mcpu=cortex-m3 -Ilib/stm32f1/include 19 | CFLAGS-$(CONFIG_MACH_STM32F2) += -mcpu=cortex-m3 -Ilib/stm32f2/include 20 | CFLAGS-$(CONFIG_MACH_STM32F4) += -mcpu=cortex-m4 -Ilib/stm32f4/include 21 | CFLAGS-$(CONFIG_MACH_STM32G0) += -mcpu=cortex-m0plus -Ilib/stm32g0/include 22 | CFLAGS-$(CONFIG_MACH_STM32H7) += -mcpu=cortex-m7 -Ilib/stm32h7/include 23 | CFLAGS += $(CFLAGS-y) -D$(MCU_UPPER) -mthumb -Ilib/cmsis-core -Ilib/fast-hash 24 | 25 | CFLAGS_katapult.elf += -nostdlib -lgcc -lc_nano 26 | CFLAGS_katapult.elf += -T $(OUT)src/generic/armcm_link.ld 27 | $(OUT)katapult.elf: $(OUT)src/generic/armcm_link.ld 28 | 29 | # Add source files 30 | mcu-y = stm32/gpio.c stm32/flash.c stm32/clockline.c stm32/dfu_reboot.c 31 | mcu-y += generic/armcm_irq.c generic/crc16_ccitt.c 32 | mcu-$(CONFIG_MACH_STM32F0) += ../lib/stm32f0/system_stm32f0xx.c 33 | mcu-$(CONFIG_MACH_STM32F0) += stm32/stm32f0.c stm32/stm32f0_timer.c 34 | mcu-$(CONFIG_MACH_STM32F0) += stm32/gpioperiph.c 35 | 36 | mcu-$(CONFIG_MACH_STM32F1) += ../lib/stm32f1/system_stm32f1xx.c 37 | mcu-$(CONFIG_MACH_STM32F1) += stm32/stm32f1.c generic/armcm_timer.c 38 | 39 | mcu-$(CONFIG_MACH_STM32F2) += ../lib/stm32f2/system_stm32f2xx.c 40 | mcu-$(CONFIG_MACH_STM32F2) += stm32/stm32f4.c generic/armcm_timer.c 41 | mcu-$(CONFIG_MACH_STM32F2) += stm32/gpioperiph.c 42 | 43 | mcu-$(CONFIG_MACH_STM32F4) += ../lib/stm32f4/system_stm32f4xx.c 44 | mcu-$(CONFIG_MACH_STM32F4) += stm32/stm32f4.c generic/armcm_timer.c 45 | mcu-$(CONFIG_MACH_STM32F4) += stm32/gpioperiph.c 46 | 47 | mcu-$(CONFIG_MACH_STM32G0) += stm32/stm32f0_timer.c 48 | mcu-$(CONFIG_MACH_STM32G0) += stm32/stm32g0.c stm32/gpioperiph.c 49 | 50 | mcu-$(CONFIG_MACH_STM32H7) += ../lib/stm32h7/system_stm32h7xx.c 51 | mcu-$(CONFIG_MACH_STM32H7) += stm32/stm32h7.c generic/armcm_timer.c 52 | mcu-$(CONFIG_MACH_STM32H7) += stm32/gpioperiph.c 53 | 54 | src-y += generic/armcm_canboot.c $(mcu-y) 55 | usb-src-$(CONFIG_HAVE_STM32_USBFS) := stm32/usbfs.c 56 | usb-src-$(CONFIG_HAVE_STM32_USBOTG) := stm32/usbotg.c 57 | src-$(CONFIG_USBSERIAL) += $(usb-src-y) stm32/chipid.c generic/usb_cdc.c 58 | serial-src-y := stm32/serial.c 59 | serial-src-$(CONFIG_MACH_STM32F0) := stm32/stm32f0_serial.c 60 | serial-src-$(CONFIG_MACH_STM32G0) := stm32/stm32f0_serial.c 61 | serial-src-$(CONFIG_MACH_STM32H7) := stm32/stm32f0_serial.c 62 | src-$(CONFIG_SERIAL) += $(serial-src-y) generic/serial_irq.c 63 | canbus-src-y := generic/canserial.c ../lib/fast-hash/fasthash.c 64 | canbus-src-$(CONFIG_HAVE_STM32_CANBUS) += stm32/can.c 65 | canbus-src-$(CONFIG_HAVE_STM32_FDCANBUS) += stm32/fdcan.c 66 | src-$(CONFIG_CANSERIAL) += $(canbus-src-y) generic/canbus.c stm32/chipid.c 67 | 68 | # Flash rules 69 | flash: $(OUT)katapult.bin 70 | @echo " Flashing $< to $(FLASH_DEVICE)" 71 | $(Q) $(if $(NOSUDO),,sudo) dfu-util -d "$(FLASH_DEVICE)" -R -a 0 -s "$(CONFIG_FLASH_START)":leave -D $(OUT)katapult.bin 72 | 73 | # Deployer build 74 | deployer-y += generic/armcm_boot.c generic/armcm_reset.c $(mcu-y) 75 | CFLAGS_deployer.elf += -nostdlib -lgcc -lc_nano 76 | CFLAGS_deployer.elf += -T $(OUT)src/generic/armcm_deployer.ld 77 | $(OUT)deployer.elf: $(OUT)src/generic/armcm_deployer.ld 78 | -------------------------------------------------------------------------------- /src/Kconfig: -------------------------------------------------------------------------------- 1 | # Main Kconfig settings 2 | 3 | VERSION := $(shell, ./scripts/make-version.sh 2> /dev/null) 4 | 5 | mainmenu "Katapult Configuration $(VERSION)" 6 | 7 | config LOW_LEVEL_OPTIONS 8 | bool 9 | default y 10 | 11 | choice 12 | prompt "Micro-controller Architecture" 13 | config MACH_LPC176X 14 | bool "LPC176x (Smoothieboard)" 15 | config MACH_STM32 16 | bool "STMicroelectronics STM32" 17 | config MACH_RP2040 18 | bool "Raspberry Pi RP2040" 19 | endchoice 20 | 21 | source "src/lpc176x/Kconfig" 22 | source "src/stm32/Kconfig" 23 | source "src/rp2040/Kconfig" 24 | 25 | # Generic configuration options for serial ports 26 | config SERIAL 27 | bool 28 | config SERIAL_BOOTLOADER_SIDECHANNEL 29 | bool 30 | config SERIAL_BAUD 31 | depends on SERIAL 32 | int "Baud rate for serial port" if LOW_LEVEL_OPTIONS 33 | default 250000 34 | help 35 | Specify the baud rate of the serial port. This should be set 36 | to 250000. Read the FAQ before changing this value. 37 | 38 | # Generic configuration options for USB 39 | config USBSERIAL 40 | bool 41 | config USBCANBUS 42 | bool 43 | config USB 44 | bool 45 | default y if USBSERIAL || USBCANBUS 46 | config USB_VENDOR_ID 47 | default 0x1d50 48 | config USB_DEVICE_ID 49 | default 0x6177 50 | config USB_SERIAL_NUMBER_CHIPID 51 | depends on USB && HAVE_CHIPID 52 | default y 53 | config USB_SERIAL_NUMBER 54 | default "12345" 55 | 56 | menu "USB ids" 57 | depends on USB && LOW_LEVEL_OPTIONS 58 | config USB_VENDOR_ID 59 | hex "USB vendor ID" if USBSERIAL 60 | config USB_DEVICE_ID 61 | hex "USB device ID" if USBSERIAL 62 | config USB_SERIAL_NUMBER_CHIPID 63 | bool "USB serial number from CHIPID" if HAVE_CHIPID 64 | config USB_SERIAL_NUMBER 65 | string "USB serial number" if !USB_SERIAL_NUMBER_CHIPID 66 | endmenu 67 | 68 | # Generic configuration options for CANbus 69 | config CANSERIAL 70 | bool 71 | config CANBUS 72 | bool 73 | default y if CANSERIAL || USBCANBUS 74 | config CANBUS_FREQUENCY 75 | int "CAN bus speed" if LOW_LEVEL_OPTIONS && CANBUS 76 | default 1000000 77 | config CANBUS_FILTER 78 | bool 79 | default y if CANSERIAL 80 | 81 | # Support setting gpio state at startup 82 | config INITIAL_PINS 83 | string "GPIO pins to set on bootloader entry" 84 | depends on LOW_LEVEL_OPTIONS 85 | help 86 | One may specify a comma separated list of gpio pins to set 87 | during bootloader entry (these gpio pins are not set if the 88 | main application is started nor are they set while checking 89 | for a bootloader request). By default the pins will be set to 90 | output high - preface a pin with a '!' character to set that 91 | pin to output low. 92 | 93 | config ENABLE_DOUBLE_RESET 94 | bool "Support bootloader entry on rapid double click of reset button" 95 | default y 96 | 97 | config ENABLE_BUTTON 98 | bool "Enable bootloader entry on button (or gpio) state" 99 | default n 100 | 101 | config BUTTON_PIN 102 | string "Button GPIO Pin" 103 | depends on ENABLE_BUTTON 104 | 105 | config ENABLE_LED 106 | bool "Enable Status LED" 107 | default n 108 | 109 | config STATUS_LED_PIN 110 | string "Status LED GPIO Pin" 111 | depends on ENABLE_LED 112 | 113 | config BUILD_DEPLOYER 114 | bool 115 | default y if FLASH_APPLICATION_ADDRESS != FLASH_BOOT_ADDRESS 116 | default n 117 | 118 | # The HAVE_x options allow boards to disable support for some commands 119 | # if the hardware does not support the feature. 120 | config HAVE_CHIPID 121 | bool 122 | default n 123 | 124 | config KATAPULT_VERSION 125 | string 126 | default "$(VERSION)" 127 | -------------------------------------------------------------------------------- /src/flashcmd.c: -------------------------------------------------------------------------------- 1 | // Command handlers for flash requests 2 | // 3 | // Copyright (C) 2021 Eric Callahan 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | #include // memmove 8 | #include "autoconf.h" // CONFIG_BLOCK_SIZE 9 | #include "board/flash.h" // flash_write_block 10 | #include "board/misc.h" // application_jump 11 | #include "byteorder.h" // cpu_to_le32 12 | #include "canboot.h" // application_jump 13 | #include "command.h" // command_respond_ack 14 | #include "flashcmd.h" // flashcmd_is_in_transfer 15 | #include "sched.h" // DECL_TASK 16 | 17 | // Handler for "connect" commands 18 | void 19 | command_connect(uint32_t *data) 20 | { 21 | uint32_t mcuwords = DIV_ROUND_UP(strlen(CONFIG_MCU), 4); 22 | uint32_t version_words = DIV_ROUND_UP(strlen(CONFIG_KATAPULT_VERSION), 4); 23 | uint32_t out[7 + mcuwords + version_words]; 24 | memset(out, 0, (7 + mcuwords + version_words) * 4); 25 | out[2] = cpu_to_le32(PROTO_VERSION); 26 | out[3] = cpu_to_le32(CONFIG_LAUNCH_APP_ADDRESS); 27 | out[4] = cpu_to_le32(CONFIG_BLOCK_SIZE); 28 | memcpy(&out[5], CONFIG_MCU, strlen(CONFIG_MCU)); 29 | memcpy( 30 | &out[6 + mcuwords], CONFIG_KATAPULT_VERSION, 31 | strlen(CONFIG_KATAPULT_VERSION) 32 | ); 33 | command_respond_ack(CMD_CONNECT, out, ARRAY_SIZE(out)); 34 | } 35 | 36 | 37 | /**************************************************************** 38 | * Command "complete" handling 39 | ****************************************************************/ 40 | 41 | static uint8_t complete; 42 | static uint32_t complete_endtime; 43 | 44 | void 45 | command_complete(uint32_t *data) 46 | { 47 | uint32_t out[3]; 48 | command_respond_ack(CMD_COMPLETE, out, ARRAY_SIZE(out)); 49 | complete = 1; 50 | complete_endtime = timer_read_time() + timer_from_us(100000); 51 | } 52 | 53 | void 54 | complete_task(void) 55 | { 56 | if (complete && timer_is_before(complete_endtime, timer_read_time())) 57 | application_jump(); 58 | } 59 | DECL_TASK(complete_task); 60 | 61 | 62 | /**************************************************************** 63 | * Flash commands 64 | ****************************************************************/ 65 | 66 | static uint8_t is_in_transfer; 67 | 68 | int 69 | flashcmd_is_in_transfer(void) 70 | { 71 | return is_in_transfer; 72 | } 73 | 74 | void 75 | command_read_block(uint32_t *data) 76 | { 77 | is_in_transfer = 1; 78 | uint32_t block_address = le32_to_cpu(data[1]); 79 | uint32_t out[CONFIG_BLOCK_SIZE / 4 + 2 + 2]; 80 | out[2] = cpu_to_le32(block_address); 81 | application_read_flash(block_address, &out[3]); 82 | command_respond_ack(CMD_REQ_BLOCK, out, ARRAY_SIZE(out)); 83 | } 84 | 85 | void 86 | command_write_block(uint32_t *data) 87 | { 88 | is_in_transfer = 1; 89 | if (command_get_arg_count(data) != (CONFIG_BLOCK_SIZE / 4) + 1) 90 | goto fail; 91 | uint32_t block_address = le32_to_cpu(data[1]); 92 | if (block_address < CONFIG_LAUNCH_APP_ADDRESS) 93 | goto fail; 94 | int ret = flash_write_block(block_address, &data[2]); 95 | if (ret < 0) 96 | goto fail; 97 | uint32_t out[4]; 98 | out[2] = cpu_to_le32(block_address); 99 | command_respond_ack(CMD_RX_BLOCK, out, ARRAY_SIZE(out)); 100 | return; 101 | fail: 102 | command_respond_command_error(); 103 | } 104 | 105 | void 106 | command_eof(uint32_t *data) 107 | { 108 | is_in_transfer = 0; 109 | int ret = flash_complete(); 110 | if (ret < 0) { 111 | command_respond_command_error(); 112 | return; 113 | } 114 | uint32_t out[4]; 115 | out[2] = cpu_to_le32(ret); 116 | command_respond_ack(CMD_RX_EOF, out, ARRAY_SIZE(out)); 117 | } 118 | -------------------------------------------------------------------------------- /lib/rp2040/hardware/regs/sysinfo.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | // ============================================================================= 7 | // Register block : SYSINFO 8 | // Version : 1 9 | // Bus type : apb 10 | // Description : None 11 | // ============================================================================= 12 | #ifndef HARDWARE_REGS_SYSINFO_DEFINED 13 | #define HARDWARE_REGS_SYSINFO_DEFINED 14 | // ============================================================================= 15 | // Register : SYSINFO_CHIP_ID 16 | // Description : JEDEC JEP-106 compliant chip identifier. 17 | #define SYSINFO_CHIP_ID_OFFSET _u(0x00000000) 18 | #define SYSINFO_CHIP_ID_BITS _u(0xffffffff) 19 | #define SYSINFO_CHIP_ID_RESET _u(0x00000000) 20 | // ----------------------------------------------------------------------------- 21 | // Field : SYSINFO_CHIP_ID_REVISION 22 | // Description : None 23 | #define SYSINFO_CHIP_ID_REVISION_RESET "-" 24 | #define SYSINFO_CHIP_ID_REVISION_BITS _u(0xf0000000) 25 | #define SYSINFO_CHIP_ID_REVISION_MSB _u(31) 26 | #define SYSINFO_CHIP_ID_REVISION_LSB _u(28) 27 | #define SYSINFO_CHIP_ID_REVISION_ACCESS "RO" 28 | // ----------------------------------------------------------------------------- 29 | // Field : SYSINFO_CHIP_ID_PART 30 | // Description : None 31 | #define SYSINFO_CHIP_ID_PART_RESET "-" 32 | #define SYSINFO_CHIP_ID_PART_BITS _u(0x0ffff000) 33 | #define SYSINFO_CHIP_ID_PART_MSB _u(27) 34 | #define SYSINFO_CHIP_ID_PART_LSB _u(12) 35 | #define SYSINFO_CHIP_ID_PART_ACCESS "RO" 36 | // ----------------------------------------------------------------------------- 37 | // Field : SYSINFO_CHIP_ID_MANUFACTURER 38 | // Description : None 39 | #define SYSINFO_CHIP_ID_MANUFACTURER_RESET "-" 40 | #define SYSINFO_CHIP_ID_MANUFACTURER_BITS _u(0x00000fff) 41 | #define SYSINFO_CHIP_ID_MANUFACTURER_MSB _u(11) 42 | #define SYSINFO_CHIP_ID_MANUFACTURER_LSB _u(0) 43 | #define SYSINFO_CHIP_ID_MANUFACTURER_ACCESS "RO" 44 | // ============================================================================= 45 | // Register : SYSINFO_PLATFORM 46 | // Description : Platform register. Allows software to know what environment it 47 | // is running in. 48 | #define SYSINFO_PLATFORM_OFFSET _u(0x00000004) 49 | #define SYSINFO_PLATFORM_BITS _u(0x00000003) 50 | #define SYSINFO_PLATFORM_RESET _u(0x00000000) 51 | // ----------------------------------------------------------------------------- 52 | // Field : SYSINFO_PLATFORM_ASIC 53 | // Description : None 54 | #define SYSINFO_PLATFORM_ASIC_RESET _u(0x0) 55 | #define SYSINFO_PLATFORM_ASIC_BITS _u(0x00000002) 56 | #define SYSINFO_PLATFORM_ASIC_MSB _u(1) 57 | #define SYSINFO_PLATFORM_ASIC_LSB _u(1) 58 | #define SYSINFO_PLATFORM_ASIC_ACCESS "RO" 59 | // ----------------------------------------------------------------------------- 60 | // Field : SYSINFO_PLATFORM_FPGA 61 | // Description : None 62 | #define SYSINFO_PLATFORM_FPGA_RESET _u(0x0) 63 | #define SYSINFO_PLATFORM_FPGA_BITS _u(0x00000001) 64 | #define SYSINFO_PLATFORM_FPGA_MSB _u(0) 65 | #define SYSINFO_PLATFORM_FPGA_LSB _u(0) 66 | #define SYSINFO_PLATFORM_FPGA_ACCESS "RO" 67 | // ============================================================================= 68 | // Register : SYSINFO_GITREF_RP2040 69 | // Description : Git hash of the chip source. Used to identify chip version. 70 | #define SYSINFO_GITREF_RP2040_OFFSET _u(0x00000040) 71 | #define SYSINFO_GITREF_RP2040_BITS _u(0xffffffff) 72 | #define SYSINFO_GITREF_RP2040_RESET "-" 73 | #define SYSINFO_GITREF_RP2040_MSB _u(31) 74 | #define SYSINFO_GITREF_RP2040_LSB _u(0) 75 | #define SYSINFO_GITREF_RP2040_ACCESS "RO" 76 | // ============================================================================= 77 | #endif // HARDWARE_REGS_SYSINFO_DEFINED 78 | --------------------------------------------------------------------------------