diff options
-rwxr-xr-x | firmware/target/arm/tms320dm320/i2c-dm320.c | 128 | ||||
-rwxr-xr-x | firmware/target/arm/tms320dm320/i2c-dm320.h | 30 |
2 files changed, 116 insertions, 42 deletions
diff --git a/firmware/target/arm/tms320dm320/i2c-dm320.c b/firmware/target/arm/tms320dm320/i2c-dm320.c index 4ca5eb7118..cb6411e412 100755 --- a/firmware/target/arm/tms320dm320/i2c-dm320.c +++ b/firmware/target/arm/tms320dm320/i2c-dm320.c | |||
@@ -7,7 +7,9 @@ | |||
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2007 by Karl Kurbjun | 10 | * Copyright (C) 2008 by Maurus Cuelenaere |
11 | * | ||
12 | * DM320 I²C driver | ||
11 | * | 13 | * |
12 | * All files in this archive are subject to the GNU General Public License. | 14 | * All files in this archive are subject to the GNU General Public License. |
13 | * See the file COPYING in the source tree root for full license agreement. | 15 | * See the file COPYING in the source tree root for full license agreement. |
@@ -17,39 +19,133 @@ | |||
17 | * | 19 | * |
18 | ****************************************************************************/ | 20 | ****************************************************************************/ |
19 | #include "system.h" | 21 | #include "system.h" |
22 | #include "thread.h" | ||
20 | #include "i2c-dm320.h" | 23 | #include "i2c-dm320.h" |
21 | 24 | ||
22 | #if 0 | 25 | #define I2C_SCS_COND_START 0x0001 |
23 | static int i2c_getack(void) | 26 | #define I2C_SCS_COND_STOP 0x0002 |
27 | #define I2C_SCS_XMIT 0x0004 | ||
28 | |||
29 | #define I2C_TX_ACK (1 << 20) | ||
30 | |||
31 | static struct mutex i2c_mtx; | ||
32 | |||
33 | static inline void i2c_begin(void) | ||
24 | { | 34 | { |
25 | return 0; | 35 | mutex_lock(&i2c_mtx); |
26 | } | 36 | } |
27 | 37 | ||
28 | static int i2c_start(void) | 38 | static inline void i2c_end(void) |
29 | { | 39 | { |
30 | return 0; | 40 | mutex_unlock(&i2c_mtx); |
31 | } | 41 | } |
32 | 42 | ||
33 | static void i2c_stop(void) | 43 | static inline bool i2c_getack(void) |
34 | { | 44 | { |
45 | return (IO_I2C_RXDATA & 0x100)>>8; | ||
46 | } | ||
47 | |||
48 | #define WAIT_FOR_I2C if(IO_I2C_SCS & 0x4){ \ | ||
49 | while(IO_I2C_SCS & 0x4) { \ | ||
50 | asm volatile("nop"); \ | ||
51 | } \ | ||
52 | } \ | ||
35 | 53 | ||
54 | static inline void i2c_start(void) | ||
55 | { | ||
56 | IO_I2C_SCS |= I2C_SCS_XMIT; | ||
57 | return; | ||
36 | } | 58 | } |
37 | 59 | ||
38 | static int i2c_outb(unsigned char byte) | 60 | int i2c_write(unsigned short address, const unsigned char *buf, int count) |
39 | { | 61 | { |
40 | (void) byte; | 62 | int i; |
41 | return 0; | 63 | int ret=0; |
64 | i2c_begin(); | ||
65 | IO_I2C_TXDATA = ( (address << 1) & 0xFF ) | (address>0x7F ? 0 : 1 ) | I2C_TX_ACK; | ||
66 | IO_I2C_SCS &= ~0x3; //clear conditions | ||
67 | IO_I2C_SCS |= I2C_SCS_COND_START; // write 'start condition' | ||
68 | i2c_start(); | ||
69 | WAIT_FOR_I2C; | ||
70 | /* experimental */ | ||
71 | if(address>0x7F){ // check if it is 10-bit instead of 7-bit | ||
72 | IO_I2C_TXDATA = ( (address >> 7) & 0xFF) | I2C_TX_ACK; | ||
73 | IO_I2C_SCS &= ~0x3; //normal transfer | ||
74 | i2c_start(); | ||
75 | WAIT_FOR_I2C; | ||
76 | IO_I2C_TXDATA = ( (address << 1) & 0xFF) | 1 | I2C_TX_ACK; | ||
77 | IO_I2C_SCS &= ~0x3; //clear conditions | ||
78 | IO_I2C_SCS |= I2C_SCS_COND_START; //write 'start condition' | ||
79 | i2c_start(); | ||
80 | WAIT_FOR_I2C; | ||
81 | } | ||
82 | |||
83 | for(i=0; i<count; i++){ | ||
84 | IO_I2C_TXDATA = buf[i] | I2C_TX_ACK; | ||
85 | IO_I2C_SCS &= ~0x3; //normal transfer | ||
86 | i2c_start(); | ||
87 | WAIT_FOR_I2C; | ||
88 | if(!i2c_getack()) | ||
89 | ret = -1; | ||
90 | } | ||
91 | IO_I2C_SCS &= ~0x3; //clear conditions | ||
92 | IO_I2C_SCS |= I2C_SCS_COND_STOP; //write 'stop condition' | ||
93 | i2c_start(); | ||
94 | WAIT_FOR_I2C; | ||
95 | i2c_end(); | ||
96 | return ret; | ||
42 | } | 97 | } |
43 | #endif | ||
44 | 98 | ||
45 | void i2c_write(int addr, const unsigned char *buf, int count) | 99 | int i2c_read(unsigned short address, unsigned char* buf, int count) |
46 | { | 100 | { |
47 | (void) addr; | 101 | int i; |
48 | (void) buf; | 102 | int ack=0; |
49 | (void) count; | 103 | i2c_begin(); |
104 | IO_I2C_TXDATA = ( (address << 1) & 0xFF ) | (address>0x7F ? 0 : 1 ) | I2C_TX_ACK; | ||
105 | IO_I2C_SCS &= ~0x3; //clear conditions | ||
106 | IO_I2C_SCS |= I2C_SCS_COND_START; // write 'start condition' | ||
107 | i2c_start(); | ||
108 | WAIT_FOR_I2C; | ||
109 | /* experimental */ | ||
110 | if(address>0x7F){ // check if it is 10-bit instead of 7-bit | ||
111 | IO_I2C_TXDATA = ( (address >> 7) & 0xFF ) | I2C_TX_ACK; | ||
112 | IO_I2C_SCS &= ~0x3; //normal transfer | ||
113 | i2c_start(); | ||
114 | WAIT_FOR_I2C; | ||
115 | IO_I2C_TXDATA = ( (address << 1) & 0xFF ) | 1 | I2C_TX_ACK; | ||
116 | IO_I2C_SCS &= ~0x3; //clear conditions | ||
117 | IO_I2C_SCS |= I2C_SCS_COND_START; //write 'start condition' | ||
118 | i2c_start(); | ||
119 | WAIT_FOR_I2C; | ||
120 | } | ||
121 | |||
122 | for(i=0; i<count; i++){ | ||
123 | unsigned short temp; | ||
124 | IO_I2C_TXDATA = 0xFF | ( (count-1)==i ? I2C_TX_ACK : 0); | ||
125 | IO_I2C_SCS &= ~0x3; //normal transfer | ||
126 | i2c_start(); | ||
127 | WAIT_FOR_I2C; | ||
128 | temp = IO_I2C_RXDATA; | ||
129 | buf[i] = temp & 0xFF; | ||
130 | ack = (temp & 0x100) >> 8; | ||
131 | } | ||
132 | IO_I2C_SCS &= ~0x3; //clear conditions | ||
133 | IO_I2C_SCS |= I2C_SCS_COND_STOP; //write 'stop condition' | ||
134 | i2c_start(); | ||
135 | WAIT_FOR_I2C; | ||
136 | i2c_end(); | ||
137 | return ack; | ||
50 | } | 138 | } |
51 | 139 | ||
52 | void i2c_init(void) | 140 | void i2c_init(void) |
53 | { | 141 | { |
54 | 142 | #if 0 //TODO: mimic OF I2C clock settings; currently this is done by the bootloader | |
143 | IO_CLK_MOD2 &= ~CLK_MOD2_I2C; // turn I²C clock off (just to be sure) | ||
144 | IO_CLK_LPCTL1 &= ~1; // set Powerdown mode to off | ||
145 | IO_CLK_SEL0 &= ~0x800; // set I²C clock to PLLA | ||
146 | IO_CLK_DIV4 &= ~0x1F; // I²C clock division = 1 | ||
147 | IO_CLK_MOD2 |= CLK_MOD2_I2C; // enable I²C clock | ||
148 | #endif | ||
149 | IO_I2C_SCS &= ~0x8; //set clock to 100 kHz | ||
150 | IO_INTC_EINT2 &= ~INTR_EINT2_I2C; // disable I²C interrupt | ||
55 | } | 151 | } |
diff --git a/firmware/target/arm/tms320dm320/i2c-dm320.h b/firmware/target/arm/tms320dm320/i2c-dm320.h index aa7ced1119..d73a334eb4 100755 --- a/firmware/target/arm/tms320dm320/i2c-dm320.h +++ b/firmware/target/arm/tms320dm320/i2c-dm320.h | |||
@@ -5,9 +5,9 @@ | |||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id: i2c-meg-fx.h 13720 2007-06-26 02:11:30Z jethead71 $ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2007 by Michael Sevakis | 10 | * Copyright (C) 2008 by Maurus Cuelenaere |
11 | * | 11 | * |
12 | * All files in this archive are subject to the GNU General Public License. | 12 | * All files in this archive are subject to the GNU General Public License. |
13 | * See the file COPYING in the source tree root for full license agreement. | 13 | * See the file COPYING in the source tree root for full license agreement. |
@@ -17,28 +17,6 @@ | |||
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | 19 | ||
20 | /* chip-specific i2c functions */ | ||
21 | |||
22 | /* IICCON */ | ||
23 | #define I2C_ACKGEN (1 << 7) | ||
24 | #define I2C_TXCLK_512 (1 << 6) | ||
25 | #define I2C_TXRX_INTENB (1 << 5) | ||
26 | #define I2C_TXRX_INTPND (1 << 4) | ||
27 | |||
28 | /* IICSTAT */ | ||
29 | #define I2C_MODE_MASTER (2 << 6) | ||
30 | #define I2C_MODE_TX (1 << 6) | ||
31 | #define I2C_BUSY (1 << 5) | ||
32 | #define I2C_START (1 << 5) | ||
33 | #define I2C_RXTX_ENB (1 << 4) | ||
34 | #define I2C_BUS_ARB_FAILED (1 << 3) | ||
35 | #define I2C_S_ADDR_STAT (1 << 2) | ||
36 | #define I2C_S_ADDR_MATCH (1 << 1) | ||
37 | #define I2C_ACK_L (1 << 0) | ||
38 | |||
39 | /* IICLC */ | ||
40 | #define I2C_FLT_ENB (1 << 2) | ||
41 | |||
42 | void i2c_init(void); | 20 | void i2c_init(void); |
43 | void i2c_write(int addr, const unsigned char *data, int count); | 21 | int i2c_write(unsigned short address, const unsigned char *data, int count); |
44 | 22 | int i2c_read(unsigned short address, unsigned char* buf, int count); | |