- adc is event based
- changed timer frequency - prepared for SW timer - added PowerSwitch_in git-svn-id: http://moon:8086/svn/projects/HendiControl@30 fda53097-d464-4ada-af97-ba876c37ca34
This commit is contained in:
@@ -5,19 +5,40 @@
|
|||||||
* Author: jens
|
* Author: jens
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
void adc_init()
|
static int16_t adc_value[16];
|
||||||
|
static size_t adc_ch = 0;
|
||||||
|
static Fifo *g_pFifo = NULL;
|
||||||
|
|
||||||
|
ISR(ADC_vect)
|
||||||
{
|
{
|
||||||
|
int16_t value_low = (int16_t)ADCL;
|
||||||
|
int16_t value_high = (int16_t)ADCH;
|
||||||
|
ADCSRA |= (1<<ADIF);
|
||||||
|
int16_t value = value_high << 8 | value_low;
|
||||||
|
adc_value[adc_ch] = value;
|
||||||
|
|
||||||
|
Msg_t msg = {AdcComplete, adc_getChannel()};
|
||||||
|
fifo_push(g_pFifo, &msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void adc_init(Fifo *pFifo)
|
||||||
|
{
|
||||||
|
g_pFifo = pFifo;
|
||||||
PRR &= ~(1 << PRADC);
|
PRR &= ~(1 << PRADC);
|
||||||
ADCSRA |= (1 << ADEN) | 7;
|
ADCSRA |= (1 << ADEN) | 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc_start_conversion(int ch)
|
void adc_start_conversion(size_t ch)
|
||||||
{
|
{
|
||||||
ADMUX = (ADMUX & 0xF0) | (ch & 0x0F) | (1 << REFS0);
|
ADMUX = (ADMUX & 0xF0) | (ch & 0x0F) | (1 << REFS0);
|
||||||
ADCSRA |= (1 << ADSC) | (1 << ADIE);
|
ADCSRA |= (1 << ADSC) | (1 << ADIE);
|
||||||
|
adc_ch = ch & 0x0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
int adc_is_fininshed()
|
int adc_is_fininshed()
|
||||||
@@ -25,3 +46,13 @@ int adc_is_fininshed()
|
|||||||
return (int)(0 == (ADCSRA & (1 << ADSC)));
|
return (int)(0 == (ADCSRA & (1 << ADSC)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t adc_getChannel()
|
||||||
|
{
|
||||||
|
return adc_ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t adc_getData()
|
||||||
|
{
|
||||||
|
return adc_value[adc_ch];
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,12 @@
|
|||||||
#ifndef ADC_H_
|
#ifndef ADC_H_
|
||||||
#define ADC_H_
|
#define ADC_H_
|
||||||
|
|
||||||
void adc_init();
|
#include "fifo.h"
|
||||||
void adc_start_conversion(int ch);
|
|
||||||
|
void adc_init(Fifo *pFifo);
|
||||||
|
void adc_start_conversion(size_t ch);
|
||||||
int adc_is_fininshed();
|
int adc_is_fininshed();
|
||||||
|
size_t adc_getChannel();
|
||||||
|
int16_t adc_getData();
|
||||||
|
|
||||||
#endif /* ADC_H_ */
|
#endif /* ADC_H_ */
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
#include "fifo.h"
|
#include "fifo.h"
|
||||||
|
#include "message.h"
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
@@ -21,7 +22,6 @@
|
|||||||
#include "mcp42x6.h"
|
#include "mcp42x6.h"
|
||||||
|
|
||||||
#define ARDUINO_NANO 1
|
#define ARDUINO_NANO 1
|
||||||
#define WITH_ADC_EVENTS 0
|
|
||||||
#define WITH_COMMAND_EVENTS 0
|
#define WITH_COMMAND_EVENTS 0
|
||||||
|
|
||||||
#define PRINT_PROMPT printf("\n:")
|
#define PRINT_PROMPT printf("\n:")
|
||||||
@@ -32,51 +32,17 @@
|
|||||||
#endif
|
#endif
|
||||||
#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_RELOAD (0xFFFF-(F_CPU/1024/4-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_HW_RELOAD (0xFFFF-(TIMER_HW_CLOCK/TIMER_IRQ_CLOCK))
|
||||||
static uint8_t ledState = 0;
|
static uint8_t ledState = 0;
|
||||||
static int16_t adc_value[16];
|
static int16_t adc_last = 0;
|
||||||
static size_t adc_ch = 0;
|
static int pwr_Switch_state_last = 0;
|
||||||
static Fifo messageFifo;
|
static Fifo messageFifo;
|
||||||
|
static int timer_count = 0;
|
||||||
enum MessageCode
|
|
||||||
{
|
|
||||||
NOP=0,
|
|
||||||
Uart,
|
|
||||||
Timer,
|
|
||||||
AdcComplete,
|
|
||||||
Command,
|
|
||||||
Error = 0xFF
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _sMsg_t
|
|
||||||
{
|
|
||||||
uint8_t code;
|
|
||||||
uint8_t data;
|
|
||||||
} Msg_t;
|
|
||||||
|
|
||||||
ISR(ADC_vect)
|
|
||||||
{
|
|
||||||
#if WITH_ADC_EVENTS
|
|
||||||
int16_t value_low = (int16_t)ADCL;
|
|
||||||
int16_t value_high = (int16_t)ADCH;
|
|
||||||
ADCSRA |= (1<<ADIF);
|
|
||||||
int16_t value = value_high << 8 | value_low;
|
|
||||||
|
|
||||||
if (((adc_value[adc_ch] - value) < -1) || ((adc_value[adc_ch] - value) > 1))
|
|
||||||
{
|
|
||||||
Msg_t msg = {AdcComplete, adc_ch};
|
|
||||||
fifo_push(&messageFifo, &msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
adc_value[adc_ch] = value;
|
|
||||||
adc_ch++;
|
|
||||||
if (adc_ch == 16)
|
|
||||||
{
|
|
||||||
adc_ch = 0;
|
|
||||||
}
|
|
||||||
adc_start_conversion(adc_ch);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
ISR(USART_RX_vect)
|
ISR(USART_RX_vect)
|
||||||
{
|
{
|
||||||
@@ -99,15 +65,24 @@ ISR(USART_RX_vect)
|
|||||||
|
|
||||||
ISR (TIMER1_OVF_vect) // Timer1 ISR
|
ISR (TIMER1_OVF_vect) // Timer1 ISR
|
||||||
{
|
{
|
||||||
Msg_t msg = {Timer, ledState};
|
TCNT1 = TIMER_HW_RELOAD;
|
||||||
fifo_push(&messageFifo, &msg);
|
|
||||||
|
|
||||||
TCNT1 = TIMER_RELOAD;
|
Msg_t msg = {Timer, ledState};
|
||||||
ledState++;
|
if (timer_count == 0)
|
||||||
if (ledState == 4)
|
|
||||||
{
|
{
|
||||||
ledState = 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);
|
||||||
@@ -119,8 +94,8 @@ int main(void)
|
|||||||
|
|
||||||
/* Replace with your application code */
|
/* Replace with your application code */
|
||||||
uart_init(BAUD_PRESCALE);
|
uart_init(BAUD_PRESCALE);
|
||||||
timer_init(TIMER_RELOAD);
|
timer_init(TIMER_HW_RELOAD, TimerClockSel_PS_8);
|
||||||
adc_init();
|
adc_init(&messageFifo);
|
||||||
i2c_init();
|
i2c_init();
|
||||||
port_init();
|
port_init();
|
||||||
|
|
||||||
@@ -132,7 +107,7 @@ int main(void)
|
|||||||
i2c_send(0x60, I2C_WRITE, dac_cmd, res);
|
i2c_send(0x60, I2C_WRITE, dac_cmd, res);
|
||||||
|
|
||||||
sei();
|
sei();
|
||||||
adc_start_conversion(adc_ch);
|
adc_start_conversion(0x06);
|
||||||
|
|
||||||
char cmdStr[16];
|
char cmdStr[16];
|
||||||
size_t cmdStrSize = 0;
|
size_t cmdStrSize = 0;
|
||||||
@@ -172,7 +147,7 @@ int main(void)
|
|||||||
if (toupper(cmdStr[0]) == 'S')
|
if (toupper(cmdStr[0]) == 'S')
|
||||||
{
|
{
|
||||||
uint16_t arg = atol(cmdStr+1);
|
uint16_t arg = atol(cmdStr+1);
|
||||||
portSet(PwrSwitch, arg != 0);
|
portSet(PwrSwitch_out, arg != 0);
|
||||||
}
|
}
|
||||||
cmdStrSize = 0;
|
cmdStrSize = 0;
|
||||||
PRINT_PROMPT;
|
PRINT_PROMPT;
|
||||||
@@ -202,32 +177,55 @@ int main(void)
|
|||||||
|
|
||||||
case AdcComplete:
|
case AdcComplete:
|
||||||
{
|
{
|
||||||
size_t ch = msg.data;
|
if (adc_getChannel() == 6)
|
||||||
if (ch == 6)
|
|
||||||
{
|
{
|
||||||
printf("ADC=%d\n", adc_value[ch]);
|
int16_t adc_curr = adc_getData();
|
||||||
uint8_t dac_cmd[] = {0x00, 0x00}; // 6.2 Write Volatile Memory (C2:C0 = ‘010’)
|
if (((adc_curr - adc_last) < -1) || ((adc_curr - adc_last) > 1))
|
||||||
size_t res = MCP47x6_write_volatile_dac(adc_value[ch]<<2, dac_cmd, sizeof(dac_cmd));
|
{
|
||||||
i2c_send(0x60, I2C_WRITE, dac_cmd, res);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Timer:
|
case Timer:
|
||||||
switch(msg.data)
|
|
||||||
{
|
{
|
||||||
case 0:
|
switch(msg.data)
|
||||||
PORTB = (PORTB & 0xFC) | 0x00;
|
{
|
||||||
break;
|
case 0:
|
||||||
case 1:
|
PORTB = (PORTB & 0xFC) | 0x00;
|
||||||
PORTB = (PORTB & 0xFC) | 0x01;
|
break;
|
||||||
break;
|
case 1:
|
||||||
case 2:
|
PORTB = (PORTB & 0xFC) | 0x01;
|
||||||
PORTB = (PORTB & 0xFC) | 0x03;
|
break;
|
||||||
break;
|
case 2:
|
||||||
case 3:
|
PORTB = (PORTB & 0xFC) | 0x03;
|
||||||
PORTB = (PORTB & 0xFC) | 0x02;
|
break;
|
||||||
break;
|
case 3:
|
||||||
|
PORTB = (PORTB & 0xFC) | 0x02;
|
||||||
|
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;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ enum PortItem
|
|||||||
Led0 = 0,
|
Led0 = 0,
|
||||||
Led1 = 1,
|
Led1 = 1,
|
||||||
Led2 = 2,
|
Led2 = 2,
|
||||||
PwrSwitch = 3,
|
PwrSwitch_out = 3,
|
||||||
|
PwrSwitch_in = 4,
|
||||||
NUM_ITEMS
|
NUM_ITEMS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
void timer_init(uint16_t TIMER_RELOAD)
|
void timer_init(uint16_t TIMER_RELOAD, TimerClockSel clockSel)
|
||||||
{
|
{
|
||||||
|
|
||||||
TCNT1 = TIMER_RELOAD;
|
TCNT1 = TIMER_RELOAD;
|
||||||
|
|
||||||
TCCR1A = 0x00;
|
TCCR1A = 0x00;
|
||||||
TCCR1B = (1<<CS10) | (1<<CS12); // Timer mode with 1024 prescaler
|
TCCR1B = (TCCR1B & TimerClockSel_mask) | clockSel;
|
||||||
TIMSK1 = (1 << TOIE1) ; // Enable timer1 overflow interrupt(TOIE1)
|
TIMSK1 = (1 << TOIE1) ; // Enable timer1 overflow interrupt(TOIE1)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,20 @@
|
|||||||
#ifndef TIMER_H_
|
#ifndef TIMER_H_
|
||||||
#define TIMER_H_
|
#define TIMER_H_
|
||||||
|
|
||||||
void timer_init(uint16_t TIMER_RELOAD);
|
typedef enum _eTimerClockSel
|
||||||
|
{
|
||||||
|
TimerClockSel_none = 0,
|
||||||
|
TimerClockSel_PS_1 = (1<<CS10),
|
||||||
|
TimerClockSel_PS_8 = (1<<CS11),
|
||||||
|
TimerClockSel_PS_64 = (1<<CS11) | (1<<CS10),
|
||||||
|
TimerClockSel_PS_256 = (1<<CS12),
|
||||||
|
TimerClockSel_PS_1024 = (1<<CS12) | (1<<CS10),
|
||||||
|
TimerClockSel_ext_T1_neg = (1<<CS12) | (1<<CS11),
|
||||||
|
TimerClockSel_ext_T1_pos = (1<<CS12) | (1<<CS11) | (1<<CS10),
|
||||||
|
TimerClockSel_mask = (1<<CS12) | (1<<CS11) | (1<<CS10),
|
||||||
|
} TimerClockSel;
|
||||||
|
|
||||||
|
void timer_init(uint16_t TIMER_RELOAD, TimerClockSel clockSel);
|
||||||
|
|
||||||
|
|
||||||
#endif /* TIMER_H_ */
|
#endif /* TIMER_H_ */
|
||||||
@@ -187,6 +187,9 @@
|
|||||||
<Compile Include="mcp42x6.h">
|
<Compile Include="mcp42x6.h">
|
||||||
<SubType>compile</SubType>
|
<SubType>compile</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="message.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="port.c">
|
<Compile Include="port.c">
|
||||||
<SubType>compile</SubType>
|
<SubType>compile</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
Reference in New Issue
Block a user