firmware.c

/*
Microcontroller firmware for the Wifon project
copyright Andrzej Surowiec 2010
emeryth@gmail.com
*/
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/sleep.h>
#define F_CPU 8000000UL
#include <util/delay.h>
#include <stdlib.h>
#define FOSC 8000000
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

void print(char indx, char indy, char pointer);


int address = 0;
unsigned char character = 0;
unsigned char row = 0;
unsigned char col = 0;
unsigned char change = 0;
char bootsplash = 1;
long int result = 0;
char counter = 0;

void USART_Init(unsigned int ubrr) {
    /*Set baud rate */
    UBRR0H = (unsigned char) (ubrr >> 8);
    UBRR0L = (unsigned char) ubrr;
    UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
    /* Set frame format: 8data, 1stop bit */
    UCSR0C = (1 << USBS0) | (3 << UCSZ00);
}

/*Send a character through UART*/
void USART_Transmit(unsigned char data) {
    /* Wait for empty transmit buffer */
    while (!(UCSR0A & (1 << UDRE0)))
        ;
    /* Put data into buffer, sends the data */
    UDR0 = data;
}

/*Send a string of characters through UART*/
void send_str(unsigned char text[], unsigned char n) {
    unsigned char i;
    for (i = 0; i < n; i++) {
        USART_Transmit(text[i]);
    }
    USART_Transmit(13);
}

/*Calculates the address of a cell on the display*/
char calculate_addr(char a) {
    if (a >= 0 && a < 16)return a;
    else if (a >= 16 && a < 32)return a + 48;
    else if (a >= 32 && a < 48)return a - 16;
    else if (a >= 48 && a < 64)return a + 32;
    return 0;
}



unsigned int debounce = 0;

/*Interrupt after receiving a character through UART*/
ISR(USART_RX_vect) {
    character = UDR0;
    if (bootsplash == 1 || counter < 120) {

        if (character == 2) {
            address = 0;
            bootsplash = 0;
        }
        if (address < 16 && character >= 32 && character < 126) {
            write(calculate_addr(address + 48), character);
            address++;
        }
        if (character == 13) {
            address = 0;
            counter++;

            int procenty = (counter * 100) / 120;
            write(calculate_addr(47), '%');
            write(calculate_addr(46), procenty % 10 + 48);
            write(calculate_addr(45), (procenty % 100 - procenty % 10) / 10 + 48);
        }
        if (counter == 120) {
            USART_Transmit('h');
            USART_Transmit(13);
        }
    } else {

        if (character == 2) {
            address = 0;
        } else if (address < 64 && character >= 32 && character < 126) {
            write(calculate_addr(address), character);
            address++;
        }

    }
}

unsigned char USART_Receive(void) {

    /* Wait for data to be received */
    while (!(UCSR0A & (1 << RXC0))) {

    }

    /* Get and return received data from buffer */
    return UDR0;
}

/*Select display mode  0 - send instruction, 1 - send data*/
void di(uint8_t w) {
    if (w) PORTB |= (1 << PORTB3);
    else PORTB &= ~(1 << PORTB3);
}

/*Change the level of the enable signal*/
void enable(uint8_t w) {
    if (w) PORTB |= (1 << PORTB0);
    else PORTB &= ~(1 << PORTB0);
}

/*Send 8 bits to the display*/
void send(uint8_t data) {

    PORTB &= 15;
    PORTB |= (data & 240);
    enable(1);
    _delay_us(40);
    enable(0);
    PORTB &= 15;
    PORTB |= ((data << 4)&240);
    enable(1);
    _delay_us(40);
    enable(0);

}

/*Write character 'chr'  to LCD address 'addr'*/
void write(unsigned char addr, unsigned char chr) {
    di(0);
    send(addr + 128);
    di(1);
    send(chr);
    di(0);
}

/*Write character a string of characters 'word' of length 'n' to LCD address 'addr'*/
void write_str(unsigned char word[], int n, unsigned char addr) {
    int i;
    for (i = 0; i < n; i++)
        write(addr++, word[i]);

}

/*Send 4 bits to the display*/
void send4(uint8_t data) {
    PORTB = data;
    enable(1);
    _delay_us(50);
    enable(0);
}

void lcd_init() {



    sei();
    /*LCD initialization*/
    debounce = 0;
    DDRB = 255;
    PORTD = 252;
    TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);
    TCCR1B = _BV(WGM12) | _BV(CS10);
    OCR1A = 70; /*value of PWM for backlight*/
    OCR1B = 70; /*value of PWM for contrastt*/

    _delay_ms(200);
    send4(32);
    send4(32);
    send4(128);

    send4(0);
    send4(192);

    send4(0);
    send4(96);
    write_str("((i))  Wifon 0.2", 16, 0);
    write_str("!\"\"\"!  booting", 14, calculate_addr(16));
    write_str("`___'", 5, calculate_addr(32));
}

int
main(void) {
    lcd_init();
    USART_Init(MYUBRR);



    /*Main loop, reads keys, the rest of the funcionality is through interrupts*/
    for (;;) {

        _delay_ms(200);
        if (!(PIND & 4)) {
            USART_Transmit('g');
            USART_Transmit(13);
        }
        if (!(PIND & 8)) {
            USART_Transmit('h');
            USART_Transmit(13);
        }
        if (!(PIND & 16)) {
            USART_Transmit('a');
            USART_Transmit(13);
        }
        if (!(PIND & 32)) {
            USART_Transmit('s');
            USART_Transmit(13);
        }
        if (!(PIND & 64)) {
            USART_Transmit('d');
            USART_Transmit(13);
        }
        if (!(PIND & 128)) {
            USART_Transmit('w');
            USART_Transmit(13);
        }

    }


    return 0;
}


Comments