diff --git a/.gitignore b/.gitignore index d623bdce..5b1d0418 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ Debug /tools/JavaConfigurator/dist/ /nbproject/private/ /Result.log +experimental settings/*-*.ini diff --git a/ACAcontrollerState.c b/ACAcontrollerState.c index 68789168..abb6bc3e 100644 --- a/ACAcontrollerState.c +++ b/ACAcontrollerState.c @@ -86,18 +86,13 @@ uint16_t ui16_x4_value = 0; uint16_t ui16_throttle_cal_b = 0; uint16_t ui16_battery_current_max_value = 0; uint16_t ui16_regen_current_max_value = 0; -uint8_t ui8_possible_motor_state = 0; -uint8_t ui8_dynamic_motor_state = 0; uint8_t ui8_BatteryVoltage = 0; //Battery Voltage read from ADC uint8_t ui8_battery_voltage_nominal =0; uint16_t ui16_motor_speed_erps = 0; uint32_t ui32_erps_filtered = 0; //filtered value of erps uint16_t ui16_virtual_erps_speed = 0; uint16_t ui16_BatteryCurrent = 0; //Battery Current read from ADC8 -uint8_t ui8_position_correction_value = 127; // in 360/256 degrees uint8_t ui8_correction_at_angle = 127; -uint16_t ui16_ADC_iq_current = 0; -uint16_t ui16_ADC_iq_current_filtered = 0; uint16_t ui16_control_state = 0; uint8_t ui8_uptime = 0; @@ -107,8 +102,6 @@ uint8_t ui8_variableDebugC = 0; int8_t i8_motor_temperature = 0; -uint8_t uint8_t_60deg_pwm_cycles[6]; -uint8_t uint8_t_hall_case[7]; uint8_t uint8_t_hall_order[6]; int8_t int8_t_hall_counter = 0; uint8_t ui8_hall_order_counter = 5; diff --git a/ACAcontrollerState.h b/ACAcontrollerState.h index 9fc0b082..e2270331 100644 --- a/ACAcontrollerState.h +++ b/ACAcontrollerState.h @@ -54,18 +54,13 @@ extern uint16_t ui16_x4_value; extern uint16_t ui16_throttle_cal_b; extern uint16_t ui16_battery_current_max_value; extern uint16_t ui16_regen_current_max_value; -extern uint8_t ui8_possible_motor_state; -extern uint8_t ui8_dynamic_motor_state; extern uint8_t ui8_BatteryVoltage; extern uint8_t ui8_battery_voltage_nominal; extern uint16_t ui16_motor_speed_erps; extern uint16_t ui16_virtual_erps_speed; extern uint32_t ui32_erps_filtered; //filtered value of erps extern uint16_t ui16_BatteryCurrent; -extern uint8_t ui8_position_correction_value; extern uint8_t ui8_correction_at_angle; -extern uint16_t ui16_ADC_iq_current; -extern uint16_t ui16_ADC_iq_current_filtered; extern uint8_t ui8_speedlimit_kph; extern uint8_t ui8_speedlimit_without_pas_kph; extern uint8_t ui8_speedlimit_actual_kph; @@ -79,8 +74,6 @@ extern uint8_t ui8_variableDebugC; extern int8_t i8_motor_temperature; -extern uint8_t uint8_t_60deg_pwm_cycles[6]; -extern uint8_t uint8_t_hall_case[7]; extern uint8_t uint8_t_hall_order[6]; extern int8_t int8_t_hall_counter; extern uint8_t ui8_hall_debug_counter; diff --git a/Makefile_windows b/Makefile similarity index 77% rename from Makefile_windows rename to Makefile index b4979787..84df032e 100644 --- a/Makefile_windows +++ b/Makefile @@ -1,110 +1,101 @@ -#Makefile for STM8 Examples with SDCC compiler -#Author: Saeid Yazdani -#Website: WWW.EMBEDONIX.COM -#Copyright 2016 -#LICENSE: GNU-LGPL - -.PHONY: all clean - -#Compiler -CC = sdcc -OBJCOPY = stm8-objcopy -SIZE = stm8-size - -#Platform -PLATFORM = stm8 - -#Product name -PNAME = main - -#Directory for helpers -IDIR = StdPeriphLib/inc -SDIR = StdPeriphLib/src - -# In case you ever want a different name for the main source file -MAINSRC = $(PNAME).c - -ELF_SECTIONS_TO_REMOVE = -R DATA -R INITIALIZED -R SSEG -R .debug_line -R .debug_loc -R .debug_abbrev -R .debug_info -R .debug_pubnames -R .debug_frame - -# These are the sources that must be compiled to .rel files: -EXTRASRCS = \ - $(SDIR)/stm8s_itc.c \ - $(SDIR)/stm8s_clk.c \ - $(SDIR)/stm8s_iwdg.c \ - $(SDIR)/stm8s_gpio.c \ - $(SDIR)/stm8s_exti.c \ - $(SDIR)/stm8s_uart2.c \ - $(SDIR)/stm8s_tim1.c \ - $(SDIR)/stm8s_tim2.c \ - $(SDIR)/stm8s_adc1.c \ - $(SDIR)/stm8s_flash.c \ - BOdisplay.c \ - ACAcontrollerState.c \ - ACAeeprom.c \ - ACAsetPoint.c \ - ACAcommons.c \ - gpio.c \ - cruise_control.c \ - uart.c \ - adc.c \ - brake.c \ - timers.c \ - pwm.c \ - motor.c \ - PAS.c \ - SPEED.c \ - display.c \ - display_kingmeter.c - -HEADERS = BOdisplay.h ACAcommons.h ACAsetPoint.h ACAcontrollerState.h ACAeeprom.h adc.h brake.h cruise_control.h gpio.h interrupts.h main.h motor.h pwm.h timers.h uart.h PAS.h SPEED.h - -# The list of .rel files can be derived from the list of their source files -RELS = $(EXTRASRCS:.c=.rel) - -INCLUDES = -I$(IDIR) -I. -CFLAGS = -m$(PLATFORM) --std-c99 --nolospre -ELF_FLAGS = --out-fmt-ihx --debug -LIBS = -# This just provides the conventional target name "all"; it is optional -# Note: I assume you set PNAME via some means not exhibited in your original file -all: $(PNAME) - -# How to build the overall program - -$(PNAME): $(MAINSRC) $(RELS) - $(CC) $(INCLUDES) $(CFLAGS) $(ELF_FLAGS) $(LIBS) $(MAINSRC) $(RELS) -# $(SIZE) $(PNAME).elf -# $(OBJCOPY) -O binary $(ELF_SECTIONS_TO_REMOVE) -# $(PNAME).elf $(PNAME).bin - -# How to build any .rel file from its corresponding .c file -# GNU would have you use a pattern rule for this, but that's GNU-specific -%.rel: %.c $(HEADERS) - $(CC) -c $(INCLUDES) $(CFLAGS) $(ELF_FLAGS) $(LIBS) -o$< $< - -# Suffixes appearing in suffix rules we care about. -# Necessary because .rel is not one of the standard suffixes. -.SUFFIXES: .c .rel - -# hex: -# $(OBJCOPY) -O ihex $(ELF_SECTIONS_TO_REMOVE) $(PNAME).elf -# $(PNAME).ihx - -# flash: -# stm8flash -cstlinkv2 -pstm8s105?6 -w$(PNAME).ihx - -ENTF = cmd /C del - -clean: - echo "Cleaning files..." - $(ENTF) *.asm - $(ENTF) *.rel - $(ENTF) *.lk - $(ENTF) *.lst - $(ENTF) *.rst - $(ENTF) *.sym - $(ENTF) *.cdb - $(ENTF) *.map - $(ENTF) *.adb - echo "Done." - +#Original Makefile template from Saeid Yazdani (c) 2016 +#LICENSE: GNU-LGPL + +.PHONY: all clean + +#Compiler +CC = sdcc + +#Platform +PLATFORM = stm8 + +#Product name +PNAME = main + +#Directory for helpers +IDIR = StdPeriphLib/inc +SDIR = StdPeriphLib/src + +# In case you ever want a different name for the main source file +MAINSRC = $(PNAME).c + +# These are the sources that must be compiled to .rel files: +EXTRASRCS = \ + $(SDIR)/stm8s_itc.c \ + $(SDIR)/stm8s_clk.c \ + $(SDIR)/stm8s_iwdg.c \ + $(SDIR)/stm8s_gpio.c \ + $(SDIR)/stm8s_exti.c \ + $(SDIR)/stm8s_uart2.c \ + $(SDIR)/stm8s_tim1.c \ + $(SDIR)/stm8s_tim2.c \ + $(SDIR)/stm8s_adc1.c \ + $(SDIR)/stm8s_flash.c \ + BOdisplay.c \ + ACAcontrollerState.c \ + ACAeeprom.c \ + ACAsetPoint.c \ + ACAcommons.c \ + gpio.c \ + cruise_control.c \ + uart.c \ + adc.c \ + brake.c \ + timers.c \ + pwm.c \ + motor.c \ + PAS.c \ + SPEED.c \ + display.c \ + display_kingmeter.c + +HEADERS = BOdisplay.h ACAcommons.h ACAsetPoint.h ACAcontrollerState.h ACAeeprom.h adc.h brake.h cruise_control.h gpio.h interrupts.h main.h motor.h pwm.h timers.h uart.h PAS.h SPEED.h + +# The list of .rel files can be derived from the list of their source files +RELS = $(EXTRASRCS:.c=.rel) + +INCLUDES = -I$(IDIR) -I. +CFLAGS = -m$(PLATFORM) --std-c99 --nolospre +ELF_FLAGS = --out-fmt-ihx --debug +LIBS = +# This just provides the conventional target name "all"; it is optional +# Note: I assume you set PNAME via some means not exhibited in your original file +all: $(PNAME) + +# How to build the overall program + +$(PNAME): $(MAINSRC) $(RELS) + $(CC) $(INCLUDES) $(CFLAGS) $(ELF_FLAGS) $(LIBS) $(MAINSRC) $(RELS) + +# How to build any .rel file from its corresponding .c file +# GNU would have you use a pattern rule for this, but that's GNU-specific +%.rel: %.c $(HEADERS) + $(CC) -c $(INCLUDES) $(CFLAGS) $(ELF_FLAGS) $(LIBS) -o$< $< + +# Suffixes appearing in suffix rules we care about. +# Necessary because .rel is not one of the standard suffixes. +.SUFFIXES: .c .rel + + +flash: + stm8flash -cstlinkv2 -pstm8s105?6 -w$(PNAME).ihx + + +ifeq ($(OS),Windows_NT) +ENTF = cmd /C del +else +ENTF = rm -f +endif + +clean: + echo "Cleaning files..." + $(ENTF) *.asm + $(ENTF) *.rel + $(ENTF) *.lk + $(ENTF) *.lst + $(ENTF) *.rst + $(ENTF) *.sym + $(ENTF) *.cdb + $(ENTF) *.map + $(ENTF) *.adb + echo "Done." diff --git a/Makefile_linux b/Makefile_linux deleted file mode 100644 index 8eaa2f01..00000000 --- a/Makefile_linux +++ /dev/null @@ -1,124 +0,0 @@ -#Makefile for STM8 Examples with SDCC compiler -#Author: Saeid Yazdani -#Website: WWW.EMBEDONIX.COM -#Copyright 2016 -#LICENSE: GNU-LGPL - -.PHONY: all clean - -#Compiler -CC = sdcc -OBJCOPY = stm8-objcopy -SIZE = stm8-size - -#Platform -PLATFORM = stm8 - -#Product name -PNAME = main - -#Directory for helpers -IDIR = StdPeriphLib/inc -SDIR = StdPeriphLib/src - -# In case you ever want a different name for the main source file -MAINSRC = $(PNAME).c - -ELF_SECTIONS_TO_REMOVE = -R DATA -R INITIALIZED -R SSEG -R .debug_line -R .debug_loc -R .debug_abbrev -R .debug_info -R .debug_pubnames -R .debug_frame - -# These are the sources that must be compiled to .rel files: -EXTRASRCS = \ - $(SDIR)/stm8s_itc.c \ - $(SDIR)/stm8s_clk.c \ - $(SDIR)/stm8s_iwdg.c \ - $(SDIR)/stm8s_gpio.c \ - $(SDIR)/stm8s_exti.c \ - $(SDIR)/stm8s_uart2.c \ - $(SDIR)/stm8s_tim1.c \ - $(SDIR)/stm8s_tim2.c \ - $(SDIR)/stm8s_adc1.c \ - $(SDIR)/stm8s_flash.c \ - BOdisplay.c \ - ACAcontrollerState.c \ - ACAeeprom.c \ - ACAsetPoint.c \ - ACAcommons.c \ - gpio.c \ - cruise_control.c \ - uart.c \ - adc.c \ - brake.c \ - timers.c \ - pwm.c \ - motor.c \ - PAS.c \ - SPEED.c \ - display.c \ - display_kingmeter.c - -HEADERS = BOdisplay.h ACAcommons.h ACAsetPoint.h ACAcontrollerState.h ACAeeprom.h adc.h brake.h cruise_control.h gpio.h interrupts.h main.h motor.h pwm.h timers.h uart.h PAS.h SPEED.h - -# The list of .rel files can be derived from the list of their source files -RELS = $(EXTRASRCS:.c=.rel) - -INCLUDES = -I$(IDIR) -I. -CFLAGS = -m$(PLATFORM) --std-c99 --nolospre -#ELF_FLAGS = --out-fmt-elf --debug -ELF_FLAGS = --out-fmt-elf -LIBS = - -# This just provides the conventional target name "all"; it is optional -# Note: I assume you set PNAME via some means not exhibited in your original file -all: $(PNAME) - -# How to build the overall program -$(PNAME): $(MAINSRC) $(RELS) - $(CC) $(INCLUDES) $(CFLAGS) $(ELF_FLAGS) $(LIBS) $(MAINSRC) $(RELS) - $(SIZE) $(PNAME).elf -A - $(OBJCOPY) -O binary $(ELF_SECTIONS_TO_REMOVE) $(PNAME).elf $(PNAME).bin - $(OBJCOPY) -O ihex $(ELF_SECTIONS_TO_REMOVE) $(PNAME).elf $(PNAME).hex - -# How to build any .rel file from its corresponding .c file -# GNU would have you use a pattern rule for this, but that's GNU-specific -%.rel: %.c $(HEADERS) - $(CC) -c $(INCLUDES) $(CFLAGS) $(ELF_FLAGS) $(LIBS) -o$< $< - -# Suffixes appearing in suffix rules we care about. -# Necessary because .rel is not one of the standard suffixes. -.SUFFIXES: .c .rel - -hex: - $(OBJCOPY) -O ihex $(ELF_SECTIONS_TO_REMOVE) $(PNAME).elf $(PNAME).ihx - -flash: - stm8flash -cstlinkv2 -pstm8s105?6 -w$(PNAME).bin - -clean: - @echo "Cleaning files..." - @rm -rf $(SDIR)/*.asm - @rm -rf $(SDIR)/*.rel - @rm -rf $(SDIR)/*.lk - @rm -rf $(SDIR)/*.lst - @rm -rf $(SDIR)/*.rst - @rm -rf $(SDIR)/*.sym - @rm -rf $(SDIR)/*.cdb - @rm -rf $(SDIR)/*.map - @rm -rf $(SDIR)/*.elf - @rm -rf $(SDIR)/*.bin - @rm -rf $(SDIR)/*.adb - @rm -rf *.asm - @rm -rf *.rel - @rm -rf *.lk - @rm -rf *.lst - @rm -rf *.rst - @rm -rf *.sym - @rm -rf *.cdb - @rm -rf *.map - @rm -rf *.adb - @rm -rf *.elf - @rm -rf main.bin - @rm -rf *.ihx - @rm -rf *.hex - - @echo "Done." - diff --git a/OSEC Parameter Configurator.jar b/OSEC Parameter Configurator.jar index 133933da..46b930e5 100644 Binary files a/OSEC Parameter Configurator.jar and b/OSEC Parameter Configurator.jar differ diff --git a/Start_Compiling.bat b/Start_Compiling.bat index 043906c4..f640cca5 100644 --- a/Start_Compiling.bat +++ b/Start_Compiling.bat @@ -3,10 +3,10 @@ REM ;%~dp0tools\cygwin\bin cd %~dp0 del main.hex sdcc --version -make -f Makefile_windows clean -make -f Makefile_windows +make clean +make ren main.ihx main.hex -make -f Makefile_windows clean +make clean STVP_CmdLine -BoardName=ST-LINK -ProgMode=SWIM -Port=USB -Device=STM8S105x6 -FileProg=main.hex -verbose -no_loop diff --git a/adc.c b/adc.c index dfba86a8..d147fd76 100755 --- a/adc.c +++ b/adc.c @@ -96,6 +96,8 @@ inline void adc_trigger(void) //inline ?! ADC1_StartConversion(); } +#define READ_MMIO_U8(x) *(volatile uint8_t*)(x) + uint8_t ui8_adc_read_phase_B_current(void) { // /* Read LSB first */ // templ = *(uint8_t*)(uint16_t)((uint16_t)ADC1_BaseAddress + (uint8_t)(Buffer << 1) + 1); @@ -104,15 +106,15 @@ uint8_t ui8_adc_read_phase_B_current(void) { //#define ADC1_BaseAddress 0x53E0 //phase_B_current --> ADC_AIN5 // 0x53E0 + 2*5 = 0x53EA - return *(uint8_t*) (0x53EA); + return READ_MMIO_U8(0x53EA); } uint16_t ui16_adc_read_phase_B_current(void) { uint16_t temph; uint8_t templ; - templ = *(uint8_t*) (0x53EB); - temph = *(uint8_t*) (0x53EA); + templ = READ_MMIO_U8(0x53EB); + temph = READ_MMIO_U8(0x53EA); return ((uint16_t) temph) << 2 | ((uint16_t) templ); } @@ -120,15 +122,15 @@ uint16_t ui16_adc_read_phase_B_current(void) { uint8_t ui8_adc_read_throttle(void) { // 0x53E0 + 2*4 = 0x53E8 // return *(uint8_t*)(0x53E8); - return *(uint8_t*) (0x53E8); + return READ_MMIO_U8(0x53E8); } uint16_t ui16_adc_read_x4_value(void) { uint16_t temph; uint8_t templ; - templ = *(uint8_t*) (0x53EF); - temph = *(uint8_t*) (0x53EE); + templ = READ_MMIO_U8(0x53EF); + temph = READ_MMIO_U8(0x53EE); return ((uint16_t) temph) << 2 | ((uint16_t) templ); @@ -136,30 +138,31 @@ uint16_t ui16_adc_read_x4_value(void) { uint8_t ui8_adc_read_motor_total_current(void) { // 0x53E0 + 2*8 = 0x53F0 - return *(uint8_t*) (0x53F0); + return READ_MMIO_U8(0x53F0); } uint16_t ui16_adc_read_motor_total_current(void) { uint16_t temph; uint8_t templ; - templ = *(uint8_t*) (0x53F1); - temph = *(uint8_t*) (0x53F0); + templ = READ_MMIO_U8(0x53F1); + temph = READ_MMIO_U8(0x53F0); return ((uint16_t) temph) << 2 | ((uint16_t) templ); } uint8_t ui8_adc_read_battery_voltage(void) { // 0x53E0 + 2*9 = 0x53F2 - return *(uint8_t*) (0x53F2); + return READ_MMIO_U8(0x53F2); } uint16_t ui16_adc_read_battery_voltage(void) { uint16_t temph; uint8_t templ; - templ = *(uint8_t*) (0x53F3); - temph = *(uint8_t*) (0x53F2); + templ = READ_MMIO_U8(0x53F3); + temph = READ_MMIO_U8(0x53F2); + temph = READ_MMIO_U8(0x53F2); return ((uint16_t) temph) << 2 | ((uint16_t) templ); } diff --git a/apply_config.sh b/apply_config.sh new file mode 100755 index 00000000..df8b3350 --- /dev/null +++ b/apply_config.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -x +make clean +make && sudo make flash +echo "Press enter to quit script..." +read dummy diff --git a/gpio.c b/gpio.c index bcb76dd5..cdbc3246 100644 --- a/gpio.c +++ b/gpio.c @@ -12,7 +12,31 @@ void gpio_init (void) { - ; + // General MCU principles: every pin should have a defined state; + // if not, the pin might float randomly and toggle spuriously and consume current in the input buffer. + // Thus, set every unused pin to input pullup. + // LEARN unk unk unk unk + GPIO_Init(GPIOA, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_6, + GPIO_MODE_IN_PU_NO_IT); + // unk (no connect) + GPIO_Init(GPIOB, GPIO_PIN_3, + GPIO_MODE_IN_PU_NO_IT); + // unk unk + GPIO_Init(GPIOC, GPIO_PIN_4 | GPIO_PIN_6, + GPIO_MODE_IN_PU_NO_IT); + // SWIM unk unk + GPIO_Init(GPIOD, GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_4, + GPIO_MODE_IN_PU_NO_IT); + // unk unk + GPIO_Init(GPIOE, GPIO_PIN_3 | GPIO_PIN_5, + GPIO_MODE_IN_PU_NO_IT); + // unk unk + GPIO_Init(GPIOG, GPIO_PIN_0 | GPIO_PIN_1, + GPIO_MODE_IN_PU_NO_IT); + // Note: on an unknown board, you should also check that every pulled up pin + // reads back as 1 (which i did for mine). If something reads back as 0, assume + // it's either used for something that drives it, or is hard-wired to ground, + // and remove it from the pullup list. } void debug_pin_init (void) diff --git a/main.c b/main.c index 0dc1a12e..ecf122b6 100644 --- a/main.c +++ b/main.c @@ -19,7 +19,6 @@ #include "uart.h" #include "adc.h" #include "brake.h" -#include "cruise_control.h" #include "timers.h" #include "pwm.h" #include "PAS.h" @@ -158,19 +157,15 @@ int main(void) { ui8_slowloop_flag = 0; //reset flag for slow loop ui8_veryslowloop_counter++; // increase counter for very slow loop + motor_slow_update_pre(); checkPasInActivity(); updateRequestedTorque(); //now calculates tq for sensor as well updateSlowLoopStates(); updateX4(); updateLight(); ui16_setpoint = (uint16_t) aca_setpoint(ui16_time_ticks_between_pas_interrupt, ui16_setpoint); //update setpoint - - //#define DO_CRUISE_CONTROL 1 -#if DO_CRUISE_CONTROL == 1 - ui16_setpoint = cruise_control(ui16_setpoint); -#endif - pwm_set_duty_cycle((uint8_t) ui16_setpoint); + motor_slow_update_post(); //pwm_set_duty_cycle ((uint8_t)ui16_sum_throttle); diff --git a/motor.c b/motor.c index b69df4aa..dabc0c5c 100755 --- a/motor.c +++ b/motor.c @@ -16,34 +16,44 @@ #include "pwm.h" #include "config.h" #include "adc.h" + #include "ACAcontrollerState.h" #include "ACAcommons.h" -uint8_t ui8_counter = 0; -uint8_t ui8_half_rotation_flag = 0; -uint8_t ui8_foc_enable_flag = 0; +/* Local only */ +static uint8_t ui8_half_rotation_flag = 0; +static uint8_t ui8_foc_enable_flag = 0; +static uint8_t ui8_assumed_motor_position = 0; +static uint8_t ui8_motor_rotor_hall_position = 0; // in 360/256 degrees +static uint8_t ui8_sinetable_precalc = 0; +static uint8_t ui8_interpolation_start_position = 0; +static uint8_t ui8_interpolation_angle = 0; +static int8_t hall_sensors_last = 0; +static uint16_t ui16_ADC_iq_current_accumulated = 4096; + +// Local except for diagnostics (main) uint16_t ui16_PWM_cycles_counter = 0; uint16_t ui16_PWM_cycles_counter_6 = 0; uint16_t ui16_PWM_cycles_counter_total = 0; +uint16_t ui16_ADC_iq_current = 0; // main plus BO +int8_t hall_sensors; // main only; plus it's an int8, should be fine. +uint8_t ui8_possible_motor_state = 0; +uint8_t ui8_dynamic_motor_state = 0; +uint8_t ui8_position_correction_value = 127; // in 360/256 degrees +// Only for diagnostics +uint8_t uint8_t_60deg_pwm_cycles[6]; +uint8_t uint8_t_hall_case[7]; -uint8_t ui8_assumed_motor_position = 0; -uint8_t ui8_sinetable_position = 0; // in 360/256 degrees -uint8_t ui8_motor_rotor_hall_position = 0; // in 360/256 degrees -uint8_t ui8_sinetable_precalc = 0; -uint8_t ui8_interpolation_start_position = 0; - -uint8_t ui8_interpolation_angle = 0; -uint16_t ui16_adc_current_phase_B = 0; -uint16_t ui16_adc_current_phase_B_accumulated = 0; -uint16_t ui16_adc_current_phase_B_filtered = 0; +// Motor->PWM (we call pwm; same context.) +uint8_t ui8_sinetable_position = 0; // in 360/256 degrees -int8_t hall_sensors; -int8_t hall_sensors_last = 0; +// Slow loop -> motor (by the motor_slow_update_post) +static uint16_t BatteryCurrent; -uint16_t ui16_ADC_iq_current_accumulated = 4096; -uint16_t ui16_iq_current_ma = 0; +// Motor-> slow loop (_pre) +static uint16_t motor_speed_erps; void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void) __interrupt(TIM1_UPD_OVF_TRG_BRK_IRQHANDLER) { adc_trigger(); @@ -70,9 +80,8 @@ void hall_sensors_read_and_action(void) { if (hall_sensors_last >0 && hall_sensors_last < 7) { uint8_t_60deg_pwm_cycles[hall_sensors_last-1] = ui16_PWM_cycles_counter_6; } - updateHallOrder(hall_sensors); + updateHallOrder(hall_sensors); // this stores the hall order elsewhere, only for debug - //printf("hall change! %d, %d \n", hall_sensors, hall_sensors_last ); hall_sensors_last = hall_sensors; if (ui8_possible_motor_state == MOTOR_STATE_COAST) { @@ -91,17 +100,17 @@ void hall_sensors_read_and_action(void) { if (ui16_PWM_cycles_counter > 20) ui16_PWM_cycles_counter_total = ui16_PWM_cycles_counter; ui16_PWM_cycles_counter = 0; - ui16_motor_speed_erps = ((uint16_t) ui16_pwm_cycles_second) / ui16_PWM_cycles_counter_total; // this division takes ~4.2us + motor_speed_erps = ((uint16_t) ui16_pwm_cycles_second) / ui16_PWM_cycles_counter_total; // this division takes ~4.2us } - if (ui16_motor_speed_erps == -1) { - ui16_motor_speed_erps = 0; + if (motor_speed_erps == -1) { + motor_speed_erps = 0; } // update motor state based on motor speed - if (ui16_motor_speed_erps > 75) { + if (motor_speed_erps > 75) { ui8_possible_motor_state = MOTOR_STATE_RUNNING_INTERPOLATION_360; - }else if (ui16_motor_speed_erps > 3) { + }else if (motor_speed_erps > 3) { ui8_possible_motor_state = MOTOR_STATE_RUNNING_INTERPOLATION_60; } else { ui8_possible_motor_state = MOTOR_STATE_RUNNING_NO_INTERPOLATION; @@ -162,15 +171,18 @@ void updateCorrection() { return; } - if (ui16_motor_speed_erps > 3 && ui16_BatteryCurrent > ui16_current_cal_b + 3) { //normal riding, - if (ui16_ADC_iq_current >> 2 > 128 && ui8_position_correction_value < 143) { + const uint8_t curr_target = 126; + const uint8_t max_angle = 143; + + if (motor_speed_erps > 3 && BatteryCurrent > ui16_current_cal_b + 3) { //normal riding, + if (ui16_ADC_iq_current >> 2 > (curr_target+2) && ui8_position_correction_value < max_angle) { ui8_position_correction_value++; } else if (ui16_ADC_iq_current >> 2 < 126 && ui8_position_correction_value > 111) { ui8_position_correction_value--; } - } else if (ui16_motor_speed_erps > 3 && ui16_BatteryCurrent < ui16_current_cal_b - 3) {//regen + } else if (motor_speed_erps > 3 && BatteryCurrent < ui16_current_cal_b - 3) {//regen ui8_position_correction_value = 127; //set advance angle to neutral value - } else if (ui16_motor_speed_erps < 3) { + } else if (motor_speed_erps < 3) { ui8_position_correction_value = 127; //reset advance angle at very low speed) } @@ -179,6 +191,8 @@ void updateCorrection() { // runs every 64us (PWM frequency) void motor_fast_loop(void) { + + /* FIXME: These counters are... not well implemented. */ if (ui16_time_ticks_for_uart_timeout < 65530) { ui16_time_ticks_for_uart_timeout++; } @@ -200,7 +214,7 @@ void motor_fast_loop(void) { ui16_PWM_cycles_counter_total = 0xffff; //(SVM_TABLE_LEN_x1024) / PWM_CYCLES_COUNTER_MAX; ui8_position_correction_value = 127; hall_sensors_last = 0; - ui16_motor_speed_erps = 0; + motor_speed_erps = 0; // next code is need for motor startup correctly @@ -305,3 +319,30 @@ void watchdog_init(void) { IWDG_SetReload(2); // 187.5us; for some reason, a value of 1 don't work, only 2 IWDG_ReloadCounter(); } + + +// Move these includes here if you want to see the identifiers that the ISR code uses +// without much regard for safety (most of whats left (except those timers) are effectively constants (except if adjusted during debug). +//#include "ACAcontrollerState.h" +//#include "ACAcommons.h" + + +// The concept here is loaned from linux; except that SDCC doesnt do typeof(x), so we need one per width. +#define READ_ONCE_U16(x) (*(const volatile uint16_t *)&(x)) +#define WRITE_ONCE_U16(x, val) \ +do { \ + *(volatile uint16_t *)&(x) = (val); \ +} while (0) + +/* Communicate between "fast loop" (ISR) and rest of the system. */ +void motor_slow_update_pre(void) { + disableInterrupts(); + ui16_motor_speed_erps = READ_ONCE_U16(motor_speed_erps); + enableInterrupts(); +} + +void motor_slow_update_post(void) { + disableInterrupts(); + WRITE_ONCE_U16(BatteryCurrent, ui16_BatteryCurrent); + enableInterrupts(); +} diff --git a/motor.h b/motor.h index 8528266e..afee4311 100755 --- a/motor.h +++ b/motor.h @@ -18,11 +18,17 @@ #define MOTOR_STATE_RUNNING_INTERPOLATION_60 2 #define MOTOR_STATE_RUNNING_INTERPOLATION_360 3 +// external for PWM (TIM1 isr context) extern uint8_t ui8_sinetable_position; -extern uint16_t ui16_speed_inverse; + +// external for debug only (and the BOdisplay... now there's an acronym.) extern uint16_t ui16_PWM_cycles_counter_total; -extern uint16_t ui16_iq_current_ma; -extern uint16_t ui16_log; +extern uint16_t ui16_ADC_iq_current; +extern uint8_t ui8_possible_motor_state; +extern uint8_t ui8_dynamic_motor_state; +extern uint8_t ui8_position_correction_value; +extern uint8_t uint8_t_60deg_pwm_cycles[6]; +extern uint8_t uint8_t_hall_case[7]; void hall_sensor_init (void); @@ -30,4 +36,9 @@ void hall_sensors_read_and_action (void); void motor_fast_loop (void); void watchdog_init (void); +// slow loop before setpoint +void motor_slow_update_pre(void); +// slow loop after setpoint +void motor_slow_update_post(void); + #endif /* _MOTOR_H_ */ diff --git a/tools/JavaConfigurator/src/OSEC.java b/tools/JavaConfigurator/src/OSEC.java index 293d7b1b..e7e9e36e 100644 --- a/tools/JavaConfigurator/src/OSEC.java +++ b/tools/JavaConfigurator/src/OSEC.java @@ -1357,8 +1357,26 @@ public void actionPerformed(ActionEvent arg0) { } } + String command; + if (System.getProperty("os.name").toLowerCase().contains("win")) { + command = "cmd /c start Start_Compiling"; + } else { + // Use the environment variable if you want to set + // a custom term on a random linux distro. + String terminal = System.getenv("TERMINAL"); + if (terminal == null) { + File tf = new File("/usr/bin/x-terminal-emulator"); + if (tf.exists()) { + terminal = "x-terminal-emulator"; + } else { + terminal = "xterm"; + } + } + command = terminal + " -e ./apply_config.sh"; + } + try { - Process process = Runtime.getRuntime().exec("cmd /c start Start_Compiling"); + Process process = Runtime.getRuntime().exec(command); } catch (IOException e1) { txtThrottlemin.setText("Error"); e1.printStackTrace(); diff --git a/uart.c b/uart.c index edbdbcef..bd7d40d5 100755 --- a/uart.c +++ b/uart.c @@ -48,6 +48,13 @@ uint8_t uart_get_buffered(void) { } return c; } + +int uart_getch(void) { + if (byte_avail_at_position() != UART_EMPTY_INDICATOR) + return uart_get_buffered(); + return -1; +} + // FIXME only needed as long as the other displays do not use new functions // and instead have their own irq handler diff --git a/uart.h b/uart.h index f8bab6e3..5ff1366b 100755 --- a/uart.h +++ b/uart.h @@ -25,4 +25,5 @@ void uart_fill_rx_packet_buffer(uint8_t *buffer, uint8_t bufferSize, uint8_t *bu void uart_init (void); void putbyte(uint8_t c); +int uart_getch(void); #endif /* _UART_H */