@@ -0,0 +1,173 @@ | |||||
/*- | |||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD | |||||
* | |||||
* Copyright (c) 1999 John D. Polstra | |||||
* Copyright (c) 1999,2001 Peter Wemm <peter@FreeBSD.org> | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* | |||||
* $FreeBSD$ | |||||
*/ | |||||
#ifndef _SYS_LINKER_SET_H_ | |||||
#define _SYS_LINKER_SET_H_ | |||||
#include <sys/cdefs.h> | |||||
/* START cdefs.h direct import from FreeBSD */ | |||||
/* This section has the follwing copyright */ | |||||
/*- | |||||
* SPDX-License-Identifier: BSD-3-Clause | |||||
* | |||||
* Copyright (c) 1991, 1993 | |||||
* The Regents of the University of California. All rights reserved. | |||||
* | |||||
* This code is derived from software contributed to Berkeley by | |||||
* Berkeley Software Design, Inc. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* 3. Neither the name of the University nor the names of its contributors | |||||
* may be used to endorse or promote products derived from this software | |||||
* without specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* | |||||
* @(#)cdefs.h 8.8 (Berkeley) 1/9/95 | |||||
* $FreeBSD$ | |||||
*/ | |||||
#define __CONCAT1(x,y) x ## y | |||||
#define __CONCAT(x,y) __CONCAT1(x,y) | |||||
#define __STRING(x) #x /* stringify without expanding x */ | |||||
#define __XSTRING(x) __STRING(x) /* expand x, then stringify */ | |||||
#define __nosanitizeaddress | |||||
#define __nosanitizememory | |||||
#define __used __attribute__((__used__)) | |||||
#define __weak_symbol __attribute__((__weak__)) | |||||
/* END cdefs.h direct import */ | |||||
/* | |||||
* The following macros are used to declare global sets of objects, which | |||||
* are collected by the linker into a `linker_set' as defined below. | |||||
* For ELF, this is done by constructing a separate segment for each set. | |||||
*/ | |||||
#if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1) | |||||
/* | |||||
* ELFv1 pointers to functions are actaully pointers to function | |||||
* descriptors. | |||||
* | |||||
* Move the symbol pointer from ".text" to ".data" segment, to make | |||||
* the GCC compiler happy: | |||||
*/ | |||||
#define __MAKE_SET_CONST | |||||
#else | |||||
#define __MAKE_SET_CONST const | |||||
#endif | |||||
/* | |||||
* Private macros, not to be used outside this header file. | |||||
*/ | |||||
#ifdef __GNUCLIKE___SECTION | |||||
/* | |||||
* The userspace address sanitizer inserts redzones around global variables, | |||||
* violating the assumption that linker set elements are packed. | |||||
*/ | |||||
#ifdef _KERNEL | |||||
#define __NOASAN | |||||
#else | |||||
#define __NOASAN __nosanitizeaddress | |||||
#endif | |||||
#define __MAKE_SET_QV(set, sym, qv) \ | |||||
void *__WEAK(__CONCAT(__start_set_,set)); \ | |||||
void *__WEAK(__CONCAT(__stop_set_,set)); \ | |||||
static void const * qv \ | |||||
__NOASAN \ | |||||
__set_##set##_sym_##sym __section("set_" #set) \ | |||||
__used = &(sym) | |||||
#define __MAKE_SET(set, sym) __MAKE_SET_QV(set, sym, __MAKE_SET_CONST) | |||||
#else /* !__GNUCLIKE___SECTION */ | |||||
#error this file needs to be ported to your compiler | |||||
#endif /* __GNUCLIKE___SECTION */ | |||||
/* | |||||
* Public macros. | |||||
*/ | |||||
#define TEXT_SET(set, sym) __MAKE_SET(set, sym) | |||||
#define DATA_SET(set, sym) __MAKE_SET(set, sym) | |||||
#define DATA_WSET(set, sym) __MAKE_SET_QV(set, sym, ) | |||||
#define BSS_SET(set, sym) __MAKE_SET(set, sym) | |||||
#define ABS_SET(set, sym) __MAKE_SET(set, sym) | |||||
#define SET_ENTRY(set, sym) __MAKE_SET(set, sym) | |||||
/* | |||||
* Initialize before referring to a given linker set. | |||||
*/ | |||||
#define SET_DECLARE(set, ptype) \ | |||||
extern ptype __weak_symbol __section("set_" #set)*__CONCAT(__start_set_,set); \ | |||||
extern ptype __weak_symbol *__CONCAT(__stop_set_,set) __section("set_" #set) | |||||
#define SET_BEGIN(set) \ | |||||
(&__CONCAT(__start_set_,set)) | |||||
#define SET_LIMIT(set) \ | |||||
(&__CONCAT(__stop_set_,set)) | |||||
/* | |||||
* Iterate over all the elements of a set. | |||||
* | |||||
* Sets always contain addresses of things, and "pvar" points to words | |||||
* containing those addresses. Thus is must be declared as "type **pvar", | |||||
* and the address of each set item is obtained inside the loop by "*pvar". | |||||
*/ | |||||
#define SET_FOREACH(pvar, set) \ | |||||
for (pvar = SET_BEGIN(set); pvar < SET_LIMIT(set); pvar++) | |||||
#define SET_ITEM(set, i) \ | |||||
((SET_BEGIN(set))[i]) | |||||
/* | |||||
* Provide a count of the items in a set. | |||||
*/ | |||||
#define SET_COUNT(set) \ | |||||
(SET_LIMIT(set) - SET_BEGIN(set)) | |||||
#endif /* _SYS_LINKER_SET_H_ */ |
@@ -1,6 +1,10 @@ | |||||
SRCS.NODE151+= board.c | SRCS.NODE151+= board.c | ||||
SRCS.NODE151+= misc.c | SRCS.NODE151+= misc.c | ||||
_SRCTOPDIR:= $(.PARSEDIR)/.. | |||||
SRCTOP?=$(_SRCTOPDIR:tA) | |||||
STM32?=$(SRCTOP)/stm32 | |||||
ARMOBJDUMP?= arm-none-eabi-objdump | ARMOBJDUMP?= arm-none-eabi-objdump | ||||
ARMCC?= arm-none-eabi-gcc | ARMCC?= arm-none-eabi-gcc | ||||
@@ -10,17 +14,22 @@ ARMCC?= arm-none-eabi-gcc | |||||
.include <$(.PARSEDIR)/mu.opts.mk> | .include <$(.PARSEDIR)/mu.opts.mk> | ||||
.if ${MK_SYSINIT} == "yes" | |||||
.PATH: $(SRCTOP) | |||||
SRCS+= sysinit.c | |||||
.endif | |||||
# Strobe | # Strobe | ||||
.if ${MK_STROBE} == "yes" | .if ${MK_STROBE} == "yes" | ||||
.PATH: $(.CURDIR)/strobe | |||||
CFLAGS+= -I$(.CURDIR)/strobe -DSTROBE_SINGLE_THREAD=1 | |||||
.PATH: $(SRCTOP)/strobe | |||||
CFLAGS+= -I$(SRCTOP)/strobe -DSTROBE_SINGLE_THREAD=1 | |||||
STROBE_SRCS+= strobe.c \ | STROBE_SRCS+= strobe.c \ | ||||
x25519.c | x25519.c | ||||
.endif | .endif | ||||
# LoRamac (SX1276) radio code | # LoRamac (SX1276) radio code | ||||
.if ${MK_SX1276} == "yes" | .if ${MK_SX1276} == "yes" | ||||
LORAMAC_SRC = $(.CURDIR)/loramac/src | |||||
LORAMAC_SRC = $(SRCTOP)/loramac/src | |||||
.PATH: $(LORAMAC_SRC)/radio/sx1276 $(LORAMAC_SRC)/system $(LORAMAC_SRC)/boards/mcu $(LORAMAC_SRC)/boards/NucleoL152 | .PATH: $(LORAMAC_SRC)/radio/sx1276 $(LORAMAC_SRC)/system $(LORAMAC_SRC)/boards/mcu $(LORAMAC_SRC)/boards/NucleoL152 | ||||
CFLAGS+= -I$(LORAMAC_SRC)/boards | CFLAGS+= -I$(LORAMAC_SRC)/boards | ||||
CFLAGS+= -I$(LORAMAC_SRC)/system | CFLAGS+= -I$(LORAMAC_SRC)/system | ||||
@@ -32,12 +41,37 @@ SRCS+= adc.c timer.c delay.c gpio.c uart.c fifo.c | |||||
SRCS+= adc-board.c delay-board.c gpio-board.c rtc-board.c lpm-board.c sx1276mb1las-board.c spi-board.c uart-board.c | SRCS+= adc-board.c delay-board.c gpio-board.c rtc-board.c lpm-board.c sx1276mb1las-board.c spi-board.c uart-board.c | ||||
.endif | .endif | ||||
# Generic STM32F103 Microcontroller | |||||
.if ${MK_STM32F103} == "yes" | |||||
ARMTARGET?= -mcpu=cortex-m3 -mthumb | |||||
.PATH: $(STM32)/f103c8t6 | |||||
LINKER_SCRIPT=$(STM32)/f103c8t6/STM32F103C8T6_FLASH.ld | |||||
SRCS+= \ | |||||
startup_stm32f103xb.s \ | |||||
stm32f1xx_hal.c \ | |||||
stm32f1xx_hal_cortex.c \ | |||||
stm32f1xx_hal_gpio.c \ | |||||
stm32f1xx_hal_pcd.c \ | |||||
stm32f1xx_hal_pcd_ex.c \ | |||||
stm32f1xx_ll_usb.c \ | |||||
system_stm32f1xx.c | |||||
CFLAGS+= -I$(STM32) | |||||
CFLAGS+= -I$(STM32)/f103c8t6 | |||||
CFLAGS+= -DSTM32F103xB | |||||
.endif | |||||
# NODE151 Microcontroller | # NODE151 Microcontroller | ||||
.if ${MK_NODE151} == "yes" | .if ${MK_NODE151} == "yes" | ||||
ARMTARGET?= -mcpu=cortex-m3 -mthumb | ARMTARGET?= -mcpu=cortex-m3 -mthumb | ||||
STM32=$(.CURDIR)/stm32 | |||||
.PATH: $(STM32)/l151ccux | .PATH: $(STM32)/l151ccux | ||||
LINKER_SCRIPT=$(STM32)/l151ccux/STM32L151CCUX_FLASH.ld | LINKER_SCRIPT=$(STM32)/l151ccux/STM32L151CCUX_FLASH.ld | ||||
SRCS+= \ | SRCS+= \ | ||||
startup_stm32l151ccux.s \ | startup_stm32l151ccux.s \ | ||||
stm32l1xx_hal.c \ | stm32l1xx_hal.c \ | ||||
@@ -3,10 +3,12 @@ | |||||
# | # | ||||
# See bsd.mkopt.mk for more information. | # See bsd.mkopt.mk for more information. | ||||
__DEFAULT_YES_OPTIONS = STROBE | |||||
__DEFAULT_YES_OPTIONS = STROBE \ | |||||
SYSINIT | |||||
__DEFAULT_NO_OPTIONS = \ | __DEFAULT_NO_OPTIONS = \ | ||||
NODE151 \ | NODE151 \ | ||||
STM32F103 \ | |||||
SX1276 \ | SX1276 \ | ||||
USB_CDC | USB_CDC | ||||
@@ -0,0 +1,39 @@ | |||||
# Copyright 2022 John-Mark Gurney. | |||||
# | |||||
# Redistribution and use in source and binary forms, with or without | |||||
# modification, are permitted provided that the following conditions | |||||
# are met: | |||||
# 1. Redistributions of source code must retain the above copyright | |||||
# notice, this list of conditions and the following disclaimer. | |||||
# 2. Redistributions in binary form must reproduce the above copyright | |||||
# notice, this list of conditions and the following disclaimer in the | |||||
# documentation and/or other materials provided with the distribution. | |||||
# | |||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
# SUCH DAMAGE. | |||||
# | |||||
PROGS = rs485gw # lora.irr | |||||
SRCS.rs485gw = rs485gw.c | |||||
SRCS.rs485gw+= misc.c | |||||
.PATH: $(.CURDIR)/.. | |||||
CFLAGS += -I$(.CURDIR)/.. | |||||
WITH_STM32F103 = yes | |||||
WITH_USB_CDC = yes | |||||
.include <../mk/boards.mk> | |||||
.include <../mk/mu.progs.mk> |
@@ -0,0 +1,346 @@ | |||||
/*- | |||||
* Copyright 2022 John-Mark Gurney. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* | |||||
*/ | |||||
#include <usbd_cdc_if.h> | |||||
#include <misc.h> | |||||
#include <stdbool.h> | |||||
#include <stdint.h> | |||||
#include <string.h> | |||||
#include <sysinit.h> | |||||
SYSINIT(hal_init, SI_SUB_HAL, SI_ORDER_FIRST, (void (*)(const void *))HAL_Init, NULL); | |||||
void | |||||
clkenable(const void *none) | |||||
{ | |||||
GPIO_InitTypeDef GPIO_InitStruct; | |||||
__HAL_RCC_GPIOB_CLK_ENABLE(); | |||||
__HAL_RCC_GPIOC_CLK_ENABLE(); | |||||
GPIO_InitStruct = (GPIO_InitTypeDef){ | |||||
.Pin = GPIO_PIN_13, | |||||
.Mode = GPIO_MODE_OUTPUT_PP, | |||||
.Pull = GPIO_NOPULL, | |||||
.Speed = GPIO_SPEED_FREQ_LOW, | |||||
}; | |||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); | |||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); | |||||
} | |||||
SYSINIT(clkenable, SI_SUB_HAL, SI_ORDER_SECOND, clkenable, NULL); | |||||
void | |||||
oscconfig(const void *none) | |||||
{ | |||||
RCC_ClkInitTypeDef clkinitstruct; | |||||
RCC_OscInitTypeDef oscinitstruct; | |||||
RCC_PeriphCLKInitTypeDef rccperiphclkinit; | |||||
__HAL_RCC_PWR_CLK_ENABLE(); | |||||
oscinitstruct = (RCC_OscInitTypeDef){ | |||||
.OscillatorType = RCC_OSCILLATORTYPE_HSE, | |||||
.HSEState = RCC_HSE_ON, | |||||
.HSEPredivValue = RCC_HSE_PREDIV_DIV1, | |||||
.PLL.PLLMUL = RCC_PLL_MUL9, | |||||
.PLL.PLLState = RCC_PLL_ON, | |||||
.PLL.PLLSource = RCC_PLLSOURCE_HSE, | |||||
}; | |||||
HAL_RCC_OscConfig(&oscinitstruct); | |||||
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 | |||||
* clocks dividers */ | |||||
clkinitstruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | | |||||
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; | |||||
clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; | |||||
clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1; | |||||
clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2; | |||||
clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1; | |||||
HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2); | |||||
/* USB clock selection */ | |||||
rccperiphclkinit = (RCC_PeriphCLKInitTypeDef){ | |||||
.PeriphClockSelection = RCC_PERIPHCLK_USB, | |||||
.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5, | |||||
}; | |||||
HAL_RCCEx_PeriphCLKConfig(&rccperiphclkinit); | |||||
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 | |||||
clocks dividers */ | |||||
clkinitstruct = (RCC_ClkInitTypeDef){ | |||||
.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2), | |||||
.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK, | |||||
.AHBCLKDivider = RCC_SYSCLK_DIV1, | |||||
.APB1CLKDivider = RCC_HCLK_DIV2, | |||||
.APB2CLKDivider = RCC_HCLK_DIV1, | |||||
}; | |||||
HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2); | |||||
} | |||||
SYSINIT(oscconfig, SI_SUB_HAL, SI_ORDER_THIRD, oscconfig, NULL); | |||||
char * | |||||
findeol(char *pos, size_t len) | |||||
{ | |||||
while (len) { | |||||
if (*pos == '\r' || *pos == '\n') | |||||
return pos; | |||||
pos++; | |||||
len--; | |||||
} | |||||
return NULL; | |||||
} | |||||
void | |||||
hexdump(const uint8_t *ptr, size_t len) | |||||
{ | |||||
int i; | |||||
for (i = 0; i < len; i++) | |||||
usb_printf("%02x", ptr[i]); | |||||
} | |||||
void | |||||
txdone(void) | |||||
{ | |||||
usb_printf("txdone\r\n"); | |||||
//Radio.Rx(0); | |||||
} | |||||
void | |||||
txtimeout(void) | |||||
{ | |||||
usb_printf("txtimeout\r\n"); | |||||
} | |||||
void | |||||
rxdone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) | |||||
{ | |||||
usb_printf("rxdone: size: %hu, rssi: %hd, snr: %d\r\ndata: ", size, rssi, snr); | |||||
hexdump(payload, size); | |||||
usb_printf("\r\n"); | |||||
} | |||||
void | |||||
rxtimeout(void) | |||||
{ | |||||
usb_printf("rxtimeout\r\n"); | |||||
} | |||||
void | |||||
rxerr(void) | |||||
{ | |||||
usb_printf("rxerr\r\n"); | |||||
} | |||||
static uint8_t | |||||
hexchartonib(char s) | |||||
{ | |||||
switch (s) { | |||||
case '0'...'9': | |||||
return s - '0'; | |||||
case 'a'...'f': | |||||
return s - 'a' + 10; | |||||
case 'A'...'F': | |||||
return s - 'A' + 10; | |||||
default: | |||||
return -1; | |||||
} | |||||
} | |||||
static bool | |||||
hexdecode(char *buf, size_t len, uint8_t *out) | |||||
{ | |||||
uint8_t topchr, botchr; | |||||
if (len % 2) | |||||
return false; | |||||
/* NB: only needed to silence a bad gcc warning */ | |||||
topchr = -1; | |||||
while (len) { | |||||
if (len % 2) { | |||||
/* bottom nibble */ | |||||
botchr = hexchartonib(*buf); | |||||
if (topchr == -1 || botchr == -1) | |||||
return false; | |||||
*out = topchr << 4 | botchr; | |||||
out++; | |||||
} else { | |||||
/* top nibble */ | |||||
topchr = hexchartonib(*buf); | |||||
} | |||||
len--; | |||||
buf++; | |||||
} | |||||
return true; | |||||
} | |||||
static const char pktstart[] = "pkt:"; | |||||
static const size_t pktstartlen = sizeof pktstart - 1; | |||||
static uint8_t pktbuf[128]; | |||||
static void | |||||
process_line(char *start, char *end) | |||||
{ | |||||
size_t len; | |||||
/* trim off leading CR/NL */ | |||||
while (start < end && (*start == '\r' || *start == '\n')) | |||||
start++; | |||||
len = end - start; | |||||
if (len >= pktstartlen && memcmp(start, pktstart, sizeof pktstart - 1) == 0) { | |||||
start += pktstartlen; | |||||
len -= pktstartlen; | |||||
if (len % 2) { | |||||
usb_printf("invalid pkt len\r\n"); | |||||
return; | |||||
} | |||||
if (!hexdecode(start, len, pktbuf)) { | |||||
usb_printf("invalid pkt\r\n"); | |||||
return; | |||||
} | |||||
//Radio.Send(pktbuf, len / 2); | |||||
return; | |||||
} | |||||
usb_printf("line: %.*s", end - start, start); | |||||
fflush(vcp_usb); | |||||
} | |||||
int | |||||
main(void) | |||||
{ | |||||
//debug_printf("starting...\n"); | |||||
//clkenable(NULL); | |||||
sysinit_run(); | |||||
//Radio.Init(&revents); | |||||
setlinebuf(vcp_usb); | |||||
#if 1 | |||||
wait_for_vcp(); | |||||
/* | |||||
* This is required to use w/ FreeBSD. This is an issue w/ the | |||||
* STM32 Core USB library: | |||||
* https://github.com/STMicroelectronics/STM32CubeL1/issues/10 | |||||
*/ | |||||
HAL_Delay(50); | |||||
usb_printf("starting...\r\n"); | |||||
#endif | |||||
uint32_t v; | |||||
char inpbuf[1024]; | |||||
char *lastcheck; | |||||
char *endchr; | |||||
int inpbufpos = 0; | |||||
int cpylen; | |||||
loop: | |||||
//BoardLowPowerHandler(); | |||||
/* while we have data */ | |||||
while (CDC_RX_LEN) { | |||||
/* store last position */ | |||||
lastcheck = &inpbuf[inpbufpos]; | |||||
/* calculate how much space left */ | |||||
cpylen = MIN(sizeof inpbuf - inpbufpos, CDC_RX_LEN); | |||||
/* copy into buffer */ | |||||
memcpy(&inpbuf[inpbufpos], CDC_RX_BUFFER, cpylen); | |||||
/* and point to end of buffer */ | |||||
inpbufpos += cpylen; | |||||
do { | |||||
/* find first end of line characters */ | |||||
endchr = findeol(lastcheck, cpylen); | |||||
if (endchr != NULL) { | |||||
/* if so, process it */ | |||||
process_line(inpbuf, endchr); | |||||
/* skip end of line char */ | |||||
endchr++; | |||||
/* move remaining buffer to the beginning */ | |||||
memmove(inpbuf, endchr, inpbufpos - (endchr - inpbuf)); | |||||
/* and store new length */ | |||||
inpbufpos = inpbufpos - (endchr - inpbuf); | |||||
/* mark begining of stream as last checked */ | |||||
lastcheck = inpbuf; | |||||
/* and try to process another line */ | |||||
continue; | |||||
} else if (inpbufpos == sizeof inpbuf) { | |||||
/* we overflowed the buffer */ | |||||
/* XXX - best way is to throw away this line */ | |||||
inpbufpos = 0; | |||||
} | |||||
} while (0); | |||||
/* if we copied all the data */ | |||||
if (cpylen == CDC_RX_LEN) { | |||||
/* declare that we are ready to receive more data */ | |||||
CDC_RX_LEN = 0; | |||||
USBD_CDC_ReceivePacket(&hUsbDeviceFS); | |||||
} else { | |||||
/* if not, move the remaining to the begining and try again */ | |||||
memmove(CDC_RX_BUFFER, &CDC_RX_BUFFER[cpylen], CDC_RX_LEN - cpylen); | |||||
CDC_RX_LEN -= cpylen; | |||||
} | |||||
} | |||||
goto loop; | |||||
} |
@@ -0,0 +1,120 @@ | |||||
/*- | |||||
* Copyright 2022 John-Mark Gurney. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* | |||||
*/ | |||||
#include <stdbool.h> | |||||
#include <stdint.h> | |||||
#include <stdlib.h> | |||||
#include <sysinit.h> | |||||
SET_DECLARE(sysinit_set, struct sysinit); | |||||
void | |||||
sysinit_run(void) | |||||
{ | |||||
const int cnt = SET_COUNT(sysinit_set); | |||||
uint16_t *idxarray = alloca(sizeof(uint16_t) * cnt); | |||||
#if defined(VERBOSE_SYSINIT) | |||||
uint16_t last; | |||||
bool verbose; | |||||
#endif | |||||
int i; | |||||
for (i = 0; i < cnt; i++) | |||||
idxarray[i] = i; | |||||
/* | |||||
* following mostly copied from FreeBSD sys/kern/init_main.c | |||||
* which has license: | |||||
* SPDX-License-Identifier: BSD-4-Clause | |||||
* | |||||
* Copyright (c) 1995 Terrence R. Lambert | |||||
* All rights reserved. | |||||
* | |||||
* Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993 | |||||
* The Regents of the University of California. All rights reserved. | |||||
* (c) UNIX System Laboratories, Inc. | |||||
* | |||||
* as copying this to RAM might be expensive, use a stack | |||||
* allocated indirection array to do the sorting instead. | |||||
*/ | |||||
uint16_t *sipp; | |||||
uint16_t *xipp; | |||||
uint16_t save; | |||||
/* | |||||
* Perform a bubble sort of the system initialization objects by | |||||
* their subsystem (primary key) and order (secondary key). | |||||
*/ | |||||
#define GI(x) (SET_BEGIN(sysinit_set)[(x)]) | |||||
#define GI_SUBSYSORDER(x) (GI((x))->si_subsys_order) | |||||
#define GI_SUBSYS(x) (GET_SUBSYS(GI_SUBSYSORDER(x))) | |||||
#define GI_ORDER(x) (GET_ORDER(GI_SUBSYSORDER(x))) | |||||
for (sipp = &idxarray[0]; sipp < &idxarray[cnt]; sipp++) { | |||||
for (xipp = sipp + 1; xipp < &idxarray[cnt]; xipp++) { | |||||
if (GI_SUBSYS(*sipp) < GI_SUBSYS(*xipp) || | |||||
(GI_SUBSYS(*sipp) == GI_SUBSYS(*xipp) && | |||||
GI_ORDER(*sipp) <= GI_ORDER(*xipp))) | |||||
continue; /* skip*/ | |||||
save = *sipp; | |||||
*sipp = *xipp; | |||||
*xipp = save; | |||||
} | |||||
} | |||||
#if defined(VERBOSE_SYSINIT) | |||||
last = SI_SUB_COPYRIGHT; | |||||
verbose = 0; | |||||
#endif | |||||
/* | |||||
* Traverse the (now) ordered list of system initialization tasks. | |||||
* Perform each task, and continue on to the next task. | |||||
*/ | |||||
for (sipp = &idxarray[0]; sipp < &idxarray[cnt]; sipp++) { | |||||
if (GI_SUBSYS(*sipp) == SI_SUB_DUMMY) | |||||
continue; /* skip dummy task(s)*/ | |||||
#if defined(VERBOSE_SYSINIT) | |||||
if (GI_SUBSYS(*sipp) > last && verbose_sysinit != 0) { | |||||
verbose = 1; | |||||
last = GI_SUBSYS(*sipp); | |||||
printf("subsystem %x\n", last); | |||||
} | |||||
if (verbose) { | |||||
printf(" %p(%p)... ", GI(*sipp)->func, | |||||
GI(*sipp)->udata); | |||||
} | |||||
#endif | |||||
/* Call function */ | |||||
(GI(*sipp)->si_func)(GI(*sipp)->si_udata); | |||||
#if defined(VERBOSE_SYSINIT) | |||||
if (verbose) | |||||
printf("done.\n"); | |||||
#endif | |||||
} | |||||
} |
@@ -0,0 +1,115 @@ | |||||
/*- | |||||
* SPDX-License-Identifier: BSD-4-Clause | |||||
* | |||||
* Copyright (c) 1995 Terrence R. Lambert | |||||
* Copyright 2022 John-Mark Gurney | |||||
* All rights reserved. | |||||
* | |||||
* Copyright (c) 1990, 1993 | |||||
* The Regents of the University of California. All rights reserved. | |||||
* (c) UNIX System Laboratories, Inc. | |||||
* All or some portions of this file are derived from material licensed | |||||
* to the University of California by American Telephone and Telegraph | |||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with | |||||
* the permission of UNIX System Laboratories, Inc. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* 3. All advertising materials mentioning features or use of this software | |||||
* must display the following acknowledgement: | |||||
* This product includes software developed by the University of | |||||
* California, Berkeley and its contributors. | |||||
* 4. Neither the name of the University nor the names of its contributors | |||||
* may be used to endorse or promote products derived from this software | |||||
* without specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* | |||||
* @(#)kernel.h 8.3 (Berkeley) 1/21/94 | |||||
* $FreeBSD$ | |||||
*/ | |||||
/* | |||||
* This system is similar to FreeBSD's SYSINIT(9), but w/ minor | |||||
* modifications. | |||||
*/ | |||||
#ifndef _SYSINIT_H_ | |||||
#define _SYSINIT_H_ 1 | |||||
#include <linker_set.h> | |||||
/* from FreeBSD sys/systm.h */ | |||||
#define CTASSERT(x) _Static_assert(x, "compile-time assertion failed") | |||||
#define MAKE_SUBORDER(subsys, order) ((uint32_t)((subsys) << 16) | (order)) | |||||
#define GET_SUBSYS(x) (((x) >> 16) & 0xffff) | |||||
#define GET_ORDER(x) ((x) & 0xffff) | |||||
enum sysinit_sub_id { | |||||
SI_SUB_DUMMY = 0x0000, /* not executed; for linker*/ | |||||
SI_SUB_HAL = 0x0010, /* Early HAL init */ | |||||
SI_SUB_GPIO = 0x0030, /* Early GPIO */ | |||||
SI_SUB_CONSOLE = 0x0700, /* Setup console/debug prints */ | |||||
SI_SUB_COPYRIGHT = 0x0800, /* start of when printf works */ | |||||
SI_SUB_STANDARD = 0x8000, /* standard later initalization */ | |||||
SI_SUB_LAST = 0xffff /* final initialization */ | |||||
}; | |||||
/* | |||||
* Some enumerated orders; "ANY" sorts last. | |||||
*/ | |||||
enum sysinit_elem_order { | |||||
SI_ORDER_FIRST = 0x0000, /* first*/ | |||||
SI_ORDER_SECOND = 0x0001, /* second*/ | |||||
SI_ORDER_THIRD = 0x0002, /* third*/ | |||||
SI_ORDER_FOURTH = 0x0003, /* fourth*/ | |||||
SI_ORDER_FIFTH = 0x0004, /* fifth*/ | |||||
SI_ORDER_SIXTH = 0x0005, /* sixth*/ | |||||
SI_ORDER_SEVENTH = 0x0006, /* seventh*/ | |||||
SI_ORDER_EIGHTH = 0x0007, /* eighth*/ | |||||
SI_ORDER_MIDDLE = 0x1000, /* somewhere in the middle */ | |||||
SI_ORDER_ANY = 0xffff /* last*/ | |||||
}; | |||||
typedef void (*sysinit_cfunc_t)(const void *); | |||||
struct sysinit { | |||||
uint32_t si_subsys_order; | |||||
sysinit_cfunc_t si_func; | |||||
const void *si_udata; | |||||
}; | |||||
#define SYSINIT(uniquifier, subsystem, order, func, udata) \ | |||||
CTASSERT((subsystem & 0xffff) == subsystem); \ | |||||
CTASSERT((order & 0xffff) == order); \ | |||||
static struct sysinit uniquifier ## _sys_init = { \ | |||||
.si_subsys_order = MAKE_SUBORDER((subsystem), (order)), \ | |||||
.si_func = (func), \ | |||||
.si_udata = (udata), \ | |||||
}; \ | |||||
DATA_SET(sysinit_set,uniquifier ## _sys_init) | |||||
void sysinit_run(void); | |||||
#endif /* _SYSINIT_H_ */ |