From 12fa2716dbc3ea80c833411b12fe403421cebb00 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Thu, 25 Jan 2018 11:00:18 -0500 Subject: [PATCH] hardware float support --- Makefile | 4 +- include/serial.h | 2 +- include/stm32l476xx.h | 1 - include/system_stm32l4xx.h | 125 ------------------------------------- src/lcd.c | 7 +++ src/main.c | 26 +++++++- src/parser.c | 83 +++++++++++++----------- src/serial.c | 4 +- src/startup_stm32l476xx.s | 2 - src/stm32l4xx_it.c | 10 +++ src/system_stm32l4xx.c | 44 ------------- src/task.c | 4 +- 12 files changed, 96 insertions(+), 216 deletions(-) delete mode 100644 include/system_stm32l4xx.h delete mode 100644 src/system_stm32l4xx.c diff --git a/Makefile b/Makefile index 5e13666..ef55a5a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,9 @@ AS = as AR = ar OBJCOPY = objcopy -MCUFLAGS = -mthumb -mcpu=cortex-m4 +MCUFLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 AFLAGS = $(MCUFLAGS) -CFLAGS = $(MCUFLAGS) -Iinclude -ffreestanding -Wall -Werror -Wextra +CFLAGS = $(MCUFLAGS) -Iinclude -fno-builtin -fsigned-char -ffreestanding -Wall -Werror -Wextra OFLAGS = -O ihex CFILES = $(wildcard src/*.c) diff --git a/include/serial.h b/include/serial.h index 97b02d7..9cb9d24 100644 --- a/include/serial.h +++ b/include/serial.h @@ -5,6 +5,6 @@ void serial_init(void); void serial_put(int c); char serial_get(void); -void serial_gets(char *buf); +void serial_gets(char *buf, int max); #endif // SERIAL_H_ diff --git a/include/stm32l476xx.h b/include/stm32l476xx.h index 7c6f9e0..3708eed 100644 --- a/include/stm32l476xx.h +++ b/include/stm32l476xx.h @@ -182,7 +182,6 @@ typedef enum */ #include "core_cm4.h" /* Cortex-M4 processor and core peripherals */ -#include "system_stm32l4xx.h" #include /** @addtogroup Peripheral_registers_structures diff --git a/include/system_stm32l4xx.h b/include/system_stm32l4xx.h deleted file mode 100644 index b68b0b9..0000000 --- a/include/system_stm32l4xx.h +++ /dev/null @@ -1,125 +0,0 @@ -/** - ****************************************************************************** - * @file system_stm32l4xx.h - * @author MCD Application Team - * @version V1.1.1 - * @date 29-April-2016 - * @brief CMSIS Cortex-M4 Device System Source File for STM32L4xx devices. - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2016 STMicroelectronics

- * - * 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 STMicroelectronics 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. - * - ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32l4xx_system - * @{ - */ - -/** - * @brief Define to prevent recursive inclusion - */ -#ifndef __SYSTEM_STM32L4XX_H -#define __SYSTEM_STM32L4XX_H - -#ifdef __cplusplus - extern "C" { -#endif - -/** @addtogroup STM32L4xx_System_Includes - * @{ - */ - -/** - * @} - */ - - -/** @addtogroup STM32L4xx_System_Exported_Variables - * @{ - */ - /* The SystemCoreClock variable is updated in three ways: - 1) by calling CMSIS function SystemCoreClockUpdate() - 2) by calling HAL API function HAL_RCC_GetSysClockFreq() - 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency - Note: If you use this function to configure the system clock; then there - is no need to call the 2 first functions listed above, since SystemCoreClock - variable is updated automatically. - */ -extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ - -extern const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */ -extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */ -extern const uint32_t MSIRangeTable[12]; /*!< MSI ranges table values */ - -/** - * @} - */ - -/** @addtogroup STM32L4xx_System_Exported_Constants - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32L4xx_System_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32L4xx_System_Exported_Functions - * @{ - */ - -extern void SystemInit(void); -extern void SystemCoreClockUpdate(void); -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /*__SYSTEM_STM32L4XX_H */ - -/** - * @} - */ - -/** - * @} - */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/lcd.c b/src/lcd.c index 1c29d54..69be7d4 100644 --- a/src/lcd.c +++ b/src/lcd.c @@ -3,6 +3,8 @@ #include #include +//#define USE_DELAY + #define LCD_D0 GPIO_PORT(A, 0) #define LCD_D1 GPIO_PORT(A, 1) #define LCD_D2 GPIO_PORT(A, 4) @@ -19,7 +21,12 @@ void lcd_pulse(void) { gpio_dout(LCD_E, 1); +#ifdef USE_DELAY delay(1); +#else + for (uint16_t i = 0; i < 10000; i++) + asm(""); +#endif // USE_DELAY gpio_dout(LCD_E, 0); } diff --git a/src/main.c b/src/main.c index 55daac9..ddf9029 100644 --- a/src/main.c +++ b/src/main.c @@ -40,6 +40,9 @@ int main(void) serial_init(); + // enable FPU + SCB->CPACR |= (0xF << 20); + task_init(kmain); while (1); @@ -57,19 +60,38 @@ void task_interpreter(void) interpreter_define_cfunc(&interp, "print", script_puts); char buf[32]; + int index; while (1) { - serial_gets(buf); + index = 0; + do { + buf[index] = serial_get(); + } while (buf[index++] != '\r' && index < 32); + buf[index - 1] = '\0'; + interpreter_doline(&interp, buf); } } +void task_suck(void) +{ + float i = 1; + + while (1) { + i += 0.123; + lcd_puti((int)(i * 1000)); + delay(2000); + } +} + +#include void kmain(void) { asm("cpsie i"); task_start(lcd_handler, 128); delay(200); - task_start(task_interpreter, 512); + task_start(task_suck, 1024); + //task_start(task_interpreter, 1024); //char *s = initrd_getfile("test.txt"); // svc puts diff --git a/src/parser.c b/src/parser.c index 35cafe2..851c860 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,19 +1,25 @@ #include -#define true 1 -#define false 0 -typedef uint8_t bool; - +#include #include -#include + +#define MAX_VAR 8 +#define MAX_STACK 8 static const char *interpreter_operators = "=("; -int strcmp(const char *s1, const char *s2) +bool strcmp(const char *a, const char *b) +{ + int i = 0; + for (; a[i] == b[i] && a[i] != '\0'; i++); + return a[i] == b[i]; +} + +bool strncmp(const char *a, const char *b, int count) { int i = 0; - for (; s1[i] == s2[i] && s1[i] != '\0'; i++); - return s1[i] == s2[i]; + for (; a[i] == b[i] && i < count; i++); + return i == count; } uint8_t isalpha(char c) @@ -50,9 +56,9 @@ void interpreter_init(interpreter *interp) { interp->status = READY; interp->vcount = 0; - interp->vars = (variable *)hcalloc(32, sizeof(variable)); - interp->names = (char **)hcalloc(32, sizeof(char *)); - interp->stack = (stack_t *)hcalloc(64, sizeof(stack_t)); + interp->vars = (variable *)hcalloc(MAX_VAR, sizeof(variable)); + interp->names = (char **)hcalloc(MAX_VAR, sizeof(char *)); + interp->stack = (stack_t *)hcalloc(MAX_STACK, sizeof(stack_t)); } void interpreter_define_value(interpreter *interp, const char *name, int32_t value) @@ -91,7 +97,7 @@ bool namencmp(const char *name, const char *s) { uint16_t i; for (i = 0; name[i] == s[i] && s[i] != '\0'; i++); - return (name[i] == '\0'); + return (name[i] == '\0' && !isname(s[i])); } uint16_t spacecount(const char *s) @@ -101,10 +107,10 @@ uint16_t spacecount(const char *s) return i; } -char *copystr(const char *s) +char *copystr(const char *s, char end) { uint16_t len = 0; - while (s[len++] != '\n'); + while (s[len++] != end); char *buf = (char *)hmalloc(len); for (uint16_t i = 0; i < len; i++) buf[i] = s[i]; @@ -119,31 +125,37 @@ char *copysubstr(const char *s, int end) return buf; } +variable *interpreter_getvar(interpreter *interp, const char *line) +{ + for (uint16_t i = 0; i < interp->vcount; i++) { + if (namencmp(interp->names[i], line)) + return &interp->vars[i]; + } + + return 0; +} + int interpreter_doline(interpreter *interp, const char *line) { variable *bits[16]; uint16_t offset = 0, boffset = 0; // check for var/func set or usage + int end; getvar: - for (uint16_t i = 0; i < interp->vcount; i++) { - if (namencmp(interp->names[i], line)) { - bits[boffset++] = &interp->vars[i]; - // get past name - for (uint16_t j = 0; interp->names[i][j] != '\0'; j++, offset++); - break; - } - } + for (end = 0; isname(line[end]); end++); + variable *var = interpreter_getvar(interp, line); - // defining new variable - if (boffset == 0) { - uint16_t end; - for (end = 0; isname(line[end]); end++); + if (var != 0) { + bits[boffset++] = var; + } else { + // defining new variable interpreter_define_value(interp, copysubstr(line, end), 0); goto getvar; // try again } - // skip whitespace + // skip whitespace/name + offset += end; offset += spacecount(line + offset); if (boffset == 0 && line[offset] != '=') @@ -154,12 +166,10 @@ getvar: // print value return -99; } else if (line[offset] == '=') { - return -23; // assignment/expression - //offset++; - //offset += spacecount(line + offset); - //if (boffset > 0) - // bits[boffset]->value = (uint32_t)copystr(line + offset); + offset++; + offset += spacecount(line + offset); + bits[0]->value = (uint32_t)copystr(line + offset, '\0'); } else if (line[offset] == '(') { // function call offset++; @@ -200,9 +210,12 @@ getvar: for (j = offsets[i]; line[j] != ' ' && line[j] != '\t' && line[j] != ',' && line[j] != ')'; j++); j -= offsets[i]; - interp->stack[i] = (char *)hmalloc(j); - for (uint16_t k = 0; k < j; k++) - ((char *)interp->stack[i])[k] = line[offsets[i] + k]; + + variable *var = interpreter_getvar(interp, line + offsets[i]); + if (var != 0) + interp->stack[i] = copystr((char *)var->value, '\0'); + else + interp->stack[i] = copysubstr(line + offsets[i], j); } ((func_t)bits[0]->value)(interp->stack); diff --git a/src/serial.c b/src/serial.c index 32fcb95..db0cfbc 100644 --- a/src/serial.c +++ b/src/serial.c @@ -26,13 +26,13 @@ char serial_get(void) return USART2->RDR & 0xFF; } -void serial_gets(char *buf) +void serial_gets(char *buf, int max) { uint16_t index = 0; do { buf[index] = serial_get(); - } while (buf[index++] != '\r'); + } while (index++ < max && buf[index] != '\r'); buf[index - 1] = '\0'; //return buf; diff --git a/src/startup_stm32l476xx.s b/src/startup_stm32l476xx.s index 57b11cb..340d080 100644 --- a/src/startup_stm32l476xx.s +++ b/src/startup_stm32l476xx.s @@ -106,8 +106,6 @@ LoopFillZerobss: cmp r2, r3 bcc FillZerobss -/* Call the clock system intitialization function.*/ - bl SystemInit /* Call static constructors */ bl __libc_init_array /* Call the application's entry point.*/ diff --git a/src/stm32l4xx_it.c b/src/stm32l4xx_it.c index 368fed5..d007607 100644 --- a/src/stm32l4xx_it.c +++ b/src/stm32l4xx_it.c @@ -1,28 +1,38 @@ #include +#include + +void perror(const char *s) +{ + lcd_puts(s); +} void NMI_Handler(void) {} void HardFault_Handler(void) { GPIOA->BSRR |= (1 << 5); + perror("Hard Fault!"); while (1); } void MemManage_Handler(void) { GPIOA->BSRR |= (1 << 5); + perror("MemManage Fault!"); while (1); } void BusFault_Handler(void) { GPIOA->BSRR |= (1 << 5); + perror("Bus Fault!"); while (1); } void UsageFault_Handler(void) { GPIOA->BSRR |= (1 << 5); + perror("Usage Fault!"); while (1); } diff --git a/src/system_stm32l4xx.c b/src/system_stm32l4xx.c deleted file mode 100644 index 4c22bfe..0000000 --- a/src/system_stm32l4xx.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "stm32l476xx.h" - -/************************* Miscellaneous Configuration ************************/ -/*!< Uncomment the following line if you need to relocate your vector Table in - Internal SRAM. */ -/* #define VECT_TAB_SRAM */ -#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. - This value must be a multiple of 0x200. */ -/******************************************************************************/ - -void SystemInit(void) -{ - /* FPU settings ------------------------------------------------------------*/ - #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ - #endif - - /* Reset the RCC clock configuration to the default reset state ------------*/ - /* Set MSION bit */ - RCC->CR |= RCC_CR_MSION; - - /* Reset CFGR register */ - RCC->CFGR = 0x00000000U; - - /* Reset HSEON, CSSON , HSION, and PLLON bits */ - RCC->CR &= 0xEAF6FFFFU; - - /* Reset PLLCFGR register */ - RCC->PLLCFGR = 0x00001000U; - - /* Reset HSEBYP bit */ - RCC->CR &= 0xFFFBFFFFU; - - /* Disable all interrupts */ - RCC->CIER = 0x00000000U; - - /* Configure the Vector Table location add offset address ------------------*/ -#ifdef VECT_TAB_SRAM - SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ -#else - SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ -#endif -} - diff --git a/src/task.c b/src/task.c index a34988a..67ff136 100644 --- a/src/task.c +++ b/src/task.c @@ -9,7 +9,7 @@ typedef struct { void (*code)(void); } task_t; -#define MAX_TASKS 4 +#define MAX_TASKS 6 static task_t tasks[MAX_TASKS]; static volatile int next_idx = 0; @@ -102,7 +102,7 @@ void PendSV_Handler(void) asm("\ mov r0, #0xFFFFFFFD; \ cpsie i; \ - bx r0; \ + bx lr; \ "); }