14
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
15
15
*/
16
16
#include "is31fl3218.h"
17
+ #include <string.h>
17
18
#include "i2c_master.h"
18
19
19
- // This is the full 8-bit address
20
- #define IS31FL3218_I2C_ADDRESS 0xA8
21
-
22
20
// These are the register addresses
23
21
#define IS31FL3218_REG_SHUTDOWN 0x00
24
22
#define IS31FL3218_REG_PWM 0x01
25
23
#define IS31FL3218_REG_CONTROL 0x13
26
24
#define IS31FL3218_REG_UPDATE 0x16
27
25
#define IS31FL3218_REG_RESET 0x17
28
26
29
- // Default timeout if no I2C response
30
- #define IS31FL3218_I2C_TIMEOUT 100
27
+ #ifndef IS31FL3218_I2C_TIMEOUT
28
+ # define IS31FL3218_I2C_TIMEOUT 100
29
+ #endif
30
+
31
+ #ifndef IS31FL3218_I2C_PERSISTENCE
32
+ # define IS31FL3218_I2C_PERSISTENCE 0
33
+ #endif
31
34
32
35
// Reusable buffer for transfers
33
36
uint8_t g_twi_transfer_buffer [20 ];
34
37
35
38
// IS31FL3218 has 18 PWM outputs and a fixed I2C address, so no chaining.
36
- // If used as RGB LED driver, LEDs are assigned RGB,RGB,RGB,RGB,RGB,RGB
37
39
uint8_t g_pwm_buffer [18 ];
38
40
bool g_pwm_buffer_update_required = false;
39
41
42
+ uint8_t g_led_control_registers [3 ] = {0 };
43
+ bool g_led_control_registers_update_required = false;
44
+
40
45
void is31fl3218_write_register (uint8_t reg , uint8_t data ) {
41
46
g_twi_transfer_buffer [0 ] = reg ;
42
47
g_twi_transfer_buffer [1 ] = data ;
43
- i2c_transmit (IS31FL3218_I2C_ADDRESS , g_twi_transfer_buffer , 2 , IS31FL3218_I2C_TIMEOUT );
48
+ #if IS31FL3218_I2C_PERSISTENCE > 0
49
+ for (uint8_t i = 0 ; i < IS31FL3218_I2C_PERSISTENCE ; i ++ ) {
50
+ if (i2c_transmit (IS31FL3218_I2C_ADDRESS << 1 , g_twi_transfer_buffer , 2 , IS31FL3218_I2C_TIMEOUT ) == 0 ) break ;
51
+ }
52
+ #else
53
+ i2c_transmit (IS31FL3218_I2C_ADDRESS << 1 , g_twi_transfer_buffer , 2 , IS31FL3218_I2C_TIMEOUT );
54
+ #endif
44
55
}
45
56
46
57
void is31fl3218_write_pwm_buffer (uint8_t * pwm_buffer ) {
47
58
g_twi_transfer_buffer [0 ] = IS31FL3218_REG_PWM ;
48
59
memcpy (g_twi_transfer_buffer + 1 , pwm_buffer , 18 );
49
60
50
- i2c_transmit (IS31FL3218_I2C_ADDRESS , g_twi_transfer_buffer , 19 , IS31FL3218_I2C_TIMEOUT );
61
+ #if IS31FL3218_I2C_PERSISTENCE > 0
62
+ for (uint8_t i = 0 ; i < IS31FL3218_I2C_PERSISTENCE ; i ++ ) {
63
+ i2c_transmit (IS31FL3218_I2C_ADDRESS << 1 , g_twi_transfer_buffer , 19 , IS31FL3218_I2C_TIMEOUT );
64
+ }
65
+ #else
66
+ i2c_transmit (IS31FL3218_I2C_ADDRESS << 1 , g_twi_transfer_buffer , 19 , IS31FL3218_I2C_TIMEOUT );
67
+ #endif
51
68
}
52
69
53
70
void is31fl3218_init (void ) {
@@ -62,36 +79,81 @@ void is31fl3218_init(void) {
62
79
is31fl3218_write_register (IS31FL3218_REG_PWM + i , 0x00 );
63
80
}
64
81
65
- // Enable all channels
82
+ // turn off all LEDs in the LED control register
66
83
for (uint8_t i = 0 ; i < 3 ; i ++ ) {
67
- is31fl3218_write_register (IS31FL3218_REG_CONTROL + i , 0b00111111 );
84
+ is31fl3218_write_register (IS31FL3218_REG_CONTROL + i , 0x00 );
68
85
}
69
86
70
87
// Load PWM registers and LED Control register data
71
88
is31fl3218_write_register (IS31FL3218_REG_UPDATE , 0x01 );
72
89
}
73
90
74
91
void is31fl3218_set_color (int index , uint8_t red , uint8_t green , uint8_t blue ) {
75
- if (g_pwm_buffer [index * 3 + 0 ] == red && g_pwm_buffer [index * 3 + 1 ] == green && g_pwm_buffer [index * 3 + 2 ] == blue ) {
92
+ is31fl3218_led_t led ;
93
+ if (index >= 0 && index < RGB_MATRIX_LED_COUNT ) {
94
+ memcpy_P (& led , (& g_is31fl3218_leds [index ]), sizeof (led ));
95
+ }
96
+ if (g_pwm_buffer [led .r - IS31FL3218_REG_PWM ] == red && g_pwm_buffer [led .g - IS31FL3218_REG_PWM ] == green && g_pwm_buffer [led .b - IS31FL3218_REG_PWM ] == blue ) {
76
97
return ;
77
98
}
78
- g_pwm_buffer [index * 3 + 0 ] = red ;
79
- g_pwm_buffer [index * 3 + 1 ] = green ;
80
- g_pwm_buffer [index * 3 + 2 ] = blue ;
81
- g_pwm_buffer_update_required = true;
99
+ g_pwm_buffer [led . r - IS31FL3218_REG_PWM ] = red ;
100
+ g_pwm_buffer [led . g - IS31FL3218_REG_PWM ] = green ;
101
+ g_pwm_buffer [led . b - IS31FL3218_REG_PWM ] = blue ;
102
+ g_pwm_buffer_update_required = true;
82
103
}
83
104
84
105
void is31fl3218_set_color_all (uint8_t red , uint8_t green , uint8_t blue ) {
85
- for (int i = 0 ; i < 6 ; i ++ ) {
106
+ for (int i = 0 ; i < RGB_MATRIX_LED_COUNT ; i ++ ) {
86
107
is31fl3218_set_color (i , red , green , blue );
87
108
}
88
109
}
89
110
111
+ void is31fl3218_set_led_control_register (uint8_t index , bool red , bool green , bool blue ) {
112
+ is31fl3218_led_t led ;
113
+ memcpy_P (& led , (& g_is31fl3218_leds [index ]), sizeof (led ));
114
+
115
+ uint8_t control_register_r = (led .r - IS31FL3218_REG_PWM ) / 6 ;
116
+ uint8_t control_register_g = (led .g - IS31FL3218_REG_PWM ) / 6 ;
117
+ uint8_t control_register_b = (led .b - IS31FL3218_REG_PWM ) / 6 ;
118
+ uint8_t bit_r = (led .r - IS31FL3218_REG_PWM ) % 6 ;
119
+ uint8_t bit_g = (led .g - IS31FL3218_REG_PWM ) % 6 ;
120
+ uint8_t bit_b = (led .b - IS31FL3218_REG_PWM ) % 6 ;
121
+
122
+ if (red ) {
123
+ g_led_control_registers [control_register_r ] |= (1 << bit_r );
124
+ } else {
125
+ g_led_control_registers [control_register_r ] &= ~(1 << bit_r );
126
+ }
127
+ if (green ) {
128
+ g_led_control_registers [control_register_g ] |= (1 << bit_g );
129
+ } else {
130
+ g_led_control_registers [control_register_g ] &= ~(1 << bit_g );
131
+ }
132
+ if (blue ) {
133
+ g_led_control_registers [control_register_b ] |= (1 << bit_b );
134
+ } else {
135
+ g_led_control_registers [control_register_b ] &= ~(1 << bit_b );
136
+ }
137
+
138
+ g_led_control_registers_update_required = true;
139
+ }
140
+
90
141
void is31fl3218_update_pwm_buffers (void ) {
91
142
if (g_pwm_buffer_update_required ) {
92
143
is31fl3218_write_pwm_buffer (g_pwm_buffer );
93
144
// Load PWM registers and LED Control register data
94
145
is31fl3218_write_register (IS31FL3218_REG_UPDATE , 0x01 );
146
+
147
+ g_pwm_buffer_update_required = false;
148
+ }
149
+ }
150
+
151
+ void is31fl3218_update_led_control_registers (void ) {
152
+ if (g_led_control_registers_update_required ) {
153
+ for (int i = 0 ; i < 3 ; i ++ ) {
154
+ is31fl3218_write_register (IS31FL3218_REG_CONTROL + i , g_led_control_registers [i ]);
155
+ }
156
+
157
+ g_led_control_registers_update_required = false;
95
158
}
96
- g_pwm_buffer_update_required = false;
97
159
}
0 commit comments