- added power switch and command - temporarly disabled command and ADC event git-svn-id: http://moon:8086/svn/projects/HendiControl@23 fda53097-d464-4ada-af97-ba876c37ca34
242 lines
4.9 KiB
C
Executable File
242 lines
4.9 KiB
C
Executable File
/*
|
||
* uart_echo.c
|
||
*
|
||
* Created: 16.08.2018 17:39:49
|
||
* Author : jens
|
||
*/
|
||
|
||
#include <ctype.h>
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <avr/io.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 1
|
||
#define WITH_ADC_EVENTS 0
|
||
#define WITH_COMMAND_EVENTS 0
|
||
|
||
#define PRINT_PROMPT printf("\n:")
|
||
#if ARDUINO_NANO
|
||
#define F_CPU (16000000UL) // MHz
|
||
#else
|
||
#define F_CPU (18432000UL) // MHz
|
||
#endif
|
||
#define USART_BAUDRATE 38400UL
|
||
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
|
||
#define TIMER_RELOAD (0xFFFF-(F_CPU/1024/4-1))
|
||
static uint8_t ledState = 0;
|
||
static int16_t adc_value[16];
|
||
static size_t adc_ch = 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
|
||
}
|
||
|
||
ISR(USART_RX_vect)
|
||
{
|
||
uint8_t rx_data = UDR0;
|
||
#if WITH_COMMAND_EVENTS
|
||
if (rx_data == ' ')
|
||
{
|
||
Msg_t msg = {Error, rx_data};
|
||
fifo_push(&messageFifo, &msg);
|
||
}
|
||
else if (rx_data >= '0' && rx_data <= '9')
|
||
{
|
||
Msg_t msg = {Command, rx_data};
|
||
fifo_push(&messageFifo, &msg);
|
||
}
|
||
#endif
|
||
Msg_t msg = {Uart, rx_data};
|
||
fifo_push(&messageFifo, &msg);
|
||
}
|
||
|
||
ISR (TIMER1_OVF_vect) // Timer1 ISR
|
||
{
|
||
Msg_t msg = {Timer, ledState};
|
||
fifo_push(&messageFifo, &msg);
|
||
|
||
TCNT1 = TIMER_RELOAD;
|
||
ledState++;
|
||
if (ledState == 4)
|
||
{
|
||
ledState = 0;
|
||
}
|
||
}
|
||
|
||
FILE uart_file = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
|
||
|
||
int main(void)
|
||
|
||
{
|
||
fifo_init(&messageFifo, 64, sizeof(Msg_t), "Fifo");
|
||
|
||
/* Replace with your application code */
|
||
uart_init(BAUD_PRESCALE);
|
||
timer_init(TIMER_RELOAD);
|
||
adc_init();
|
||
i2c_init();
|
||
port_init();
|
||
|
||
stdout = &uart_file;
|
||
printf("\nHendi Control v1.0-beta\n");
|
||
|
||
uint8_t dac_cmd[] = {0x00, 0x00, 0x00}; // 6.1 Write Volatile DAC Register (C2:C0 = ‘00x’)
|
||
size_t res = MCP47x6_write_volatile_mem(0x0000, dac_cmd, sizeof(dac_cmd));
|
||
i2c_send(0x60, I2C_WRITE, dac_cmd, res);
|
||
|
||
sei();
|
||
adc_start_conversion(adc_ch);
|
||
|
||
char cmdStr[16];
|
||
size_t cmdStrSize = 0;
|
||
PRINT_PROMPT;
|
||
while (1)
|
||
{
|
||
Msg_t msg;
|
||
if (!fifo_isEmpty(&messageFifo))
|
||
{
|
||
cli();
|
||
fifo_pop(&messageFifo, &msg);
|
||
sei();
|
||
|
||
switch(msg.code)
|
||
{
|
||
case Uart:
|
||
{
|
||
// Process Uart message
|
||
cmdStr[cmdStrSize] = 0;
|
||
if (cmdStrSize < sizeof(cmdStr))
|
||
{
|
||
char c = msg.data;
|
||
|
||
// Command finished with CR/LF
|
||
if (c == 0x0A || c == 0x0D)
|
||
{
|
||
// Power Control
|
||
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);
|
||
}
|
||
|
||
// Switch Control
|
||
if (toupper(cmdStr[0]) == 'S')
|
||
{
|
||
uint16_t arg = atol(cmdStr+1);
|
||
portSet(PwrSwitch, arg != 0);
|
||
}
|
||
cmdStrSize = 0;
|
||
PRINT_PROMPT;
|
||
}
|
||
else
|
||
{
|
||
cmdStr[cmdStrSize++] = c;
|
||
printf("%c", c);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("Invalid command : %s\n", cmdStr);
|
||
cmdStrSize = 0;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case Command:
|
||
{
|
||
printf("Command : %c\n", msg.data);
|
||
uint8_t dac_cmd[] = {0x00, 0x00}; // 6.2 Write Volatile Memory (C2:C0 = ‘010’)
|
||
size_t res = MCP47x6_write_volatile_dac((uint16_t)(msg.data-'0')<<8, dac_cmd, sizeof(dac_cmd));
|
||
i2c_send(0x60, I2C_WRITE, dac_cmd, res);
|
||
}
|
||
break;
|
||
|
||
case AdcComplete:
|
||
{
|
||
size_t ch = msg.data;
|
||
if (ch == 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);
|
||
}
|
||
}
|
||
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;
|
||
}
|
||
break;
|
||
|
||
case Error:
|
||
printf("Error!!!\n");
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|