comparison romdb.c @ 770:a3b90f746dcf

Broken EEPROM support
author Michael Pavone <pavone@retrodev.com>
date Tue, 14 Jul 2015 18:28:05 -0700
parents 4638b88bc72d
children 1b82b282b829
comparison
equal deleted inserted replaced
769:4638b88bc72d 770:a3b90f746dcf
14 #define RAM_FLAGS 0x1B2 14 #define RAM_FLAGS 0x1B2
15 #define RAM_START 0x1B4 15 #define RAM_START 0x1B4
16 #define RAM_END 0x1B8 16 #define RAM_END 0x1B8
17 #define REGION_START 0x1F0 17 #define REGION_START 0x1F0
18 18
19 void eeprom_init(eeprom_state *state) 19 enum {
20 I2C_IDLE,
21 I2C_START,
22 I2C_DEVICE_ACK,
23 I2C_ADDRESS_HI,
24 I2C_ADDRESS_HI_ACK,
25 I2C_ADDRESS,
26 I2C_ADDRESS_ACK,
27 I2C_READ,
28 I2C_READ_ACK,
29 I2C_WRITE,
30 I2C_WRITE_ACK
31 };
32
33 char * i2c_states[] = {
34 "idle",
35 "start",
36 "device ack",
37 "address hi",
38 "address hi ack",
39 "address",
40 "address ack",
41 "read",
42 "read_ack",
43 "write",
44 "write_ack"
45 };
46
47 void eeprom_init(eeprom_state *state, uint8_t *buffer, uint32_t size)
20 { 48 {
21 state->slave_sda = 1; 49 state->slave_sda = 1;
22 state->host_sda = state->scl = 0; 50 state->host_sda = state->scl = 0;
51 state->buffer = buffer;
52 state->size = size;
53 state->state = I2C_IDLE;
23 } 54 }
24 55
25 void set_host_sda(eeprom_state *state, uint8_t val) 56 void set_host_sda(eeprom_state *state, uint8_t val)
26 { 57 {
27 if (state->scl) { 58 if (state->scl) {
28 if (val & ~state->host_sda) { 59 if (val & ~state->host_sda) {
29 //stop condition 60 //low to high, stop condition
61 state->state = I2C_IDLE;
62 state->slave_sda = 1;
30 } else if (~val & state->host_sda) { 63 } else if (~val & state->host_sda) {
31 //start condition 64 //high to low, start condition
65 state->state = I2C_START;
66 state->slave_sda = 1;
67 state->counter = 8;
32 } 68 }
33 } 69 }
34 state->host_sda = val; 70 state->host_sda = val;
35 } 71 }
36 72
37 void set_scl(eeprom_state *state, uint8_t val) 73 void set_scl(eeprom_state *state, uint8_t val)
38 { 74 {
39 if (val & ~state->scl) { 75 if (val & ~state->scl) {
40 //latch sda 76 //low to high transition
77 switch (state->state)
78 {
79 case I2C_START:
80 case I2C_ADDRESS_HI:
81 case I2C_ADDRESS:
82 case I2C_WRITE:
83 state->latch = state->host_sda << 7 | state->latch >> 1;
84 state->counter--;
85 if (!state->counter) {
86 switch (state->state & 0x7F)
87 {
88 case I2C_START:
89 state->state = I2C_DEVICE_ACK;
90 break;
91 case I2C_ADDRESS_HI:
92 state->address = state->latch << 8;
93 state->state = I2C_ADDRESS_HI_ACK;
94 break;
95 case I2C_ADDRESS:
96 state->address |= state->latch;
97 state->state = I2C_ADDRESS_ACK;
98 break;
99 case I2C_WRITE:
100 state->buffer[state->address] = state->latch;
101 state->state = I2C_WRITE_ACK;
102 state->address++;
103 //TODO: page mask
104 state->address &= state->size-1;
105 break;
106 }
107 }
108 break;
109 case I2C_DEVICE_ACK:
110 if (state->latch & 1) {
111 state->state = I2C_READ;
112 state->counter = 8;
113 state->latch = state->buffer[state->address];
114 state->address++;
115 //TODO: page mask
116 state->address &= state->size-1;
117 } else {
118 if (state->size < 256) {
119 state->address = state->latch >> 1;
120 state->state = I2C_WRITE;
121 } else if (state->size < 8192) {
122 state->address = state->latch << 8;
123 state->state = I2C_ADDRESS;
124 } else {
125 state->state = I2C_ADDRESS_HI;
126 }
127 state->counter = 8;
128 }
129 break;
130 case I2C_ADDRESS_HI_ACK:
131 state->state = I2C_ADDRESS;
132 break;
133 case I2C_ADDRESS_ACK:
134 state->state = I2C_WRITE;
135 break;
136 case I2C_READ:
137 state->counter--;
138 if (!state->counter) {
139 state->state = I2C_READ_ACK;
140 }
141 break;
142 case I2C_READ_ACK:
143 state->state = I2C_READ;
144 break;
145 case I2C_WRITE_ACK:
146 state->state = I2C_WRITE;
147 break;
148 }
149 } else if (~val & state->scl) {
150 //high to low transition
151 switch (state->state & 0x7F)
152 {
153 case I2C_DEVICE_ACK:
154 case I2C_ADDRESS_HI_ACK:
155 case I2C_ADDRESS_ACK:
156 case I2C_READ_ACK:
157 case I2C_WRITE_ACK:
158 state->slave_sda = 0;
159 break;
160 case I2C_READ:
161 state->slave_sda = state->latch >> 7;
162 state->latch = state->latch << 1;
163 break;
164 default:
165 state->slave_sda = 1;
166 break;
167 }
41 } 168 }
42 state->scl = val; 169 state->scl = val;
43 } 170 }
44 171
45 uint8_t get_sda(eeprom_state *state) 172 uint8_t get_sda(eeprom_state *state)
190 if (map->sda_write_mask) { 317 if (map->sda_write_mask) {
191 printf("sda: %d\n", (value & map->sda_write_mask) != 0); 318 printf("sda: %d\n", (value & map->sda_write_mask) != 0);
192 set_host_sda(&gen->eeprom, (value & map->sda_write_mask) != 0); 319 set_host_sda(&gen->eeprom, (value & map->sda_write_mask) != 0);
193 } 320 }
194 if (map->scl_mask) { 321 if (map->scl_mask) {
195 printf("scl: %d\n", (value & map->scl_mask) != 0); 322 set_scl(&gen->eeprom, (value & map->scl_mask) != 0);
196 set_scl(&gen->eeprom, (value & map->sda_write_mask) != 0); 323 printf("scl: %d, state: %s, counter: %d\n", (value & map->scl_mask) != 0, i2c_states[gen->eeprom.state], gen->eeprom.counter);
197 } 324 }
198 return context; 325 return context;
199 } 326 }
200 327
201 void * write_eeprom_i2c_b(uint32_t address, void * context, uint8_t value) 328 void * write_eeprom_i2c_b(uint32_t address, void * context, uint8_t value)
219 if (map->sda_write_mask & mask) { 346 if (map->sda_write_mask & mask) {
220 printf("sda: %d\n", (expanded & map->sda_write_mask) != 0); 347 printf("sda: %d\n", (expanded & map->sda_write_mask) != 0);
221 set_host_sda(&gen->eeprom, (expanded & map->sda_write_mask) != 0); 348 set_host_sda(&gen->eeprom, (expanded & map->sda_write_mask) != 0);
222 } 349 }
223 if (map->scl_mask & mask) { 350 if (map->scl_mask & mask) {
224 printf("scl: %d\n", (expanded & map->scl_mask) != 0); 351 printf("scl: %d, state: %s\n", (expanded & map->scl_mask) != 0, i2c_states[gen->eeprom.state]);
225 set_scl(&gen->eeprom, (expanded & map->scl_mask) != 0); 352 set_scl(&gen->eeprom, (expanded & map->scl_mask) != 0);
226 } 353 }
227 return context; 354 return context;
228 } 355 }
229 356