hardware float support

master
Clyne Sullivan 7 years ago
parent bf230d6a74
commit 12fa2716db

@ -4,9 +4,9 @@ AS = as
AR = ar AR = ar
OBJCOPY = objcopy OBJCOPY = objcopy
MCUFLAGS = -mthumb -mcpu=cortex-m4 MCUFLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16
AFLAGS = $(MCUFLAGS) AFLAGS = $(MCUFLAGS)
CFLAGS = $(MCUFLAGS) -Iinclude -ffreestanding -Wall -Werror -Wextra CFLAGS = $(MCUFLAGS) -Iinclude -fno-builtin -fsigned-char -ffreestanding -Wall -Werror -Wextra
OFLAGS = -O ihex OFLAGS = -O ihex
CFILES = $(wildcard src/*.c) CFILES = $(wildcard src/*.c)

@ -5,6 +5,6 @@ void serial_init(void);
void serial_put(int c); void serial_put(int c);
char serial_get(void); char serial_get(void);
void serial_gets(char *buf); void serial_gets(char *buf, int max);
#endif // SERIAL_H_ #endif // SERIAL_H_

@ -182,7 +182,6 @@ typedef enum
*/ */
#include "core_cm4.h" /* Cortex-M4 processor and core peripherals */ #include "core_cm4.h" /* Cortex-M4 processor and core peripherals */
#include "system_stm32l4xx.h"
#include <stdint.h> #include <stdint.h>
/** @addtogroup Peripheral_registers_structures /** @addtogroup Peripheral_registers_structures

@ -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
*
* <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
*
* 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****/

@ -3,6 +3,8 @@
#include <gpio.h> #include <gpio.h>
#include <string.h> #include <string.h>
//#define USE_DELAY
#define LCD_D0 GPIO_PORT(A, 0) #define LCD_D0 GPIO_PORT(A, 0)
#define LCD_D1 GPIO_PORT(A, 1) #define LCD_D1 GPIO_PORT(A, 1)
#define LCD_D2 GPIO_PORT(A, 4) #define LCD_D2 GPIO_PORT(A, 4)
@ -19,7 +21,12 @@
void lcd_pulse(void) void lcd_pulse(void)
{ {
gpio_dout(LCD_E, 1); gpio_dout(LCD_E, 1);
#ifdef USE_DELAY
delay(1); delay(1);
#else
for (uint16_t i = 0; i < 10000; i++)
asm("");
#endif // USE_DELAY
gpio_dout(LCD_E, 0); gpio_dout(LCD_E, 0);
} }

@ -40,6 +40,9 @@ int main(void)
serial_init(); serial_init();
// enable FPU
SCB->CPACR |= (0xF << 20);
task_init(kmain); task_init(kmain);
while (1); while (1);
@ -57,19 +60,38 @@ void task_interpreter(void)
interpreter_define_cfunc(&interp, "print", script_puts); interpreter_define_cfunc(&interp, "print", script_puts);
char buf[32]; char buf[32];
int index;
while (1) { 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); interpreter_doline(&interp, buf);
} }
} }
void task_suck(void)
{
float i = 1;
while (1) {
i += 0.123;
lcd_puti((int)(i * 1000));
delay(2000);
}
}
#include <stdio.h>
void kmain(void) void kmain(void)
{ {
asm("cpsie i"); asm("cpsie i");
task_start(lcd_handler, 128); task_start(lcd_handler, 128);
delay(200); delay(200);
task_start(task_interpreter, 512); task_start(task_suck, 1024);
//task_start(task_interpreter, 1024);
//char *s = initrd_getfile("test.txt"); //char *s = initrd_getfile("test.txt");
// svc puts // svc puts

@ -1,19 +1,25 @@
#include <parser.h> #include <parser.h>
#define true 1 #include <stdbool.h>
#define false 0
typedef uint8_t bool;
#include <heap.h> #include <heap.h>
#include <clock.h>
#define MAX_VAR 8
#define MAX_STACK 8
static const char *interpreter_operators = "=("; 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; int i = 0;
for (; s1[i] == s2[i] && s1[i] != '\0'; i++); for (; a[i] == b[i] && i < count; i++);
return s1[i] == s2[i]; return i == count;
} }
uint8_t isalpha(char c) uint8_t isalpha(char c)
@ -50,9 +56,9 @@ void interpreter_init(interpreter *interp)
{ {
interp->status = READY; interp->status = READY;
interp->vcount = 0; interp->vcount = 0;
interp->vars = (variable *)hcalloc(32, sizeof(variable)); interp->vars = (variable *)hcalloc(MAX_VAR, sizeof(variable));
interp->names = (char **)hcalloc(32, sizeof(char *)); interp->names = (char **)hcalloc(MAX_VAR, sizeof(char *));
interp->stack = (stack_t *)hcalloc(64, sizeof(stack_t)); interp->stack = (stack_t *)hcalloc(MAX_STACK, sizeof(stack_t));
} }
void interpreter_define_value(interpreter *interp, const char *name, int32_t value) 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; uint16_t i;
for (i = 0; name[i] == s[i] && s[i] != '\0'; 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) uint16_t spacecount(const char *s)
@ -101,10 +107,10 @@ uint16_t spacecount(const char *s)
return i; return i;
} }
char *copystr(const char *s) char *copystr(const char *s, char end)
{ {
uint16_t len = 0; uint16_t len = 0;
while (s[len++] != '\n'); while (s[len++] != end);
char *buf = (char *)hmalloc(len); char *buf = (char *)hmalloc(len);
for (uint16_t i = 0; i < len; i++) for (uint16_t i = 0; i < len; i++)
buf[i] = s[i]; buf[i] = s[i];
@ -119,31 +125,37 @@ char *copysubstr(const char *s, int end)
return buf; 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) int interpreter_doline(interpreter *interp, const char *line)
{ {
variable *bits[16]; variable *bits[16];
uint16_t offset = 0, boffset = 0; uint16_t offset = 0, boffset = 0;
// check for var/func set or usage // check for var/func set or usage
int end;
getvar: getvar:
for (uint16_t i = 0; i < interp->vcount; i++) { for (end = 0; isname(line[end]); end++);
if (namencmp(interp->names[i], line)) { variable *var = interpreter_getvar(interp, line);
bits[boffset++] = &interp->vars[i];
// get past name
for (uint16_t j = 0; interp->names[i][j] != '\0'; j++, offset++);
break;
}
}
// defining new variable if (var != 0) {
if (boffset == 0) { bits[boffset++] = var;
uint16_t end; } else {
for (end = 0; isname(line[end]); end++); // defining new variable
interpreter_define_value(interp, copysubstr(line, end), 0); interpreter_define_value(interp, copysubstr(line, end), 0);
goto getvar; // try again goto getvar; // try again
} }
// skip whitespace // skip whitespace/name
offset += end;
offset += spacecount(line + offset); offset += spacecount(line + offset);
if (boffset == 0 && line[offset] != '=') if (boffset == 0 && line[offset] != '=')
@ -154,12 +166,10 @@ getvar:
// print value // print value
return -99; return -99;
} else if (line[offset] == '=') { } else if (line[offset] == '=') {
return -23;
// assignment/expression // assignment/expression
//offset++; offset++;
//offset += spacecount(line + offset); offset += spacecount(line + offset);
//if (boffset > 0) bits[0]->value = (uint32_t)copystr(line + offset, '\0');
// bits[boffset]->value = (uint32_t)copystr(line + offset);
} else if (line[offset] == '(') { } else if (line[offset] == '(') {
// function call // function call
offset++; offset++;
@ -200,9 +210,12 @@ getvar:
for (j = offsets[i]; line[j] != ' ' && line[j] != '\t' && for (j = offsets[i]; line[j] != ' ' && line[j] != '\t' &&
line[j] != ',' && line[j] != ')'; j++); line[j] != ',' && line[j] != ')'; j++);
j -= offsets[i]; j -= offsets[i];
interp->stack[i] = (char *)hmalloc(j);
for (uint16_t k = 0; k < j; k++) variable *var = interpreter_getvar(interp, line + offsets[i]);
((char *)interp->stack[i])[k] = line[offsets[i] + k]; 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); ((func_t)bits[0]->value)(interp->stack);

@ -26,13 +26,13 @@ char serial_get(void)
return USART2->RDR & 0xFF; return USART2->RDR & 0xFF;
} }
void serial_gets(char *buf) void serial_gets(char *buf, int max)
{ {
uint16_t index = 0; uint16_t index = 0;
do { do {
buf[index] = serial_get(); buf[index] = serial_get();
} while (buf[index++] != '\r'); } while (index++ < max && buf[index] != '\r');
buf[index - 1] = '\0'; buf[index - 1] = '\0';
//return buf; //return buf;

@ -106,8 +106,6 @@ LoopFillZerobss:
cmp r2, r3 cmp r2, r3
bcc FillZerobss bcc FillZerobss
/* Call the clock system intitialization function.*/
bl SystemInit
/* Call static constructors */ /* Call static constructors */
bl __libc_init_array bl __libc_init_array
/* Call the application's entry point.*/ /* Call the application's entry point.*/

@ -1,28 +1,38 @@
#include <stm32l476xx.h> #include <stm32l476xx.h>
#include <lcd.h>
void perror(const char *s)
{
lcd_puts(s);
}
void NMI_Handler(void) {} void NMI_Handler(void) {}
void HardFault_Handler(void) void HardFault_Handler(void)
{ {
GPIOA->BSRR |= (1 << 5); GPIOA->BSRR |= (1 << 5);
perror("Hard Fault!");
while (1); while (1);
} }
void MemManage_Handler(void) void MemManage_Handler(void)
{ {
GPIOA->BSRR |= (1 << 5); GPIOA->BSRR |= (1 << 5);
perror("MemManage Fault!");
while (1); while (1);
} }
void BusFault_Handler(void) void BusFault_Handler(void)
{ {
GPIOA->BSRR |= (1 << 5); GPIOA->BSRR |= (1 << 5);
perror("Bus Fault!");
while (1); while (1);
} }
void UsageFault_Handler(void) void UsageFault_Handler(void)
{ {
GPIOA->BSRR |= (1 << 5); GPIOA->BSRR |= (1 << 5);
perror("Usage Fault!");
while (1); while (1);
} }

@ -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
}

@ -9,7 +9,7 @@ typedef struct {
void (*code)(void); void (*code)(void);
} task_t; } task_t;
#define MAX_TASKS 4 #define MAX_TASKS 6
static task_t tasks[MAX_TASKS]; static task_t tasks[MAX_TASKS];
static volatile int next_idx = 0; static volatile int next_idx = 0;
@ -102,7 +102,7 @@ void PendSV_Handler(void)
asm("\ asm("\
mov r0, #0xFFFFFFFD; \ mov r0, #0xFFFFFFFD; \
cpsie i; \ cpsie i; \
bx r0; \ bx lr; \
"); ");
} }

Loading…
Cancel
Save