added led interface

This commit is contained in:
ayabusa 2024-03-31 18:17:46 +02:00
parent 6d11674ae4
commit 3a161a1181
16 changed files with 118 additions and 124 deletions

View File

@ -17,6 +17,8 @@
"streambuf": "cpp", "streambuf": "cpp",
"system_error": "cpp", "system_error": "cpp",
"tuple": "cpp", "tuple": "cpp",
"main.h": "c" "main.h": "c",
"led.h": "c",
"stm32f730xx.h": "c"
} }
} }

View File

@ -50,18 +50,19 @@ LFLAGS += -mthumb
LFLAGS += -Wall LFLAGS += -Wall
LFLAGS += --specs=nosys.specs LFLAGS += --specs=nosys.specs
LFLAGS += -nostdlib LFLAGS += -nostdlib
LFLAGS += -lgcc
LFLAGS += -T$(LSCRIPT) LFLAGS += -T$(LSCRIPT)
# AS_SRC = $(SRC_DIR)/core.S # AS_SRC = $(SRC_DIR)/core.S
#C_SRC = $(SRC_DIR)/main.c #C_SRC = $(SRC_DIR)/main.c
CPP_SRC := $(wildcard $(SRC_DIR)/*.cpp) CPP_SRC := $(wildcard $(SRC_DIR)/*.cpp) $(wildcard $(SRC_DIR)/Laplace/*.cpp)
C_SRC := $(wildcard $(SRC_DIR)/*.c) $(wildcard $(SRC_DIR)/Laplace/*.c)
INCLUDE = -I./ INCLUDE = -I./
INCLUDE += -I./device INCLUDE += -I./device
#OBJS = $(BUILD_DIR)/$(notdir $(AS_SRC:.S=.o)) #OBJS = $(BUILD_DIR)/$(notdir $(AS_SRC:.S=.o))
#OBJS += $(BUILD_DIR)/$(notdir $(C_SRC:.c=.o)) #OBJS += $(BUILD_DIR)/$(notdir $(C_SRC:.c=.o))
OBJS += $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(C_SRC))
OBJS += $(patsubst $(SRC_DIR)/%.cpp, $(BUILD_DIR)/%.o, $(CPP_SRC)) OBJS += $(patsubst $(SRC_DIR)/%.cpp, $(BUILD_DIR)/%.o, $(CPP_SRC))
.PHONY: all .PHONY: all

View File

@ -10,6 +10,6 @@ This is a bare metal os attempt on the numworks n0110
## TODO ## TODO
- [x] Working thing - [x] Working thing
- [ ] Led interface - [x] Led interface
- [ ] Keyboard interface - [ ] Keyboard interface
- [ ] Screen interface - [ ] Screen interface

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,2 @@
# Laplace
Laplace is the abstraction layer of Zeta, it is used to control the led, keyboard, screen ...

View File

@ -0,0 +1,59 @@
#include "led.h"
// Variable to store the current state of LEDs
uint8_t led_state = 0;
void led_init(){
// It should be set to push-pull low-speed output.
// setup red led
GPIOB->MODER &= ~(0x3 << (RED_LED_PIN*2));
GPIOB->MODER |= (0x1 << (RED_LED_PIN*2));
GPIOB->OTYPER &= ~(1 << RED_LED_PIN);
// setup green led
GPIOB->MODER &= ~(0x3 << (GREEN_LED_PIN*2));
GPIOB->MODER |= (0x1 << (GREEN_LED_PIN*2));
GPIOB->OTYPER &= ~(1 << GREEN_LED_PIN);
// setup blue led
GPIOB->MODER &= ~(0x3 << (BLUE_LED_PIN*2));
GPIOB->MODER |= (0x1 << (BLUE_LED_PIN*2));
GPIOB->OTYPER &= ~(1 << BLUE_LED_PIN);
}
void set_led_red(bool state){
if(state){
led_state |= (1 << RED_LED_PIN);
}else{
led_state &= ~(1 << RED_LED_PIN);
}
GPIOB->ODR = led_state;
}
void set_led_green(bool state){
if(state){
led_state |= (1 << GREEN_LED_PIN);
}else{
led_state &= ~(1 << GREEN_LED_PIN);
}
GPIOB->ODR = led_state;
}
void set_led_blue(bool state){
if(state){
led_state |= (1 << BLUE_LED_PIN);
}else{
led_state &= ~(1 << BLUE_LED_PIN);
}
GPIOB->ODR = led_state;
}
void set_led_all(bool state){
if(state){
led_state = (1 << RED_LED_PIN) | (1 << GREEN_LED_PIN) | (1 << BLUE_LED_PIN);
}else{
led_state = 0;
}
GPIOB->ODR = led_state;
}

View File

@ -0,0 +1,23 @@
/** @file led.h
*
* @brief Control the led
*
*/
#ifndef LED_H
#define LED_H
#define RED_LED_PIN (4)
#define GREEN_LED_PIN (5)
#define BLUE_LED_PIN (0)
#include <stdbool.h>
#include "../device/stm32f730xx.h"
void led_init();
void set_led_red(bool state);
void set_led_green(bool state);
void set_led_blue(bool state);
void set_led_all(bool state);
#endif

View File

@ -1,79 +0,0 @@
/*
* Test program to boot an STM32 chip with the absolute
* minimum required code for teaching about the chips.
*
* Copyright William Ransohoff, Vivonomicon, LLC, 2017
*
* Open source under the MIT License
*/
.syntax unified
.cpu cortex-m7
.fpu softvfp
.thumb
// Global values.
.global vtable
.global reset_handler
/*
* The vector table.
* Most entries are ommitted for simplicity.
*/
/*
* The Reset handler. Called on reset.
*/
.type reset_handler, %function
reset_handler:
// Set the stack pointer to the end of the stack.
// The '_estack' value is defined in our linker script.
LDR r0, =_estack
MOV sp, r0
// Copy data from flash to RAM data init section.
// R2 will store our progress along the sidata section.
MOVS r0, #0
// Load the start/end addresses of the data section,
// and the start of the data init section.
LDR r1, =_sdata
LDR r2, =_edata
LDR r3, =_sidata
B copy_sidata_loop
copy_sidata:
// Offset the data init section by our copy progress.
LDR r4, [r3, r0]
// Copy the current word into data, and increment.
STR r4, [r1, r0]
ADDS r0, r0, #4
copy_sidata_loop:
// Unless we've copied the whole data section, copy the
// next word from sidata->data.
ADDS r4, r0, r1
CMP r4, r2
BCC copy_sidata
// Once we are done copying the data section into RAM,
// move on to filling the BSS section with 0s.
MOVS r0, #0
LDR r1, =_sbss
LDR r2, =_ebss
B reset_bss_loop
// Zero out the BSS segment.
reset_bss:
// Store a 0 and increment by a word.
STR r0, [r1]
ADDS r1, r1, #4
reset_bss_loop:
// We'll use R1 to count progress here; if we aren't
// done, reset the next word and increment.
CMP r1, r2
BCC reset_bss
// Branch to the 'main' method.
B main
.size reset_handler, .-reset_handler

View File

@ -1,9 +1,11 @@
/* Label for the program's entry point */ /* This is the linker file it required to map out the memory.
/*ENTRY(reset_handler)*/ * This linker is heavely inspired by epsilon/omega/upsilon and their bootloader_common.ld.
/* End of RAM / Start of stack */ * It is necessary if we want our os to be considered as valid.
/* (4KB SRAM) */ * At this time we can only compile this os to slot B, but it might change in the future */
/* epsilon stuff */
/* numworks stuff */
STACK_SIZE = 32K; STACK_SIZE = 32K;
FIRST_FLASH_SECTOR_SIZE = 4K; FIRST_FLASH_SECTOR_SIZE = 4K;
SIGNED_PAYLOAD_LENGTH = 8; SIGNED_PAYLOAD_LENGTH = 8;
@ -28,15 +30,18 @@ SECTIONS
. = ORIGIN(FLASH) + SIGNED_PAYLOAD_LENGTH; . = ORIGIN(FLASH) + SIGNED_PAYLOAD_LENGTH;
} >FLASH } >FLASH
/* Contains some info and is requiered to be considered as a valid slot by the bootloader.
* Located in info_headers.cpp */
.kernel_header : { .kernel_header : {
KEEP(*(.kernel_header)) KEEP(*(.kernel_header))
} >FLASH } >FLASH
/* Nothing in there for now */
.slot_info : { .slot_info : {
*(.slot_info*) *(.slot_info*)
} >RAM } >RAM
/* The vector table goes at the start of flash. */ /* The vector table (handle all the interrupts) located in vector_table.cpp */
.isr_vector_table ORIGIN(RAM) + 512 : AT(ORIGIN(FLASH) + SIZEOF(.signed_payload_prefix) + SIZEOF(.kernel_header)) { .isr_vector_table ORIGIN(RAM) + 512 : AT(ORIGIN(FLASH) + SIZEOF(.signed_payload_prefix) + SIZEOF(.kernel_header)) {
/* When booting, the STM32F412 fetches the content of address 0x0, and /* When booting, the STM32F412 fetches the content of address 0x0, and
* extracts from it various key infos: the initial value of the PC register * extracts from it various key infos: the initial value of the PC register
@ -57,6 +62,7 @@ SECTIONS
_isr_vector_table_end_ram = .; _isr_vector_table_end_ram = .;
} >RAM } >RAM
/* this is to prevent the bootloader from booting straight up in our os (we set all to 0) */
.exam_mode_buffer ORIGIN(FLASH) + SIZEOF(.signed_payload_prefix) + SIZEOF(.kernel_header) + SIZEOF(.isr_vector_table) : { .exam_mode_buffer ORIGIN(FLASH) + SIZEOF(.signed_payload_prefix) + SIZEOF(.kernel_header) + SIZEOF(.isr_vector_table) : {
. = ALIGN(4K); . = ALIGN(4K);
_exam_mode_buffer_start = .; _exam_mode_buffer_start = .;
@ -66,7 +72,8 @@ SECTIONS
_exam_mode_buffer_end = .; _exam_mode_buffer_end = .;
} >FLASH } >FLASH
/* External flash memory */ /* Contains some more info and is requiered to be considered as a valid slot by the bootloader.
* Located in info_headers.cpp */
.userland_header : { .userland_header : {
. = ORIGIN(FLASH) + USERLAND_OFFSET; . = ORIGIN(FLASH) + USERLAND_OFFSET;
KEEP(*(.userland_header)); KEEP(*(.userland_header));
@ -77,6 +84,7 @@ SECTIONS
*(.text) *(.text)
*(.text.*) *(.text.*)
} >FLASH } >FLASH
/* The 'rodata' section contains read-only data, /* The 'rodata' section contains read-only data,
* constants, strings, information that won't change. */ * constants, strings, information that won't change. */
.rodata : { .rodata : {
@ -84,6 +92,7 @@ SECTIONS
*(.rodata.*) *(.rodata.*)
} >FLASH } >FLASH
/* TODO, understand what is it's purpose */
.init_array : { .init_array : {
. = ALIGN(4); . = ALIGN(4);
_init_array_start = .; _init_array_start = .;

View File

@ -1,21 +0,0 @@
#include "main.h"
/* Main program. */
int main(void) {
// Enable the GPIOa and GPIOC peripheral in RCC.
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN ;
// C0 is connected to the LED
// It should be set to push-pull low-speed output.
GPIOB->MODER &= ~(0x3 << (LED_PIN*2));
GPIOB->MODER |= (0x1 << (LED_PIN*2));
GPIOB->OTYPER &= ~(1 << LED_PIN);
// set the led on
GPIOB->ODR = (1 << LED_PIN);
while (0)
{
GPIOB->ODR = (1 << LED_PIN);
}
}

View File

@ -1,7 +0,0 @@
#ifndef _VVC_MAIN_H
#define _VVC_MAIN_H
#include <stdint.h>
#include "device/stm32f730xx.h"
// Define GPIOB pin mappings for our LED and button.
#define LED_PIN (3) // led on PC0
#endif

View File

@ -2,8 +2,9 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "device/stm32f730xx.h" #include "device/stm32f730xx.h"
#include "Laplace/led.h"
#define LED_PIN (4) // PC0 //#define LED_PIN (4) // PB0
typedef void (*cxx_constructor)(); typedef void (*cxx_constructor)();
@ -42,6 +43,7 @@ void* memset_custom(void* ptr, int value, size_t num_bytes) {
return ptr; return ptr;
} }
// This the first function when the os boot
void __attribute__((noinline)) start() { void __attribute__((noinline)) start() {
/* Copy data section to RAM /* Copy data section to RAM
* The data section is R/W but its initialization value matters. It's stored * The data section is R/W but its initialization value matters. It's stored
@ -56,19 +58,22 @@ void __attribute__((noinline)) start() {
size_t bssSectionLength = (&_bss_section_end_ram - &_bss_section_start_ram); size_t bssSectionLength = (&_bss_section_end_ram - &_bss_section_start_ram);
memset_custom(&_bss_section_start_ram, 0, bssSectionLength); memset_custom(&_bss_section_start_ram, 0, bssSectionLength);
// Enable the GPIOa and GPIOC peripheral in RCC. // Enable the GPIO peripheral in RCC.
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN ; RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN ;
led_init();
// C0 is connected to the LED. set_led_green(true);
set_led_red(true);
/*
// B0 is connected to the LED.
// It should be set to push-pull low-speed output. // It should be set to push-pull low-speed output.
GPIOB->MODER &= ~(0x3 << (LED_PIN*2)); GPIOB->MODER &= ~(0x3 << (LED_PIN*2));
GPIOB->MODER |= (0x1 << (LED_PIN*2)); GPIOB->MODER |= (0x1 << (LED_PIN*2));
GPIOB->OTYPER &= ~(1 << LED_PIN); GPIOB->OTYPER &= ~(1 << LED_PIN);
GPIOB->ODR = (1 << LED_PIN); GPIOB->ODR = (1 << LED_PIN);
*/
while (0) while (0)
{ {
GPIOB->ODR = (1 << LED_PIN); // code
} }
} }