commit 1b6f444f4aa61596880b8db0f4bfcf5ae53ceee1 Author: Wolfgang Hottgenroth Date: Wed Jun 12 23:15:34 2024 +0200 initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c63ce08 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.o +firmware.txt +firmware.elf +firmware.map + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3d6f7ff --- /dev/null +++ b/Makefile @@ -0,0 +1,35 @@ +TOOLCHAIN_PREFIX=/opt/msp430-gcc +CC=$(TOOLCHAIN_PREFIX)/bin/msp430-elf-gcc +OBJDUMP=$(TOOLCHAIN_PREFIX)/bin/msp430-elf-objdump + +ARTIFACT=firmware +MCU=msp430g2553 +DEBUGFLAGS= +DEBUGFLAGS+= -g3 -ggdb -gdwarf-2 +COMMONFLAGS=-Wall -mmcu=$(MCU) -I $(TOOLCHAIN_PREFIX)/include -O0 -g0 $(DEBUGFLAGS) +CFLAGS=$(COMMONFLAGS) -std=gnu99 +ASFLAGS=$(COMMONFLAGS) -D__ASSEMBLER__ + +LDFLAGS=-mmcu=$(MCU) -L $(TOOLCHAIN_PREFIX)/include + +$(ARTIFACT).elf: main.o scheduler.o + $(CC) -o $@ $(LDFLAGS) $^ + $(OBJDUMP) -D $(ARTIFACT).elf > $(ARTIFACT).txt + +.c.o: + $(CC) $(CFLAGS) -c $< + +.S.o: + $(CC) $(ASFLAGS) -c $< + + +.PHONY: all +all: $(ARTIFACT).elf + +.PHONY: clean +clean: + -rm -f *.o $(ARTIFACT).elf $(ARTIFACT).txt + +.PHONY: upload +upload: $(ARTIFACT).elf + mspdebug rf2500 "prog $(ARTIFACT).elf" diff --git a/firmware.gdb b/firmware.gdb new file mode 100644 index 0000000..6312fd6 --- /dev/null +++ b/firmware.gdb @@ -0,0 +1,2 @@ +target remote localhost:2000 +file firmware.elf diff --git a/main.c b/main.c new file mode 100644 index 0000000..62c52b6 --- /dev/null +++ b/main.c @@ -0,0 +1,29 @@ +#include +#include +#include + +#include "scheduler.h" + +int main() { + WDTCTL = WDTPW | WDTHOLD; + + __disable_interrupt(); + + // highest possible system clock + DCOCTL = DCO0 | DCO1 | DCO2; + BCSCTL1 = XT2OFF | RSEL0 | RSEL1 | RSEL2 | RSEL3; + BCSCTL2 = 0; + BCSCTL3 = 0; + + + schInit(); + + + + __enable_interrupt(); + + + while (1) { + schExec(); + } +} diff --git a/scheduler.c b/scheduler.c new file mode 100644 index 0000000..c10a1c7 --- /dev/null +++ b/scheduler.c @@ -0,0 +1,107 @@ +#include +#include +#include "scheduler.h" + +tTask tasks[MAX_NUM_OF_TASKS]; + + +uint32_t seconds; + +void schInit() { + TACCR0 = 19600; + TACCTL0 = CCIE; + TACTL = MC_1 | ID_0 | TASSEL_2 | TACLR; + + for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) { + tasks[i].delay = 0; + tasks[i].period = 0; + tasks[i].run = 0; + tasks[i].exec = NULL; + tasks[i].handle = NULL; + } + + seconds = 0; + + // LED + P2DIR |= BIT6; + P2OUT &= ~BIT6; + P2SEL &= ~BIT6; + P2SEL2 &= ~BIT6; +} + +void __attribute__ ((interrupt (TIMER0_A0_VECTOR))) schUpdate() { + static uint16_t milliSeconds = 0; + if (milliSeconds >= 1000) { + seconds += 1; + milliSeconds = 0; + P2OUT ^= BIT6; + } + milliSeconds += 1; + + for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) { + if (tasks[i].exec != NULL) { + if (tasks[i].delay == 0) { + tasks[i].delay = tasks[i].period; + tasks[i].run++; + } else { + tasks[i].delay--; + } + } + } +} + +uint16_t schAdd(void (*exec)(void *), void *handle, uint32_t delay, uint32_t period) { + uint16_t taskId = 0xffff; + for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) { + if (tasks[i].exec == NULL) { + tasks[i].delay = delay; + tasks[i].period = period; + if (delay == 0 && period == 0) { + tasks[i].run = 1; + } else { + tasks[i].run = 0; + } + tasks[i].exec = exec; + tasks[i].handle = handle; + taskId = i; + break; + } + } + return taskId; +} + +void schDel(uint16_t taskId) { + tasks[taskId].exec = NULL; +} + +void schExec() { + for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) { + // synchronize access to tasks[].run + __disable_interrupt(); + if (tasks[i].exec != NULL && tasks[i].run > 0) { + tasks[i].run--; + // synchronize access to tasks[].run + // reenable interrupts before actually executing task + __enable_interrupt(); + tasks[i].exec(tasks[i].handle); + if (tasks[i].period == 0) { + tasks[i].exec = NULL; + } + } else { + // synchronize access to tasks[].run + // reenable interrupts in case task is not yet executable + __enable_interrupt(); + } + } +} + +uint32_t getSeconds() { + uint32_t s; + + __disable_interrupt(); + s = seconds; + __enable_interrupt(); + + return s; +} + diff --git a/scheduler.h b/scheduler.h new file mode 100644 index 0000000..485a567 --- /dev/null +++ b/scheduler.h @@ -0,0 +1,27 @@ +#ifndef PONTCOOPSCHEDULER_H_ +#define PONTCOOPSCHEDULER_H_ + + +#include + + + +#define MAX_NUM_OF_TASKS 4 + + +typedef struct { + uint16_t delay; + uint16_t period; + uint8_t run; + void (*exec)(void *handle); + void *handle; +} tTask; + + +void schInit(); +uint16_t schAdd(void (*exec)(void *), void *handle, uint32_t delay, uint32_t period); +void schDel(uint16_t taskId); +void schExec(); + + +#endif /* PONTCOOPSCHEDULER_H_ */