-refactored
git-svn-id: http://moon:8086/svn/projects/HendiControl@22 fda53097-d464-4ada-af97-ba876c37ca34
This commit is contained in:
@@ -10,6 +10,15 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
#include "fifo.h"
|
||||||
|
#include "adc.h"
|
||||||
|
#include "port.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "uart.h"
|
||||||
|
#include "i2c.h"
|
||||||
|
#include "mcp42x6.h"
|
||||||
|
|
||||||
#define ARDUINO_NANO
|
#define ARDUINO_NANO
|
||||||
|
|
||||||
#ifdef ARDUINO_NANO
|
#ifdef ARDUINO_NANO
|
||||||
@@ -23,11 +32,13 @@
|
|||||||
static uint8_t ledState = 0;
|
static uint8_t ledState = 0;
|
||||||
static int16_t adc_value[16];
|
static int16_t adc_value[16];
|
||||||
static size_t adc_ch = 0;
|
static size_t adc_ch = 0;
|
||||||
|
static Fifo messageFifo;
|
||||||
|
|
||||||
enum MessageCode
|
enum MessageCode
|
||||||
{
|
{
|
||||||
NOP=0,
|
NOP=0,
|
||||||
Command,
|
Command,
|
||||||
|
Uart,
|
||||||
Timer,
|
Timer,
|
||||||
AdcComplete,
|
AdcComplete,
|
||||||
Error = 0xFF
|
Error = 0xFF
|
||||||
@@ -39,84 +50,6 @@ typedef struct _sMsg_t
|
|||||||
uint8_t data;
|
uint8_t data;
|
||||||
} Msg_t;
|
} Msg_t;
|
||||||
|
|
||||||
typedef struct _sFifo
|
|
||||||
{
|
|
||||||
void **ppData;
|
|
||||||
size_t capacity;
|
|
||||||
size_t itemSize;
|
|
||||||
size_t fill;
|
|
||||||
size_t wi;
|
|
||||||
size_t ri;
|
|
||||||
const char *pName;
|
|
||||||
} Fifo;
|
|
||||||
|
|
||||||
static Fifo messageFifo;
|
|
||||||
|
|
||||||
void Fifo_init(Fifo *pObj, size_t capacity, size_t itemSize, const char *pName)
|
|
||||||
{
|
|
||||||
pObj->wi = 0;
|
|
||||||
pObj->ri = 0;
|
|
||||||
pObj->fill = 0;
|
|
||||||
pObj->capacity = capacity;
|
|
||||||
pObj->itemSize = itemSize;
|
|
||||||
pObj->ppData = (void**)malloc(capacity);
|
|
||||||
|
|
||||||
for (int i=0; i < capacity; i++)
|
|
||||||
{
|
|
||||||
pObj->ppData[i] = (void*)malloc(itemSize);
|
|
||||||
}
|
|
||||||
pObj->pName = pName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Fifo_free(Fifo *pObj)
|
|
||||||
{
|
|
||||||
for (int i=0; i < pObj->capacity; i++)
|
|
||||||
{
|
|
||||||
free(pObj->ppData[i]);
|
|
||||||
}
|
|
||||||
free (pObj->ppData);
|
|
||||||
pObj->itemSize = 0;
|
|
||||||
pObj->capacity = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Fifo_push(Fifo *pObj, void *pItem)
|
|
||||||
{
|
|
||||||
if (pObj->fill >= pObj->capacity)
|
|
||||||
{
|
|
||||||
printf("%s: Fifo is full\n", pObj->pName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memcpy(pObj->ppData[pObj->wi], pItem, pObj->itemSize);
|
|
||||||
pObj->wi++;
|
|
||||||
pObj->fill++;
|
|
||||||
if (pObj->wi == pObj->capacity)
|
|
||||||
{
|
|
||||||
pObj->wi = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int Fifo_pop(Fifo *pObj, void *pItem)
|
|
||||||
{
|
|
||||||
if (!pObj->fill)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memcpy(pItem, pObj->ppData[pObj->ri], pObj->itemSize);
|
|
||||||
pObj->ri++;
|
|
||||||
pObj->fill--;
|
|
||||||
if (pObj->ri == pObj->capacity)
|
|
||||||
{
|
|
||||||
pObj->ri = 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Fifo_isEmpty(Fifo *pObj)
|
|
||||||
{
|
|
||||||
return pObj->fill == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void adc_start_conversion(int ch);
|
|
||||||
ISR(ADC_vect)
|
ISR(ADC_vect)
|
||||||
{
|
{
|
||||||
int16_t value_low = (int16_t)ADCL;
|
int16_t value_low = (int16_t)ADCL;
|
||||||
@@ -127,7 +60,7 @@ ISR(ADC_vect)
|
|||||||
if (((adc_value[adc_ch] - value) < -1) || ((adc_value[adc_ch] - value) > 1))
|
if (((adc_value[adc_ch] - value) < -1) || ((adc_value[adc_ch] - value) > 1))
|
||||||
{
|
{
|
||||||
Msg_t msg = {AdcComplete, adc_ch};
|
Msg_t msg = {AdcComplete, adc_ch};
|
||||||
Fifo_push(&messageFifo, &msg);
|
fifo_push(&messageFifo, &msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
adc_value[adc_ch] = value;
|
adc_value[adc_ch] = value;
|
||||||
@@ -145,19 +78,21 @@ ISR(USART_RX_vect)
|
|||||||
if (rx_data == ' ')
|
if (rx_data == ' ')
|
||||||
{
|
{
|
||||||
Msg_t msg = {Error, rx_data};
|
Msg_t msg = {Error, rx_data};
|
||||||
Fifo_push(&messageFifo, &msg);
|
fifo_push(&messageFifo, &msg);
|
||||||
}
|
}
|
||||||
else if (rx_data >= '0' && rx_data <= '9')
|
else if (rx_data >= '0' && rx_data <= '9')
|
||||||
{
|
{
|
||||||
Msg_t msg = {Command, rx_data};
|
Msg_t msg = {Command, rx_data};
|
||||||
Fifo_push(&messageFifo, &msg);
|
fifo_push(&messageFifo, &msg);
|
||||||
}
|
}
|
||||||
|
Msg_t msg = {Uart, rx_data};
|
||||||
|
fifo_push(&messageFifo, &msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
ISR (TIMER1_OVF_vect) // Timer1 ISR
|
ISR (TIMER1_OVF_vect) // Timer1 ISR
|
||||||
{
|
{
|
||||||
Msg_t msg = {Timer, ledState};
|
Msg_t msg = {Timer, ledState};
|
||||||
Fifo_push(&messageFifo, &msg);
|
fifo_push(&messageFifo, &msg);
|
||||||
|
|
||||||
TCNT1 = TIMER_RELOAD;
|
TCNT1 = TIMER_RELOAD;
|
||||||
ledState++;
|
ledState++;
|
||||||
@@ -167,201 +102,15 @@ ISR (TIMER1_OVF_vect) // Timer1 ISR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_init()
|
|
||||||
{
|
|
||||||
// Set baud rate
|
|
||||||
UBRR0L = (uint8_t)BAUD_PRESCALE;
|
|
||||||
UBRR0H = (uint8_t)(BAUD_PRESCALE >> 8);
|
|
||||||
|
|
||||||
// Enable receiver and transmitter
|
|
||||||
UCSR0B = (1<<TXEN0)|(1<<RXEN0);
|
|
||||||
|
|
||||||
// Enable RX interrupt
|
|
||||||
UCSR0B |= (1<<RXCIE0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void timer_init()
|
|
||||||
{
|
|
||||||
|
|
||||||
TCNT1 = TIMER_RELOAD;
|
|
||||||
|
|
||||||
TCCR1A = 0x00;
|
|
||||||
TCCR1B = (1<<CS10) | (1<<CS12); // Timer mode with 1024 prescaler
|
|
||||||
TIMSK1 = (1 << TOIE1) ; // Enable timer1 overflow interrupt(TOIE1)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
enum I2C
|
|
||||||
{
|
|
||||||
I2C_START = 0x08,
|
|
||||||
I2C_REPEATED_START = 0x10,
|
|
||||||
I2C_SLA_ACK = 0x18,
|
|
||||||
I2C_SLA_NACK = 0x20,
|
|
||||||
I2C_DATA_ACK = 0x28,
|
|
||||||
I2C_DATA_NACK = 0x30,
|
|
||||||
I2C_LOST = 0x38,
|
|
||||||
I2C_READ = 0x01,
|
|
||||||
I2C_WRITE = 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
void i2c_init()
|
|
||||||
{
|
|
||||||
TWBR = 0xFF;
|
|
||||||
TWSR = 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
void i2c_send(uint8_t addr, uint8_t rw, uint8_t *data, size_t size)
|
|
||||||
{
|
|
||||||
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
|
|
||||||
// Send START condition
|
|
||||||
do
|
|
||||||
{
|
|
||||||
while (!(TWCR &(1<<TWINT))); // Wait for TWINT Flag set. This indicates
|
|
||||||
// that the START condition has been
|
|
||||||
// transmitted.
|
|
||||||
if((TWSR & 0xF8) != I2C_START)
|
|
||||||
{
|
|
||||||
printf("Error I2C_START\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
TWDR = addr<<1 | rw; // Load SLA_W into TWDR Register. Clear
|
|
||||||
// TWINT bit in TWCR to start transmission of
|
|
||||||
// address.
|
|
||||||
TWCR = (1<<TWINT) | (1<<TWEN);
|
|
||||||
while (!(TWCR &(1<<TWINT))); // Wait for TWINT Flag set. This indicates
|
|
||||||
// that the SLA+W has been transmitted, and
|
|
||||||
// ACK/NACK has been received.
|
|
||||||
|
|
||||||
|
|
||||||
if ((TWSR & 0xF8) != I2C_SLA_ACK)
|
|
||||||
{
|
|
||||||
printf("Error I2C_SLA_ACK\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Check value of TWI Status Register. Mask
|
|
||||||
// prescaler bits. If status different from
|
|
||||||
// MT_SLA_ACK go to ERROR
|
|
||||||
for (size_t i=0; i < size; i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
TWDR = *(data++);
|
|
||||||
TWCR = (1<<TWINT) | (1<<TWEN);
|
|
||||||
// Load DATA into TWDR Register. Clear
|
|
||||||
// TWINT bit in TWCR to start transmission of
|
|
||||||
// data.
|
|
||||||
|
|
||||||
while (!(TWCR & (1<<TWINT)));
|
|
||||||
// Wait for TWINT Flag set. This indicates
|
|
||||||
// that the DATA has been transmitted, and
|
|
||||||
// ACK/NACK has been received}
|
|
||||||
|
|
||||||
if ((TWSR & 0xF8) != I2C_DATA_ACK)
|
|
||||||
{
|
|
||||||
printf("Error I2C_DATA_ACK\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Check value of TWI Status Register. Mask
|
|
||||||
// prescaler bits. If status different from
|
|
||||||
// MT_DATA_ACK go to ERROR.
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (0);
|
|
||||||
TWCR = (1<<TWINT)| (1<<TWEN)|(1<<TWSTO); // Transmit STOP condition.
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void adc_init()
|
|
||||||
{
|
|
||||||
PRR &= ~(1 << PRADC);
|
|
||||||
ADCSRA |= (1 << ADEN) | 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
void adc_start_conversion(int ch)
|
|
||||||
{
|
|
||||||
ADMUX = (ADMUX & 0xF0) | (ch & 0x0F) | (1 << REFS0);
|
|
||||||
ADCSRA |= (1 << ADSC) | (1 << ADIE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int adc_is_fininshed()
|
|
||||||
{
|
|
||||||
return (int)(0 == (ADCSRA & (1 << ADSC)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void uart_putc(char c)
|
|
||||||
{
|
|
||||||
while((UCSR0A & (1<<UDRE0)) == 0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
UDR0 = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uart_putchar(char c, FILE *stream)
|
|
||||||
{
|
|
||||||
uart_putc(c);
|
|
||||||
if (c == 0x0A)
|
|
||||||
{
|
|
||||||
uart_putc(0x0D);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uart_puts(char const *str)
|
|
||||||
{
|
|
||||||
while(*str)
|
|
||||||
{
|
|
||||||
char c = *(str++);
|
|
||||||
uart_putc(c);
|
|
||||||
if (c == 0x0A)
|
|
||||||
{
|
|
||||||
uart_putc(0x0D);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void port_init()
|
|
||||||
{
|
|
||||||
PORTB = PORTB | 0x03;
|
|
||||||
DDRB = DDB1 | DDB2;
|
|
||||||
|
|
||||||
}
|
|
||||||
FILE uart_file = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
|
FILE uart_file = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
|
||||||
|
|
||||||
enum MCP47x6_flags
|
|
||||||
{
|
|
||||||
C0 = 0x20,
|
|
||||||
C1 = 0x40,
|
|
||||||
C2 = 0x80,
|
|
||||||
PDN0 = 0x10,
|
|
||||||
PDN1 = 0x20,
|
|
||||||
mask = 0xF0
|
|
||||||
};
|
|
||||||
|
|
||||||
size_t MCP47x6_write_volatile_dac(uint16_t dac_value, uint8_t *buffer, size_t size)
|
|
||||||
{
|
|
||||||
*(buffer++) = ~mask & (uint8_t)(dac_value >> 8);
|
|
||||||
*(buffer++) = (uint8_t)(dac_value >> 0);
|
|
||||||
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t MCP47x6_write_volatile_mem(uint16_t dac_value, uint8_t *buffer, size_t size)
|
|
||||||
{
|
|
||||||
*(buffer++) = mask & 0x40;
|
|
||||||
dac_value <<= 4;
|
|
||||||
*(buffer++) = (uint8_t)(dac_value >> 8);
|
|
||||||
*(buffer++) = (uint8_t)(dac_value >> 0);
|
|
||||||
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
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();
|
uart_init(BAUD_PRESCALE);
|
||||||
timer_init();
|
timer_init(TIMER_RELOAD);
|
||||||
adc_init();
|
adc_init();
|
||||||
i2c_init();
|
i2c_init();
|
||||||
|
|
||||||
@@ -374,17 +123,44 @@ int main(void)
|
|||||||
|
|
||||||
sei();
|
sei();
|
||||||
adc_start_conversion(adc_ch);
|
adc_start_conversion(adc_ch);
|
||||||
|
|
||||||
|
char cmdStr[16];
|
||||||
|
size_t cmdStrSize = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
Msg_t msg;
|
Msg_t msg;
|
||||||
if (!Fifo_isEmpty(&messageFifo))
|
if (!fifo_isEmpty(&messageFifo))
|
||||||
{
|
{
|
||||||
cli();
|
cli();
|
||||||
Fifo_pop(&messageFifo, &msg);
|
fifo_pop(&messageFifo, &msg);
|
||||||
sei();
|
sei();
|
||||||
|
|
||||||
switch(msg.code)
|
switch(msg.code)
|
||||||
{
|
{
|
||||||
|
case Uart:
|
||||||
|
{
|
||||||
|
cmdStr[cmdStrSize] = 0;
|
||||||
|
if (cmdStrSize < sizeof(cmdStr))
|
||||||
|
{
|
||||||
|
char c = msg.data;
|
||||||
|
if (c == 0x0A || c == 0x0D)
|
||||||
|
{
|
||||||
|
printf("Command : %s\n", cmdStr);
|
||||||
|
cmdStrSize = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmdStr[cmdStrSize++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Invalid command : %s\n", cmdStr);
|
||||||
|
cmdStrSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case Command:
|
case Command:
|
||||||
{
|
{
|
||||||
printf("Command : %c\n", msg.data);
|
printf("Command : %c\n", msg.data);
|
||||||
|
|||||||
@@ -160,9 +160,51 @@
|
|||||||
</ToolchainSettings>
|
</ToolchainSettings>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="adc.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="adc.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="fifo.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="fifo.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="i2c.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="i2c.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="main.c">
|
<Compile Include="main.c">
|
||||||
<SubType>compile</SubType>
|
<SubType>compile</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="mcp42x6.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="mcp42x6.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="port.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="port.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="timer.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="timer.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="uart.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="uart.h">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
|
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
Reference in New Issue
Block a user