aboutsummaryrefslogtreecommitdiff
path: root/drivers/avr
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/avr')
-rwxr-xr-xdrivers/avr/i2c_master.c89
-rwxr-xr-xdrivers/avr/i2c_master.h2
-rw-r--r--drivers/avr/is31fl3731.c56
-rw-r--r--drivers/avr/is31fl3731.h10
4 files changed, 115 insertions, 42 deletions
diff --git a/drivers/avr/i2c_master.c b/drivers/avr/i2c_master.c
index cd3c2e1c8..97f690043 100755
--- a/drivers/avr/i2c_master.c
+++ b/drivers/avr/i2c_master.c
@@ -6,6 +6,7 @@
6#include <util/twi.h> 6#include <util/twi.h>
7 7
8#include "i2c_master.h" 8#include "i2c_master.h"
9#include "timer.h"
9 10
10#define F_SCL 400000UL // SCL frequency 11#define F_SCL 400000UL // SCL frequency
11#define Prescaler 1 12#define Prescaler 1
@@ -24,8 +25,18 @@ uint8_t i2c_start(uint8_t address)
24 TWCR = 0; 25 TWCR = 0;
25 // transmit START condition 26 // transmit START condition
26 TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); 27 TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
27 // wait for end of transmission 28
28 while( !(TWCR & (1<<TWINT)) ); 29 #ifdef I2C_TIMEOUT
30 uint16_t timeout_timer = timer_read();
31 while( !(TWCR & (1<<TWINT)) ) {
32 if ((timer_read() - timeout_timer) > I2C_TIMEOUT) {
33 return 2; // should make these codes standard
34 }
35 }
36 #else
37 // wait for end of transmission
38 while( !(TWCR & (1<<TWINT)) );
39 #endif
29 40
30 // check if the start condition was successfully transmitted 41 // check if the start condition was successfully transmitted
31 if(((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)){ return 1; } 42 if(((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)){ return 1; }
@@ -34,8 +45,18 @@ uint8_t i2c_start(uint8_t address)
34 TWDR = address; 45 TWDR = address;
35 // start transmission of address 46 // start transmission of address
36 TWCR = (1<<TWINT) | (1<<TWEN); 47 TWCR = (1<<TWINT) | (1<<TWEN);
37 // wait for end of transmission 48
38 while( !(TWCR & (1<<TWINT)) ); 49 #ifdef I2C_TIMEOUT
50 timeout_timer = timer_read();
51 while( !(TWCR & (1<<TWINT)) ) {
52 if ((timer_read() - timeout_timer) > I2C_TIMEOUT) {
53 return 2; // should make these codes standard
54 }
55 }
56 #else
57 // wait for end of transmission
58 while( !(TWCR & (1<<TWINT)) );
59 #endif
39 60
40 // check if the device has acknowledged the READ / WRITE mode 61 // check if the device has acknowledged the READ / WRITE mode
41 uint8_t twst = TW_STATUS & 0xF8; 62 uint8_t twst = TW_STATUS & 0xF8;
@@ -50,8 +71,18 @@ uint8_t i2c_write(uint8_t data)
50 TWDR = data; 71 TWDR = data;
51 // start transmission of data 72 // start transmission of data
52 TWCR = (1<<TWINT) | (1<<TWEN); 73 TWCR = (1<<TWINT) | (1<<TWEN);
74
75 #ifdef I2C_TIMEOUT
76 uint16_t timeout_timer = timer_read();
77 while( !(TWCR & (1<<TWINT)) ) {
78 if ((timer_read() - timeout_timer) > I2C_TIMEOUT) {
79 return 2; // should make these codes standard
80 }
81 }
82 #else
53 // wait for end of transmission 83 // wait for end of transmission
54 while( !(TWCR & (1<<TWINT)) ); 84 while( !(TWCR & (1<<TWINT)) );
85 #endif
55 86
56 if( (TW_STATUS & 0xF8) != TW_MT_DATA_ACK ){ return 1; } 87 if( (TW_STATUS & 0xF8) != TW_MT_DATA_ACK ){ return 1; }
57 88
@@ -63,8 +94,19 @@ uint8_t i2c_read_ack(void)
63 94
64 // start TWI module and acknowledge data after reception 95 // start TWI module and acknowledge data after reception
65 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA); 96 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
66 // wait for end of transmission 97
67 while( !(TWCR & (1<<TWINT)) ); 98 #ifdef I2C_TIMEOUT
99 uint16_t timeout_timer = timer_read();
100 while( !(TWCR & (1<<TWINT)) ) {
101 if ((timer_read() - timeout_timer) > I2C_TIMEOUT) {
102 return 2; // should make these codes standard
103 }
104 }
105 #else
106 // wait for end of transmission
107 while( !(TWCR & (1<<TWINT)) );
108 #endif
109
68 // return received data from TWDR 110 // return received data from TWDR
69 return TWDR; 111 return TWDR;
70} 112}
@@ -74,8 +116,19 @@ uint8_t i2c_read_nack(void)
74 116
75 // start receiving without acknowledging reception 117 // start receiving without acknowledging reception
76 TWCR = (1<<TWINT) | (1<<TWEN); 118 TWCR = (1<<TWINT) | (1<<TWEN);
77 // wait for end of transmission 119
78 while( !(TWCR & (1<<TWINT)) ); 120 #ifdef I2C_TIMEOUT
121 uint16_t timeout_timer = timer_read();
122 while( !(TWCR & (1<<TWINT)) ) {
123 if ((timer_read() - timeout_timer) > I2C_TIMEOUT) {
124 return 2; // should make these codes standard
125 }
126 }
127 #else
128 // wait for end of transmission
129 while( !(TWCR & (1<<TWINT)) );
130 #endif
131
79 // return received data from TWDR 132 // return received data from TWDR
80 return TWDR; 133 return TWDR;
81} 134}
@@ -144,10 +197,22 @@ uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t le
144 return 0; 197 return 0;
145} 198}
146 199
147void i2c_stop(void) 200uint8_t i2c_stop(void)
148{ 201{
149 // transmit STOP condition 202 // transmit STOP condition
150 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); 203 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
151 // wait until stop condition is executed and bus released 204
152 while(TWCR & (1<<TWSTO)); 205 #ifdef I2C_TIMEOUT
206 uint16_t timeout_timer = timer_read();
207 while(TWCR & (1<<TWSTO)) {
208 if ((timer_read() - timeout_timer) > I2C_TIMEOUT) {
209 return 2; // should make these codes standard
210 }
211 }
212 #else
213 // wait for end of transmission
214 while(TWCR & (1<<TWSTO));
215 #endif
216
217 return 0;
153} 218}
diff --git a/drivers/avr/i2c_master.h b/drivers/avr/i2c_master.h
index 2479d28d5..868680714 100755
--- a/drivers/avr/i2c_master.h
+++ b/drivers/avr/i2c_master.h
@@ -17,6 +17,6 @@ uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length);
17uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length); 17uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length);
18uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length); 18uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
19uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length); 19uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
20void i2c_stop(void); 20uint8_t i2c_stop(void);
21 21
22#endif // I2C_MASTER_H 22#endif // I2C_MASTER_H
diff --git a/drivers/avr/is31fl3731.c b/drivers/avr/is31fl3731.c
index 13dfe6eaf..158b77b7b 100644
--- a/drivers/avr/is31fl3731.c
+++ b/drivers/avr/is31fl3731.c
@@ -78,18 +78,19 @@ bool g_led_control_registers_update_required = false;
78// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09 78// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09
79 79
80 80
81void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data ) 81uint8_t IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data )
82{ 82{
83 g_twi_transfer_buffer[0] = reg; 83 g_twi_transfer_buffer[0] = reg;
84 g_twi_transfer_buffer[1] = data; 84 g_twi_transfer_buffer[1] = data;
85 85
86 //Transmit data until succesful 86 //Transmit data until succesful
87 //while(i2c_transmit(addr << 1, g_twi_transfer_buffer,2) != 0); 87 //while(i2c_transmit(addr << 1, g_twi_transfer_buffer,2) != 0);
88 i2c_transmit(addr << 1, g_twi_transfer_buffer,2); 88 return i2c_transmit(addr << 1, g_twi_transfer_buffer,2);
89} 89}
90 90
91void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ) 91uint8_t IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
92{ 92{
93 uint8_t ret = 0;
93 // assumes bank is already selected 94 // assumes bank is already selected
94 95
95 // transmit PWM registers in 9 transfers of 16 bytes 96 // transmit PWM registers in 9 transfers of 16 bytes
@@ -110,64 +111,67 @@ void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
110 111
111 //Transmit buffer until succesful 112 //Transmit buffer until succesful
112 //while(i2c_transmit(addr << 1, g_twi_transfer_buffer,17) != 0); 113 //while(i2c_transmit(addr << 1, g_twi_transfer_buffer,17) != 0);
113 i2c_transmit(addr << 1, g_twi_transfer_buffer,17); 114 ret |= i2c_transmit(addr << 1, g_twi_transfer_buffer, 17);
114
115 } 115 }
116 return ret;
116} 117}
117 118
118void IS31FL3731_init( uint8_t addr ) 119uint8_t IS31FL3731_init( uint8_t addr )
119{ 120{
121 uint8_t ret = 0;
120 // In order to avoid the LEDs being driven with garbage data 122 // In order to avoid the LEDs being driven with garbage data
121 // in the LED driver's PWM registers, first enable software shutdown, 123 // in the LED driver's PWM registers, first enable software shutdown,
122 // then set up the mode and other settings, clear the PWM registers, 124 // then set up the mode and other settings, clear the PWM registers,
123 // then disable software shutdown. 125 // then disable software shutdown.
124 126
125 // select "function register" bank 127 // select "function register" bank
126 IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG ); 128 ret |= IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
127 129
128 // enable software shutdown 130 // enable software shutdown
129 IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x00 ); 131 ret |= IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x00 );
130 // this delay was copied from other drivers, might not be needed 132 // this delay was copied from other drivers, might not be needed
131 _delay_ms( 10 ); 133 _delay_ms( 10 );
132 134
133 // picture mode 135 // picture mode
134 IS31FL3731_write_register( addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE ); 136 ret |= IS31FL3731_write_register( addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE );
135 // display frame 0 137 // display frame 0
136 IS31FL3731_write_register( addr, ISSI_REG_PICTUREFRAME, 0x00 ); 138 ret |= IS31FL3731_write_register( addr, ISSI_REG_PICTUREFRAME, 0x00 );
137 // audio sync off 139 // audio sync off
138 IS31FL3731_write_register( addr, ISSI_REG_AUDIOSYNC, 0x00 ); 140 ret |= IS31FL3731_write_register( addr, ISSI_REG_AUDIOSYNC, 0x00 );
139 141
140 // select bank 0 142 // select bank 0
141 IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 ); 143 ret |= IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
142 144
143 // turn off all LEDs in the LED control register 145 // turn off all LEDs in the LED control register
144 for ( int i = 0x00; i <= 0x11; i++ ) 146 for ( int i = 0x00; i <= 0x11; i++ )
145 { 147 {
146 IS31FL3731_write_register( addr, i, 0x00 ); 148 ret |= IS31FL3731_write_register( addr, i, 0x00 );
147 } 149 }
148 150
149 // turn off all LEDs in the blink control register (not really needed) 151 // turn off all LEDs in the blink control register (not really needed)
150 for ( int i = 0x12; i <= 0x23; i++ ) 152 for ( int i = 0x12; i <= 0x23; i++ )
151 { 153 {
152 IS31FL3731_write_register( addr, i, 0x00 ); 154 ret |= IS31FL3731_write_register( addr, i, 0x00 );
153 } 155 }
154 156
155 // set PWM on all LEDs to 0 157 // set PWM on all LEDs to 0
156 for ( int i = 0x24; i <= 0xB3; i++ ) 158 for ( int i = 0x24; i <= 0xB3; i++ )
157 { 159 {
158 IS31FL3731_write_register( addr, i, 0x00 ); 160 ret |= IS31FL3731_write_register( addr, i, 0x00 );
159 } 161 }
160 162
161 // select "function register" bank 163 // select "function register" bank
162 IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG ); 164 ret |= IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
163 165
164 // disable software shutdown 166 // disable software shutdown
165 IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x01 ); 167 ret |= IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x01 );
166 168
167 // select bank 0 and leave it selected. 169 // select bank 0 and leave it selected.
168 // most usage after initialization is just writing PWM buffers in bank 0 170 // most usage after initialization is just writing PWM buffers in bank 0
169 // as there's not much point in double-buffering 171 // as there's not much point in double-buffering
170 IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 ); 172 ret |= IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
173
174 return ret;
171} 175}
172 176
173void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) 177void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
@@ -223,25 +227,29 @@ void IS31FL3731_set_led_control_register( uint8_t index, bool red, bool green, b
223 227
224} 228}
225 229
226void IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 ) 230uint8_t IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 )
227{ 231{
232 uint8_t ret = 0;
228 if ( g_pwm_buffer_update_required ) 233 if ( g_pwm_buffer_update_required )
229 { 234 {
230 IS31FL3731_write_pwm_buffer( addr1, g_pwm_buffer[0] ); 235 ret |= IS31FL3731_write_pwm_buffer( addr1, g_pwm_buffer[0] );
231 IS31FL3731_write_pwm_buffer( addr2, g_pwm_buffer[1] ); 236 ret |= IS31FL3731_write_pwm_buffer( addr2, g_pwm_buffer[1] );
232 } 237 }
233 g_pwm_buffer_update_required = false; 238 g_pwm_buffer_update_required = false;
239 return ret;
234} 240}
235 241
236void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 ) 242uint8_t IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 )
237{ 243{
244 uint8_t ret = 0;
238 if ( g_led_control_registers_update_required ) 245 if ( g_led_control_registers_update_required )
239 { 246 {
240 for ( int i=0; i<18; i++ ) 247 for ( int i=0; i<18; i++ )
241 { 248 {
242 IS31FL3731_write_register(addr1, i, g_led_control_registers[0][i] ); 249 ret |= IS31FL3731_write_register(addr1, i, g_led_control_registers[0][i] );
243 IS31FL3731_write_register(addr2, i, g_led_control_registers[1][i] ); 250 ret |= IS31FL3731_write_register(addr2, i, g_led_control_registers[1][i] );
244 } 251 }
245 } 252 }
253 return ret;
246} 254}
247 255
diff --git a/drivers/avr/is31fl3731.h b/drivers/avr/is31fl3731.h
index 3d30fc67b..62632e276 100644
--- a/drivers/avr/is31fl3731.h
+++ b/drivers/avr/is31fl3731.h
@@ -31,9 +31,9 @@ typedef struct is31_led {
31 31
32extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; 32extern const is31_led g_is31_leds[DRIVER_LED_TOTAL];
33 33
34void IS31FL3731_init( uint8_t addr ); 34uint8_t IS31FL3731_init( uint8_t addr );
35void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data ); 35uint8_t IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data );
36void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ); 36uint8_t IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer );
37 37
38void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); 38void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue );
39void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue ); 39void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue );
@@ -44,8 +44,8 @@ void IS31FL3731_set_led_control_register( uint8_t index, bool red, bool green, b
44// (eg. from a timer interrupt). 44// (eg. from a timer interrupt).
45// Call this while idle (in between matrix scans). 45// Call this while idle (in between matrix scans).
46// If the buffer is dirty, it will update the driver with the buffer. 46// If the buffer is dirty, it will update the driver with the buffer.
47void IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 ); 47uint8_t IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 );
48void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 ); 48uint8_t IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 );
49 49
50#define C1_1 0x24 50#define C1_1 0x24
51#define C1_2 0x25 51#define C1_2 0x25