diff --git a/scheduler/Makefile b/scheduler/Makefile new file mode 100755 index 0000000000000000000000000000000000000000..1b1fc47ac978ad8ebbcb4cd4ce4c56a4ab5c2123 --- /dev/null +++ b/scheduler/Makefile @@ -0,0 +1,89 @@ +# setup +# modified by zerom for WinARM 8/2010 + +COMPILE_OPTS = -mlittle-endian -mthumb -mthumb-interwork +COMPILE_OPTS += -Wall -O2 -fno-common +#COMPILE_OPTS += -Wall -g -fno-common +COMPILE_OPTS += -ffreestanding -nostdlib + +COMPILE_OPTS_M4_FPU = -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mcpu=cortex-m4 +COMPILE_OPTS_M0 = -mfloat-abi=softfp -mcpu=cortex-m0 +COMPILE_OPTS_M0plus = -mfloat-abi=softfp -mcpu=cortex-m0plus +COMPILE_OPTS_M3 = -mfloat-abi=softfp -mcpu=cortex-m3 + +INCLUDE_DIRS = -I./include/ -I../utils/include + +DOC_DIR = ./doc + +TCHAIN_PREFIX=arm-none-eabi- + +CC = $(TCHAIN_PREFIX)gcc +CFLAGS = $(COMPILE_OPTS) $(INCLUDE_DIRS) + +AR = $(TCHAIN_PREFIX)ar +ARFLAGS = cr + +SCHEDULER_OUT_M4_FPU = ./lib/scheduler_m4_fpu.a +SCHEDULER_OUT_M0 = ./lib/scheduler_m0.a +SCHEDULER_OUT_M0plus = ./lib/scheduler_m0plus.a +SCHEDULER_OUT_M3 = ./lib/scheduler_m3.a + +SRC_DIR=./src/ +SRC=$(wildcard $(SRC_DIR)*.c) + +SCHEDULER_M4_FPU_OBJ_DIR=build/m4_fpu/ +SCHEDULER_M4_FPU_OBJS_TMP = $(notdir $(SRC:.c=.o)) +SCHEDULER_M4_FPU_OBJS = $(patsubst %,$(SCHEDULER_M4_FPU_OBJ_DIR)%,$(SCHEDULER_M4_FPU_OBJS_TMP)) + +SCHEDULER_M0_OBJ_DIR=build/m0/ +SCHEDULER_M0_OBJS_TMP = $(notdir $(SRC:.c=.o)) +SCHEDULER_M0_OBJS = $(patsubst %,$(SCHEDULER_M0_OBJ_DIR)%,$(SCHEDULER_M0_OBJS_TMP)) + +SCHEDULER_M0plus_OBJ_DIR=build/m0plus/ +SCHEDULER_M0plus_OBJS_TMP = $(notdir $(SRC:.c=.o)) +SCHEDULER_M0plus_OBJS = $(patsubst %,$(SCHEDULER_M0plus_OBJ_DIR)%,$(SCHEDULER_M0plus_OBJS_TMP)) + +SCHEDULER_M3_OBJ_DIR=build/m3/ +SCHEDULER_M3_OBJS_TMP = $(notdir $(SRC:.c=.o)) +SCHEDULER_M3_OBJS = $(patsubst %,$(SCHEDULER_M3_OBJ_DIR)%,$(SCHEDULER_M3_OBJS_TMP)) + +all: $(SCHEDULER_OUT_M4_FPU) $(SCHEDULER_OUT_M0) $(SCHEDULER_OUT_M0plus) $(SCHEDULER_OUT_M3) +$(SCHEDULER_M4_FPU_OBJ_DIR)%.o: $(SRC_DIR)%.c + $(CC) -c $(CFLAGS) $(COMPILE_OPTS_M4_FPU) -o $@ $< +$(SCHEDULER_M0_OBJ_DIR)%.o: $(SRC_DIR)%.c + $(CC) -c $(CFLAGS) $(COMPILE_OPTS_M0) -o $@ $< +$(SCHEDULER_M0plus_OBJ_DIR)%.o: $(SRC_DIR)%.c + $(CC) -c $(CFLAGS) $(COMPILE_OPTS_M0plus) -o $@ $< +$(SCHEDULER_M3_OBJ_DIR)%.o: $(SRC_DIR)%.c + $(CC) -c $(CFLAGS) $(COMPILE_OPTS_M3) -o $@ $< +mkdir_build: + mkdir -p build/m4_fpu + mkdir -p build/m0 + mkdir -p build/m0plus + mkdir -p build/m3 +$(SCHEDULER_OUT_M4_FPU): mkdir_build $(SCHEDULER_M4_FPU_OBJS) + mkdir -p lib + $(AR) $(ARFLAGS) $@ $(SCHEDULER_M4_FPU_OBJS) +$(SCHEDULER_OUT_M0): mkdir_build $(SCHEDULER_M0_OBJS) + mkdir -p lib + $(AR) $(ARFLAGS) $@ $(SCHEDULER_M0_OBJS) +$(SCHEDULER_OUT_M0plus): mkdir_build $(SCHEDULER_M0plus_OBJS) + mkdir -p lib + $(AR) $(ARFLAGS) $@ $(SCHEDULER_M0plus_OBJS) +$(SCHEDULER_OUT_M3): mkdir_build $(SCHEDULER_M3_OBJS) + mkdir -p lib + $(AR) $(ARFLAGS) $@ $(SCHEDULER_M3_OBJS) + +doc: + doxygen $(DOC_DIR)/doxygen.conf + +clean: + rm -f $(SCHEDULER_M4_FPU_OBJS) + rm -f $(SCHEDULER_M0_OBJS) + rm -f $(SCHEDULER_M0plus_OBJS) + rm -f $(SCHEDULER_M3_OBJS) + rm -rf lib + rm -rf build + rm -rf doc/html + +.PHONY: all clean doc diff --git a/scheduler/include/scheduler.h b/scheduler/include/scheduler.h new file mode 100644 index 0000000000000000000000000000000000000000..cdbdae51afea7b792d61cded39081c118bf8bcbe --- /dev/null +++ b/scheduler/include/scheduler.h @@ -0,0 +1,51 @@ +#ifndef _SCHEDULER_H +#define _SCHEDULER_H + +#ifndef SCHEDULER_MAX_CHANNELS + #define SCHEDULER_MAX_CHANNELS 4 +#endif + +#ifndef TIM_CHANNEL_1 + #define TIM_CHANNEL_1 0x00000000U +#endif + +#ifndef TIM_CHANNEL_2 + #define TIM_CHANNEL_2 0x00000004U +#endif + +#ifndef TIM_CHANNEL_3 + #define TIM_CHANNEL_3 0x00000008U +#endif + +#ifndef TIM_CHANNEL_4 + #define TIM_CHANNEL_4 0x0000000CU +#endif + +typedef enum {SCHED_CH1=0,SCHED_CH2=1,SCHED_CH3=2,SCHED_CH4=3} sched_channel_t; + +typedef struct{ + void (*function)(void); + unsigned char period_ms; + unsigned int pulse; + unsigned char enabled; +}TSchedulerChannel; + +typedef struct{ + TSchedulerChannel channels[SCHEDULER_MAX_CHANNELS]; + unsigned char num_channels; + unsigned short int prescaler; + void (* start)(sched_channel_t); + void (* stop)(sched_channel_t); + void (* set_pulse)(sched_channel_t,unsigned short,unsigned char); +}TScheduler; + +void scheduler_init(TScheduler *scheduler,unsigned char num_channels, unsigned short int prescaler); +void scheduler_interrupt(TScheduler *scheduler,sched_channel_t channel_id); +unsigned short int scheduler_get_pulse(TScheduler *scheduler, sched_channel_t channel_id); +void scheduler_set_channel(TScheduler *scheduler,sched_channel_t channel_id, void (*function)(void), unsigned char period_ms); +void scheduler_enable_channel(TScheduler *scheduler,sched_channel_t channel_id); +void scheduler_change_period(TScheduler *scheduler,sched_channel_t channel_id,unsigned char period_ms); +void scheduler_disable_channel(TScheduler *scheduler,sched_channel_t channel_id); + +#endif + diff --git a/scheduler/src/scheduler.c b/scheduler/src/scheduler.c new file mode 100644 index 0000000000000000000000000000000000000000..a9bfd0d96ffad632eaadb31c5a7c718492d46b80 --- /dev/null +++ b/scheduler/src/scheduler.c @@ -0,0 +1,100 @@ +#include "scheduler.h" + +extern unsigned int SystemCoreClock; + +/* private functions */ +unsigned short int scheduler_ms_to_pulse(TScheduler *scheduler,unsigned char period_ms) +{ + return (SystemCoreClock/(scheduler->prescaler*1000))*period_ms; +} + +unsigned int scheduler_get_channel(sched_channel_t channel_id) +{ + switch(channel_id) + { + case SCHED_CH1: return TIM_CHANNEL_1; + case SCHED_CH2: return TIM_CHANNEL_2; + case SCHED_CH3: return TIM_CHANNEL_3; + case SCHED_CH4: return TIM_CHANNEL_4; + default: return TIM_CHANNEL_1; + } +} + +void scheduler_init(TScheduler *scheduler,unsigned char num_channels, unsigned short int prescaler) +{ + unsigned char i=0; + + for(i=0;i<SCHEDULER_MAX_CHANNELS;i++) + { + scheduler->channels[i].function=0x00000000; + scheduler->channels[i].period_ms=0; + scheduler->channels[i].enabled=0x00; + } + scheduler->num_channels=num_channels; + scheduler->prescaler=prescaler; + scheduler->stop=0x00000000; + scheduler->start=0x00000000; + scheduler->set_pulse=0x00000000; +} + +void scheduler_interrupt(TScheduler *scheduler,sched_channel_t channel_id) +{ + if(channel_id<scheduler->num_channels) + { + if(scheduler->set_pulse!=0x00000000) + scheduler->set_pulse(channel_id,scheduler->channels[channel_id].pulse,0x01); + if(scheduler->channels[channel_id].function!=0x00000000) + scheduler->channels[channel_id].function(); + } +} + +void scheduler_set_channel(TScheduler *scheduler,sched_channel_t channel_id, void (*function)(void), unsigned char period_ms) +{ + if(channel_id<scheduler->num_channels) + { + if(scheduler->channels[channel_id].enabled==0x01) + { + if(scheduler->stop!=0x00000000) + scheduler->stop(channel_id); + scheduler->channels[channel_id].enabled=0x00; + } + scheduler->channels[channel_id].function=function; + scheduler->channels[channel_id].period_ms=period_ms; + scheduler->channels[channel_id].pulse=scheduler_ms_to_pulse(scheduler,period_ms); + } +} + +void scheduler_enable_channel(TScheduler *scheduler,sched_channel_t channel_id) +{ + if(channel_id<scheduler->num_channels) + { + if(scheduler->channels[channel_id].enabled==0x00) + { + if(scheduler->set_pulse!=0x00000000) + scheduler->set_pulse(channel_id,scheduler->channels[channel_id].pulse,0x00); + if(scheduler->start!=0x00000000) + scheduler->start(channel_id); + scheduler->channels[channel_id].enabled=0x01; + } + } +} + +void scheduler_change_period(TScheduler *scheduler,sched_channel_t channel_id,unsigned char period_ms) +{ + if(channel_id<scheduler->num_channels) + scheduler->channels[channel_id].period_ms=period_ms; +} + +void scheduler_disable_channel(TScheduler *scheduler,sched_channel_t channel_id) +{ + if(channel_id<scheduler->num_channels) + { + if(scheduler->channels[channel_id].enabled==0x01) + { + if(scheduler->stop!=0x00000000) + scheduler->stop(channel_id); + scheduler->channels[channel_id].enabled=0x0; + } + } +} +