Merge pull request #1975 from cesanta/hwtest

Cleanup, adopt for HW test
This commit is contained in:
Sergio R. Caprile 2023-01-20 16:26:05 -03:00 committed by GitHub
commit b04612e80d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 72 deletions

View File

@ -98,6 +98,7 @@ jobs:
- path: stm32/stm32-nucleo-f429z
- path: stm32/stm32-nucleo-h743z
- path: stm32/nucleo-f429zi-baremetal
target: test
- path: stm32/nucleo-f429zi-freertos-mip
- path: stm32/nucleo-f429zi-usb-rndis
- path: stm32/nucleo-f746zg-baremetal
@ -135,7 +136,7 @@ jobs:
- uses: actions/checkout@v3
- run: sudo apt -y install gcc-arm-none-eabi
- name: ${{ matrix.example.path }}
run: make -C examples/${{ matrix.example.path }} build
run: make -C examples/${{ matrix.example.path }} ${{ matrix.example.target || 'build' }} VCON_API_KEY=${{secrets.VCON_API_KEY}}
zephyr_examples:
runs-on: ubuntu-latest
steps:

View File

@ -109,6 +109,7 @@ static void mqtt_fn(struct mg_connection *c, int ev, void *ev_data, void *fnd) {
c->is_hexdumping = 1;
mg_mqtt_sub(s_mqtt, mg_str(s_config.sub), 2);
send_notification(c->mgr, "{%Q:%Q,%Q:null}", "name", "config", "data");
MG_INFO(("MQTT connected, server %s", MQTT_SERVER));
} else if (ev == MG_EV_MQTT_MSG) {
struct mg_mqtt_message *mm = ev_data;
send_notification(c->mgr, "{%Q:%Q,%Q:{%Q: %.*Q, %Q: %.*Q, %Q: %d}}", "name",

View File

@ -1,42 +1,35 @@
TARGET = firmware
ROOT ?= $(realpath $(CURDIR)/../../..)
D ?= docker
DOCKER ?= $(D) run --rm -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/armgcc
CROSS ?= arm-none-eabi
CFLAGS ?= -W -Wall -Wextra -Werror -Wundef -Wshadow -Wdouble-promotion \
-Wformat-truncation -fno-common -Wconversion \
-g3 -Os -ffunction-sections -fdata-sections -I. -I$(ROOT) \
-DMG_ARCH=MG_ARCH_NEWLIB -DMIP_DEBUG=1 -DMG_ENABLE_PACKED_FS=1 \
-DMG_ENABLE_CUSTOM_MILLIS=1 -DxMG_ENABLE_LINES=1 -DMG_ENABLE_MIP=1 \
-g3 -Os -ffunction-sections -fdata-sections -I. \
-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 $(EXTRA_CFLAGS)
LDFLAGS ?= -Tlink.ld -nostartfiles -nostdlib --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
SOURCES = boot.c main.c syscalls.c \
$(ROOT)/mongoose.c \
$(ROOT)/examples/device-dashboard/packed_fs.c \
$(ROOT)/examples/device-dashboard/net.c
SOURCES = boot.c main.c syscalls.c
all build example: $(TARGET).bin
# Add Mongoose-specific flags and source files
CFLAGS += -I../../.. -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1 -DMG_ENABLE_MIP=1 -DMG_ENABLE_PACKED_FS=1
SOURCES += ../../../mongoose.c ../../device-dashboard/net.c ../../device-dashboard/packed_fs.c
$(TARGET).bin: $(TARGET).elf
$(DOCKER) $(CROSS)-objcopy -O binary $< $@
all build example: firmware.bin
$(TARGET).elf: $(SOURCES) mcu.h
$(DOCKER) $(CROSS)-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@
firmware.bin: firmware.elf
arm-none-eabi-objcopy -O binary $< $@
# Build on Windows. Download Win32 Zip from ARM GCC downloads, unzip to c:\armgcc
ARMGCC ?= c:/armgcc
windows: $(TARGET).bin
windows: CROSS = $(ARMGCC)/bin/arm-none-eabi
windows: DOCKER =
# Show top 10 stack-hungry functions
su: CFLAGS += -fstack-usage
su: $(TARGET).elf
cat *.su | sort -rnk2 | head -10
firmware.elf: $(SOURCES) mcu.h
arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@
# Note: on "unknown chip id" flash error, wire BOOT0 to VDD and st-flash erase
flash: $(TARGET).bin
st-flash --reset write $(TARGET).bin 0x8000000
flash: firmware.bin
st-flash --reset write $< 0x8000000
# Requires env variable VCON_API_KEY set
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/2
test: update
curl --fail -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=5 | tee /tmp/output.txt
grep 'Ethernet: up' /tmp/output.txt
grep 'MQTT connected' /tmp/output.txt
update: firmware.bin
curl --fail -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
clean:
@rm -rf $(TARGET).* *.su
@rm -rf firmware.* *.su

View File

@ -4,19 +4,14 @@
#include "mcu.h"
#include "mongoose.h"
#define LED1 PIN('B', 0) // On-board LED pin (green)
#define LED2 PIN('B', 7) // On-board LED pin (blue)
#define LED3 PIN('B', 14) // On-board LED pin (red)
#define BTN1 PIN('C', 13) // On-board user button
#define LED1 PIN('B', 0) // On-board LED pin (green)
#define LED2 PIN('B', 7) // On-board LED pin (blue)
#define LED3 PIN('B', 14) // On-board LED pin (red)
#define BTN1 PIN('C', 13) // On-board user button
#define BLINK_PERIOD_MS 1000 // LED blinking period in millis
static uint64_t s_ticks, s_exti; // Counters, increased by IRQ handlers
static void blink_cb(void *arg) { // Blink periodically
// MG_INFO(("ticks: %u", (unsigned) s_ticks));
gpio_toggle(LED2);
(void) arg;
}
uint64_t mg_millis(void) { // Declare our own uptime function
return s_ticks; // Return number of milliseconds since boot
}
@ -36,15 +31,22 @@ void EXTI15_10_IRQHandler(void) { // External interrupt handler
gpio_write(LED1, gpio_read(BTN1)); // No debounce. Turn LED if button pressed
}
static void timer_cb(void *arg) {
gpio_toggle(LED2); // Blink LED
bool up = ((struct mip_if *) arg)->state == MIP_STATE_READY;
MG_INFO(("Ethernet: %s", up ? "up" : "down")); // Show network status
}
int main(void) {
static struct uart *uart = UART3; // Use UART3 - its attached to debug
clock_init(); // Set clock to 180MHz
systick_init(FREQ / 1000); // Increment s_ticks every ms
gpio_output(LED1); // Setup green LED
gpio_output(LED2); // Setup blue LED
gpio_input(BTN1); // Set button to input
irq_exti_attach(BTN1); // Attach BTN1 to exti
uart_init(uart, 115200); // It is wired to the debug port
clock_init(); // Set clock to 180MHz
systick_init(SYS_FREQUENCY / 1000); // Increment s_ticks every ms
gpio_output(LED1); // Setup green LED
gpio_output(LED2); // Setup blue LED
gpio_input(BTN1); // Set button to input
irq_exti_attach(BTN1); // Attach BTN1 to exti
uart_init(UART1, 115200); // Initialise debug printf
MG_INFO(("Starting, CPU freq %g MHz", (double) SYS_FREQUENCY / 1000000));
// Initialise Ethernet. Enable MAC GPIO pins, see
// https://www.farnell.com/datasheets/2014265.pdf section 6.10
@ -65,23 +67,30 @@ int main(void) {
struct mg_mgr mgr; // Initialise Mongoose event manager
mg_mgr_init(&mgr); // and attach it to the MIP interface
mg_log_set(MG_LL_DEBUG); // Set log level
mg_timer_add(&mgr, 500, MG_TIMER_REPEAT, blink_cb, &mgr);
// Initialise Mongoose network stack
// Specify MAC address, and IP/mask/GW in network byte order for static
// IP configuration. If IP/mask/GW are unset, DHCP is going to be used
struct mip_driver_stm32_data driver_data = {.mdc_cr = 4}; // See driver_stm32.h
struct mip_if mif = {
.mac = {2, 0, 1, 2, 3, 5},
.driver = &mip_driver_stm32,
.driver_data = &driver_data,
};
struct mip_driver_stm32_data driver_data = {.mdc_cr = 4}; // driver_stm32.h
struct mip_if mif = {.mac = {2, 0, 1, 2, 3, 5},
.driver = &mip_driver_stm32,
.driver_data = &driver_data};
mip_init(&mgr, &mif);
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_cb, &mif);
MG_INFO(("Init done, starting main loop"));
MG_INFO(("Waiting until network is up..."));
while (mif.state != MIP_STATE_READY) {
mg_mgr_poll(&mgr, 0);
}
MG_INFO(("Initialising application..."));
extern void device_dashboard_fn(struct mg_connection *, int, void *, void *);
mg_http_listen(&mgr, "http://0.0.0.0", device_dashboard_fn, &mgr);
for (;;) mg_mgr_poll(&mgr, 0); // Infinite event loop
MG_INFO(("Starting event loop"));
for (;;) {
mg_mgr_poll(&mgr, 0);
}
return 0;
}

View File

@ -20,10 +20,10 @@
// 33.4: The AHB clock must be at least 25 MHz when Ethernet is used
enum { APB1_PRE = 5 /* AHB clock / 4 */, APB2_PRE = 4 /* AHB clock / 2 */ };
enum { PLL_HSI = 16, PLL_M = 8, PLL_N = 180, PLL_P = 2 }; // Run at 180 Mhz
//#define PLL_FREQ PLL_HSI
#define PLL_FREQ (PLL_HSI * PLL_N / PLL_M / PLL_P)
#define FLASH_LATENCY 5
#define FREQ (PLL_FREQ * 1000000)
#define SYS_FREQUENCY ((PLL_HSI * PLL_N / PLL_M / PLL_P) * 1000000)
#define APB2_FREQUENCY (SYS_FREQUENCY / (BIT(APB2_PRE - 3)))
#define APB1_FREQUENCY (SYS_FREQUENCY / (BIT(APB1_PRE - 3)))
static inline void spin(volatile uint32_t count) {
while (count--) asm("nop");
@ -93,13 +93,11 @@ struct gpio {
};
#define GPIO(N) ((struct gpio *) (0x40020000 + 0x400 * (N)))
static struct gpio *gpio_bank(uint16_t pin) {
return GPIO(PINBANK(pin));
}
static struct gpio *gpio_bank(uint16_t pin) { return GPIO(PINBANK(pin)); }
static inline void gpio_toggle(uint16_t pin) {
struct gpio *gpio = gpio_bank(pin);
uint32_t mask = BIT(PINNO(pin));
gpio->BSRR |= mask << (gpio->ODR & mask ? 16 : 0);
gpio->BSRR = mask << (gpio->ODR & mask ? 16 : 0);
}
static inline int gpio_read(uint16_t pin) {
return gpio_bank(pin)->IDR & BIT(PINNO(pin)) ? 1 : 0;
@ -163,10 +161,11 @@ static inline void uart_init(struct uart *uart, unsigned long baud) {
// https://www.st.com/resource/en/datasheet/stm32f429zi.pdf
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 == UART1) RCC->APB2ENR |= BIT(4);
if (uart == UART2) RCC->APB1ENR |= BIT(17);
if (uart == UART3) RCC->APB1ENR |= BIT(18);
if (uart == UART1) freq = APB2_FREQUENCY, RCC->APB2ENR |= BIT(4);
if (uart == UART2) freq = APB1_FREQUENCY, RCC->APB1ENR |= BIT(17);
if (uart == UART3) freq = APB1_FREQUENCY, RCC->APB1ENR |= BIT(18);
if (uart == UART1) tx = PIN('A', 9), rx = PIN('A', 10);
if (uart == UART2) tx = PIN('A', 2), rx = PIN('A', 3);
@ -174,9 +173,8 @@ static inline void uart_init(struct uart *uart, unsigned long baud) {
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 / 4 / baud; // Baud rate, "4" is APBx prescaler, different from APBx_PRE
// TODO(): make this configurable ?
uart->CR1 = 0; // Disable this UART
uart->BRR = freq / baud; // Set baud rate
uart->CR1 |= BIT(13) | BIT(2) | BIT(3); // Set UE, RE, TE
}
static inline void uart_write_byte(struct uart *uart, uint8_t byte) {

View File

@ -53,7 +53,7 @@ int _getpid(void) {
int _write(int fd, char *ptr, int len) {
(void) fd, (void) ptr, (void) len;
if (fd == 1) uart_write_buf(UART3, ptr, (size_t) len);
if (fd == 1) uart_write_buf(UART1, ptr, (size_t) len);
return -1;
}