Skip to content

Commit 2f9f8c3

Browse files
committedJan 23, 2016
firmware/lm32: refactor i2c (simplify and avoid duplication)
1 parent b7cefbd commit 2f9f8c3

13 files changed

+214
-242
lines changed
 

‎firmware/lm32/Makefile

-69
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ OBJECTS=isr.o \
88
processor.o \
99
hdmi_in0.o \
1010
hdmi_in1.o \
11-
hdmi_out0_i2c.o \
1211
hdmi_out0.o \
13-
hdmi_out1_i2c.o \
1412
hdmi_out1.o \
1513
pattern.o \
1614
edid.o \
@@ -21,9 +19,7 @@ OBJECTS=isr.o \
2119
fx2.o \
2220
i2c.o \
2321
main.o \
24-
opsis_eeprom_i2c.o \
2522
opsis_eeprom.o \
26-
tofe_eeprom_i2c.o \
2723
tofe_eeprom.o \
2824

2925
all: firmware.bin
@@ -58,71 +54,6 @@ main.o: main.c
5854
%.o: %.S
5955
$(assemble)
6056

61-
define gen_i2c
62-
@echo " GEN " $@
63-
@sed -e "s/XI2C/I2C/g;s/Xi2c/i2c/g" $< > $@
64-
endef
65-
66-
i2c.c: Xi2c.c
67-
$(gen_i2c)
68-
69-
i2c.h: Xi2c.h
70-
$(gen_i2c)
71-
72-
i2c.o: i2c.h
73-
74-
define gen_opsis_eeprom_i2c
75-
@echo " GEN " $@
76-
@sed -e "s/XI2C/OPSIS_EEPROM_I2C/g;s/Xi2c/opsis_eeprom_i2c/g" $< > $@
77-
endef
78-
79-
opsis_eeprom_i2c.c: Xi2c.c
80-
$(gen_opsis_eeprom_i2c)
81-
82-
opsis_eeprom_i2c.h: Xi2c.h
83-
$(gen_opsis_eeprom_i2c)
84-
85-
opsis_eeprom_i2c.o: opsis_eeprom_i2c.h
86-
87-
define gen_tofe_eeprom_i2c
88-
@echo " GEN " $@
89-
@sed -e "s/XI2C/TOFE_EEPROM_I2C/g;s/Xi2c/tofe_eeprom_i2c/g" $< > $@
90-
endef
91-
92-
tofe_eeprom_i2c.c: Xi2c.c
93-
$(gen_tofe_eeprom_i2c)
94-
95-
tofe_eeprom_i2c.h: Xi2c.h
96-
$(gen_tofe_eeprom_i2c)
97-
98-
tofe_eeprom_i2c.o: tofe_eeprom_i2c.h
99-
100-
define gen_hdmi_out0_i2c
101-
@echo " GEN " $@
102-
@sed -e "s/XI2C/HDMI_OUT0_I2C/g;s/Xi2c/hdmi_out0_i2c/g" $< > $@
103-
endef
104-
105-
hdmi_out0_i2c.c: Xi2c.c
106-
$(gen_hdmi_out0_i2c)
107-
108-
hdmi_out0_i2c.h: Xi2c.h
109-
$(gen_hdmi_out0_i2c)
110-
111-
hdmi_out0_i2c.o: hdmi_out0_i2c.h
112-
113-
define gen_hdmi_out1_i2c
114-
@echo " GEN " $@
115-
@sed -e "s/XI2C/HDMI_OUT1_I2C/g;s/Xi2c/hdmi_out1_i2c/g" $< > $@
116-
endef
117-
118-
hdmi_out1_i2c.c: Xi2c.c
119-
$(gen_hdmi_out1_i2c)
120-
121-
hdmi_out1_i2c.h: Xi2c.h
122-
$(gen_hdmi_out1_i2c)
123-
124-
hdmi_out1_i2c.o: hdmi_out1_i2c.h
125-
12657
libs:
12758
$(MAKE) -C $(MSCDIR)/software/libcompiler-rt
12859
$(MAKE) -C $(MSCDIR)/software/libbase

