diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f84d41e8..6066762b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -129,7 +129,7 @@ jobs: run: make -C examples/stm32/nucleo-f746zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - if: ${{ env.GO == 1 }} run: make -C examples/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}} - - run: echo GO=0 >> $GITHUB_ENV ; if ./test/match_changed_files.sh '^src|examples/stm32/nucleo-f7.*-cube-'; then echo GO=1 >> $GITHUB_ENV ; fi + - run: echo GO=0 >> $GITHUB_ENV ; if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f7.*-cube-'; then echo GO=1 >> $GITHUB_ENV ; fi - if: ${{ env.GO == 1 }} run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5 - if: ${{ env.GO == 1 }} @@ -149,7 +149,7 @@ jobs: run: make -C examples/stm32/nucleo-f429zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - if: ${{ env.GO == 1 }} run: make -C examples/stm32/nucleo-f429zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - - run: echo GO=0 >> $GITHUB_ENV ; if ./test/match_changed_files.sh '^src|examples/stm32/nucleo-f4.*-cube-'; then echo GO=1 >> $GITHUB_ENV ; fi + - run: echo GO=0 >> $GITHUB_ENV ; if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f4.*-cube-'; then echo GO=1 >> $GITHUB_ENV ; fi - if: ${{ env.GO == 1 }} run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2 - if: ${{ env.GO == 1 }} @@ -169,7 +169,7 @@ jobs: run: make -C examples/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - if: ${{ env.GO == 1 }} run: make -C examples/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - - run: echo GO=0 >> $GITHUB_ENV ; if ./test/match_changed_files.sh '^src|examples/stm32/nucleo-h7.*-cube-'; then echo GO=1 >> $GITHUB_ENV ; fi + - run: echo GO=0 >> $GITHUB_ENV ; if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h7.*-cube-'; then echo GO=1 >> $GITHUB_ENV ; fi - if: ${{ env.GO == 1 }} run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6 - if: ${{ env.GO == 1 }} @@ -183,13 +183,24 @@ jobs: - run: if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/ti/ek-tm4c" ; then echo GO=1 >> $GITHUB_ENV ; fi - if: ${{ env.GO == 1 }} run: sudo apt -y update; sudo apt -y install gcc-arm-none-eabi - - run: echo GO=0 > $GITHUB_ENV ; if ./test/match_changed_files.sh "^src|examples/ti/ek-tm4c1294xl-baremetal" ; then echo GO=1 > $GITHUB_ENV ; fi - if: ${{ env.GO == 1 }} run: make -C examples/ti/ek-tm4c1294xl-baremetal test VCON_API_KEY=${{secrets.VCON_API_KEY}} - - run: echo GO=0 > $GITHUB_ENV ; if ./test/match_changed_files.sh "^src|examples/ti/ek-tm4c1294xl-freertos" ; then echo GO=1 > $GITHUB_ENV ; fi - if: ${{ env.GO == 1 }} run: make -C examples/ti/ek-tm4c1294xl-freertos test VCON_API_KEY=${{secrets.VCON_API_KEY}} + test_same54: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: { fetch-depth: 2 } + - run: if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/microchip/same54" ; then echo GO=1 >> $GITHUB_ENV ; fi + - if: ${{ env.GO == 1 }} + run: sudo apt -y update; sudo apt -y install gcc-arm-none-eabi + - if: ${{ env.GO == 1 }} + run: make -C examples/microchip/same54/device-dashboard test VCON_API_KEY=${{secrets.VCON_API_KEY}} + - if: ${{ env.GO == 1 }} + run: make -C examples/microchip/same54/mqtt-client test VCON_API_KEY=${{secrets.VCON_API_KEY}} + test_pico_w5500: runs-on: ubuntu-latest steps: @@ -225,15 +236,8 @@ jobs: - path: esp32/device-dashboard - path: esp32/uart-bridge - path: esp8266/http-client-server - - path: stm32/nucleo-f429zi-make-baremetal-builtin - - path: stm32/nucleo-f429zi-make-freertos-builtin - - path: stm32/nucleo-f429zi-make-baremetal-builtin-rndis - - path: stm32/nucleo-f746zg-make-baremetal-builtin - - path: stm32/nucleo-f746zg-make-freertos-builtin - - path: stm32/nucleo-f746zg-make-freertos-tcp - - path: stm32/nucleo-f746zg-make-baremetal-builtin-rndis - - path: stm32/nucleo-h743zi-make-baremetal-builtin - - path: stm32/nucleo-h743zi-make-freertos-builtin + - path: microchip/same54/device-dashboard + - path: infineon/infineon-xmc4700_4800-lwip-rtx-rtos - path: nxp/nxp-mimxrt1020-azurertos - path: nxp/nxp-frdmk66f-freertos - path: nxp/nxp-lpcxpresso54s018m-freertos @@ -253,14 +257,22 @@ jobs: - path: nxp/nxp-lpcxpresso54628-lwip-freertos - path: nxp/nxp-twrk65f180m-lwip-freertos - path: nxp/nxp-twrkv58f220m-lwip-freertos - - path: infineon/infineon-xmc4700_4800-lwip-rtx-rtos - - path: ti/ti-ek-tm4c1294xl-http-server - - path: ti/ek-tm4c1294xl-baremetal - - path: ti/ek-tm4c1294xl-freertos - path: rp2040/pico-rmii - path: rp2040/pico-rndis-dashboard - path: rp2040/pico-w - path: rp2040/pico-w5500 + - path: stm32/nucleo-f429zi-make-baremetal-builtin + - path: stm32/nucleo-f429zi-make-freertos-builtin + - path: stm32/nucleo-f429zi-make-baremetal-builtin-rndis + - path: stm32/nucleo-f746zg-make-baremetal-builtin + - path: stm32/nucleo-f746zg-make-freertos-builtin + - path: stm32/nucleo-f746zg-make-freertos-tcp + - path: stm32/nucleo-f746zg-make-baremetal-builtin-rndis + - path: stm32/nucleo-h743zi-make-baremetal-builtin + - path: stm32/nucleo-h743zi-make-freertos-builtin + - path: ti/ti-ek-tm4c1294xl-http-server + - path: ti/ek-tm4c1294xl-baremetal + - path: ti/ek-tm4c1294xl-freertos name: ${{ matrix.example.path }} steps: - uses: actions/checkout@v3 diff --git a/examples/microchip/same54/Makefile b/examples/microchip/same54/device-dashboard/Makefile similarity index 64% rename from examples/microchip/same54/Makefile rename to examples/microchip/same54/device-dashboard/Makefile index 9dfe63c6..7ae349c6 100644 --- a/examples/microchip/same54/Makefile +++ b/examples/microchip/same54/device-dashboard/Makefile @@ -1,20 +1,20 @@ -CFLAGS = -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion +CFLAGS = -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion CFLAGS += -Wformat-truncation -fno-common -Wconversion -CFLAGS += -g -O2 -ffunction-sections -fdata-sections +CFLAGS += -g3 -Os -ffunction-sections -fdata-sections CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -CFLAGS += -D__SAME54P20A__ -Icmsis_sam/include #-Icmsis_sam/xc32/include -#CFLAGS += -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -CFLAGS += -mcpu=cortex-m4 -mthumb -mfloat-abi=softfp -mfpu=fpv4-sp-d16 +CFLAGS += -D__SAME54P20A__ -Icmsis_sam/include +CFLAGS += -mcpu=cortex-m4 -mthumb -mfloat-abi=softfp LDFLAGS ?= -Tlink.ld -nostartfiles -nostdlib --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map SOURCES = main.c syscalls.c startup.c -#SOURCES += cmsis_sam/xc32/ATSAME54P20A/startup_atsame54p20a.c +# Mongoose-specific source code files and build options. See https://mongoose.ws/documentation/#build-options SOURCES += mongoose.c net.c packed_fs.c -CFLAGS += -DMG_ENABLE_TCPIP=1 -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1 #-DMG_ENABLE_LINES=1 +CFLAGS += -DMG_ENABLE_TCPIP=1 -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1 -DMG_ENABLE_LINES=1 CFLAGS += -DMG_ENABLE_DRIVER_SAME54=1 -DMG_ENABLE_CUSTOM_RANDOM=1 -DMG_ENABLE_PACKED_FS=1 $(CFLAGS_EXTRA) -VCON_API_KEY=IBrJL5K4arSGMiAXbUKWdG6I2gM +# Example specific build options. See README.md +CFLAGS += -DHTTP_URL=\"http://0.0.0.0/\" ifeq ($(OS),Windows_NT) RM = cmd /C del /Q /F @@ -24,33 +24,30 @@ endif build: firmware.bin -firmware.elf: cmsis_core cmsis_sam hal.h link.ld Makefile $(SOURCES) - arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -o $@ - firmware.bin: firmware.elf arm-none-eabi-objcopy -O binary $< $@ +firmware.elf: cmsis_core cmsis_sam hal.h link.ld Makefile $(SOURCES) + arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -o $@ + flash: firmware.bin bossac -p /dev/cu.usb* -w -v -b $< cmsis_core: git clone --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@ - cmsis_sam: curl -sL https://packs.download.microchip.com/Microchip.SAME54_DFP.3.8.234.pack -o $@.zip mkdir $@ && cd $@ && unzip ../$@.zip -# git clone --depth 1 -b master https://github.com/modm-io/cmsis-header-sam $@ - -clean: - $(RM) firmware.* cmsis_* *.zip # Automated test via https://vcon.io/automated-firmware-tests/. Set VCON_API_KEY and update DEVICE_URL DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/9 -fota: CFLAGS += -DUART_DEBUG=USART1 -fota: firmware.bin +update: firmware.bin curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$< -test: fota + +test update: CFLAGS += -DUART_DEBUG=USART1 +test: update curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=5 | tee /tmp/output.txt - egrep '^tick:.*CPU 180 MHz' /tmp/output.txt -watch: fota - curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=999 + grep 'READY, IP:' /tmp/output.txt # Check for network init + +clean: + $(RM) firmware.* cmsis_core cmsis_sam *.zip diff --git a/examples/microchip/same54/hal.h b/examples/microchip/same54/device-dashboard/hal.h similarity index 100% rename from examples/microchip/same54/hal.h rename to examples/microchip/same54/device-dashboard/hal.h diff --git a/examples/microchip/same54/link.ld b/examples/microchip/same54/device-dashboard/link.ld similarity index 100% rename from examples/microchip/same54/link.ld rename to examples/microchip/same54/device-dashboard/link.ld diff --git a/examples/microchip/same54/main.c b/examples/microchip/same54/device-dashboard/main.c similarity index 100% rename from examples/microchip/same54/main.c rename to examples/microchip/same54/device-dashboard/main.c diff --git a/examples/microchip/same54/device-dashboard/mongoose.c b/examples/microchip/same54/device-dashboard/mongoose.c new file mode 120000 index 00000000..7a2752cb --- /dev/null +++ b/examples/microchip/same54/device-dashboard/mongoose.c @@ -0,0 +1 @@ +../../../../mongoose.c \ No newline at end of file diff --git a/examples/microchip/same54/device-dashboard/mongoose.h b/examples/microchip/same54/device-dashboard/mongoose.h new file mode 120000 index 00000000..daff1633 --- /dev/null +++ b/examples/microchip/same54/device-dashboard/mongoose.h @@ -0,0 +1 @@ +../../../../mongoose.h \ No newline at end of file diff --git a/examples/microchip/same54/device-dashboard/net.c b/examples/microchip/same54/device-dashboard/net.c new file mode 120000 index 00000000..d0758f09 --- /dev/null +++ b/examples/microchip/same54/device-dashboard/net.c @@ -0,0 +1 @@ +../../../device-dashboard/net.c \ No newline at end of file diff --git a/examples/microchip/same54/device-dashboard/net.h b/examples/microchip/same54/device-dashboard/net.h new file mode 120000 index 00000000..413c4173 --- /dev/null +++ b/examples/microchip/same54/device-dashboard/net.h @@ -0,0 +1 @@ +../../../device-dashboard/net.h \ No newline at end of file diff --git a/examples/microchip/same54/device-dashboard/packed_fs.c b/examples/microchip/same54/device-dashboard/packed_fs.c new file mode 120000 index 00000000..ebd127df --- /dev/null +++ b/examples/microchip/same54/device-dashboard/packed_fs.c @@ -0,0 +1 @@ +../../../device-dashboard/packed_fs.c \ No newline at end of file diff --git a/examples/microchip/same54/startup.c b/examples/microchip/same54/device-dashboard/startup.c similarity index 100% rename from examples/microchip/same54/startup.c rename to examples/microchip/same54/device-dashboard/startup.c diff --git a/examples/microchip/same54/syscalls.c b/examples/microchip/same54/device-dashboard/syscalls.c similarity index 100% rename from examples/microchip/same54/syscalls.c rename to examples/microchip/same54/device-dashboard/syscalls.c diff --git a/examples/microchip/same54/mongoose.c b/examples/microchip/same54/mongoose.c deleted file mode 120000 index 5e522bbc..00000000 --- a/examples/microchip/same54/mongoose.c +++ /dev/null @@ -1 +0,0 @@ -../../../mongoose.c \ No newline at end of file diff --git a/examples/microchip/same54/mongoose.h b/examples/microchip/same54/mongoose.h deleted file mode 120000 index ee4ac823..00000000 --- a/examples/microchip/same54/mongoose.h +++ /dev/null @@ -1 +0,0 @@ -../../../mongoose.h \ No newline at end of file diff --git a/examples/microchip/same54/mqtt-client/Makefile b/examples/microchip/same54/mqtt-client/Makefile new file mode 100644 index 00000000..d9b58960 --- /dev/null +++ b/examples/microchip/same54/mqtt-client/Makefile @@ -0,0 +1,54 @@ +CFLAGS = -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion +CFLAGS += -Wformat-truncation -fno-common -Wconversion +CFLAGS += -g3 -Os -ffunction-sections -fdata-sections +CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include +CFLAGS += -D__SAME54P20A__ -Icmsis_sam/include +CFLAGS += -mcpu=cortex-m4 -mthumb -mfloat-abi=softfp +LDFLAGS ?= -Tlink.ld -nostartfiles -nostdlib --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map + +SOURCES = main.c syscalls.c startup.c + +# Mongoose-specific source code files and build options. See https://mongoose.ws/documentation/#build-options +SOURCES += mongoose.c +CFLAGS += -DMG_ENABLE_TCPIP=1 -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1 -DMG_ENABLE_LINES=1 +CFLAGS += -DMG_ENABLE_DRIVER_SAME54=1 -DMG_ENABLE_CUSTOM_RANDOM=1 -DMG_ENABLE_PACKED_FS=1 $(CFLAGS_EXTRA) + +# Example specific build options. See README.md +CFLAGS += -DHTTP_URL=\"http://0.0.0.0/\" + +ifeq ($(OS),Windows_NT) + RM = cmd /C del /Q /F +else + RM = rm -rf +endif + +build: firmware.bin + +firmware.bin: firmware.elf + arm-none-eabi-objcopy -O binary $< $@ + +firmware.elf: cmsis_core cmsis_sam hal.h link.ld Makefile $(SOURCES) + arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -o $@ + +flash: firmware.bin + bossac -p /dev/cu.usb* -w -v -b $< + +cmsis_core: + git clone --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@ +cmsis_sam: + curl -sL https://packs.download.microchip.com/Microchip.SAME54_DFP.3.8.234.pack -o $@.zip + mkdir $@ && cd $@ && unzip ../$@.zip + +# Automated test via https://vcon.io/automated-firmware-tests/. Set VCON_API_KEY and update DEVICE_URL +DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/9 +update: firmware.bin + curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$< + +test update: CFLAGS += -DUART_DEBUG=USART1 +test: update + curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=5 | tee /tmp/output.txt + grep 'READY, IP:' /tmp/output.txt # Check for network init + grep 'RECEIVED hello' /tmp/output.txt # Check for MQTT success + +clean: + $(RM) firmware.* cmsis_core cmsis_sam *.zip diff --git a/examples/microchip/same54/mqtt-client/hal.h b/examples/microchip/same54/mqtt-client/hal.h new file mode 100644 index 00000000..226548b8 --- /dev/null +++ b/examples/microchip/same54/mqtt-client/hal.h @@ -0,0 +1,219 @@ +// Copyright (c) 2022 Cesanta Software Limited +// SPDX-License-Identifier: MIT +// +// https://ww1.microchip.com/downloads/aemDocuments/documents/MCU32/ProductDocuments/DataSheets/SAM-D5x-E5x-Family-Data-Sheet-DS60001507.pdf +// https://ww1.microchip.com/downloads/en/DeviceDoc/70005321A.pdf + +#ifndef LED_PIN +#define LED_PIN PIN('C', 18) +#endif + +#ifndef BUTTON_PIN +#define BUTTON_PIN PIN('B', 31) +#endif + +#ifndef UART_DEBUG +#define UART_DEBUG USART1 +#endif + +#pragma once +#include + +#include +#include +#include +#include + +#define BIT(x) (1UL << (x)) +#define SETBITS(R, CLEARMASK, SETMASK) (R) = ((R) & ~(CLEARMASK)) | (SETMASK) +#define PIN(bank, num) ((((bank) - 'A') << 8) | (num)) +#define PINNO(pin) (pin & 255) +#define PINBANK(pin) (pin >> 8) + +static inline void spin(volatile uint32_t count) { + while (count--) (void) 0; +} + +static inline uint32_t clock_sys_freq(void) { + return 48000000U; +} + +enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT, GPIO_MODE_AF, GPIO_MODE_ANALOG }; +enum { GPIO_OTYPE_PUSH_PULL, GPIO_OTYPE_OPEN_DRAIN }; +enum { GPIO_SPEED_LOW, GPIO_SPEED_MEDIUM, GPIO_SPEED_HIGH, GPIO_SPEED_INSANE }; +enum { GPIO_PULL_NONE, GPIO_PULL_UP, GPIO_PULL_DOWN }; +#define GPIO(N) ((port_group_registers_t *) (PORT_BASE_ADDRESS + 0x80 * (N))) +typedef port_group_registers_t GPIO_TypeDef; +static inline GPIO_TypeDef *gpio_bank(uint16_t pin) { + return GPIO(PINBANK(pin)); +} +static inline void gpio_toggle(uint16_t pin) { + gpio_bank(pin)->PORT_OUTTGL = BIT(PINNO(pin)); +} +static inline bool gpio_read(uint16_t pin) { + return gpio_bank(pin)->PORT_IN & BIT(PINNO(pin)); +} +static inline void gpio_write(uint16_t pin, bool val) { + GPIO_TypeDef *gpio = gpio_bank(pin); + if (val) { + gpio->PORT_OUTSET = BIT(PINNO(pin)); + } else { + gpio->PORT_OUTCLR = BIT(PINNO(pin)); + } +} +static inline void gpio_init(uint16_t pin, uint8_t mode, uint8_t type, + uint8_t speed, uint8_t pull, uint8_t af) { + (void) type, (void) speed, (void) pull, (void) af; + GPIO_TypeDef *gpio = gpio_bank(pin); + uint32_t mask = BIT(PINNO(pin)); + MCLK_REGS->MCLK_APBBMASK |= MCLK_APBBMASK_PORT_Msk; + if (mode == GPIO_MODE_INPUT) { + gpio->PORT_DIRCLR = mask; + } else { + gpio->PORT_DIRSET = mask; + } +} +static inline void gpio_input(uint16_t pin) { + gpio_init(pin, GPIO_MODE_INPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, + GPIO_PULL_NONE, 0); +} +static inline void gpio_output(uint16_t pin) { + gpio_init(pin, GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, + GPIO_PULL_NONE, 0); +} + +typedef sercom_usart_int_registers_t USART_TypeDef; +#define USART1 ((USART_TypeDef *) SERCOM0_BASE_ADDRESS) +#define USART2 ((USART_TypeDef *) SERCOM1_BASE_ADDRESS) +#define USART3 ((USART_TypeDef *) SERCOM2_BASE_ADDRESS) +static inline bool uart_init(USART_TypeDef *uart, unsigned long baud) { + uint16_t rx = 0, tx = 0; // Pins + uint8_t rx_mux = 0, tx_mux = 0; + if (uart == USART1) { + MCLK_REGS->MCLK_APBAMASK |= MCLK_APBAMASK_SERCOM0_Msk; + GCLK_REGS->GCLK_PCHCTRL[SERCOM0_GCLK_ID_CORE] = + GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN_Msk; + GCLK_REGS->GCLK_PCHCTRL[SERCOM0_GCLK_ID_SLOW] = + GCLK_PCHCTRL_GEN_GCLK3 | GCLK_PCHCTRL_CHEN_Msk; + tx = PIN('A', 4), rx = PIN('A', 5); + rx_mux = MUX_PA05D_SERCOM0_PAD1, tx_mux = MUX_PA04D_SERCOM0_PAD0; + } else if (uart == USART2) { + MCLK_REGS->MCLK_APBAMASK |= MCLK_APBAMASK_SERCOM1_Msk; + tx = PIN('C', 27), rx = PIN('C', 28); + } else if (uart == USART3) { + MCLK_REGS->MCLK_APBBMASK |= MCLK_APBBMASK_SERCOM2_Msk; + tx = PIN('A', 9), rx = PIN('A', 8); + } else { + return false; + } + gpio_bank(rx)->PORT_WRCONFIG = + PORT_WRCONFIG_PMUX(rx_mux) | PORT_WRCONFIG_WRPMUX(1) | + PORT_WRCONFIG_PMUXEN(1) | PORT_WRCONFIG_WRPINCFG(1) | BIT(PINNO(rx)); + gpio_bank(tx)->PORT_WRCONFIG = + PORT_WRCONFIG_PMUX(tx_mux) | PORT_WRCONFIG_WRPMUX(1) | + PORT_WRCONFIG_PMUXEN(1) | PORT_WRCONFIG_WRPINCFG(1) | BIT(PINNO(tx)); + uart->SERCOM_CTRLA = SERCOM_USART_INT_CTRLA_DORD(1) | + SERCOM_USART_INT_CTRLA_MODE(1 /* INT_CLK */) | + SERCOM_USART_INT_CTRLA_RXPO(1 /* PAD1 */) | + SERCOM_USART_INT_CTRLA_TXPO(0 /* PAD0 */) | + SERCOM_USART_INT_CTRLA_SAMPR(1); + uart->SERCOM_BAUD = (uint16_t) (clock_sys_freq() / (16 * baud)); + uart->SERCOM_CTRLB = SERCOM_USART_INT_CTRLB_RXEN(1) | + SERCOM_USART_INT_CTRLB_TXEN(1) | + SERCOM_USART_INT_CTRLB_CHSIZE(0); + while (uart->SERCOM_SYNCBUSY & SERCOM_USART_INT_SYNCBUSY_CTRLB_Msk) spin(1); + uart->SERCOM_CTRLA |= SERCOM_USART_INT_CTRLA_ENABLE(1); + while (uart->SERCOM_SYNCBUSY & SERCOM_USART_INT_SYNCBUSY_ENABLE_Msk) spin(1); + return true; +} +static inline void uart_write_byte(USART_TypeDef *uart, uint8_t byte) { + while (!(uart->SERCOM_INTFLAG & SERCOM_USART_INT_INTFLAG_DRE_Msk)) spin(1); + uart->SERCOM_DATA = byte; +} +static inline void uart_write_buf(USART_TypeDef *uart, char *buf, size_t len) { + while (len-- > 0) uart_write_byte(uart, *(uint8_t *) buf++); +} +static inline bool uart_read_ready(USART_TypeDef *uart) { + return (uart->SERCOM_INTFLAG & SERCOM_USART_EXT_INTFLAG_RXC_Msk); +} +static inline uint8_t uart_read_byte(USART_TypeDef *uart) { + return (uint8_t) (uart->SERCOM_DATA & 255U); +} + +static inline void rng_init(void) { + MCLK_REGS->MCLK_APBCMASK |= MCLK_APBCMASK_TRNG_Msk; + TRNG_REGS->TRNG_CTRLA = TRNG_CTRLA_ENABLE_Msk; +} +static inline uint32_t rng_read(void) { + while ((TRNG_REGS->TRNG_INTFLAG & TRNG_INTFLAG_DATARDY_Msk) == 0) spin(1); + return TRNG_REGS->TRNG_DATA; +} + +#define UID_BASE_W0 0x008061FC // Word 0 location of the 128-bit chip ID +#define UID_BASE_W1_3 0x00806010 // Words 1-3 location of the 128-bit chip ID + +#define UUID(n) ((n >= 0 && n <= 3) ? \ + (((uint8_t *) UID_BASE_W0)[n]) : \ + (((uint8_t *) UID_BASE_W1_3)[n - 4])) + +#define GENERATE_LOCALLY_ADMINISTERED_MAC() \ + { \ + 2, UUID(0) ^ UUID(1) ^ UUID(2), UUID(3) ^ UUID(4) ^ UUID(5), \ + UUID(6) ^ UUID(7) ^ UUID(8), UUID(9) ^ UUID(10) ^ UUID(11), \ + UUID(12) ^ UUID(13) ^ UUID(14) ^ UUID(15) \ + } + +static inline bool timer_expired(volatile uint64_t *t, uint64_t prd, + uint64_t now) { + if (now + prd < *t) *t = 0; // Time wrapped? Reset timer + if (*t == 0) *t = now + prd; // Firt poll? Set expiration + if (*t > now) return false; // Not expired yet, return + *t = (now - *t) > prd ? now + prd : *t + prd; // Next expiration time + return true; // Expired, return true +} + +static inline void clock_init(void) { + SCB->CPACR |= (15U << 20); // Enable FPU + SysTick_Config(clock_sys_freq() / 1000); // Sys tick every 1ms +} + +static inline void gpio_set_irq_handler(uint16_t pin, void (*fn)(void *), + void *arg) { + (void) pin, (void) fn, (void) arg; +} + +static inline void ethernet_init(void) { + uint16_t pins[] = {PIN('A', 12), PIN('A', 13), PIN('A', 14), PIN('A', 15), + PIN('A', 17), PIN('A', 18), PIN('A', 19), PIN('C', 11), + PIN('C', 12), PIN('C', 20)}; + uint32_t af[] = {MUX_PA12L_GMAC_GRX1, MUX_PA13L_GMAC_GRX0, + MUX_PA14L_GMAC_GTXCK, MUX_PA15L_GMAC_GRXER, + MUX_PA17L_GMAC_GTXEN, MUX_PA18L_GMAC_GTX0, + MUX_PA19L_GMAC_GTX1, MUX_PC11L_GMAC_GMDC, + MUX_PC12L_GMAC_GMDIO, MUX_PC20L_GMAC_GRXDV}; + + MCLK_REGS->MCLK_APBBMASK |= MCLK_APBBMASK_PORT_Msk; + + for (size_t i = 0; i < sizeof(pins) / sizeof(pins[0]); i++) { + int bank = PINBANK(pins[i]), no = PINNO(pins[i]); + PORT_REGS->GROUP[bank].PORT_PINCFG[no] |= PORT_PINCFG_PMUXEN_Msk; + volatile uint8_t *m = &PORT_REGS->GROUP[bank].PORT_PMUX[no / 2], v = m[0]; + if (no & 1) { + m[0] = (uint8_t) ((v & ~0xf0) | PORT_PMUX_PMUXO(af[i])); + } else { + m[0] = (uint8_t) ((v & ~0x0f) | PORT_PMUX_PMUXE(af[i])); + } + } + + PORT_REGS->GROUP[0].PORT_PINCFG[17] |= PORT_PINCFG_DRVSTR_Msk; + PORT_REGS->GROUP[0].PORT_PINCFG[18] |= PORT_PINCFG_DRVSTR_Msk; + PORT_REGS->GROUP[0].PORT_PINCFG[19] |= PORT_PINCFG_DRVSTR_Msk; + + // Reset PHY + uint16_t phy_pin = PIN('C', 21); + gpio_output(phy_pin); + gpio_write(phy_pin, false); + spin(999); + gpio_write(phy_pin, true); + spin(999); +} diff --git a/examples/microchip/same54/mqtt-client/link.ld b/examples/microchip/same54/mqtt-client/link.ld new file mode 100644 index 00000000..f66bbb90 --- /dev/null +++ b/examples/microchip/same54/mqtt-client/link.ld @@ -0,0 +1,25 @@ +ENTRY(Reset_Handler); +MEMORY { + flash(rx) : ORIGIN = 0x00000000, LENGTH = 1024k + sram(rwx) : ORIGIN = 0x20000000, LENGTH = 256k +} +_estack = ORIGIN(sram) + LENGTH(sram); + +SECTIONS { + .vectors : { FILL(256) KEEP(*(.vectors)) } > flash + .text : { *(.text*) } > flash + .rodata : { *(.rodata*) } > flash + + .data : { + _sdata = .; + *(.first_data) + *(.data SORT(.data.*)) + _edata = .; + } > sram AT > flash + _sidata = LOADADDR(.data); + + .bss : { _sbss = .; *(.bss SORT(.bss.*) COMMON) _ebss = .; } > sram + + . = ALIGN(8); + _end = .; +} diff --git a/examples/microchip/same54/mqtt-client/main.c b/examples/microchip/same54/mqtt-client/main.c new file mode 100644 index 00000000..0988574a --- /dev/null +++ b/examples/microchip/same54/mqtt-client/main.c @@ -0,0 +1,120 @@ +// Copyright (c) 2023 Cesanta Software Limited +// All rights reserved + +#include "hal.h" +#include "mongoose.h" + +static const char *s_url = "mqtt://broker.hivemq.com:1883"; +static const char *s_sub_topic = "mg/+/test"; // Publish topic +static const char *s_pub_topic = "mg/clnt/test"; // Subscribe topic +static const uint8_t s_qos = 1; // MQTT QoS +static struct mg_connection *s_conn; // Client connection + +void SystemInit(void) { // Called automatically by startup code + clock_init(); + rng_init(); +} + +static volatile uint64_t s_ticks; // Milliseconds since boot +void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms + s_ticks++; +} + +uint64_t mg_millis(void) { // Let Mongoose use our uptime function + return s_ticks; // Return number of milliseconds since boot +} + +void mg_random(void *buf, size_t len) { // Use on-board RNG + for (size_t n = 0; n < len; n += sizeof(uint32_t)) { + uint32_t r = rng_read(); + memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r)); + } +} + +static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { + if (ev == MG_EV_OPEN) { + MG_INFO(("%lu CREATED", c->id)); + // c->is_hexdumping = 1; + } else if (ev == MG_EV_ERROR) { + // On error, log error message + MG_ERROR(("%lu ERROR %s", c->id, (char *) ev_data)); + } else if (ev == MG_EV_MQTT_OPEN) { + // MQTT connect is successful + struct mg_str subt = mg_str(s_sub_topic); + struct mg_str pubt = mg_str(s_pub_topic), data = mg_str("hello"); + MG_INFO(("%lu CONNECTED to %s", c->id, s_url)); + struct mg_mqtt_opts sub_opts; + memset(&sub_opts, 0, sizeof(sub_opts)); + sub_opts.topic = subt; + sub_opts.qos = s_qos; + mg_mqtt_sub(c, &sub_opts); + MG_INFO(("%lu SUBSCRIBED to %.*s", c->id, (int) subt.len, subt.ptr)); + struct mg_mqtt_opts pub_opts; + memset(&pub_opts, 0, sizeof(pub_opts)); + pub_opts.topic = pubt; + pub_opts.message = data; + pub_opts.qos = s_qos, pub_opts.retain = false; + mg_mqtt_pub(c, &pub_opts); + MG_INFO(("%lu PUBLISHED %.*s -> %.*s", c->id, (int) data.len, data.ptr, + (int) pubt.len, pubt.ptr)); + } else if (ev == MG_EV_MQTT_MSG) { + // When we get echo response, print it + struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data; + MG_INFO(("%lu RECEIVED %.*s <- %.*s", c->id, (int) mm->data.len, + mm->data.ptr, (int) mm->topic.len, mm->topic.ptr)); + } else if (ev == MG_EV_CLOSE) { + MG_INFO(("%lu CLOSED", c->id)); + s_conn = NULL; // Mark that we're closed + } + (void) fn_data; +} + +// Timer function - recreate client connection if it is closed +static void timer_fn(void *arg) { + struct mg_mgr *mgr = (struct mg_mgr *) arg; + struct mg_mqtt_opts opts = {.clean = true, + .qos = s_qos, + .topic = mg_str(s_pub_topic), + .version = 4, + .message = mg_str("bye")}; + if (s_conn == NULL) s_conn = mg_mqtt_connect(mgr, s_url, &opts, fn, NULL); +} + +int main(void) { + gpio_input(BUTTON_PIN); + gpio_output(LED_PIN); + uart_init(UART_DEBUG, 115200); + ethernet_init(); + MG_INFO(("Starting, CPU freq %g MHz", (double) clock_sys_freq() / 1000000)); + + struct mg_mgr mgr; // Initialise + mg_mgr_init(&mgr); // Mongoose event manager + mg_log_set(MG_LL_DEBUG); // Set log level + + // Initialise Mongoose network stack + struct mg_tcpip_driver_same54_data driver_data = {.mdc_cr = 5}; + struct mg_tcpip_if mif = { + .mac = GENERATE_LOCALLY_ADMINISTERED_MAC() /*{2, 3, 4, 5, 6, 7}*/, + // Uncomment below for static configuration: + // .ip = mg_htonl(MG_U32(192, 168, 0, 223)), + // .mask = mg_htonl(MG_U32(255, 255, 255, 0)), + // .gw = mg_htonl(MG_U32(192, 168, 0, 1)), + .driver = &mg_tcpip_driver_same54, + .driver_data = &driver_data}; + mg_tcpip_init(&mgr, &mif); + + MG_INFO(("MAC: %M. Waiting for IP...", mg_print_mac, mif.mac)); + while (mif.state != MG_TCPIP_STATE_READY) { + mg_mgr_poll(&mgr, 0); + } + + MG_INFO(("Initialising application...")); + mg_timer_add(&mgr, 3000, MG_TIMER_REPEAT | MG_TIMER_RUN_NOW, timer_fn, &mgr); + + MG_INFO(("Starting event loop")); + for (;;) { + mg_mgr_poll(&mgr, 0); + } + + return 0; +} diff --git a/examples/microchip/same54/mqtt-client/mongoose.c b/examples/microchip/same54/mqtt-client/mongoose.c new file mode 120000 index 00000000..7a2752cb --- /dev/null +++ b/examples/microchip/same54/mqtt-client/mongoose.c @@ -0,0 +1 @@ +../../../../mongoose.c \ No newline at end of file diff --git a/examples/microchip/same54/mqtt-client/mongoose.h b/examples/microchip/same54/mqtt-client/mongoose.h new file mode 120000 index 00000000..daff1633 --- /dev/null +++ b/examples/microchip/same54/mqtt-client/mongoose.h @@ -0,0 +1 @@ +../../../../mongoose.h \ No newline at end of file diff --git a/examples/microchip/same54/mqtt-client/myMakefile b/examples/microchip/same54/mqtt-client/myMakefile new file mode 100644 index 00000000..9b171144 --- /dev/null +++ b/examples/microchip/same54/mqtt-client/myMakefile @@ -0,0 +1,55 @@ +CFLAGS = -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion +CFLAGS += -Wformat-truncation -fno-common -Wconversion +CFLAGS += -g3 -Os -ffunction-sections -fdata-sections +CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include +CFLAGS += -D__SAME54P20A__ -Icmsis_sam/include +CFLAGS += -mcpu=cortex-m4 -mthumb -mfloat-abi=softfp +LDFLAGS ?= -Tlink.ld -nostartfiles -nostdlib --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map + +SOURCES = main.c syscalls.c startup.c + +# Mongoose-specific source code files and build options. See https://mongoose.ws/documentation/#build-options +SOURCES += mongoose.c +CFLAGS += -DMG_ENABLE_TCPIP=1 -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1 -DMG_ENABLE_LINES=1 +CFLAGS += -DMG_ENABLE_DRIVER_SAME54=1 -DMG_ENABLE_CUSTOM_RANDOM=1 -DMG_ENABLE_PACKED_FS=1 $(CFLAGS_EXTRA) + +# Example specific build options. See README.md +CFLAGS += -DHTTP_URL=\"http://0.0.0.0/\" + +ifeq ($(OS),Windows_NT) + RM = cmd /C del /Q /F +else + RM = rm -rf +endif + +build: firmware.bin + +firmware.bin: firmware.elf + arm-none-eabi-objcopy -O binary $< $@ + +firmware.elf: cmsis_core cmsis_sam hal.h link.ld Makefile $(SOURCES) + arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -o $@ + +flash: firmware.bin + bossac -p /dev/cu.usb* -w -v -b $< + +cmsis_core: + git clone --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@ +cmsis_sam: + curl -sL https://packs.download.microchip.com/Microchip.SAME54_DFP.3.8.234.pack -o $@.zip + mkdir $@ && cd $@ && unzip ../$@.zip + +# Automated test via https://vcon.io/automated-firmware-tests/. Set VCON_API_KEY and update DEVICE_URL +DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/9 +VCON_API_KEY ?= "IBrJL5K4arSGMiAXbUKWdG6I2gM" +update: firmware.bin + curl -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$< + +test update: CFLAGS += -DUART_DEBUG=USART1 +test: update + curl -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=10 | tee /tmp/output.txt + grep 'READY, IP:' /tmp/output.txt # Check for network init + grep 'RECEIVED hello' /tmp/output.txt # Check for MQTT success + +clean: + $(RM) firmware.* cmsis_core cmsis_sam *.zip diff --git a/examples/microchip/same54/mqtt-client/startup.c b/examples/microchip/same54/mqtt-client/startup.c new file mode 100644 index 00000000..28ef30e2 --- /dev/null +++ b/examples/microchip/same54/mqtt-client/startup.c @@ -0,0 +1,332 @@ +// SPDX-FileCopyrightText: 2022-2023 Cesanta Software Limited +// SPDX-License-Identifier: MIT + +#include "hal.h" + +void Reset_Handler(void); // Defined below +void Dummy_Handler(void); // Defined below +void SysTick_Handler(void); // Defined in main.c +void SystemInit(void); // Defined in main.c, called by reset handler +void _estack(void); // Defined in link.ld + +#define WEAK_ALIAS __attribute__((weak, alias("Default_Handler"))) + +WEAK_ALIAS void NMI_Handler(void); +WEAK_ALIAS void HardFault_Handler(void); +WEAK_ALIAS void MemoryManagement_Handler(void); +WEAK_ALIAS void BusFault_Handler(void); +WEAK_ALIAS void UsageFault_Handler(void); +WEAK_ALIAS void SVCall_Handler(void); +WEAK_ALIAS void DebugMonitor_Handler(void); +WEAK_ALIAS void PendSV_Handler(void); +WEAK_ALIAS void SysTick_Handler(void); + +WEAK_ALIAS void PM_Handler(void); +WEAK_ALIAS void MCLK_Handler(void); +WEAK_ALIAS void OSCCTRL_XOSC0_Handler(void); +WEAK_ALIAS void OSCCTRL_XOSC1_Handler(void); +WEAK_ALIAS void OSCCTRL_DFLL_Handler(void); +WEAK_ALIAS void OSCCTRL_DPLL0_Handler(void); +WEAK_ALIAS void OSCCTRL_DPLL1_Handler(void); +WEAK_ALIAS void OSC32KCTRL_Handler(void); +WEAK_ALIAS void SUPC_OTHER_Handler(void); +WEAK_ALIAS void SUPC_BODDET_Handler(void); +WEAK_ALIAS void WDT_Handler(void); +WEAK_ALIAS void RTC_Handler(void); +WEAK_ALIAS void EIC_EXTINT_0_Handler(void); +WEAK_ALIAS void EIC_EXTINT_1_Handler(void); +WEAK_ALIAS void EIC_EXTINT_2_Handler(void); +WEAK_ALIAS void EIC_EXTINT_3_Handler(void); +WEAK_ALIAS void EIC_EXTINT_4_Handler(void); +WEAK_ALIAS void EIC_EXTINT_5_Handler(void); +WEAK_ALIAS void EIC_EXTINT_6_Handler(void); +WEAK_ALIAS void EIC_EXTINT_7_Handler(void); +WEAK_ALIAS void EIC_EXTINT_8_Handler(void); +WEAK_ALIAS void EIC_EXTINT_9_Handler(void); +WEAK_ALIAS void EIC_EXTINT_10_Handler(void); +WEAK_ALIAS void EIC_EXTINT_11_Handler(void); +WEAK_ALIAS void EIC_EXTINT_12_Handler(void); +WEAK_ALIAS void EIC_EXTINT_13_Handler(void); +WEAK_ALIAS void EIC_EXTINT_14_Handler(void); +WEAK_ALIAS void EIC_EXTINT_15_Handler(void); +WEAK_ALIAS void FREQM_Handler(void); +WEAK_ALIAS void NVMCTRL_0_Handler(void); +WEAK_ALIAS void NVMCTRL_1_Handler(void); +WEAK_ALIAS void DMAC_0_Handler(void); +WEAK_ALIAS void DMAC_1_Handler(void); +WEAK_ALIAS void DMAC_2_Handler(void); +WEAK_ALIAS void DMAC_3_Handler(void); +WEAK_ALIAS void DMAC_OTHER_Handler(void); +WEAK_ALIAS void EVSYS_0_Handler(void); +WEAK_ALIAS void EVSYS_1_Handler(void); +WEAK_ALIAS void EVSYS_2_Handler(void); +WEAK_ALIAS void EVSYS_3_Handler(void); +WEAK_ALIAS void EVSYS_OTHER_Handler(void); +WEAK_ALIAS void PAC_Handler(void); +WEAK_ALIAS void RAMECC_Handler(void); +WEAK_ALIAS void SERCOM0_0_Handler(void); +WEAK_ALIAS void SERCOM0_1_Handler(void); +WEAK_ALIAS void SERCOM0_2_Handler(void); +WEAK_ALIAS void SERCOM0_OTHER_Handler(void); +WEAK_ALIAS void SERCOM1_0_Handler(void); +WEAK_ALIAS void SERCOM1_1_Handler(void); +WEAK_ALIAS void SERCOM1_2_Handler(void); +WEAK_ALIAS void SERCOM1_OTHER_Handler(void); +WEAK_ALIAS void SERCOM2_0_Handler(void); +WEAK_ALIAS void SERCOM2_1_Handler(void); +WEAK_ALIAS void SERCOM2_2_Handler(void); +WEAK_ALIAS void SERCOM2_OTHER_Handler(void); +WEAK_ALIAS void SERCOM3_0_Handler(void); +WEAK_ALIAS void SERCOM3_1_Handler(void); +WEAK_ALIAS void SERCOM3_2_Handler(void); +WEAK_ALIAS void SERCOM3_OTHER_Handler(void); +WEAK_ALIAS void SERCOM4_0_Handler(void); +WEAK_ALIAS void SERCOM4_1_Handler(void); +WEAK_ALIAS void SERCOM4_2_Handler(void); +WEAK_ALIAS void SERCOM4_OTHER_Handler(void); +WEAK_ALIAS void SERCOM5_0_Handler(void); +WEAK_ALIAS void SERCOM5_1_Handler(void); +WEAK_ALIAS void SERCOM5_2_Handler(void); +WEAK_ALIAS void SERCOM5_OTHER_Handler(void); +WEAK_ALIAS void SERCOM6_0_Handler(void); +WEAK_ALIAS void SERCOM6_1_Handler(void); +WEAK_ALIAS void SERCOM6_2_Handler(void); +WEAK_ALIAS void SERCOM6_OTHER_Handler(void); +WEAK_ALIAS void SERCOM7_0_Handler(void); +WEAK_ALIAS void SERCOM7_1_Handler(void); +WEAK_ALIAS void SERCOM7_2_Handler(void); +WEAK_ALIAS void SERCOM7_OTHER_Handler(void); +WEAK_ALIAS void CAN0_Handler(void); +WEAK_ALIAS void CAN1_Handler(void); +WEAK_ALIAS void USB_OTHER_Handler(void); +WEAK_ALIAS void USB_SOF_HSOF_Handler(void); +WEAK_ALIAS void USB_TRCPT0_Handler(void); +WEAK_ALIAS void USB_TRCPT1_Handler(void); +WEAK_ALIAS void GMAC_Handler(void); +WEAK_ALIAS void TCC0_OTHER_Handler(void); +WEAK_ALIAS void TCC0_MC0_Handler(void); +WEAK_ALIAS void TCC0_MC1_Handler(void); +WEAK_ALIAS void TCC0_MC2_Handler(void); +WEAK_ALIAS void TCC0_MC3_Handler(void); +WEAK_ALIAS void TCC0_MC4_Handler(void); +WEAK_ALIAS void TCC0_MC5_Handler(void); +WEAK_ALIAS void TCC1_OTHER_Handler(void); +WEAK_ALIAS void TCC1_MC0_Handler(void); +WEAK_ALIAS void TCC1_MC1_Handler(void); +WEAK_ALIAS void TCC1_MC2_Handler(void); +WEAK_ALIAS void TCC1_MC3_Handler(void); +WEAK_ALIAS void TCC2_OTHER_Handler(void); +WEAK_ALIAS void TCC2_MC0_Handler(void); +WEAK_ALIAS void TCC2_MC1_Handler(void); +WEAK_ALIAS void TCC2_MC2_Handler(void); +WEAK_ALIAS void TCC3_OTHER_Handler(void); +WEAK_ALIAS void TCC3_MC0_Handler(void); +WEAK_ALIAS void TCC3_MC1_Handler(void); +WEAK_ALIAS void TCC4_OTHER_Handler(void); +WEAK_ALIAS void TCC4_MC0_Handler(void); +WEAK_ALIAS void TCC4_MC1_Handler(void); +WEAK_ALIAS void TC0_Handler(void); +WEAK_ALIAS void TC1_Handler(void); +WEAK_ALIAS void TC2_Handler(void); +WEAK_ALIAS void TC3_Handler(void); +WEAK_ALIAS void TC4_Handler(void); +WEAK_ALIAS void TC5_Handler(void); +WEAK_ALIAS void TC6_Handler(void); +WEAK_ALIAS void TC7_Handler(void); +WEAK_ALIAS void PDEC_OTHER_Handler(void); +WEAK_ALIAS void PDEC_MC0_Handler(void); +WEAK_ALIAS void PDEC_MC1_Handler(void); +WEAK_ALIAS void ADC0_OTHER_Handler(void); +WEAK_ALIAS void ADC0_RESRDY_Handler(void); +WEAK_ALIAS void ADC1_OTHER_Handler(void); +WEAK_ALIAS void ADC1_RESRDY_Handler(void); +WEAK_ALIAS void AC_Handler(void); +WEAK_ALIAS void DAC_OTHER_Handler(void); +WEAK_ALIAS void DAC_EMPTY_0_Handler(void); +WEAK_ALIAS void DAC_EMPTY_1_Handler(void); +WEAK_ALIAS void DAC_RESRDY_0_Handler(void); +WEAK_ALIAS void DAC_RESRDY_1_Handler(void); +WEAK_ALIAS void I2S_Handler(void); +WEAK_ALIAS void PCC_Handler(void); +WEAK_ALIAS void AES_Handler(void); +WEAK_ALIAS void TRNG_Handler(void); +WEAK_ALIAS void ICM_Handler(void); +WEAK_ALIAS void PUKCC_Handler(void); +WEAK_ALIAS void QSPI_Handler(void); +WEAK_ALIAS void SDHC0_Handler(void); +WEAK_ALIAS void SDHC1_Handler(void); + +__attribute__((section(".vectors"))) void (*const tab[16 + 138])(void) = { + _estack, + Reset_Handler, + NMI_Handler, + HardFault_Handler, + MemoryManagement_Handler, + BusFault_Handler, + UsageFault_Handler, + NULL, + NULL, + NULL, + NULL, + SVCall_Handler, + DebugMonitor_Handler, + NULL, + PendSV_Handler, + SysTick_Handler, + PM_Handler, // 0 Power + MCLK_Handler, // 1 Main + OSCCTRL_XOSC0_Handler, // 2 Oscillators + OSCCTRL_XOSC1_Handler, // 3 Oscillators + OSCCTRL_DFLL_Handler, // 4 Oscillators + OSCCTRL_DPLL0_Handler, // 5 Oscillators + OSCCTRL_DPLL1_Handler, // 6 Oscillators + OSC32KCTRL_Handler, // 7 32kHz + SUPC_OTHER_Handler, // 8 Supply + SUPC_BODDET_Handler, // 9 Supply + WDT_Handler, // 10 Watchdog + RTC_Handler, // 11 Real-Time + EIC_EXTINT_0_Handler, // 12 External + EIC_EXTINT_1_Handler, // 13 External + EIC_EXTINT_2_Handler, // 14 External + EIC_EXTINT_3_Handler, // 15 External + EIC_EXTINT_4_Handler, // 16 External + EIC_EXTINT_5_Handler, // 17 External + EIC_EXTINT_6_Handler, // 18 External + EIC_EXTINT_7_Handler, // 19 External + EIC_EXTINT_8_Handler, // 20 External + EIC_EXTINT_9_Handler, // 21 External + EIC_EXTINT_10_Handler, // 22 External + EIC_EXTINT_11_Handler, // 23 External + EIC_EXTINT_12_Handler, // 24 External + EIC_EXTINT_13_Handler, // 25 External + EIC_EXTINT_14_Handler, // 26 External + EIC_EXTINT_15_Handler, // 27 External + FREQM_Handler, // 28 Frequency + NVMCTRL_0_Handler, // 29 Non-Volatile + NVMCTRL_1_Handler, // 30 Non-Volatile + DMAC_0_Handler, // 31 Direct + DMAC_1_Handler, // 32 Direct + DMAC_2_Handler, // 33 Direct + DMAC_3_Handler, // 34 Direct + DMAC_OTHER_Handler, // 35 Direct + EVSYS_0_Handler, // 36 Event + EVSYS_1_Handler, // 37 Event + EVSYS_2_Handler, // 38 Event + EVSYS_3_Handler, // 39 Event + EVSYS_OTHER_Handler, // 40 Event + PAC_Handler, // 41 Peripheral + 0, // 42 Reserved + 0, // 43 Reserved + 0, // 44 Reserved + RAMECC_Handler, // 45 RAM + SERCOM0_0_Handler, // 46 Serial + SERCOM0_1_Handler, // 47 Serial + SERCOM0_2_Handler, // 48 Serial + SERCOM0_OTHER_Handler, // 49 Serial + SERCOM1_0_Handler, // 50 Serial + SERCOM1_1_Handler, // 51 Serial + SERCOM1_2_Handler, // 52 Serial + SERCOM1_OTHER_Handler, // 53 Serial + SERCOM2_0_Handler, // 54 Serial + SERCOM2_1_Handler, // 55 Serial + SERCOM2_2_Handler, // 56 Serial + SERCOM2_OTHER_Handler, // 57 Serial + SERCOM3_0_Handler, // 58 Serial + SERCOM3_1_Handler, // 59 Serial + SERCOM3_2_Handler, // 60 Serial + SERCOM3_OTHER_Handler, // 61 Serial + SERCOM4_0_Handler, // 62 Serial + SERCOM4_1_Handler, // 63 Serial + SERCOM4_2_Handler, // 64 Serial + SERCOM4_OTHER_Handler, // 65 Serial + SERCOM5_0_Handler, // 66 Serial + SERCOM5_1_Handler, // 67 Serial + SERCOM5_2_Handler, // 68 Serial + SERCOM5_OTHER_Handler, // 69 Serial + SERCOM6_0_Handler, // 70 Serial + SERCOM6_1_Handler, // 71 Serial + SERCOM6_2_Handler, // 72 Serial + SERCOM6_OTHER_Handler, // 73 Serial + SERCOM7_0_Handler, // 74 Serial + SERCOM7_1_Handler, // 75 Serial + SERCOM7_2_Handler, // 76 Serial + SERCOM7_OTHER_Handler, // 77 Serial + CAN0_Handler, // 78 Control + CAN1_Handler, // 79 Control + USB_OTHER_Handler, // 80 Universal + USB_SOF_HSOF_Handler, // 81 Universal + USB_TRCPT0_Handler, // 82 Universal + USB_TRCPT1_Handler, // 83 Universal + GMAC_Handler, // 84 Ethernet + TCC0_OTHER_Handler, // 85 Timer + TCC0_MC0_Handler, // 86 Timer + TCC0_MC1_Handler, // 87 Timer + TCC0_MC2_Handler, // 88 Timer + TCC0_MC3_Handler, // 89 Timer + TCC0_MC4_Handler, // 90 Timer + TCC0_MC5_Handler, // 91 Timer + TCC1_OTHER_Handler, // 92 Timer + TCC1_MC0_Handler, // 93 Timer + TCC1_MC1_Handler, // 94 Timer + TCC1_MC2_Handler, // 95 Timer + TCC1_MC3_Handler, // 96 Timer + TCC2_OTHER_Handler, // 97 Timer + TCC2_MC0_Handler, // 98 Timer + TCC2_MC1_Handler, // 99 Timer + TCC2_MC2_Handler, // 100 Timer + TCC3_OTHER_Handler, // 101 Timer + TCC3_MC0_Handler, // 102 Timer + TCC3_MC1_Handler, // 103 Timer + TCC4_OTHER_Handler, // 104 Timer + TCC4_MC0_Handler, // 105 Timer + TCC4_MC1_Handler, // 106 Timer + TC0_Handler, // 107 Basic + TC1_Handler, // 108 Basic + TC2_Handler, // 109 Basic + TC3_Handler, // 110 Basic + TC4_Handler, // 111 Basic + TC5_Handler, // 112 Basic + TC6_Handler, // 113 Basic + TC7_Handler, // 114 Basic + PDEC_OTHER_Handler, // 115 Quadrature + PDEC_MC0_Handler, // 116 Quadrature + PDEC_MC1_Handler, // 117 Quadrature + ADC0_OTHER_Handler, // 118 Analog + ADC0_RESRDY_Handler, // 119 Analog + ADC1_OTHER_Handler, // 120 Analog + ADC1_RESRDY_Handler, // 121 Analog + AC_Handler, // 122 Analog + DAC_OTHER_Handler, // 123 Digital-to-Analog + DAC_EMPTY_0_Handler, // 124 Digital-to-Analog + DAC_EMPTY_1_Handler, // 125 Digital-to-Analog + DAC_RESRDY_0_Handler, // 126 Digital-to-Analog + DAC_RESRDY_1_Handler, // 127 Digital-to-Analog + I2S_Handler, // 128 Inter-IC + PCC_Handler, // 129 Parallel + AES_Handler, // 130 Advanced + TRNG_Handler, // 131 True + ICM_Handler, // 132 Integrity + PUKCC_Handler, // 133 PUblic-Key + QSPI_Handler, // 134 Quad + SDHC0_Handler, // 135 SD/MMC + SDHC1_Handler // 136 SD/MMC +}; + +__attribute__((naked, noreturn)) void Reset_Handler(void) { + // Clear BSS section, and copy data section from flash to RAM + extern long _sbss, _ebss, _sdata, _edata, _sidata; + for (long *src = &_sbss; src < &_ebss; src++) *src = 0; + for (long *src = &_sdata, *dst = &_sidata; src < &_edata;) *src++ = *dst++; + + SCB->VTOR = (uint32_t) &tab; + SystemInit(); + + // Call main() + extern void main(void); + main(); + for (;;) (void) 0; // Infinite loop +} + +void Default_Handler(void) { + for (;;) (void) 0; +} diff --git a/examples/microchip/same54/mqtt-client/syscalls.c b/examples/microchip/same54/mqtt-client/syscalls.c new file mode 100644 index 00000000..fbf0b74b --- /dev/null +++ b/examples/microchip/same54/mqtt-client/syscalls.c @@ -0,0 +1,89 @@ +// Copyright (c) 2022 Cesanta Software Limited +// All rights reserved + +#include + +#include "hal.h" + +int _fstat(int fd, struct stat *st) { + if (fd < 0) return -1; + st->st_mode = S_IFCHR; + return 0; +} + +void *_sbrk(int incr) { + extern char _end; + static unsigned char *heap = NULL; + unsigned char *prev_heap; + if (heap == NULL) heap = (unsigned char *) &_end; + prev_heap = heap; + heap += incr; + return prev_heap; +} + +int _open(const char *path) { + (void) path; + return -1; +} + +int _close(int fd) { + (void) fd; + return -1; +} + +int _isatty(int fd) { + (void) fd; + return 1; +} + +int _lseek(int fd, int ptr, int dir) { + (void) fd, (void) ptr, (void) dir; + return 0; +} + +void _exit(int status) { + (void) status; + for (;;) asm volatile("BKPT #0"); +} + +void _kill(int pid, int sig) { + (void) pid, (void) sig; +} + +int _getpid(void) { + return -1; +} + +int _write(int fd, char *ptr, int len) { + (void) fd, (void) ptr, (void) len; + if (fd == 1) uart_write_buf(UART_DEBUG, ptr, (size_t) len); + return -1; +} + +int _read(int fd, char *ptr, int len) { + (void) fd, (void) ptr, (void) len; + return -1; +} + +int _link(const char *a, const char *b) { + (void) a, (void) b; + return -1; +} + +int _unlink(const char *a) { + (void) a; + return -1; +} + +int _stat(const char *path, struct stat *st) { + (void) path, (void) st; + return -1; +} + +int mkdir(const char *path, mode_t mode) { + (void) path, (void) mode; + return -1; +} + +void _init(void) { +} diff --git a/examples/microchip/same54/net.c b/examples/microchip/same54/net.c deleted file mode 120000 index fe0e6f06..00000000 --- a/examples/microchip/same54/net.c +++ /dev/null @@ -1 +0,0 @@ -../../device-dashboard/net.c \ No newline at end of file diff --git a/examples/microchip/same54/net.h b/examples/microchip/same54/net.h deleted file mode 120000 index 9de896ef..00000000 --- a/examples/microchip/same54/net.h +++ /dev/null @@ -1 +0,0 @@ -../../device-dashboard/net.h \ No newline at end of file diff --git a/examples/microchip/same54/packed_fs.c b/examples/microchip/same54/packed_fs.c deleted file mode 120000 index e06bf092..00000000 --- a/examples/microchip/same54/packed_fs.c +++ /dev/null @@ -1 +0,0 @@ -../../device-dashboard/packed_fs.c \ No newline at end of file