summaryrefslogtreecommitdiffstats
path: root/sw/programmer/avr/main.c
blob: 90d05faf8afe2dd0d1c357084375712c4ec82581 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "fileinfo.h"
#include "usart.h"
#include <util/delay.h>

#define EEPROM_TICK_MS  10

#define ADDRCR      PORTB
#define EEPROMCR    PORTC
#define EEPROMDR    PORTD

#define ADDR_BIT    0
#define ADDR_EL     3
#define ADDR_EH     4
#define ADDR_DL     5
#define ADDR_DH     6

#define EEPROM_WR   0
#define EEPROM_RD   1
#define EEPROM_CLK  2


void eeprom_write(uint16_t addr, uint8_t byte);
void eeprom_tick();

int main(void)
{
    uint8_t *buffer, i;
    uint16_t addr;
    size_t read;

    struct file_info *finfo =  malloc(sizeof(struct file_info));

    DDRB = 0x7F;
    DDRC = 0x83;
    DDRD = 0xFC;

    /* get configuration */
    usart_init(1200); 

    usart_print("EEPROM Programmer\n\r");

    do {
        usart_print("Waiting for configuration\n\r");
        read = usart_read((uint8_t *) finfo, sizeof(struct file_info));
    } while (read != sizeof(struct file_info));

    usart_print("Programmer Ready\n<waiting for binary>\n\r");

    buffer = malloc(finfo->blklen);
    addr = finfo->start_addr;

    /* read file */
    while ((read = usart_read(buffer, finfo->blklen))) {
        for (i = 0; i < read; i++) {
            eeprom_write(addr + i, *(buffer++));
        }

        addr += finfo->blklen;
    }

    return 0;
}


void eeprom_write(uint16_t addr, uint8_t byte)
{
    int bit;

    /* set address */
    for (bit = 0; bit < 8; bit++) {
        // clear bit
        ADDRCR &= ~0x07;
        // select the bit
        ADDRCR |= bit;

        // write bit for lower byte
        if (addr & _BV(bit))
            ADDRCR |= _BV(ADDR_DL);
        else
            ADDRCR &= ~_BV(ADDR_DL);

        // write bit for higher byte
        if ((addr>>8) & _BV(bit))
            ADDRCR |= _BV(ADDR_DH);
        else
            ADDRCR &= ~_BV(ADDR_DH);
    }

    /* set data */
    EEPROMDR = byte;
    EEPROMCR &= ~(_BV(ADDR_EH) | _BV(ADDR_EL));

    /* write eeprom */
    EEPROMCR &= ~_BV(EEPROM_WR);
    eeprom_tick();

    EEPROMCR |= _BV(EEPROM_WR);
    EEPROMCR |= _BV(ADDR_EH) | _BV(ADDR_EL);
}

/* pulse the clock line for the eeprom */
void eeprom_tick()
{
    EEPROMCR |= _BV(EEPROM_CLK);
    _delay_ms(EEPROM_TICK_MS);         
    EEPROMCR &= ~_BV(EEPROM_CLK);
    _delay_ms(EEPROM_TICK_MS);         
}