This commit is contained in:
Wolfgang Hottgenroth 2024-03-07 15:51:44 +01:00
commit 68bb67e9af
11 changed files with 349 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.o
firmware.*

31
Makefile Normal file
View File

@ -0,0 +1,31 @@
TOOLCHAIN_PREFIX=/opt/msp430-gcc
CC=$(TOOLCHAIN_PREFIX)/bin/msp430-elf-gcc
OBJDUMP=$(TOOLCHAIN_PREFIX)/bin/msp430-elf-objdump
ARTIFACT=firmware
MCU=msp430g2553
CFLAGS=-Wall -mmcu=$(MCU) -std=gnu99 -I $(TOOLCHAIN_PREFIX)/include -O3 -g0
# for debugging
#CFLAGS=-Wall -mmcu=$(MCU) -std=gnu99 -I $(TOOLCHAIN_PREFIX)/include -g3 -ggdb -gdwarf-2
LDFLAGS=-mmcu=$(MCU) -L $(TOOLCHAIN_PREFIX)/include
$(ARTIFACT).elf: main.o led.o time.o PontCoopScheduler.o spi.o
$(CC) -o $@ $(LDFLAGS) $^
$(OBJDUMP) -D $(ARTIFACT).elf > $(ARTIFACT).txt
.c.o:
$(CC) $(CFLAGS) -c $<
.PHONY: all
all: $(ARTIFACT).elf
.PHONY: clean
clean:
-rm -f *.o *.elf
.PHONY: upload
upload: $(ARTIFACT).elf
mspdebug rf2500 "prog $(ARTIFACT).elf"

88
PontCoopScheduler.c Normal file
View File

@ -0,0 +1,88 @@
/*
* PontCoopScheduler.c
*
* Created on: 29.08.2016
* Author: wn
*/
#include <stdlib.h>
#include "PontCoopScheduler.h"
tTask tasks[MAX_NUM_OF_TASKS];
void schInit() {
for (uint8_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;
}
}
void schAdd(void (*exec)(void *), void *handle, uint32_t delay, uint32_t period) {
for (uint8_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;
break;
}
}
}
void schDel(void (*exec)(void *), void *handle) {
for (uint8_t i = 0; i < MAX_NUM_OF_TASKS; i++) {
if ((tasks[i].exec == exec) && (tasks[i].handle == handle)) {
tasks[i].exec = NULL;
break;
}
}
}
void schExec() {
for (uint8_t i = 0; i < MAX_NUM_OF_TASKS; i++) {
if (tasks[i].exec != NULL && tasks[i].run > 0) {
tasks[i].run--;
tasks[i].exec(tasks[i].handle);
if (tasks[i].period == 0) {
tasks[i].exec = NULL;
}
}
}
}
void schUpdate() {
for (uint8_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--;
}
}
}
}
uint8_t schTaskCnt() {
uint8_t cnt = 0;
for (uint8_t i = 0; i < MAX_NUM_OF_TASKS; i++) {
if (tasks[i].exec != NULL){
cnt++;
}
}
return cnt;
}

36
PontCoopScheduler.h Normal file
View File

@ -0,0 +1,36 @@
/*
* PontCoopScheduler.h
*
* Created on: 29.08.2016
* Author: wn
*/
#ifndef PONTCOOPSCHEDULER_H_
#define PONTCOOPSCHEDULER_H_
#include <stdint.h>
#define MAX_NUM_OF_TASKS 32
typedef struct {
uint32_t delay;
uint32_t period;
uint8_t run;
void (*exec)(void *handle);
void *handle;
} tTask;
void schInit();
void schAdd(void (*exec)(void *), void *handle, uint32_t delay, uint32_t period);
void schDel(void (*exec)(void *), void *handle);
void schExec();
void schUpdate();
uint8_t schTaskCnt();
#endif /* PONTCOOPSCHEDULER_H_ */

46
led.c Normal file
View File

@ -0,0 +1,46 @@
#include "led.h"
#include <msp430g2553.h>
#include "PontCoopScheduler.h"
#include <stdlib.h>
void ledGreenOn() {
P1OUT |= BIT0;
}
void ledGreenOff() {
P1OUT &= ~BIT0;
}
void ledBlueOn() {
P1OUT |= BIT1;
}
void ledBlueOff() {
P1OUT &= ~BIT1;
}
void ledExec() {
static int i = 0;
if (i == 0) {
ledGreenOff();
ledBlueOn();
i = 1;
} else {
ledGreenOn();
ledBlueOff();
i = 0;
}
}
void ledInit() {
// BIT0: green
// BIT1: blue
P1DIR |= BIT0|BIT1;
P1OUT |= BIT0|BIT1;
schAdd(ledExec, NULL, 0, 50);
}

13
led.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef LED_H_
#define LED_H_
void ledBlueOff();
void ledBlueOn();
void ledGreenOff();
void ledGreenOn();
void ledInit();
void ledExec();
#endif /* LED_H_ */

36
main.c Normal file
View File

@ -0,0 +1,36 @@
#include <msp430g2553.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include "time.h"
#include "PontCoopScheduler.h"
#include "led.h"
#include "spi.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;
timeInit();
schInit();
ledInit();
spiInit();
__enable_interrupt();
while (1) {
schExec();
}
}

45
spi.c Normal file
View File

@ -0,0 +1,45 @@
#include "spi.h"
#include <msp430g2553.h>
#include "PontCoopScheduler.h"
#include <stdlib.h>
#include <stdint.h>
static void spiSendOctet(uint8_t v) {
while (!(UC0IFG & UCB0TXIFG));
UCB0TXBUF = v;
}
void spiExec() {
// enable spi
UCB0CTL1 &= ~UCSWRST;
spiSendOctet(0x00);
spiSendOctet(0x0d);
// disable spi
UCB0CTL1 |= UCSWRST;
// reschedule
schAdd(spiExec, NULL, 1000, 0);
}
void spiInit() {
UCB0CTL0 = UCMST | UCSYNC;
UCB0CTL1 = UCSSEL_3;
UCB0BR0 = 8;
UCB0BR1 = 0;
// UCB0CLK, UCB0SOMI, UCB0SIMO
P1SEL |= BIT5 | BIT6 | BIT7;
P1SEL2 |= BIT5 | BIT6 | BIT7;
P1OUT |= BIT5 | BIT7;
// P1.3 is signal line
P1DIR &= ~BIT3;
schAdd(spiExec, NULL, 1000, 0);
}

9
spi.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef _SPI_H_
#define _SPI_H_
void spiInit();
void spiExec();
#endif // _SPI_H_

30
time.c Normal file
View File

@ -0,0 +1,30 @@
#include <msp430g2553.h>
#include <stdint.h>
#include "time.h"
#include "PontCoopScheduler.h"
volatile uint32_t timestamp;
void __attribute__ ((interrupt (TIMER0_A0_VECTOR))) ta0_isr() {
timestamp++;
schUpdate();
}
void timeInit() {
timestamp = 0;
TACCR0 = 32;
TACCTL0 = CCIE;
TACTL = MC_1 | ID_0 | TASSEL_1 | TACLR;
}
uint32_t getMillis() {
return timestamp;
}
void ms_active_delay(uint16_t delay) {
uint32_t start = timestamp;
while (start + delay > timestamp);
}

12
time.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef TIME_H_
#define TIME_H_
#include <stdint.h>
void timeInit();
uint32_t getMillis();
void ms_active_delay(uint16_t delay);
#endif /* TIME_H_ */