-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
482 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
CFLAGS = -W -Wall -Wextra -Werror -Wundef -Wshadow -Wdouble-promotion | ||
CFLAGS += -Wformat-truncation -fno-common -Wconversion -Wno-sign-conversion | ||
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections | ||
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_mcu/devices/MIMXRT1021 #-DCPU_MIMXRT1021DAG5A | ||
CFLAGS += -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 | ||
LDFLAGS ?= -Tlink.ld -nostdlib -nostartfiles --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map | ||
# cmsis_mcu/devices/MIMXRT1021/gcc/MIMXRT1021xxxxx_ram.ld | ||
# cmsis_mcu/devices/MIMXRT1021/system_MIMXRT1021.c | ||
|
||
SOURCES = main.c syscalls.c sysinit.c | ||
SOURCES += cmsis_mcu/devices/MIMXRT1021/gcc/startup_MIMXRT1021.S | ||
|
||
# Mongoose-specific. 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 | ||
CFLAGS += -DMG_ENABLE_CUSTOM_RANDOM=1 #-DMG_ENABLE_PACKED_FS=1 | ||
CFLAGS += $(CFLAGS_EXTRA) | ||
|
||
# Example specific build options. See README.md | ||
#CFLAGS += -DHTTP_URL=\"http://0.0.0.0/\" -DHTTPS_URL=\"https://0.0.0.0/\" | ||
|
||
ifeq ($(OS),Windows_NT) | ||
RM = cmd /C del /Q /F /S | ||
else | ||
RM = rm -rf | ||
endif | ||
|
||
all build example: firmware.bin | ||
|
||
firmware.bin: firmware.elf | ||
arm-none-eabi-objcopy -O binary $< $@ | ||
|
||
firmware.elf: cmsis_core cmsis_mcu $(SOURCES) hal.h link.ld Makefile | ||
arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@ | ||
|
||
flash: firmware.bin | ||
st-flash --reset write $< 0x8000000 | ||
|
||
cmsis_core: # ARM CMSIS core headers | ||
git clone -q --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@ | ||
cmsis_mcu: | ||
curl -sL https://mcuxpresso.nxp.com/cmsis_pack/repo/NXP.MIMXRT1021_DFP.17.0.0.pack -o $@.zip | ||
mkdir $@ && cd $@ && unzip -q ../$@.zip | ||
# https://mcuxpresso.nxp.com/cmsis_pack/repo/NXP.EVK-MIMXRT1020_BSP.17.0.0.pack | ||
# https://mcuxpresso.nxp.com/cmsis_pack/repo/NXP.MIMXRT1021_DFP.17.0.0.pack | ||
mbedtls: # mbedTLS library | ||
git clone --depth 1 -b v2.28.2 https://github.com/mbed-tls/mbedtls $@ | ||
|
||
ifeq ($(TLS), mbedtls) | ||
CFLAGS += -DMG_TLS=MG_TLS_MBED -Wno-conversion -Imbedtls/include | ||
CFLAGS += -DMBEDTLS_CONFIG_FILE=\"mbedtls_config.h\" mbedtls/library/*.c | ||
firmware.elf: mbedtls | ||
endif | ||
|
||
# Automated remote test. Requires env variable VCON_API_KEY set. See https://vcon.io/automated-firmware-tests/ | ||
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/4 | ||
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 | ||
|
||
clean: | ||
$(RM) firmware.* *.su cmsis_core cmsis_mcu mbedtls *.zip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
// Copyright (c) 2023 Cesanta Software Limited | ||
// All rights reserved | ||
// https://www.nxp.com/webapp/Download?colCode=IMXRT1020RM | ||
// https://cache.nxp.com/secured/assets/documents/en/user-guide/MIMXRT1020EVKHUG.pdf | ||
|
||
#pragma once | ||
|
||
#include "MIMXRT1021.h" | ||
// #include "drivers/fsl_clock.h" | ||
|
||
#include <stdbool.h> | ||
#include <stdint.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
#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) | ||
|
||
#define LED PIN('A', 6) // Use LED for blinking, GPIO_AD_B0_06. RM tbl 9-1 | ||
|
||
#ifndef UART_DEBUG | ||
#define UART_DEBUG LPUART1 | ||
#endif | ||
|
||
#define SYS_FREQUENCY 16000000 | ||
|
||
static inline void spin(volatile uint32_t count) { | ||
while (count--) (void) 0; | ||
} | ||
|
||
static inline GPIO_Type *gpio_bank(uint16_t pin) { | ||
switch (PINBANK(pin)) { | ||
case 1: return (GPIO_Type *) GPIO1_BASE; | ||
case 2: return (GPIO_Type *) GPIO2_BASE; | ||
case 3: return (GPIO_Type *) GPIO3_BASE; | ||
case 5: return (GPIO_Type *) GPIO5_BASE; | ||
default: return NULL; | ||
} | ||
} | ||
|
||
enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT, GPIO_MODE_AF, GPIO_MODE_ANALOG }; | ||
// enum { GPIO_OTYPE_PUSH_PULL, GPIO_OTYPE_OPEN_DRAIN }; | ||
// enum { GPIO_PULL_NONE, GPIO_PULL_UP, GPIO_PULL_DOWN }; | ||
|
||
#if 0 | ||
static inline void CLOCK_ControlGate(clock_ip_name_t name, | ||
clock_gate_value_t value) { | ||
uint32_t index = ((uint32_t) name) >> 8U; | ||
uint32_t shift = ((uint32_t) name) & 0x1FU; | ||
volatile uint32_t *reg; | ||
assert(index <= 6UL); | ||
reg = (volatile uint32_t *) ((uint32_t) ((volatile uint32_t *) &CCM->CCGR0) + | ||
sizeof(volatile uint32_t *) * index); | ||
SDK_ATOMIC_LOCAL_CLEAR_AND_SET(reg, (3UL << shift), | ||
(((uint32_t) value) << shift)); | ||
} | ||
|
||
static inline void CLOCK_EnableClock(clock_ip_name_t name) { | ||
CLOCK_ControlGate(name, kCLOCK_ClockNeededRunWait); | ||
} | ||
#endif | ||
|
||
enum { CLOCK_OFF = 0U, CLOCK_ON_RUN = 1U, CLOCK_ON_RUN_WAIT = 3U }; | ||
static inline void clock_periph(uint32_t index, uint32_t shift, uint32_t val) { | ||
volatile uint32_t *r = &CCM->CCGR0; | ||
SETBITS(r[index], 3UL << shift, val << shift); | ||
} | ||
|
||
static inline void gpio_init(uint16_t pin, uint8_t mode) { | ||
GPIO_Type *gpio = gpio_bank(pin); | ||
uint32_t mask = (uint32_t) BIT(PINNO(pin)); | ||
|
||
// Enable clock | ||
switch (PINBANK(pin)) { | ||
case 1: clock_periph(1, CCM_CCGR1_CG13_SHIFT, CLOCK_ON_RUN_WAIT); break; | ||
case 2: clock_periph(0, CCM_CCGR0_CG15_SHIFT, CLOCK_ON_RUN_WAIT); break; | ||
case 3: clock_periph(2, CCM_CCGR2_CG13_SHIFT, CLOCK_ON_RUN_WAIT); break; | ||
case 5: clock_periph(1, CCM_CCGR1_CG15_SHIFT, CLOCK_ON_RUN_WAIT); break; | ||
default: break; | ||
} | ||
|
||
gpio->IMR &= ~mask; | ||
if (mode == GPIO_MODE_INPUT) { | ||
gpio->GDIR &= ~mask; | ||
} else { | ||
gpio->GDIR |= mask; | ||
} | ||
} | ||
static inline void gpio_input(uint16_t pin) { | ||
gpio_init(pin, GPIO_MODE_INPUT); | ||
} | ||
static inline void gpio_output(uint16_t pin) { | ||
gpio_init(pin, GPIO_MODE_OUTPUT); | ||
} | ||
static inline bool gpio_read(uint16_t pin) { | ||
GPIO_Type *gpio = gpio_bank(pin); | ||
uint32_t mask = (uint32_t) BIT(PINNO(pin)); | ||
return gpio->DR & mask; | ||
} | ||
static inline void gpio_write(uint16_t pin, bool value) { | ||
GPIO_Type *gpio = gpio_bank(pin); | ||
uint32_t mask = (uint32_t) BIT(PINNO(pin)); | ||
if (value) { | ||
gpio->DR |= mask; | ||
} else { | ||
gpio->DR &= ~mask; | ||
} | ||
} | ||
static inline void gpio_toggle(uint16_t pin) { | ||
gpio_write(pin, !gpio_read(pin)); | ||
} | ||
|
||
static inline void uart_init(LPUART_Type *uart, unsigned long baud) { | ||
(void) uart, (void) baud; | ||
} | ||
#if 0 | ||
|
||
static inline void uart_init(LPUART_Type *uart, unsigned long baud) { | ||
uint8_t af = 7; // Alternate function | ||
uint16_t rx = 0, tx = 0; // pins | ||
uint32_t freq = 0; // Bus frequency. UART1 is on APB2, rest on APB1 | ||
|
||
if (uart == USART1) freq = APB2_FREQUENCY, RCC->APB2ENR |= BIT(4); | ||
if (uart == USART2) freq = APB1_FREQUENCY, RCC->APB1ENR |= BIT(17); | ||
if (uart == USART3) freq = APB1_FREQUENCY, RCC->APB1ENR |= BIT(18); | ||
|
||
if (uart == USART1) tx = PIN('A', 9), rx = PIN('A', 10); | ||
if (uart == USART2) tx = PIN('A', 2), rx = PIN('A', 3); | ||
if (uart == USART3) tx = PIN('D', 8), rx = PIN('D', 9); | ||
|
||
gpio_init(tx, GPIO_MODE_AF, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, 0, af); | ||
gpio_init(rx, GPIO_MODE_AF, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, 0, af); | ||
uart->CR1 = 0; // Disable this UART | ||
uart->BRR = freq / baud; // Set baud rate | ||
uart->CR1 |= BIT(0) | BIT(2) | BIT(3); // Set UE, RE, TE | ||
} | ||
#endif | ||
static inline void uart_write_byte(LPUART_Type *uart, uint8_t byte) { | ||
// uart->TDR = byte; | ||
// while ((uart->ISR & BIT(7)) == 0) spin(1); | ||
(void) uart, (void) byte; | ||
} | ||
static inline void uart_write_buf(LPUART_Type *uart, char *buf, size_t len) { | ||
while (len-- > 0) uart_write_byte(uart, *(uint8_t *) buf++); | ||
} | ||
static inline int uart_read_ready(LPUART_Type *uart) { | ||
(void) uart; | ||
// return uart->ISR & BIT(5); // If RXNE bit is set, data is ready | ||
return 0; | ||
} | ||
static inline uint8_t uart_read_byte(LPUART_Type *uart) { | ||
(void) uart; | ||
// return (uint8_t) (uart->RDR & 255); | ||
return 0; | ||
} | ||
|
||
static inline void rng_init(void) { | ||
} | ||
static inline uint32_t rng_read(void) { | ||
return 42; | ||
} | ||
static inline void ethernet_init(void) { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
ENTRY(Reset_Handler); | ||
MEMORY { | ||
flash_cfg(rx) : ORIGIN = 0x60000000, LENGTH = 4k | ||
flash_ivt(rx) : ORIGIN = 0x60001000, LENGTH = 4k | ||
flash_irq(rx) : ORIGIN = 0x60002000, LENGTH = 1k | ||
flash_code(rx) : ORIGIN = 0x60002400, LENGTH = 8183k | ||
|
||
ram0(rx) : ORIGIN = 0x00000000, LENGTH = 64k | ||
ram1(rw) : ORIGIN = 0x20000000, LENGTH = 64k | ||
ram2(rw) : ORIGIN = 0x20200000, LENGTH = 128k | ||
} | ||
__StackTop = ORIGIN(ram2) + LENGTH(ram2); | ||
|
||
SECTIONS { | ||
.cfg : { __FLASH_BASE = .; KEEP(* (.cfg)) } > flash_cfg | ||
.ivt : { KEEP(*(.ivt)) } > flash_ivt | ||
.irq : { KEEP(*(.isr_vector)) } > flash_irq | ||
.text : { *(.text* .text.*) *(.rodata*) __etext = .; } > flash_code | ||
.data : { __data_start__ = .; *(.data SORT(.data.*)) __data_end__ = .; } > ram1 AT > flash_code | ||
.bss : { __bss_start__ = .; *(.bss SORT(.bss.*) COMMON) __bss_end__ = .; } > ram1 | ||
_end = .; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
cmsis_mcu/devices/MIMXRT1021/gcc/MIMXRT1021xxxxx_ram.ld |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// Copyright (c) 2022-2023 Cesanta Software Limited | ||
// All rights reserved | ||
|
||
#include "hal.h" | ||
#include "mongoose.h" | ||
// #include "net.h" | ||
|
||
#define BLINK_PERIOD_MS 1000 // LED blinking period in millis | ||
|
||
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 timer_fn(void *arg) { | ||
//gpio_toggle(LED); // Blink LED | ||
//struct mg_tcpip_if *ifp = arg; // And show | ||
//const char *names[] = {"down", "up", "req", "ready"}; // network stats | ||
//MG_INFO(("Ethernet: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u", | ||
// names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent, | ||
// ifp->ndrop, ifp->nerr)); | ||
MG_INFO(("%p", arg)); | ||
} | ||
|
||
int main(void) { | ||
gpio_output(LED); // Setup blue LED | ||
|
||
for (;;) { | ||
gpio_toggle(LED); | ||
spin(99999); | ||
} | ||
|
||
|
||
uart_init(UART_DEBUG, 115200); // Initialise debug printf | ||
ethernet_init(); // Initialise ethernet pins | ||
MG_INFO(("Starting, CPU freq %g MHz", (double) SystemCoreClock / 1000000)); | ||
|
||
struct mg_mgr mgr; // Initialise | ||
mg_mgr_init(&mgr); // Mongoose event manager | ||
mg_log_set(MG_LL_DEBUG); // Set log level | ||
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, NULL); | ||
|
||
#if 0 | ||
// Initialise Mongoose network stack | ||
struct mg_tcpip_driver_stm32_data driver_data = {.mdc_cr = 4}; | ||
struct mg_tcpip_if mif = {.mac = GENERATE_LOCALLY_ADMINISTERED_MAC(), | ||
// 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_stm32, | ||
.driver_data = &driver_data}; | ||
mg_tcpip_init(&mgr, &mif); | ||
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, &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...")); | ||
web_init(&mgr); | ||
#endif | ||
|
||
MG_INFO(("Starting event loop")); | ||
for (;;) { | ||
mg_mgr_poll(&mgr, 0); | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../mongoose.c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../mongoose.h |
Oops, something went wrong.