- software timer is event based

- completed main functions



git-svn-id: http://moon:8086/svn/projects/HendiControl@31 fda53097-d464-4ada-af97-ba876c37ca34
This commit is contained in:
2019-02-28 21:59:52 +00:00
parent 8a8bb762e0
commit 8c83ebf1fb
4 changed files with 211 additions and 110 deletions
+106 -57
View File
@@ -33,16 +33,14 @@
#define USART_BAUDRATE 38400UL #define USART_BAUDRATE 38400UL
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#define TIMER_HW_CLOCK (F_CPU/8) #define TIMER_HW_CLOCK (F_CPU/8)
#define TIMER_IRQ_CLOCK 1000 #define TIMER_IRQ_CLOCK 1000UL
#define TIMER_SW_CLOCK 10
#define TIMER_SW_RELOAD (TIMER_IRQ_CLOCK/TIMER_SW_CLOCK)
#define TIMER_HW_RELOAD (0xFFFF-(TIMER_HW_CLOCK/TIMER_IRQ_CLOCK)) #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 uint8_t ledState = 0;
static int16_t adc_last = 0; static int16_t adc_last = 0;
static int pwr_Switch_state_last = 0;
static Fifo messageFifo; static Fifo messageFifo;
static int timer_count = 0;
ISR(USART_RX_vect) ISR(USART_RX_vect)
{ {
@@ -63,38 +61,44 @@ ISR(USART_RX_vect)
fifo_push(&messageFifo, &msg); 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); 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"); fifo_init(&messageFifo, 64, sizeof(Msg_t), "Fifo");
/* Replace with your application code */ /* Replace with your application code */
uart_init(BAUD_PRESCALE); uart_init(BAUD_PRESCALE);
timer_init(TIMER_HW_RELOAD, TimerClockSel_PS_8); timer_init(&messageFifo, TIMER_HW_RELOAD, TimerClockSel_PS_8);
adc_init(&messageFifo); adc_init(&messageFifo);
i2c_init(); i2c_init();
port_init(); port_init();
@@ -107,13 +111,18 @@ int main(void)
i2c_send(0x60, I2C_WRITE, dac_cmd, res); i2c_send(0x60, I2C_WRITE, dac_cmd, res);
sei(); sei();
adc_start_conversion(0x06);
char cmdStr[16]; char cmdStr[16];
size_t cmdStrSize = 0; size_t cmdStrSize = 0;
PRINT_PROMPT; PRINT_PROMPT;
// Start Timer
timer_start(TIMER_GENERAL, 0);
timer_start(TIMER_ADC, 0);
while (1) while (1)
{ {
state_next = state;
Msg_t msg; Msg_t msg;
if (!fifo_isEmpty(&messageFifo)) if (!fifo_isEmpty(&messageFifo))
{ {
@@ -131,6 +140,11 @@ int main(void)
{ {
char c = msg.data; char c = msg.data;
if (state != StateNormal && state != StateRemote)
{
break;
}
// Command finished with CR/LF // Command finished with CR/LF
if (c == 0x0A || c == 0x0D) if (c == 0x0A || c == 0x0D)
{ {
@@ -138,16 +152,19 @@ int main(void)
if (toupper(cmdStr[0]) == 'P') if (toupper(cmdStr[0]) == 'P')
{ {
uint16_t arg = atol(cmdStr+1); uint16_t arg = atol(cmdStr+1);
uint8_t dac_cmd[] = {0x00, 0x00}; // 6.2 Write Volatile Memory (C2:C0 = 010) setPower(arg);
size_t res = MCP47x6_write_volatile_dac(arg, dac_cmd, sizeof(dac_cmd)); timer_start(TIMER_TIMEOUT, TIMER_SW_DELAY_MS(5000));
i2c_send(0x60, I2C_WRITE, dac_cmd, res); sei();
state_next = StateRemote;
} }
// Switch Control // Switch Control
if (toupper(cmdStr[0]) == 'S') if (toupper(cmdStr[0]) == 'S')
{ {
uint16_t arg = atol(cmdStr+1); 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; cmdStrSize = 0;
PRINT_PROMPT; PRINT_PROMPT;
@@ -177,24 +194,44 @@ int main(void)
case AdcComplete: case AdcComplete:
{ {
int16_t adc_curr = adc_getData();
if (adc_getChannel() == 6) if (adc_getChannel() == 6)
{ {
int16_t adc_curr = adc_getData();
if (((adc_curr - adc_last) < -1) || ((adc_curr - adc_last) > 1)) 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) if (state == StateOff)
size_t res = MCP47x6_write_volatile_dac(adc_curr<<2, dac_cmd, sizeof(dac_cmd)); {
i2c_send(0x60, I2C_WRITE, dac_cmd, res); 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; adc_last = adc_curr;
} }
}
}
break; break;
case Timer: case Timer:
{ {
switch(msg.data) int timer_id = msg.data;
switch(timer_id)
{
case TIMER_GENERAL:
{
timer_start(timer_id, TIMER_SW_DELAY_MS(500));
switch(ledState)
{ {
case 0: case 0:
PORTB = (PORTB & 0xFC) | 0x00; PORTB = (PORTB & 0xFC) | 0x00;
@@ -209,31 +246,43 @@ int main(void)
PORTB = (PORTB & 0xFC) | 0x02; PORTB = (PORTB & 0xFC) | 0x02;
break; break;
} }
#if 0 ledState++;
int state = portGet(PwrSwitch_in); if (ledState == 4)
{
ledState = 0;
}
}
break;
if (state != pwr_Switch_state_last) case TIMER_TIMEOUT:
{ {
if (state) printf("Timeout!\n");
setPower(0);
setSwitch(0);
state_next = StateError;
}
break;
case TIMER_ADC:
{ {
printf("Power switch is ON\n"); timer_start(timer_id, TIMER_SW_DELAY_MS(50));
}
else
{
printf("Power switch is OFF\n");
}
}
pwr_Switch_state_last = state;
#endif
adc_start_conversion(0x06); adc_start_conversion(0x06);
} }
break; break;
}
}
break;
case Error: case Error:
printf("Error!!!\n"); printf("Error!!!\n");
break; break;
} }
} }
if (state != state_next)
{
printf("State change \"%s\" => \"%s\"\n", state_str[state], state_str[state_next]);
}
state = state_next;
} }
} }
+39 -1
View File
@@ -6,16 +6,54 @@
*/ */
#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h>
#include "timer.h" #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; TCNT1 = TIMER_RELOAD;
TCCR1A = 0x00; TCCR1A = 0x00;
TCCR1B = (TCCR1B & TimerClockSel_mask) | clockSel; TCCR1B = (TCCR1B & TimerClockSel_mask) | clockSel;
TIMSK1 = (1 << TOIE1) ; // Enable timer1 overflow interrupt(TOIE1) 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();
} }
+17 -3
View File
@@ -9,6 +9,21 @@
#ifndef TIMER_H_ #ifndef TIMER_H_
#define 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 typedef enum _eTimerClockSel
{ {
TimerClockSel_none = 0, TimerClockSel_none = 0,
@@ -22,7 +37,6 @@ typedef enum _eTimerClockSel
TimerClockSel_mask = (1<<CS12) | (1<<CS11) | (1<<CS10), TimerClockSel_mask = (1<<CS12) | (1<<CS11) | (1<<CS10),
} TimerClockSel; } TimerClockSel;
void timer_init(uint16_t TIMER_RELOAD, TimerClockSel clockSel); void timer_init(Fifo *pFifo, uint16_t TIMER_RELOAD, TimerClockSel clockSel);
void timer_start(TimerId timerId, uint16_t count);
#endif /* TIMER_H_ */ #endif /* TIMER_H_ */
+1 -1
View File
@@ -156,7 +156,7 @@
</ListValues> </ListValues>
</avrgcc.assembler.general.IncludePaths> </avrgcc.assembler.general.IncludePaths>
<avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel> <avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel>
</AvrGcc> </AvrGcc>
</ToolchainSettings> </ToolchainSettings>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>