aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryiancar <yiangosyiangou@cytanet.com.cy>2018-05-14 15:17:24 +0100
committerJack Humbert <jack.humb@gmail.com>2018-05-14 10:17:24 -0400
commita98a91cf1b923107e9f26df316c1ef2192ff14f7 (patch)
tree112b22b9ee2f212b4a58e57d2e4b4906d1ef7636
parentf42ec8aa866386ed0ab8faf7acf9c396aa482519 (diff)
downloadqmk_firmware-a98a91cf1b923107e9f26df316c1ef2192ff14f7.tar.gz
qmk_firmware-a98a91cf1b923107e9f26df316c1ef2192ff14f7.zip
Rgb matrix fixes, I2C library can now retry if it has failed (#2943)
* Added Modular keyboards L,R and NUM Created code modules for the 3 modules of the modular keyboard. Original idea by MechboardsUK. Uses i2c implementation similar to lets split * Remove modular from master This is to fix incorrect branching * General fixes for RGB_matrix - Complited speed support for all effects - Fixed raindrop effects to initialized after toggle - Fixed raindrop effects to use all available LEDs - Fixed effect step reverse function - Moved RGB_MATRIX_SOLID_REACTIVE under correct flag * Documentation update for RGBmatrix * More doc updates * I2C library can now retry if it has failed - Replaced the original TWIlib by LFKeyboard's modified version - Allows for an extra argument on TWITransmitData, if blocking is set to 1 function will retry to transmit on failure. Good for noisy boards. * RGB Matrix, use alternative I2C library TWIlib seems to be hanging for me sometimes probably due to ISR routine. I have used i2c_master as a good alternative. Note: this commit is for Wilba6582 to verify before merge * Update rgb_matrix.c * RGB matrix cleanup - Remove TWIlib
-rw-r--r--common_features.mk2
-rw-r--r--drivers/avr/TWIlib.c232
-rw-r--r--drivers/avr/TWIlib.h82
-rwxr-xr-xdrivers/avr/i2c_master.c149
-rwxr-xr-xdrivers/avr/i2c_master.h22
-rw-r--r--drivers/avr/is31fl3731.c36
-rw-r--r--quantum/rgb_matrix.c6
7 files changed, 185 insertions, 344 deletions
diff --git a/common_features.mk b/common_features.mk
index 7ba7d4815..0778f8e0f 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -117,7 +117,7 @@ endif
117ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes) 117ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
118 OPT_DEFS += -DRGB_MATRIX_ENABLE 118 OPT_DEFS += -DRGB_MATRIX_ENABLE
119 SRC += is31fl3731.c 119 SRC += is31fl3731.c
120 SRC += TWIlib.c 120 SRC += i2c_master.c
121 SRC += $(QUANTUM_DIR)/color.c 121 SRC += $(QUANTUM_DIR)/color.c
122 SRC += $(QUANTUM_DIR)/rgb_matrix.c 122 SRC += $(QUANTUM_DIR)/rgb_matrix.c
123 CIE1931_CURVE = yes 123 CIE1931_CURVE = yes
diff --git a/drivers/avr/TWIlib.c b/drivers/avr/TWIlib.c
deleted file mode 100644
index b39e3054a..000000000
--- a/drivers/avr/TWIlib.c
+++ /dev/null
@@ -1,232 +0,0 @@
1/*
2 * TWIlib.c
3 *
4 * Created: 6/01/2014 10:41:33 PM
5 * Author: Chris Herring
6 * http://www.chrisherring.net/all/tutorial-interrupt-driven-twi-interface-for-avr-part1/
7 */
8
9#include <avr/io.h>
10#include <avr/interrupt.h>
11#include "TWIlib.h"
12#include "util/delay.h"
13
14void TWIInit()
15{
16 TWIInfo.mode = Ready;
17 TWIInfo.errorCode = 0xFF;
18 TWIInfo.repStart = 0;
19 // Set pre-scalers (no pre-scaling)
20 TWSR = 0;
21 // Set bit rate
22 TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
23 // Enable TWI and interrupt
24 TWCR = (1 << TWIE) | (1 << TWEN);
25}
26
27uint8_t isTWIReady()
28{
29 if ( (TWIInfo.mode == Ready) | (TWIInfo.mode == RepeatedStartSent) )
30 {
31 return 1;
32 }
33 else
34 {
35 return 0;
36 }
37}
38
39uint8_t TWITransmitData(void *const TXdata, uint8_t dataLen, uint8_t repStart)
40{
41 if (dataLen <= TXMAXBUFLEN)
42 {
43 // Wait until ready
44 while (!isTWIReady()) {_delay_us(1);}
45 // Set repeated start mode
46 TWIInfo.repStart = repStart;
47 // Copy data into the transmit buffer
48 uint8_t *data = (uint8_t *)TXdata;
49 for (int i = 0; i < dataLen; i++)
50 {
51 TWITransmitBuffer[i] = data[i];
52 }
53 // Copy transmit info to global variables
54 TXBuffLen = dataLen;
55 TXBuffIndex = 0;
56
57 // If a repeated start has been sent, then devices are already listening for an address
58 // and another start does not need to be sent.
59 if (TWIInfo.mode == RepeatedStartSent)
60 {
61 TWIInfo.mode = Initializing;
62 TWDR = TWITransmitBuffer[TXBuffIndex++]; // Load data to transmit buffer
63 TWISendTransmit(); // Send the data
64 }
65 else // Otherwise, just send the normal start signal to begin transmission.
66 {
67 TWIInfo.mode = Initializing;
68 TWISendStart();
69 }
70
71 }
72 else
73 {
74 return 1; // return an error if data length is longer than buffer
75 }
76 return 0;
77}
78
79uint8_t TWIReadData(uint8_t TWIaddr, uint8_t bytesToRead, uint8_t repStart)
80{
81 // Check if number of bytes to read can fit in the RXbuffer
82 if (bytesToRead < RXMAXBUFLEN)
83 {
84 // Reset buffer index and set RXBuffLen to the number of bytes to read
85 RXBuffIndex = 0;
86 RXBuffLen = bytesToRead;
87 // Create the one value array for the address to be transmitted
88 uint8_t TXdata[1];
89 // Shift the address and AND a 1 into the read write bit (set to write mode)
90 TXdata[0] = (TWIaddr << 1) | 0x01;
91 // Use the TWITransmitData function to initialize the transfer and address the slave
92 TWITransmitData(TXdata, 1, repStart);
93 }
94 else
95 {
96 return 0;
97 }
98 return 1;
99}
100
101ISR (TWI_vect)
102{
103 switch (TWI_STATUS)
104 {
105 // ----\/ ---- MASTER TRANSMITTER OR WRITING ADDRESS ----\/ ---- //
106 case TWI_MT_SLAW_ACK: // SLA+W transmitted and ACK received
107 // Set mode to Master Transmitter
108 TWIInfo.mode = MasterTransmitter;
109 case TWI_START_SENT: // Start condition has been transmitted
110 case TWI_MT_DATA_ACK: // Data byte has been transmitted, ACK received
111 if (TXBuffIndex < TXBuffLen) // If there is more data to send
112 {
113 TWDR = TWITransmitBuffer[TXBuffIndex++]; // Load data to transmit buffer
114 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
115 TWISendTransmit(); // Send the data
116 }
117 // This transmission is complete however do not release bus yet
118 else if (TWIInfo.repStart)
119 {
120 TWIInfo.errorCode = 0xFF;
121 TWISendStart();
122 }
123 // All transmissions are complete, exit
124 else
125 {
126 TWIInfo.mode = Ready;
127 TWIInfo.errorCode = 0xFF;
128 TWISendStop();
129 }
130 break;
131
132 // ----\/ ---- MASTER RECEIVER ----\/ ---- //
133
134 case TWI_MR_SLAR_ACK: // SLA+R has been transmitted, ACK has been received
135 // Switch to Master Receiver mode
136 TWIInfo.mode = MasterReceiver;
137 // If there is more than one byte to be read, receive data byte and return an ACK
138 if (RXBuffIndex < RXBuffLen-1)
139 {
140 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
141 TWISendACK();
142 }
143 // Otherwise when a data byte (the only data byte) is received, return NACK
144 else
145 {
146 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
147 TWISendNACK();
148 }
149 break;
150
151 case TWI_MR_DATA_ACK: // Data has been received, ACK has been transmitted.
152
153 /// -- HANDLE DATA BYTE --- ///
154 TWIReceiveBuffer[RXBuffIndex++] = TWDR;
155 // If there is more than one byte to be read, receive data byte and return an ACK
156 if (RXBuffIndex < RXBuffLen-1)
157 {
158 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
159 TWISendACK();
160 }
161 // Otherwise when a data byte (the only data byte) is received, return NACK
162 else
163 {
164 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
165 TWISendNACK();
166 }
167 break;
168
169 case TWI_MR_DATA_NACK: // Data byte has been received, NACK has been transmitted. End of transmission.
170
171 /// -- HANDLE DATA BYTE --- ///
172 TWIReceiveBuffer[RXBuffIndex++] = TWDR;
173 // This transmission is complete however do not release bus yet
174 if (TWIInfo.repStart)
175 {
176 TWIInfo.errorCode = 0xFF;
177 TWISendStart();
178 }
179 // All transmissions are complete, exit
180 else
181 {
182 TWIInfo.mode = Ready;
183 TWIInfo.errorCode = 0xFF;
184 TWISendStop();
185 }
186 break;
187
188 // ----\/ ---- MT and MR common ----\/ ---- //
189
190 case TWI_MR_SLAR_NACK: // SLA+R transmitted, NACK received
191 case TWI_MT_SLAW_NACK: // SLA+W transmitted, NACK received
192 case TWI_MT_DATA_NACK: // Data byte has been transmitted, NACK received
193 case TWI_LOST_ARBIT: // Arbitration has been lost
194 // Return error and send stop and set mode to ready
195 if (TWIInfo.repStart)
196 {
197 TWIInfo.errorCode = TWI_STATUS;
198 TWISendStart();
199 }
200 // All transmissions are complete, exit
201 else
202 {
203 TWIInfo.mode = Ready;
204 TWIInfo.errorCode = TWI_STATUS;
205 TWISendStop();
206 }
207 break;
208 case TWI_REP_START_SENT: // Repeated start has been transmitted
209 // Set the mode but DO NOT clear TWINT as the next data is not yet ready
210 TWIInfo.mode = RepeatedStartSent;
211 break;
212
213 // ----\/ ---- SLAVE RECEIVER ----\/ ---- //
214
215 // TODO IMPLEMENT SLAVE RECEIVER FUNCTIONALITY
216
217 // ----\/ ---- SLAVE TRANSMITTER ----\/ ---- //
218
219 // TODO IMPLEMENT SLAVE TRANSMITTER FUNCTIONALITY
220
221 // ----\/ ---- MISCELLANEOUS STATES ----\/ ---- //
222 case TWI_NO_RELEVANT_INFO: // It is not really possible to get into this ISR on this condition
223 // Rather, it is there to be manually set between operations
224 break;
225 case TWI_ILLEGAL_START_STOP: // Illegal START/STOP, abort and return error
226 TWIInfo.errorCode = TWI_ILLEGAL_START_STOP;
227 TWIInfo.mode = Ready;
228 TWISendStop();
229 break;
230 }
231
232}
diff --git a/drivers/avr/TWIlib.h b/drivers/avr/TWIlib.h
deleted file mode 100644
index 23fd1f09a..000000000
--- a/drivers/avr/TWIlib.h
+++ /dev/null
@@ -1,82 +0,0 @@
1/*
2 * TWIlib.h
3 *
4 * Created: 6/01/2014 10:38:42 PM
5 * Author: Chris Herring
6 * http://www.chrisherring.net/all/tutorial-interrupt-driven-twi-interface-for-avr-part1/
7 */
8
9
10#ifndef TWILIB_H_
11#define TWILIB_H_
12// TWI bit rate (was 100000)
13#define TWI_FREQ 400000
14// Get TWI status
15#define TWI_STATUS (TWSR & 0xF8)
16// Transmit buffer length
17#define TXMAXBUFLEN 20
18// Receive buffer length
19#define RXMAXBUFLEN 20
20// Global transmit buffer
21uint8_t TWITransmitBuffer[TXMAXBUFLEN];
22// Global receive buffer
23volatile uint8_t TWIReceiveBuffer[RXMAXBUFLEN];
24// Buffer indexes
25volatile int TXBuffIndex; // Index of the transmit buffer. Is volatile, can change at any time.
26int RXBuffIndex; // Current index in the receive buffer
27// Buffer lengths
28int TXBuffLen; // The total length of the transmit buffer
29int RXBuffLen; // The total number of bytes to read (should be less than RXMAXBUFFLEN)
30
31typedef enum {
32 Ready,
33 Initializing,
34 RepeatedStartSent,
35 MasterTransmitter,
36 MasterReceiver,
37 SlaceTransmitter,
38 SlaveReciever
39 } TWIMode;
40
41 typedef struct TWIInfoStruct{
42 TWIMode mode;
43 uint8_t errorCode;
44 uint8_t repStart;
45 }TWIInfoStruct;
46TWIInfoStruct TWIInfo;
47
48
49// TWI Status Codes
50#define TWI_START_SENT 0x08 // Start sent
51#define TWI_REP_START_SENT 0x10 // Repeated Start sent
52// Master Transmitter Mode
53#define TWI_MT_SLAW_ACK 0x18 // SLA+W sent and ACK received
54#define TWI_MT_SLAW_NACK 0x20 // SLA+W sent and NACK received
55#define TWI_MT_DATA_ACK 0x28 // DATA sent and ACK received
56#define TWI_MT_DATA_NACK 0x30 // DATA sent and NACK received
57// Master Receiver Mode
58#define TWI_MR_SLAR_ACK 0x40 // SLA+R sent, ACK received
59#define TWI_MR_SLAR_NACK 0x48 // SLA+R sent, NACK received
60#define TWI_MR_DATA_ACK 0x50 // Data received, ACK returned
61#define TWI_MR_DATA_NACK 0x58 // Data received, NACK returned
62
63// Miscellaneous States
64#define TWI_LOST_ARBIT 0x38 // Arbitration has been lost
65#define TWI_NO_RELEVANT_INFO 0xF8 // No relevant information available
66#define TWI_ILLEGAL_START_STOP 0x00 // Illegal START or STOP condition has been detected
67#define TWI_SUCCESS 0xFF // Successful transfer, this state is impossible from TWSR as bit2 is 0 and read only
68
69
70#define TWISendStart() (TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)) // Send the START signal, enable interrupts and TWI, clear TWINT flag to resume transfer.
71#define TWISendStop() (TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN)|(1<<TWIE)) // Send the STOP signal, enable interrupts and TWI, clear TWINT flag.
72#define TWISendTransmit() (TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE)) // Used to resume a transfer, clear TWINT and ensure that TWI and interrupts are enabled.
73#define TWISendACK() (TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE)|(1<<TWEA)) // FOR MR mode. Resume a transfer, ensure that TWI and interrupts are enabled and respond with an ACK if the device is addressed as a slave or after it receives a byte.
74#define TWISendNACK() (TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE)) // FOR MR mode. Resume a transfer, ensure that TWI and interrupts are enabled but DO NOT respond with an ACK if the device is addressed as a slave or after it receives a byte.
75
76// Function declarations
77uint8_t TWITransmitData(void *const TXdata, uint8_t dataLen, uint8_t repStart);
78void TWIInit(void);
79uint8_t TWIReadData(uint8_t TWIaddr, uint8_t bytesToRead, uint8_t repStart);
80uint8_t isTWIReady(void);
81
82#endif // TWICOMMS_H_ \ No newline at end of file
diff --git a/drivers/avr/i2c_master.c b/drivers/avr/i2c_master.c
new file mode 100755
index 000000000..f4a4bb7b0
--- /dev/null
+++ b/drivers/avr/i2c_master.c
@@ -0,0 +1,149 @@
1/* Library made by: g4lvanix
2 * Github repository: https://github.com/g4lvanix/I2C-master-lib
3 */
4
5#include <avr/io.h>
6#include <util/twi.h>
7
8#include "i2c_master.h"
9
10#define F_SCL 400000UL // SCL frequency
11#define Prescaler 1
12#define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16 ) / 2)
13
14void i2c_init(void)
15{
16 TWBR = (uint8_t)TWBR_val;
17}
18
19uint8_t i2c_start(uint8_t address)
20{
21 // reset TWI control register
22 TWCR = 0;
23 // transmit START condition
24 TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
25 // wait for end of transmission
26 while( !(TWCR & (1<<TWINT)) );
27
28 // check if the start condition was successfully transmitted
29 if((TWSR & 0xF8) != TW_START){ return 1; }
30
31 // load slave address into data register
32 TWDR = address;
33 // start transmission of address
34 TWCR = (1<<TWINT) | (1<<TWEN);
35 // wait for end of transmission
36 while( !(TWCR & (1<<TWINT)) );
37
38 // check if the device has acknowledged the READ / WRITE mode
39 uint8_t twst = TW_STATUS & 0xF8;
40 if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
41
42 return 0;
43}
44
45uint8_t i2c_write(uint8_t data)
46{
47 // load data into data register
48 TWDR = data;
49 // start transmission of data
50 TWCR = (1<<TWINT) | (1<<TWEN);
51 // wait for end of transmission
52 while( !(TWCR & (1<<TWINT)) );
53
54 if( (TWSR & 0xF8) != TW_MT_DATA_ACK ){ return 1; }
55
56 return 0;
57}
58
59uint8_t i2c_read_ack(void)
60{
61
62 // start TWI module and acknowledge data after reception
63 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
64 // wait for end of transmission
65 while( !(TWCR & (1<<TWINT)) );
66 // return received data from TWDR
67 return TWDR;
68}
69
70uint8_t i2c_read_nack(void)
71{
72
73 // start receiving without acknowledging reception
74 TWCR = (1<<TWINT) | (1<<TWEN);
75 // wait for end of transmission
76 while( !(TWCR & (1<<TWINT)) );
77 // return received data from TWDR
78 return TWDR;
79}
80
81uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length)
82{
83 if (i2c_start(address | I2C_WRITE)) return 1;
84
85 for (uint16_t i = 0; i < length; i++)
86 {
87 if (i2c_write(data[i])) return 1;
88 }
89
90 i2c_stop();
91
92 return 0;
93}
94
95uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length)
96{
97 if (i2c_start(address | I2C_READ)) return 1;
98
99 for (uint16_t i = 0; i < (length-1); i++)
100 {
101 data[i] = i2c_read_ack();
102 }
103 data[(length-1)] = i2c_read_nack();
104
105 i2c_stop();
106
107 return 0;
108}
109
110uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
111{
112 if (i2c_start(devaddr | 0x00)) return 1;
113
114 i2c_write(regaddr);
115
116 for (uint16_t i = 0; i < length; i++)
117 {
118 if (i2c_write(data[i])) return 1;
119 }
120
121 i2c_stop();
122
123 return 0;
124}
125
126uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
127{
128 if (i2c_start(devaddr)) return 1;
129
130 i2c_write(regaddr);
131
132 if (i2c_start(devaddr | 0x01)) return 1;
133
134 for (uint16_t i = 0; i < (length-1); i++)
135 {
136 data[i] = i2c_read_ack();
137 }
138 data[(length-1)] = i2c_read_nack();
139
140 i2c_stop();
141
142 return 0;
143}
144
145void i2c_stop(void)
146{
147 // transmit STOP condition
148 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
149}
diff --git a/drivers/avr/i2c_master.h b/drivers/avr/i2c_master.h
new file mode 100755
index 000000000..2479d28d5
--- /dev/null
+++ b/drivers/avr/i2c_master.h
@@ -0,0 +1,22 @@
1/* Library made by: g4lvanix
2 * Github repository: https://github.com/g4lvanix/I2C-master-lib
3 */
4
5#ifndef I2C_MASTER_H
6#define I2C_MASTER_H
7
8#define I2C_READ 0x01
9#define I2C_WRITE 0x00
10
11void i2c_init(void);
12uint8_t i2c_start(uint8_t address);
13uint8_t i2c_write(uint8_t data);
14uint8_t i2c_read_ack(void);
15uint8_t i2c_read_nack(void);
16uint8_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);
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);
20void i2c_stop(void);
21
22#endif // I2C_MASTER_H
diff --git a/drivers/avr/is31fl3731.c b/drivers/avr/is31fl3731.c
index e5941cf41..c7a99e3a3 100644
--- a/drivers/avr/is31fl3731.c
+++ b/drivers/avr/is31fl3731.c
@@ -20,7 +20,7 @@
20#include <avr/io.h> 20#include <avr/io.h>
21#include <util/delay.h> 21#include <util/delay.h>
22#include <string.h> 22#include <string.h>
23#include "TWIlib.h" 23#include "i2c_master.h"
24#include "progmem.h" 24#include "progmem.h"
25 25
26// This is a 7-bit address, that gets left-shifted and bit 0 26// This is a 7-bit address, that gets left-shifted and bit 0
@@ -50,7 +50,7 @@
50#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine' 50#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine'
51 51
52// Transfer buffer for TWITransmitData() 52// Transfer buffer for TWITransmitData()
53uint8_t g_twi_transfer_buffer[TXMAXBUFLEN]; 53uint8_t g_twi_transfer_buffer[20];
54 54
55// These buffers match the IS31FL3731 PWM registers 0x24-0xB3. 55// These buffers match the IS31FL3731 PWM registers 0x24-0xB3.
56// Storing them like this is optimal for I2C transfers to the registers. 56// Storing them like this is optimal for I2C transfers to the registers.
@@ -80,17 +80,11 @@ bool g_led_control_registers_update_required = false;
80 80
81void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data ) 81void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data )
82{ 82{
83 g_twi_transfer_buffer[0] = (addr << 1) | 0x00; 83 g_twi_transfer_buffer[0] = reg;
84 g_twi_transfer_buffer[1] = reg; 84 g_twi_transfer_buffer[1] = data;
85 g_twi_transfer_buffer[2] = data; 85
86 86 //Transmit data until succesful
87 // Set the error code to have no relevant information 87 while(i2c_transmit(addr << 1, g_twi_transfer_buffer,2) != 0);
88 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
89 // Continuously attempt to transmit data until a successful transmission occurs
90 //while ( TWIInfo.errorCode != 0xFF )
91 //{
92 TWITransmitData( g_twi_transfer_buffer, 3, 0 );
93 //}
94} 88}
95 89
96void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ) 90void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
@@ -100,29 +94,21 @@ void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
100 // transmit PWM registers in 9 transfers of 16 bytes 94 // transmit PWM registers in 9 transfers of 16 bytes
101 // g_twi_transfer_buffer[] is 20 bytes 95 // g_twi_transfer_buffer[] is 20 bytes
102 96
103 // set the I2C address
104 g_twi_transfer_buffer[0] = (addr << 1) | 0x00;
105
106 // iterate over the pwm_buffer contents at 16 byte intervals 97 // iterate over the pwm_buffer contents at 16 byte intervals
107 for ( int i = 0; i < 144; i += 16 ) 98 for ( int i = 0; i < 144; i += 16 )
108 { 99 {
109 // set the first register, e.g. 0x24, 0x34, 0x44, etc. 100 // set the first register, e.g. 0x24, 0x34, 0x44, etc.
110 g_twi_transfer_buffer[1] = 0x24 + i; 101 g_twi_transfer_buffer[0] = 0x24 + i;
111 // copy the data from i to i+15 102 // copy the data from i to i+15
112 // device will auto-increment register for data after the first byte 103 // device will auto-increment register for data after the first byte
113 // thus this sets registers 0x24-0x33, 0x34-0x43, etc. in one transfer 104 // thus this sets registers 0x24-0x33, 0x34-0x43, etc. in one transfer
114 for ( int j = 0; j < 16; j++ ) 105 for ( int j = 0; j < 16; j++ )
115 { 106 {
116 g_twi_transfer_buffer[2 + j] = pwm_buffer[i + j]; 107 g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j];
117 } 108 }
118 109
119 // Set the error code to have no relevant information 110 //Transmit buffer until succesful
120 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO; 111 while(i2c_transmit(addr << 1, g_twi_transfer_buffer,17) != 0);
121 // Continuously attempt to transmit data until a successful transmission occurs
122 while ( TWIInfo.errorCode != 0xFF )
123 {
124 TWITransmitData( g_twi_transfer_buffer, 16 + 2, 0 );
125 }
126 } 112 }
127} 113}
128 114
diff --git a/quantum/rgb_matrix.c b/quantum/rgb_matrix.c
index f3d012bc3..992ce99de 100644
--- a/quantum/rgb_matrix.c
+++ b/quantum/rgb_matrix.c
@@ -18,7 +18,7 @@
18 18
19#include "rgb_matrix.h" 19#include "rgb_matrix.h"
20#include <avr/io.h> 20#include <avr/io.h>
21#include "TWIlib.h" 21#include "i2c_master.h"
22#include <util/delay.h> 22#include <util/delay.h>
23#include <avr/interrupt.h> 23#include <avr/interrupt.h>
24#include "progmem.h" 24#include "progmem.h"
@@ -722,10 +722,8 @@ void rgb_matrix_indicators_user(void) {}
722// } 722// }
723 723
724void rgb_matrix_init_drivers(void) { 724void rgb_matrix_init_drivers(void) {
725 //sei();
726
727 // Initialize TWI 725 // Initialize TWI
728 TWIInit(); 726 i2c_init();
729 IS31FL3731_init( DRIVER_ADDR_1 ); 727 IS31FL3731_init( DRIVER_ADDR_1 );
730 IS31FL3731_init( DRIVER_ADDR_2 ); 728 IS31FL3731_init( DRIVER_ADDR_2 );
731 729