/* * uart_echo.c * * Created: 16.08.2018 17:39:49 * Author : jens */ #include #include #include #include #include #include "fifo.h" #include "adc.h" #include "port.h" #include "timer.h" #include "uart.h" #include "i2c.h" #include "mcp42x6.h" #define ARDUINO_NANO #ifdef 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, Command, Uart, Timer, AdcComplete, Error = 0xFF }; typedef struct _sMsg_t { uint8_t code; uint8_t data; } Msg_t; ISR(ADC_vect) { int16_t value_low = (int16_t)ADCL; int16_t value_high = (int16_t)ADCH; ADCSRA |= (1< 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); } ISR(USART_RX_vect) { uint8_t rx_data = UDR0; 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); } 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(); stdout = &uart_file; printf("UART test version 1.0\n\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; while (1) { Msg_t msg; if (!fifo_isEmpty(&messageFifo)) { cli(); fifo_pop(&messageFifo, &msg); sei(); 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: { 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: DDRB = (DDRB & 0xFC) | 0x00; printf("----------- Timer -----------\n"); break; case 1: DDRB = (DDRB & 0xFC) | 0x01; break; case 2: DDRB = (DDRB & 0xFC) | 0x03; break; case 3: DDRB = (DDRB & 0xFC) | 0x02; break; } break; case Error: printf("Error!!!\n"); break; } } } }