From 8c83ebf1fb56a3128f3aaa64aa382a74f04d9332 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Thu, 28 Feb 2019 21:59:52 +0000 Subject: [PATCH] - software timer is event based - completed main functions git-svn-id: http://moon:8086/svn/projects/HendiControl@31 fda53097-d464-4ada-af97-ba876c37ca34 --- Control/firmware/uart_echo/main.c | 187 +++++++++++++-------- Control/firmware/uart_echo/timer.c | 44 ++++- Control/firmware/uart_echo/timer.h | 20 ++- Control/firmware/uart_echo/uart_echo.cproj | 70 ++++---- 4 files changed, 211 insertions(+), 110 deletions(-) diff --git a/Control/firmware/uart_echo/main.c b/Control/firmware/uart_echo/main.c index ec0133d..495b364 100755 --- a/Control/firmware/uart_echo/main.c +++ b/Control/firmware/uart_echo/main.c @@ -33,16 +33,14 @@ #define USART_BAUDRATE 38400UL #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) #define TIMER_HW_CLOCK (F_CPU/8) -#define TIMER_IRQ_CLOCK 1000 -#define TIMER_SW_CLOCK 10 -#define TIMER_SW_RELOAD (TIMER_IRQ_CLOCK/TIMER_SW_CLOCK) - +#define TIMER_IRQ_CLOCK 1000UL #define TIMER_HW_RELOAD (0xFFFF-(TIMER_HW_CLOCK/TIMER_IRQ_CLOCK)) + +#define TIMER_SW_DELAY_MS(dly) ((dly*TIMER_IRQ_CLOCK)/1000UL) + static uint8_t ledState = 0; static int16_t adc_last = 0; -static int pwr_Switch_state_last = 0; static Fifo messageFifo; -static int timer_count = 0; ISR(USART_RX_vect) { @@ -63,38 +61,44 @@ ISR(USART_RX_vect) fifo_push(&messageFifo, &msg); } -ISR (TIMER1_OVF_vect) // Timer1 ISR -{ - TCNT1 = TIMER_HW_RELOAD; - - Msg_t msg = {Timer, ledState}; - if (timer_count == 0) - { - timer_count = TIMER_SW_RELOAD; - fifo_push(&messageFifo, &msg); - ledState++; - if (ledState == 4) - { - ledState = 0; - } - } - else - { - timer_count--; - } - -} - FILE uart_file = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); -int main(void) - +void setSwitch(int on) { + const char *sw_str[2] = {"OFF", "ON"}; + printf("Set switch to %s\n", sw_str[on != 0]); + portSet(PwrSwitch_out, on != 0); +} + +void setPower(uint16_t power) +{ + printf("Set Power to %d\n", power); + uint8_t dac_cmd[] = {0x00, 0x00}; // 6.2 Write Volatile Memory (C2:C0 = ‘010’) + size_t res = MCP47x6_write_volatile_dac(power, dac_cmd, sizeof(dac_cmd)); + i2c_send(0x60, I2C_WRITE, dac_cmd, res); +} + +typedef enum _eState_t +{ + StateOff = 0, + StateNormal = 1, + StateRemote = 2, + StateError = 3, + State_NumStates +} State_t; + +int main(void) +{ + const char *state_str[State_NumStates] = {"Off","Normal","Remote","Error"}; + + State_t state = StateOff; + State_t state_next = StateOff; + fifo_init(&messageFifo, 64, sizeof(Msg_t), "Fifo"); /* Replace with your application code */ uart_init(BAUD_PRESCALE); - timer_init(TIMER_HW_RELOAD, TimerClockSel_PS_8); + timer_init(&messageFifo, TIMER_HW_RELOAD, TimerClockSel_PS_8); adc_init(&messageFifo); i2c_init(); port_init(); @@ -107,13 +111,18 @@ int main(void) i2c_send(0x60, I2C_WRITE, dac_cmd, res); sei(); - adc_start_conversion(0x06); char cmdStr[16]; size_t cmdStrSize = 0; PRINT_PROMPT; + + // Start Timer + timer_start(TIMER_GENERAL, 0); + timer_start(TIMER_ADC, 0); + while (1) { + state_next = state; Msg_t msg; if (!fifo_isEmpty(&messageFifo)) { @@ -131,6 +140,11 @@ int main(void) { char c = msg.data; + if (state != StateNormal && state != StateRemote) + { + break; + } + // Command finished with CR/LF if (c == 0x0A || c == 0x0D) { @@ -138,16 +152,19 @@ int main(void) if (toupper(cmdStr[0]) == 'P') { uint16_t arg = atol(cmdStr+1); - uint8_t dac_cmd[] = {0x00, 0x00}; // 6.2 Write Volatile Memory (C2:C0 = ‘010’) - size_t res = MCP47x6_write_volatile_dac(arg, dac_cmd, sizeof(dac_cmd)); - i2c_send(0x60, I2C_WRITE, dac_cmd, res); + setPower(arg); + timer_start(TIMER_TIMEOUT, TIMER_SW_DELAY_MS(5000)); + sei(); + state_next = StateRemote; } // Switch Control if (toupper(cmdStr[0]) == 'S') { uint16_t arg = atol(cmdStr+1); - portSet(PwrSwitch_out, arg != 0); + setSwitch(arg); + timer_start(TIMER_TIMEOUT, TIMER_SW_DELAY_MS(5000)); + state_next = StateRemote; } cmdStrSize = 0; PRINT_PROMPT; @@ -177,55 +194,81 @@ int main(void) case AdcComplete: { + int16_t adc_curr = adc_getData(); if (adc_getChannel() == 6) { - int16_t adc_curr = adc_getData(); if (((adc_curr - adc_last) < -1) || ((adc_curr - adc_last) > 1)) { - printf("ADC=%d\n", adc_curr); - uint8_t dac_cmd[] = {0x00, 0x00}; // 6.2 Write Volatile Memory (C2:C0 = ‘010’) - size_t res = MCP47x6_write_volatile_dac(adc_curr<<2, dac_cmd, sizeof(dac_cmd)); - i2c_send(0x60, I2C_WRITE, dac_cmd, res); - adc_last = adc_curr; + + if (state == StateOff) + { + if (adc_curr > 2) + { + setSwitch(1); + state_next = StateNormal; + } + } + if (state == StateNormal || state == StateError) + { + if (adc_curr < 2) + { + state_next = StateOff; + setSwitch(0); + } + setPower(adc_curr << 2); + } } } + adc_last = adc_curr; } break; case Timer: { - switch(msg.data) + int timer_id = msg.data; + switch(timer_id) { - case 0: - PORTB = (PORTB & 0xFC) | 0x00; + case TIMER_GENERAL: + { + timer_start(timer_id, TIMER_SW_DELAY_MS(500)); + switch(ledState) + { + case 0: + PORTB = (PORTB & 0xFC) | 0x00; + break; + case 1: + PORTB = (PORTB & 0xFC) | 0x01; + break; + case 2: + PORTB = (PORTB & 0xFC) | 0x03; + break; + case 3: + PORTB = (PORTB & 0xFC) | 0x02; + break; + } + ledState++; + if (ledState == 4) + { + ledState = 0; + } + } break; - case 1: - PORTB = (PORTB & 0xFC) | 0x01; + + case TIMER_TIMEOUT: + { + printf("Timeout!\n"); + setPower(0); + setSwitch(0); + state_next = StateError; + } break; - case 2: - PORTB = (PORTB & 0xFC) | 0x03; - break; - case 3: - PORTB = (PORTB & 0xFC) | 0x02; + case TIMER_ADC: + { + timer_start(timer_id, TIMER_SW_DELAY_MS(50)); + adc_start_conversion(0x06); + } break; } -#if 0 - int state = portGet(PwrSwitch_in); - - if (state != pwr_Switch_state_last) - { - if (state) - { - printf("Power switch is ON\n"); - } - else - { - printf("Power switch is OFF\n"); - } - } - pwr_Switch_state_last = state; -#endif - adc_start_conversion(0x06); } break; @@ -234,6 +277,12 @@ int main(void) break; } } + if (state != state_next) + { + printf("State change \"%s\" => \"%s\"\n", state_str[state], state_str[state_next]); + } + state = state_next; + } } diff --git a/Control/firmware/uart_echo/timer.c b/Control/firmware/uart_echo/timer.c index f66eb68..27cdce8 100644 --- a/Control/firmware/uart_echo/timer.c +++ b/Control/firmware/uart_echo/timer.c @@ -6,16 +6,54 @@ */ #include +#include #include "timer.h" +#include "message.h" -void timer_init(uint16_t TIMER_RELOAD, TimerClockSel clockSel) +static uint16_t timer_reload = 0; +static Timer_t user_timer[16]; +static Fifo *g_pFifo = NULL; + +ISR (TIMER1_OVF_vect) // Timer1 ISR { - + TCNT1 = timer_reload; + + for (int i=0; i < 16; i++) + { + if (user_timer[i].isRunning) + { + if (user_timer[i].count > 0) + { + user_timer[i].count--; + } + else + { + Msg_t msg = {Timer, i}; + if (fifo_push(g_pFifo, &msg)) + { + user_timer[i].isRunning = 0; + } + } + } + } +} + +void timer_init(Fifo *pFifo, uint16_t TIMER_RELOAD, TimerClockSel clockSel) +{ + g_pFifo = pFifo; + timer_reload = TIMER_RELOAD; TCNT1 = TIMER_RELOAD; TCCR1A = 0x00; TCCR1B = (TCCR1B & TimerClockSel_mask) | clockSel; TIMSK1 = (1 << TOIE1) ; // Enable timer1 overflow interrupt(TOIE1) - +} + +void timer_start(TimerId timerId, uint16_t count) +{ + cli(); + user_timer[timerId].count = count; + user_timer[timerId].isRunning = 1; + sei(); } diff --git a/Control/firmware/uart_echo/timer.h b/Control/firmware/uart_echo/timer.h index c66c98a..7e659a8 100644 --- a/Control/firmware/uart_echo/timer.h +++ b/Control/firmware/uart_echo/timer.h @@ -9,6 +9,21 @@ #ifndef TIMER_H_ #define TIMER_H_ +#include "fifo.h" + +typedef enum _eTimerId +{ + TIMER_GENERAL = 0, + TIMER_TIMEOUT = 1, + TIMER_ADC = 2 +} TimerId; + +typedef struct _sTimer_t +{ + int isRunning; + uint16_t count; +} Timer_t; + typedef enum _eTimerClockSel { TimerClockSel_none = 0, @@ -22,7 +37,6 @@ typedef enum _eTimerClockSel TimerClockSel_mask = (1< - -mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.150\gcc\dev\atmega328p" - True - True - True - True - False - True - True - - - DEBUG - - - - - %24(PackRepoDir)\atmel\ATmega_DFP\1.2.150\include - - - Optimize debugging experience (-Og) - True - True - Default (-g2) - True - - - libm - - - - - %24(PackRepoDir)\atmel\ATmega_DFP\1.2.150\include - - - Default (-Wa,-g) - + -mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.150\gcc\dev\atmega328p" + True + True + True + True + False + True + True + + + DEBUG + + + + + %24(PackRepoDir)\atmel\ATmega_DFP\1.2.150\include + + + Optimize debugging experience (-Og) + True + True + Default (-g2) + True + + + libm + + + + + %24(PackRepoDir)\atmel\ATmega_DFP\1.2.150\include + + + Default (-Wa,-g) +