All pastes #1395470 Raw Edit

AVR Interface to 1994 Magna TS E

public text v1 · immutable
#1395470 ·published 2009-04-18 01:18 UTC
rendered paste body
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include "lcd.h"

#define FALSE 0
#define TRUE 1

#define USART_BAUD 1953
#define MY_UBRR (F_CPU/16/USART_BAUD)-1
static FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putc, NULL, _FDEV_SETUP_WRITE);

volatile int i = 0, c_req = 0, c_rep = 0, c_tx, c_rx;
volatile unsigned char ecu_response = '\0';
volatile unsigned char ecu_current_cmd = '\0';
volatile uint8_t ecu_status = 0; /* 0 = Ready, 1 = Waiting for reply, 2 = Own Response Received, 3 = Reply Received */
unsigned int timer1_last = 0;

void
adc_setup()
{
    ADCSRA |= /* PS=128 */_BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0) | _BV(ADIE) | _BV(ADEN);

    ADMUX |= _BV(REFS0); /* AVCC reference */
    // ADMUX |= _BV(ADLAR); /* Left-adjust values for easy 8-bit values */
}

void
uart_setup()
{
    UBRRH = ((MY_UBRR) >> 8);
    UBRRL = MY_UBRR;
    UCSRC |= _BV(URSEL) | _BV(UCSZ0) | _BV(UCSZ1);
    UCSRB |= _BV(RXEN) | _BV(TXEN) | _BV(RXCIE);
}

uint8_t
ecu_req(unsigned char req)
{
    if ((UCSRA & _BV(UDRE)) && (ecu_status == 0)) {
        ecu_current_cmd = req;
        UDR = req;
        ecu_status = 1;
        c_tx++;
        return TRUE;
    } else {
        return FALSE;
    }
}

uint8_t
ecu_reply()
{
    if (ecu_status == 4) {
        ecu_status = 0;
        return TRUE;
    } else {
        return FALSE;
    }
}

void
timer1_setup()
{
    TCCR1B |= _BV(CS10) | _BV(CS12);
}

int main(void)
{
    adc_setup();
    uart_setup();
    timer1_setup();
    sei(); /* Enable interrupts */

    lcd_init(LCD_DISP_ON);
    lcd_command(LCD_ON_CURSOR);
    stdout = &lcd_stream;
    printf("Penny.");

    for(;;) {
        unsigned int timer_check = 0;
        if (ecu_status == 4) {
            c_rep++;
            ecu_reply();
        } 
        if (ecu_status == 0) {
            c_req++;
            ecu_req(0x21);
        }

        timer_check = TCNT1;
        if (timer_check > 1800) {
            lcd_gotoxy(7, 1);
            fprintf(stdout, "E:%#x U:%3u", ecu_response, i);
            lcd_gotoxy(7, 2);
            fprintf(stdout, "T:%3u R:%3u", c_tx, c_rx);
            lcd_gotoxy(3, 3);
            fprintf(stdout, "S:%1u Q:%3u P:%3u",ecu_status, c_req, c_rep);
            TCNT1 = 0;
            i++;
        }
    }

    return 0;   /* never reached */
}

ISR(SIG_UART_RECV)
{
    char x;
    c_rx++;
    x = UDR;
    if (ecu_status == 1) {
        ecu_status = 2;
    } else if (ecu_status == 2) {
        ecu_response = x;
        ecu_status = 3;
    } else if (ecu_status == 3) {
        if (x == 0xe0) {
            ecu_status = 4;
        }
    }
}