scheduler added, tuned for 1ms

This commit is contained in:
Wolfgang Hottgenroth 2024-03-26 10:44:23 +01:00
parent d8e34ec209
commit 48c83f0b2d
5 changed files with 133 additions and 29 deletions

View File

@ -7,11 +7,11 @@ MCU=msp430g2553
CFLAGS=-Wall -mmcu=$(MCU) -std=gnu99 -I $(TOOLCHAIN_PREFIX)/include -O1 -g0 CFLAGS=-Wall -mmcu=$(MCU) -std=gnu99 -I $(TOOLCHAIN_PREFIX)/include -O1 -g0
# for debugging # for debugging
#CFLAGS+= -g3 -ggdb -gdwarf-2 CFLAGS+= -g3 -ggdb -gdwarf-2
LDFLAGS=-mmcu=$(MCU) -L $(TOOLCHAIN_PREFIX)/include LDFLAGS=-mmcu=$(MCU) -L $(TOOLCHAIN_PREFIX)/include
$(ARTIFACT).elf: main.o $(ARTIFACT).elf: main.o scheduler.o
$(CC) -o $@ $(LDFLAGS) $^ $(CC) -o $@ $(LDFLAGS) $^
$(OBJDUMP) -D $(ARTIFACT).elf > $(ARTIFACT).txt $(OBJDUMP) -D $(ARTIFACT).elf > $(ARTIFACT).txt

View File

@ -0,0 +1,2 @@
target remote localhost:2000
file firmware.elf

View File

@ -2,12 +2,14 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "notes.h"
#include "scheduler.h"
#define ADDR_DATA_REG P2OUT #define ADDR_DATA_REG P2OUT
#define BUS_CTRL_REG P1OUT #define BUS_CTRL_REG P1OUT
#define BC1 BIT0 #define BC1 BIT3
#define BDIR BIT1 #define BDIR BIT1
#define _CS BIT3
#define R0 0 #define R0 0
#define R1 1 #define R1 1
@ -24,12 +26,6 @@
#define R14 014 #define R14 014
#define R15 015 #define R15 015
inline static void BUS_OP_ENABLE_CS() {
BUS_CTRL_REG &= ~_CS;
}
inline static void BUS_OP_DISABLE_CS() {
BUS_CTRL_REG |= _CS;
}
inline static void BUS_OP_NACT() { inline static void BUS_OP_NACT() {
BUS_CTRL_REG &= ~(BDIR | BC1); BUS_CTRL_REG &= ~(BDIR | BC1);
} }
@ -62,9 +58,6 @@ asm volatile (
static void writePSG(uint8_t address, uint8_t data) { static void writePSG(uint8_t address, uint8_t data) {
// according to "State Timing" (p. 15) of datasheet // according to "State Timing" (p. 15) of datasheet
// select chip
//BUS_OP_ENABLE_CS();
// put bus into inactive state // put bus into inactive state
BUS_OP_NACT(); BUS_OP_NACT();
@ -85,16 +78,11 @@ static void writePSG(uint8_t address, uint8_t data) {
// set inactive again // set inactive again
BUS_OP_NACT(); BUS_OP_NACT();
// deselect chip
//BUS_OP_DISABLE_CS();
} }
static void writeFrequency(uint8_t channel, uint16_t frequencyCode) { static void writeFrequency(uint8_t channel, uint16_t frequencyCode) {
uint8_t fine = frequencyCode & 0x00ff; writePSG(R0 + (channel * 2), (frequencyCode & 0x00ff));
uint8_t coarse = (frequencyCode >> 8) & 0x000f; writePSG(R1 + (channel * 2), ((frequencyCode >> 8) & 0x000f));
writePSG(R0 + (channel * 2), fine);
writePSG(R1 + (channel * 2), coarse);
} }
int main() { int main() {
@ -137,14 +125,12 @@ int main() {
delay(); delay();
// bus control lines // bus control lines
// BIT0: BC1 // BIT3: BC1
// BIT1: BDIR // BIT1: BDIR
// BIT3: /CS P1DIR |= BIT1 | BIT3;
P1DIR |= BIT0 | BIT1 | BIT3;
// put bus into inactive state // put bus into inactive state
BUS_CTRL_REG &= ~(BDIR | BC1); BUS_CTRL_REG &= ~(BDIR | BC1);
BUS_CTRL_REG |= _CS;
// release sound chip from reset state // release sound chip from reset state
P1OUT |= BIT2; P1OUT |= BIT2;
@ -153,11 +139,12 @@ int main() {
delay(); delay();
schInit();
__enable_interrupt(); __enable_interrupt();
BUS_OP_ENABLE_CS();
/* /*
// single tone // single tone
@ -191,9 +178,9 @@ int main() {
/* /*
// Akkord // Akkord
writeFrequency(0, 01527); writeFrequency(0, C5);
writeFrequency(1, 01247); writeFrequency(1, E5);
writeFrequency(2, 01073); writeFrequency(2, G5);
writePSG(R7, 0b11111000); writePSG(R7, 0b11111000);
writePSG(R10, 03); writePSG(R10, 03);
writePSG(R11, 03); writePSG(R11, 03);
@ -201,9 +188,9 @@ int main() {
*/ */
BUS_OP_DISABLE_CS();
while (1) { while (1) {
schExec();
} }
} }

86
sound-driver/scheduler.c Normal file
View File

@ -0,0 +1,86 @@
#include <stdlib.h>
#include <msp430g2553.h>
#include "scheduler.h"
tTask tasks[MAX_NUM_OF_TASKS];
void schInit() {
P1DIR |= BIT0;
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;
}
}
void __attribute__ ((interrupt (TIMER0_A0_VECTOR))) schUpdate() {
P1OUT ^= BIT0;
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--;
}
}
}
}
void schAdd(void (*exec)(void *), void *handle, uint32_t delay, uint32_t period) {
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;
break;
}
}
}
/*
void schDel(void (*exec)(void *), void *handle) {
for (uint16_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 (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();
}
}
}

29
sound-driver/scheduler.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef PONTCOOPSCHEDULER_H_
#define PONTCOOPSCHEDULER_H_
#include <stdint.h>
#define MAX_NUM_OF_TASKS 2
typedef struct {
uint16_t delay;
uint16_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_ */