- 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:
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,16 +6,54 @@
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.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;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<<CS12) | (1<<CS11) | (1<<CS10),
|
||||
} 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_ */
|
||||
@@ -122,41 +122,41 @@
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<ToolchainSettings>
|
||||
<AvrGcc>
|
||||
<avrgcc.common.Device>-mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.150\gcc\dev\atmega328p"</avrgcc.common.Device>
|
||||
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
||||
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
||||
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
||||
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
|
||||
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
|
||||
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||
<avrgcc.compiler.symbols.DefSymbols>
|
||||
<ListValues>
|
||||
<Value>DEBUG</Value>
|
||||
</ListValues>
|
||||
</avrgcc.compiler.symbols.DefSymbols>
|
||||
<avrgcc.compiler.directories.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.150\include</Value>
|
||||
</ListValues>
|
||||
</avrgcc.compiler.directories.IncludePaths>
|
||||
<avrgcc.compiler.optimization.level>Optimize debugging experience (-Og)</avrgcc.compiler.optimization.level>
|
||||
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
||||
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
|
||||
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
||||
<avrgcc.linker.libraries.Libraries>
|
||||
<ListValues>
|
||||
<Value>libm</Value>
|
||||
</ListValues>
|
||||
</avrgcc.linker.libraries.Libraries>
|
||||
<avrgcc.assembler.general.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.150\include</Value>
|
||||
</ListValues>
|
||||
</avrgcc.assembler.general.IncludePaths>
|
||||
<avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel>
|
||||
</AvrGcc>
|
||||
<avrgcc.common.Device>-mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.150\gcc\dev\atmega328p"</avrgcc.common.Device>
|
||||
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
||||
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
||||
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
||||
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
|
||||
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
|
||||
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||
<avrgcc.compiler.symbols.DefSymbols>
|
||||
<ListValues>
|
||||
<Value>DEBUG</Value>
|
||||
</ListValues>
|
||||
</avrgcc.compiler.symbols.DefSymbols>
|
||||
<avrgcc.compiler.directories.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.150\include</Value>
|
||||
</ListValues>
|
||||
</avrgcc.compiler.directories.IncludePaths>
|
||||
<avrgcc.compiler.optimization.level>Optimize debugging experience (-Og)</avrgcc.compiler.optimization.level>
|
||||
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
||||
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
|
||||
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
||||
<avrgcc.linker.libraries.Libraries>
|
||||
<ListValues>
|
||||
<Value>libm</Value>
|
||||
</ListValues>
|
||||
</avrgcc.linker.libraries.Libraries>
|
||||
<avrgcc.assembler.general.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.150\include</Value>
|
||||
</ListValues>
|
||||
</avrgcc.assembler.general.IncludePaths>
|
||||
<avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel>
|
||||
</AvrGcc>
|
||||
</ToolchainSettings>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user