blob: e9fec62f9721b39d1dccf77e5a13dd7ea88e94f4 (
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
#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_set_addr(uint16_t addr);
void eeprom_write(uint16_t addr, uint8_t byte);
uint8_t eeprom_read(uint16_t addr);
int main(void)
{
uint8_t *buffer, i;
size_t read;
struct file_blk *blk = malloc(sizeof(struct file_blk));
DDRB = 0x7F;
DDRC = 0x1F;
DDRD = 0xFD;
/* get configuration */
usart_init(1200);
while (usart_read((uint8_t *) blk, sizeof(struct file_blk))) {
buffer = malloc(blk->size);
read = usart_read(buffer, blk->size);
for (i = 0; i < read; i++) {
eeprom_write(blk->addr +i, buffer[i]);
_delay_ms(5);
eeprom_read(blk->addr +i); // != buffer[i];
}
free(buffer);
usart_send_byte(0x06);
usart_send_byte(0x06);
usart_send_byte(0x06);
}
free(blk);
return 0;
}
void eeprom_set_addr(uint16_t addr)
{
int bit;
for (bit = 0; bit < 8; bit++) {
// clear bits
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);
_delay_ms(5);
}
}
void eeprom_write(uint16_t addr, uint8_t byte)
{
eeprom_set_addr(addr);
DDRC |= 0x18; // ED1 ED0
DDRD |= 0xFC; // ED7-ED2
/* set data */
EEPROMDR = byte & 0xFC;
// because EEPROMDR0 and EEPROMDR1 are used by Tx and Rx
EEPROMCR = (PINC & 0xE7) | (byte & 0x03)<<3;
/* enable address output */
EEPROMCR &= ~(_BV(ADDR_EH) | _BV(ADDR_EL));
/* write eeprom */
EEPROMCR &= ~_BV(EEPROM_WR);
_delay_ms(5);
/* reset */
EEPROMCR |= _BV(EEPROM_WR);
EEPROMCR |= _BV(ADDR_EH) | _BV(ADDR_EL);
}
uint8_t eeprom_read(uint16_t addr)
{
uint8_t data;
eeprom_set_addr(addr);
DDRC &= ~0x18;
DDRD &= ~0xFC;
/* enable address output */
EEPROMCR &= ~(_BV(ADDR_EH) | _BV(ADDR_EL));
/* enable read eeprom */
EEPROMCR &= ~_BV(EEPROM_RD);
data = (PINC & 0x18) | (PIND & 0xFB);
_delay_ms(5);
/* reset */
EEPROMCR |= _BV(EEPROM_RD);
EEPROMCR |= _BV(ADDR_EH) | _BV(ADDR_EL);
return data;
}
|