Files
HendiControlFirmware/Control/firmware/uart_echo/main.c
T
jens 8a8bb762e0 - 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
2019-02-28 19:18:40 +00:00

240 lines
5.2 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 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 "message.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_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_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_last = 0;
static int pwr_Switch_state_last = 0;
static Fifo messageFifo;
static int timer_count = 0;
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
{
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)
{
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);
adc_init(&messageFifo);
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(0x06);
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_out, 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:
{
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;
}
}
}
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;
}
#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;
case Error:
printf("Error!!!\n");
break;
}
}
}
}