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
110
111
112
113
114
115
116
117
118
119
|
#include "usart.h"
#include <stdio.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
struct file_blk
{
uint16_t addr;
uint16_t size;
};
void eeprom_write(uint16_t addr, uint8_t byte);
void eeprom_tick();
int main(void)
{
uint8_t *buffer, i;
size_t read;
char str[64];
struct file_blk *blk = malloc(sizeof(struct file_blk));
DDRB = 0x7F;
DDRC = 0x83;
DDRD = 0xFC;
/* get configuration */
usart_init(1200);
usart_print("programmer Ready\n<waiting for binary>\n\r");
while (usart_read((uint8_t *) blk, sizeof(struct file_blk))) {
buffer = malloc(blk->size);
read = usart_read(buffer, blk->size);
#ifdef DEBUG
sprintf(str, "info : reading block from addr %d of size %d\n\r",
blk->addr, blk->size);
usart_print(str);
if (read != blk->size) {
sprintf(str, "error: expected %d but read %d\n\r",
blk->size, read);
usart_print(str);
}
#endif
for (i = 0; i < read; i++) {
eeprom_write(blk->addr +i, buffer[i]);
}
free(buffer);
}
free(blk);
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);
}
|