- 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:
2019-02-28 19:18:40 +00:00
parent a22ffe8384
commit 8a8bb762e0
7 changed files with 133 additions and 82 deletions
+33 -2
View File
@@ -5,19 +5,40 @@
* Author: jens
*/
#include <stddef.h>
#include <avr/io.h>
#include <avr/interrupt.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);
ADCSRA |= (1 << ADEN) | 7;
}
void adc_start_conversion(int ch)
void adc_start_conversion(size_t ch)
{
ADMUX = (ADMUX & 0xF0) | (ch & 0x0F) | (1 << REFS0);
ADCSRA |= (1 << ADSC) | (1 << ADIE);
adc_ch = ch & 0x0F;
}
int adc_is_fininshed()
@@ -25,3 +46,13 @@ int adc_is_fininshed()
return (int)(0 == (ADCSRA & (1 << ADSC)));
}
size_t adc_getChannel()
{
return adc_ch;
}
int16_t adc_getData()
{
return adc_value[adc_ch];
}
+6 -2
View File
@@ -9,8 +9,12 @@
#ifndef ADC_H_
#define ADC_H_
void adc_init();
void adc_start_conversion(int ch);
#include "fifo.h"
void adc_init(Fifo *pFifo);
void adc_start_conversion(size_t ch);
int adc_is_fininshed();
size_t adc_getChannel();
int16_t adc_getData();
#endif /* ADC_H_ */
+72 -74
View File
@@ -13,6 +13,7 @@
#include <avr/interrupt.h>
#include "fifo.h"
#include "message.h"
#include "adc.h"
#include "port.h"
#include "timer.h"
@@ -21,7 +22,6 @@
#include "mcp42x6.h"
#define ARDUINO_NANO 1
#define WITH_ADC_EVENTS 0
#define WITH_COMMAND_EVENTS 0
#define PRINT_PROMPT printf("\n:")
@@ -32,51 +32,17 @@
#endif
#define USART_BAUDRATE 38400UL
#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 int16_t adc_value[16];
static size_t adc_ch = 0;
static int16_t adc_last = 0;
static int pwr_Switch_state_last = 0;
static Fifo messageFifo;
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
}
static int timer_count = 0;
ISR(USART_RX_vect)
{
@@ -99,15 +65,24 @@ ISR(USART_RX_vect)
ISR (TIMER1_OVF_vect) // Timer1 ISR
{
Msg_t msg = {Timer, ledState};
fifo_push(&messageFifo, &msg);
TCNT1 = TIMER_HW_RELOAD;
TCNT1 = TIMER_RELOAD;
ledState++;
if (ledState == 4)
Msg_t msg = {Timer, ledState};
if (timer_count == 0)
{
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);
@@ -119,8 +94,8 @@ int main(void)
/* Replace with your application code */
uart_init(BAUD_PRESCALE);
timer_init(TIMER_RELOAD);
adc_init();
timer_init(TIMER_HW_RELOAD, TimerClockSel_PS_8);
adc_init(&messageFifo);
i2c_init();
port_init();
@@ -132,7 +107,7 @@ int main(void)
i2c_send(0x60, I2C_WRITE, dac_cmd, res);
sei();
adc_start_conversion(adc_ch);
adc_start_conversion(0x06);
char cmdStr[16];
size_t cmdStrSize = 0;
@@ -172,7 +147,7 @@ int main(void)
if (toupper(cmdStr[0]) == 'S')
{
uint16_t arg = atol(cmdStr+1);
portSet(PwrSwitch, arg != 0);
portSet(PwrSwitch_out, arg != 0);
}
cmdStrSize = 0;
PRINT_PROMPT;
@@ -202,32 +177,55 @@ int main(void)
case AdcComplete:
{
size_t ch = msg.data;
if (ch == 6)
if (adc_getChannel() == 6)
{
printf("ADC=%d\n", adc_value[ch]);
uint8_t dac_cmd[] = {0x00, 0x00}; // 6.2 Write Volatile Memory (C2:C0 = 010)
size_t res = MCP47x6_write_volatile_dac(adc_value[ch]<<2, dac_cmd, sizeof(dac_cmd));
i2c_send(0x60, I2C_WRITE, dac_cmd, res);
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;
}
}
}
break;
case Timer:
switch(msg.data)
{
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;
switch(msg.data)
{
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;
}
#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;
+2 -1
View File
@@ -14,7 +14,8 @@ enum PortItem
Led0 = 0,
Led1 = 1,
Led2 = 2,
PwrSwitch = 3,
PwrSwitch_out = 3,
PwrSwitch_in = 4,
NUM_ITEMS
};
+2 -2
View File
@@ -8,13 +8,13 @@
#include <avr/io.h>
#include "timer.h"
void timer_init(uint16_t TIMER_RELOAD)
void timer_init(uint16_t TIMER_RELOAD, TimerClockSel clockSel)
{
TCNT1 = TIMER_RELOAD;
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)
}
+15 -1
View File
@@ -9,6 +9,20 @@
#ifndef 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_ */
@@ -187,6 +187,9 @@
<Compile Include="mcp42x6.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="message.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="port.c">
<SubType>compile</SubType>
</Compile>