‎firmware/lm32/Xi2c.c

-113
This file was deleted.

‎firmware/lm32/Xi2c.h

-19
This file was deleted.

‎firmware/lm32/hdmi_out0.c

+20-11
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,37 @@
11
#include <generated/csr.h>
2-
#ifdef CSR_HDMI_OUT0_BASE
2+
#ifdef CSR_HDMI_OUT0_I2C_W_ADDR
33
#include <stdio.h>
4+
#include "i2c.h"
45
#include "hdmi_out0.h"
56

7+
I2C hdmi_out0_i2c;
68
int hdmi_out0_debug_enabled = 0;
79

10+
void hdmi_out0_i2c_init(void) {
11+
hdmi_out0_i2c.w_read = hdmi_out0_i2c_w_read;
12+
hdmi_out0_i2c.w_write = hdmi_out0_i2c_w_write;
13+
hdmi_out0_i2c.r_read = hdmi_out0_i2c_r_read;
14+
i2c_init(&hdmi_out0_i2c);
15+
}
16+
817
void hdmi_out0_print_edid(void) {
918
int eeprom_addr, e, extension_number = 0;
1019
unsigned char b;
1120
unsigned char sum = 0;
1221

13-
hdmi_out0_i2c_start_cond();
14-
b = hdmi_out0_i2c_write(0xa0);
22+
i2c_start_cond(&hdmi_out0_i2c);
23+
b = i2c_write(&hdmi_out0_i2c, 0xa0);
1524
if (!b && hdmi_out0_debug_enabled)
1625
printf("hdmi_out0: NACK while writing slave address!\n");
17-
b = hdmi_out0_i2c_write(0x00);
26+
b = i2c_write(&hdmi_out0_i2c, 0x00);
1827
if (!b && hdmi_out0_debug_enabled)
1928
printf("hdmi_out0: NACK while writing eeprom address!\n");
20-
hdmi_out0_i2c_start_cond();
21-
b = hdmi_out0_i2c_write(0xa1);
29+
i2c_start_cond(&hdmi_out0_i2c);
30+
b = i2c_write(&hdmi_out0_i2c, 0xa1);
2231
if (!b && hdmi_out0_debug_enabled)
2332
printf("hdmi_out0: NACK while writing slave address (2)!\n");
2433
for (eeprom_addr = 0 ; eeprom_addr < 128 ; eeprom_addr++) {
25-
b = hdmi_out0_i2c_read(eeprom_addr == 127 && extension_number == 0 ? 0 : 1);
34+
b = i2c_read(&hdmi_out0_i2c, eeprom_addr == 127 && extension_number == 0 ? 0 : 1);
2635
sum +=b;
2736
printf("%02X ", b);
2837
if(!((eeprom_addr+1) % 16))
@@ -32,7 +41,7 @@ void hdmi_out0_print_edid(void) {
3241
if(eeprom_addr == 127 && sum != 0)
3342
{
3443
printf("Checksum ERROR in EDID block 0\n");
35-
hdmi_out0_i2c_stop_cond();
44+
i2c_stop_cond(&hdmi_out0_i2c);
3645
return;
3746
}
3847
}
@@ -41,20 +50,20 @@ void hdmi_out0_print_edid(void) {
4150
printf("\n");
4251
sum = 0;
4352
for (eeprom_addr = 0 ; eeprom_addr < 128 ; eeprom_addr++) {
44-
b = hdmi_out0_i2c_read(eeprom_addr == 127 && e == extension_number - 1 ? 0 : 1);
53+
b = i2c_read(&hdmi_out0_i2c, eeprom_addr == 127 && e == extension_number - 1 ? 0 : 1);
4554
sum += b;
4655
printf("%02X ", b);
4756
if(!((eeprom_addr+1) % 16))
4857
printf("\n");
4958
if(eeprom_addr == 127 && sum != 0)
5059
{
5160
printf("Checksum ERROR in EDID extension block %d\n", e);
52-
hdmi_out0_i2c_stop_cond();
61+
i2c_stop_cond(&hdmi_out0_i2c);
5362
return;
5463
}
5564
}
5665
}
57-
hdmi_out0_i2c_stop_cond();
66+
i2c_stop_cond(&hdmi_out0_i2c);
5867
}
5968

6069
#endif

‎firmware/lm32/hdmi_out0.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include <generated/csr.h>
22
#ifdef CSR_HDMI_OUT0_I2C_W_ADDR
3-
#include "hdmi_out0_i2c.h"
43

4+
void hdmi_out0_i2c_init(void);
55
void hdmi_out0_print_edid(void);
66

77
#endif

‎firmware/lm32/hdmi_out1.c

+20-11
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,37 @@
11
#include <generated/csr.h>
2-
#ifdef CSR_HDMI_OUT1_BASE
2+
#ifdef CSR_HDMI_OUT1_I2C_W_ADDR
33
#include <stdio.h>
4+
#include "i2c.h"
45
#include "hdmi_out1.h"
56

7+
I2C hdmi_out1_i2c;
68
int hdmi_out1_debug_enabled = 0;
79

10+
void hdmi_out1_i2c_init(void) {
11+
hdmi_out1_i2c.w_read = hdmi_out1_i2c_w_read;
12+
hdmi_out1_i2c.w_write = hdmi_out1_i2c_w_write;
13+
hdmi_out1_i2c.r_read = hdmi_out1_i2c_r_read;
14+
i2c_init(&hdmi_out1_i2c);
15+
}
16+
817
void hdmi_out1_print_edid(void) {
918
int eeprom_addr, e, extension_number = 0;
1019
unsigned char b;
1120
unsigned char sum = 0;
1221

13-
hdmi_out1_i2c_start_cond();
14-
b = hdmi_out1_i2c_write(0xa0);
22+
i2c_start_cond(&hdmi_out1_i2c);
23+
b = i2c_write(&hdmi_out1_i2c, 0xa0);
1524
if (!b && hdmi_out1_debug_enabled)
1625
printf("hdmi_out1: NACK while writing slave address!\n");
17-
b = hdmi_out1_i2c_write(0x00);
26+
b = i2c_write(&hdmi_out1_i2c, 0x00);
1827
if (!b && hdmi_out1_debug_enabled)
1928
printf("hdmi_out1: NACK while writing eeprom address!\n");
20-
hdmi_out1_i2c_start_cond();
21-
b = hdmi_out1_i2c_write(0xa1);
29+
i2c_start_cond(&hdmi_out1_i2c);
30+
b = i2c_write(&hdmi_out1_i2c, 0xa1);
2231
if (!b && hdmi_out1_debug_enabled)
2332
printf("hdmi_out1: NACK while writing slave address (2)!\n");
2433
for (eeprom_addr = 0 ; eeprom_addr < 128 ; eeprom_addr++) {
25-
b = hdmi_out1_i2c_read(eeprom_addr == 127 && extension_number == 0 ? 0 : 1);
34+
b = i2c_read(&hdmi_out1_i2c, eeprom_addr == 127 && extension_number == 0 ? 0 : 1);
2635
sum +=b;
2736
printf("%02X ", b);
2837
if(!((eeprom_addr+1) % 16))
@@ -32,7 +41,7 @@ void hdmi_out1_print_edid(void) {
3241
if(eeprom_addr == 127 && sum != 0)
3342
{
3443
printf("Checksum ERROR in EDID block 0\n");
35-
hdmi_out1_i2c_stop_cond();
44+
i2c_stop_cond(&hdmi_out1_i2c);
3645
return;
3746
}
3847
}
@@ -41,20 +50,20 @@ void hdmi_out1_print_edid(void) {
4150
printf("\n");
4251
sum = 0;
4352
for (eeprom_addr = 0 ; eeprom_addr < 128 ; eeprom_addr++) {
44-
b = hdmi_out1_i2c_read(eeprom_addr == 127 && e == extension_number - 1 ? 0 : 1);
53+
b = i2c_read(&hdmi_out1_i2c, eeprom_addr == 127 && e == extension_number - 1 ? 0 : 1);
4554
sum += b;
4655
printf("%02X ", b);
4756
if(!((eeprom_addr+1) % 16))
4857
printf("\n");
4958
if(eeprom_addr == 127 && sum != 0)
5059
{
5160
printf("Checksum ERROR in EDID extension block %d\n", e);
52-
hdmi_out1_i2c_stop_cond();
61+
i2c_stop_cond(&hdmi_out1_i2c);
5362
return;
5463
}
5564
}
5665
}
57-
hdmi_out1_i2c_stop_cond();
66+
i2c_stop_cond(&hdmi_out1_i2c);
5867
}
5968

6069
#endif

‎firmware/lm32/hdmi_out1.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include <generated/csr.h>
22
#ifdef CSR_HDMI_OUT1_I2C_W_ADDR
3-
#include "hdmi_out1_i2c.h"
43

4+
void hdmi_out1_i2c_init(void);
55
void hdmi_out1_print_edid(void);
66

77
#endif

‎firmware/lm32/i2c.c

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#include "i2c.h"
2+
3+
/* I2C bit banging */
4+
int i2c_init(I2C *i2c)
5+
{
6+
unsigned int timeout;
7+
8+
i2c->started = 0;
9+
i2c->w_write(I2C_SCL);
10+
/* Check the I2C bus is ready */
11+
timeout = 1000;
12+
while((timeout > 0) && (!(i2c->r_read() & I2C_SDAIN))) timeout--;
13+
14+
return timeout;
15+
}
16+
17+
void i2c_delay(void)
18+
{
19+
unsigned int i;
20+
21+
for(i=0;i<1000;i++) __asm__("nop");
22+
}
23+
24+
/* I2C bit-banging functions from http://en.wikipedia.org/wiki/I2c */
25+
unsigned int i2c_read_bit(I2C *i2c)
26+
{
27+
unsigned int bit;
28+
29+
/* Let the slave drive data */
30+
i2c->w_write(0);
31+
i2c_delay();
32+
i2c->w_write(I2C_SCL);
33+
i2c_delay();
34+
bit = i2c->r_read() & I2C_SDAIN;
35+
i2c_delay();
36+
i2c->w_write(0);
37+
return bit;
38+
}
39+
40+
void i2c_write_bit(I2C *i2c, unsigned int bit)
41+
{
42+
if(bit) {
43+
i2c->w_write(I2C_SDAOE | I2C_SDAOUT);
44+
} else {
45+
i2c->w_write(I2C_SDAOE);
46+
}
47+
i2c_delay();
48+
/* Clock stretching */
49+
i2c->w_write(i2c->w_read() | I2C_SCL);
50+
i2c_delay();
51+
i2c->w_write(i2c->w_read() & ~I2C_SCL);
52+
}
53+
54+
void i2c_start_cond(I2C *i2c)
55+
{
56+
if(i2c->started) {
57+
/* set SDA to 1 */
58+
i2c->w_write(I2C_SDAOE | I2C_SDAOUT);
59+
i2c_delay();
60+
i2c->w_write(i2c->w_read() | I2C_SCL);
61+
i2c_delay();
62+
}
63+
/* SCL is high, set SDA from 1 to 0 */
64+
i2c->w_write(I2C_SDAOE|I2C_SCL);
65+
i2c_delay();
66+
i2c->w_write(I2C_SDAOE);
67+
i2c->started = 1;
68+
}
69+
70+
void i2c_stop_cond(I2C *i2c)
71+
{
72+
/* set SDA to 0 */
73+
i2c->w_write(I2C_SDAOE);
74+
i2c_delay();
75+
/* Clock stretching */
76+
i2c->w_write(I2C_SDAOE | I2C_SCL);
77+
/* SCL is high, set SDA from 0 to 1 */
78+
i2c->w_write(I2C_SCL);
79+
i2c_delay();
80+
i2c->started = 0;
81+
}
82+
83+
unsigned int i2c_write(I2C *i2c, unsigned char byte)
84+
{
85+
unsigned int bit;
86+
unsigned int ack;
87+
88+
for(bit = 0; bit < 8; bit++) {
89+
i2c_write_bit(i2c, byte & 0x80);
90+
byte <<= 1;
91+
}
92+
ack = !i2c_read_bit(i2c);
93+
return ack;
94+
}
95+
96+
unsigned char i2c_read(I2C *i2c, int ack)
97+
{
98+
unsigned char byte = 0;
99+
unsigned int bit;
100+
101+
for(bit = 0; bit < 8; bit++) {
102+
byte <<= 1;
103+
byte |= i2c_read_bit(i2c);
104+
}
105+
i2c_write_bit(i2c, !ack);
106+
return byte;
107+
}

‎firmware/lm32/i2c.h

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#ifndef __I2C_H
2+
#define __I2C_H
3+
4+
#define I2C_SCL 0x01
5+
#define I2C_SDAOE 0x02
6+
#define I2C_SDAOUT 0x04
7+
8+
#define I2C_SDAIN 0x01
9+
10+
typedef unsigned char (*i2c_w_read_t)(void);
11+
typedef void (*i2c_w_write_t)(unsigned char value);
12+
typedef unsigned char (*i2c_r_read_t)(void);
13+
14+
typedef struct {
15+
i2c_w_read_t w_read;
16+
i2c_w_write_t w_write;
17+
i2c_r_read_t r_read;
18+
int started;
19+
} I2C;
20+
21+
int i2c_init(I2C *i2c);
22+
void i2c_delay(void);
23+
unsigned int i2c_read_bit(I2C *i2c);
24+
void i2c_write_bit(I2C *i2c, unsigned int bit);
25+
void i2c_start_cond(I2C *i2c);
26+
void i2c_stop_cond(I2C *i2c);
27+
unsigned int i2c_write(I2C *i2c, unsigned char byte);
28+
unsigned char i2c_read(I2C *i2c, int ack);
29+
30+
#endif /* __I2C_H */

‎firmware/lm32/opsis_eeprom.c

+16-8
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,43 @@
11
#include <generated/csr.h>
22
#ifdef CSR_OPSIS_EEPROM_I2C_BASE
33
#include <stdio.h>
4-
#include "opsis_eeprom_i2c.h"
4+
#include "i2c.h"
55
#include "opsis_eeprom.h"
66

7+
I2C opsis_eeprom_i2c;
78
int opsis_eeprom_debug_enabled = 0;
89

10+
void opsis_eeprom_i2c_init(void) {
11+
opsis_eeprom_i2c.w_read = opsis_eeprom_i2c_w_read;
12+
opsis_eeprom_i2c.w_write = opsis_eeprom_i2c_w_write;
13+
opsis_eeprom_i2c.r_read = opsis_eeprom_i2c_r_read;
14+
i2c_init(&opsis_eeprom_i2c);
15+
}
16+
917
void opsis_eeprom_dump(void) {
1018
int opsis_eeprom_addr = 0;
1119
unsigned char b;
1220

13-
opsis_eeprom_i2c_start_cond();
14-
b = opsis_eeprom_i2c_write(0xa0);
21+
i2c_start_cond(&opsis_eeprom_i2c);
22+
b = i2c_write(&opsis_eeprom_i2c, 0xa0);
1523
if (!b && opsis_eeprom_debug_enabled)
1624
printf("opsis_eeprom: NACK while writing slave address!\n");
17-
b = opsis_eeprom_i2c_write(0x00);
25+
b = i2c_write(&opsis_eeprom_i2c, 0x00);
1826
if (!b && opsis_eeprom_debug_enabled)
1927
printf("opsis_eeprom: NACK while writing opsis_eeprom address!\n");
2028

21-
opsis_eeprom_i2c_start_cond();
22-
b = opsis_eeprom_i2c_write(0xa1);
29+
i2c_start_cond(&opsis_eeprom_i2c);
30+
b = i2c_write(&opsis_eeprom_i2c, 0xa1);
2331
if (!b && opsis_eeprom_debug_enabled)
2432
printf("opsis_eeprom: NACK while writing slave address (2)!\n");
2533

2634
for (opsis_eeprom_addr = 0 ; opsis_eeprom_addr < 256 ; opsis_eeprom_addr++) {
27-
b = opsis_eeprom_i2c_read(1);
35+
b = i2c_read(&opsis_eeprom_i2c, 1);
2836
printf("%02X ", b);
2937
if(!((opsis_eeprom_addr+1) % 16))
3038
printf("\n");
3139
}
32-
opsis_eeprom_i2c_stop_cond();
40+
i2c_stop_cond(&opsis_eeprom_i2c);
3341
}
3442

3543
#endif

‎firmware/lm32/opsis_eeprom.h

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <generated/csr.h>
22
#ifdef CSR_TOFE_EEPROM_I2C_W_ADDR
33

4+
void opsis_eeprom_i2c_init(void);
45
void opsis_eeprom_dump(void);
56

67
#endif

‎firmware/lm32/tofe_eeprom.c

+17-9
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,43 @@
11
#include <generated/csr.h>
22
#ifdef CSR_TOFE_EEPROM_I2C_BASE
33
#include <stdio.h>
4-
#include "tofe_eeprom_i2c.h"
4+
#include "i2c.h"
55
#include "tofe_eeprom.h"
66

7+
I2C tofe_eeprom_i2c;
78
int tofe_eeprom_debug_enabled = 0;
89

10+
void tofe_eeprom_i2c_init(void) {
11+
tofe_eeprom_i2c.w_read = tofe_eeprom_i2c_w_read;
12+
tofe_eeprom_i2c.w_write = tofe_eeprom_i2c_w_write;
13+
tofe_eeprom_i2c.r_read = tofe_eeprom_i2c_r_read;
14+
i2c_init(&tofe_eeprom_i2c);
15+
}
16+
917
void tofe_eeprom_dump(void) {
1018
int tofe_eeprom_addr = 0;
1119
unsigned char b;
1220

13-
tofe_eeprom_i2c_start_cond();
14-
b = tofe_eeprom_i2c_write(0xa0);
21+
i2c_start_cond(&tofe_eeprom_i2c);
22+
b = i2c_write(&tofe_eeprom_i2c, 0xa0);
1523
if (!b && tofe_eeprom_debug_enabled)
1624
printf("tofe_eeprom: NACK while writing slave address!\n");
17-
b = tofe_eeprom_i2c_write(0x00);
25+
b = i2c_write(&tofe_eeprom_i2c, 0x00);
1826
if (!b && tofe_eeprom_debug_enabled)
1927
printf("tofe_eeprom: NACK while writing tofe_eeprom address!\n");
2028

21-
tofe_eeprom_i2c_start_cond();
22-
b = tofe_eeprom_i2c_write(0xa1);
29+
i2c_start_cond(&tofe_eeprom_i2c);
30+
b = i2c_write(&tofe_eeprom_i2c, 0xa1);
2331
if (!b && tofe_eeprom_debug_enabled)
2432
printf("tofe_eeprom: NACK while writing slave address (2)!\n");
2533

2634
for (tofe_eeprom_addr = 0 ; tofe_eeprom_addr < 256 ; tofe_eeprom_addr++) {
27-
b = tofe_eeprom_i2c_read(1);
35+
b = i2c_read(&tofe_eeprom_i2c, 1);
2836
printf("%02X ", b);
2937
if(!((tofe_eeprom_addr+1) % 16))
3038
printf("\n");
3139
}
32-
tofe_eeprom_i2c_stop_cond();
40+
i2c_stop_cond(&tofe_eeprom_i2c);
3341
}
3442

35-
#endif
43+
#endif

‎firmware/lm32/tofe_eeprom.h

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <generated/csr.h>
22
#ifdef CSR_TOFE_EEPROM_I2C_W_ADDR
33

4+
void tofe_eeprom_i2c_init(void);
45
void tofe_eeprom_dump(void);
56

67
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.