@@ -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+= misc.c | |||
_SRCTOPDIR:= $(.PARSEDIR)/.. | |||
SRCTOP?=$(_SRCTOPDIR:tA) | |||
STM32?=$(SRCTOP)/stm32 | |||
ARMOBJDUMP?= arm-none-eabi-objdump | |||
ARMCC?= arm-none-eabi-gcc | |||
@@ -10,17 +14,22 @@ ARMCC?= arm-none-eabi-gcc | |||
.include <$(.PARSEDIR)/mu.opts.mk> | |||
.if ${MK_SYSINIT} == "yes" | |||
.PATH: $(SRCTOP) | |||
SRCS+= sysinit.c | |||
.endif | |||
# Strobe | |||
.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 \ | |||
x25519.c | |||
.endif | |||
# LoRamac (SX1276) radio code | |||
.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 | |||
CFLAGS+= -I$(LORAMAC_SRC)/boards | |||
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 | |||
.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 | |||
.if ${MK_NODE151} == "yes" | |||
ARMTARGET?= -mcpu=cortex-m3 -mthumb | |||
STM32=$(.CURDIR)/stm32 | |||
.PATH: $(STM32)/l151ccux | |||
LINKER_SCRIPT=$(STM32)/l151ccux/STM32L151CCUX_FLASH.ld | |||
SRCS+= \ | |||
startup_stm32l151ccux.s \ | |||
stm32l1xx_hal.c \ | |||
@@ -3,10 +3,12 @@ | |||
# | |||
# See bsd.mkopt.mk for more information. | |||
__DEFAULT_YES_OPTIONS = STROBE | |||
__DEFAULT_YES_OPTIONS = STROBE \ | |||
SYSINIT | |||
__DEFAULT_NO_OPTIONS = \ | |||
NODE151 \ | |||
STM32F103 \ | |||
SX1276 \ | |||
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_ */ |