diff options
author | Joel Challis <git@zvecr.com> | 2021-07-27 23:55:51 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-27 23:55:51 +0100 |
commit | 3858a784c702d75d207e62c6cdf4449eed41c789 (patch) | |
tree | 17713862786ea5951f7fb15605df7e2082fdc34b /drivers | |
parent | 56443fe3cf19768f34e065319d50164d4e99dd3c (diff) | |
download | qmk_firmware-3858a784c702d75d207e62c6cdf4449eed41c789.tar.gz qmk_firmware-3858a784c702d75d207e62c6cdf4449eed41c789.zip |
Align AW20216 driver (#13712)
* Align AW20216 driver
* Update drivers/awinic/aw20216.h
Co-authored-by: Ryan <fauxpark@gmail.com>
* Review comments
* formatting fixes
* stop if start failed?
* review comments
Co-authored-by: Ryan <fauxpark@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/awinic/aw20216.c | 131 | ||||
-rw-r--r-- | drivers/awinic/aw20216.h | 5 |
2 files changed, 48 insertions, 88 deletions
diff --git a/drivers/awinic/aw20216.c b/drivers/awinic/aw20216.c index 776653fa6..c608c0ab4 100644 --- a/drivers/awinic/aw20216.c +++ b/drivers/awinic/aw20216.c | |||
@@ -45,8 +45,6 @@ | |||
45 | 45 | ||
46 | #define AW_PWM_REGISTER_COUNT 216 | 46 | #define AW_PWM_REGISTER_COUNT 216 |
47 | 47 | ||
48 | #define AW_SPI_START(PIN) spi_start(PIN, false, 0, AW_SPI_DIVISOR) | ||
49 | |||
50 | #ifndef AW_SCALING_MAX | 48 | #ifndef AW_SCALING_MAX |
51 | # define AW_SCALING_MAX 150 | 49 | # define AW_SCALING_MAX 150 |
52 | #endif | 50 | #endif |
@@ -55,128 +53,89 @@ | |||
55 | # define AW_GLOBAL_CURRENT_MAX 150 | 53 | # define AW_GLOBAL_CURRENT_MAX 150 |
56 | #endif | 54 | #endif |
57 | 55 | ||
58 | #ifndef DRIVER_1_CS | ||
59 | # define DRIVER_1_CS B13 | ||
60 | #endif | ||
61 | |||
62 | #ifndef DRIVER_1_EN | ||
63 | # define DRIVER_1_EN C13 | ||
64 | #endif | ||
65 | |||
66 | #ifndef AW_SPI_DIVISOR | 56 | #ifndef AW_SPI_DIVISOR |
67 | # define AW_SPI_DIVISOR 4 | 57 | # define AW_SPI_DIVISOR 4 |
68 | #endif | 58 | #endif |
69 | 59 | ||
70 | uint8_t g_spi_transfer_buffer[3] = {0}; | ||
71 | uint8_t g_pwm_buffer[DRIVER_COUNT][AW_PWM_REGISTER_COUNT]; | 60 | uint8_t g_pwm_buffer[DRIVER_COUNT][AW_PWM_REGISTER_COUNT]; |
72 | bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false}; | 61 | bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false}; |
73 | 62 | ||
74 | bool AW20216_write_register(pin_t slave_pin, uint8_t page, uint8_t reg, uint8_t data) { | 63 | bool AW20216_write(pin_t cs_pin, uint8_t page, uint8_t reg, uint8_t* data, uint8_t len) { |
75 | // Do we need to call spi_stop() if this fails? | 64 | static uint8_t s_spi_transfer_buffer[2] = {0}; |
76 | if (!AW_SPI_START(slave_pin)) { | 65 | |
66 | if (!spi_start(cs_pin, false, 0, AW_SPI_DIVISOR)) { | ||
67 | spi_stop(); | ||
77 | return false; | 68 | return false; |
78 | } | 69 | } |
79 | 70 | ||
80 | g_spi_transfer_buffer[0] = (AWINIC_ID | page | AW_WRITE); | 71 | s_spi_transfer_buffer[0] = (AWINIC_ID | page | AW_WRITE); |
81 | g_spi_transfer_buffer[1] = reg; | 72 | s_spi_transfer_buffer[1] = reg; |
82 | g_spi_transfer_buffer[2] = data; | ||
83 | 73 | ||
84 | if (spi_transmit(g_spi_transfer_buffer, 3) != SPI_STATUS_SUCCESS) { | 74 | if (spi_transmit(s_spi_transfer_buffer, 2) != SPI_STATUS_SUCCESS) { |
85 | spi_stop(); | 75 | spi_stop(); |
86 | return false; | 76 | return false; |
87 | } | 77 | } |
78 | |||
79 | if (spi_transmit(data, len) != SPI_STATUS_SUCCESS) { | ||
80 | spi_stop(); | ||
81 | return false; | ||
82 | } | ||
83 | |||
88 | spi_stop(); | 84 | spi_stop(); |
89 | return true; | 85 | return true; |
90 | } | 86 | } |
91 | 87 | ||
92 | bool AW20216_init_scaling(void) { | 88 | static inline bool AW20216_write_register(pin_t cs_pin, uint8_t page, uint8_t reg, uint8_t value) { |
89 | // Little wrapper so callers need not care about sending a buffer | ||
90 | return AW20216_write(cs_pin, page, reg, &value, 1); | ||
91 | } | ||
92 | |||
93 | static void AW20216_init_scaling(pin_t cs_pin) { | ||
93 | // Set constant current to the max, control brightness with PWM | 94 | // Set constant current to the max, control brightness with PWM |
94 | aw_led led; | 95 | for (uint8_t i = 0; i < AW_PWM_REGISTER_COUNT; i++) { |
95 | for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { | 96 | AW20216_write_register(cs_pin, AW_PAGE_SCALING, i, AW_SCALING_MAX); |
96 | led = g_aw_leds[i]; | ||
97 | if (led.driver == 0) { | ||
98 | AW20216_write_register(DRIVER_1_CS, AW_PAGE_SCALING, led.r, AW_SCALING_MAX); | ||
99 | AW20216_write_register(DRIVER_1_CS, AW_PAGE_SCALING, led.g, AW_SCALING_MAX); | ||
100 | AW20216_write_register(DRIVER_1_CS, AW_PAGE_SCALING, led.b, AW_SCALING_MAX); | ||
101 | } | ||
102 | #ifdef DRIVER_2_CS | ||
103 | else if (led.driver == 1) { | ||
104 | AW20216_write_register(DRIVER_2_CS, AW_PAGE_SCALING, led.r, AW_SCALING_MAX); | ||
105 | AW20216_write_register(DRIVER_2_CS, AW_PAGE_SCALING, led.g, AW_SCALING_MAX); | ||
106 | AW20216_write_register(DRIVER_2_CS, AW_PAGE_SCALING, led.b, AW_SCALING_MAX); | ||
107 | } | ||
108 | #endif | ||
109 | } | 97 | } |
110 | return true; | ||
111 | } | 98 | } |
112 | 99 | ||
113 | bool AW20216_soft_enable(void) { | 100 | static inline void AW20216_init_current_limit(pin_t cs_pin) { |
114 | AW20216_write_register(DRIVER_1_CS, AW_PAGE_FUNCTION, AW_REG_CONFIGURATION, AW_CONFIG_DEFAULT | AW_CHIPEN); | 101 | // Push config |
115 | #ifdef DRIVER_2_CS | 102 | AW20216_write_register(cs_pin, AW_PAGE_FUNCTION, AW_REG_GLOBALCURRENT, AW_GLOBAL_CURRENT_MAX); |
116 | AW20216_write_register(DRIVER_2_CS, AW_PAGE_FUNCTION, AW_REG_CONFIGURATION, AW_CONFIG_DEFAULT | AW_CHIPEN); | ||
117 | #endif | ||
118 | return true; | ||
119 | } | 103 | } |
120 | 104 | ||
121 | void AW20216_update_pwm(int index, uint8_t red, uint8_t green, uint8_t blue) { | 105 | static inline void AW20216_soft_enable(pin_t cs_pin) { |
122 | aw_led led = g_aw_leds[index]; | 106 | // Push config |
123 | if (led.driver == 0) { | 107 | AW20216_write_register(cs_pin, AW_PAGE_FUNCTION, AW_REG_CONFIGURATION, AW_CONFIG_DEFAULT | AW_CHIPEN); |
124 | AW20216_write_register(DRIVER_1_CS, AW_PAGE_PWM, led.r, red); | ||
125 | AW20216_write_register(DRIVER_1_CS, AW_PAGE_PWM, led.g, green); | ||
126 | AW20216_write_register(DRIVER_1_CS, AW_PAGE_PWM, led.b, blue); | ||
127 | } | ||
128 | #ifdef DRIVER_2_CS | ||
129 | else if (led.driver == 1) { | ||
130 | AW20216_write_register(DRIVER_2_CS, AW_PAGE_PWM, led.r, red); | ||
131 | AW20216_write_register(DRIVER_2_CS, AW_PAGE_PWM, led.g, green); | ||
132 | AW20216_write_register(DRIVER_2_CS, AW_PAGE_PWM, led.b, blue); | ||
133 | } | ||
134 | #endif | ||
135 | return; | ||
136 | } | 108 | } |
137 | 109 | ||
138 | void AW20216_init(void) { | 110 | void AW20216_init(pin_t cs_pin, pin_t en_pin) { |
139 | // All LEDs should start with all scaling and PWM registers as off | 111 | setPinOutput(en_pin); |
140 | setPinOutput(DRIVER_1_EN); | 112 | writePinHigh(en_pin); |
141 | writePinHigh(DRIVER_1_EN); | 113 | |
142 | AW20216_write_register(DRIVER_1_CS, AW_PAGE_FUNCTION, AW_REG_GLOBALCURRENT, AW_GLOBAL_CURRENT_MAX); | 114 | // Drivers should start with all scaling and PWM registers as off |
143 | #ifdef DRIVER_2_EN | 115 | AW20216_init_current_limit(cs_pin); |
144 | setPinOutput(DRIVER_2_EN); | 116 | AW20216_init_scaling(cs_pin); |
145 | writePinHigh(DRIVER_2_EN); | 117 | |
146 | AW20216_write_register(DRIVER_2_CS, AW_PAGE_FUNCTION, AW_REG_GLOBALCURRENT, AW_GLOBAL_CURRENT_MAX); | 118 | AW20216_soft_enable(cs_pin); |
147 | #endif | ||
148 | AW20216_init_scaling(); | ||
149 | AW20216_soft_enable(); | ||
150 | return; | ||
151 | } | 119 | } |
152 | 120 | ||
153 | void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | 121 | void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { |
154 | aw_led led = g_aw_leds[index]; | 122 | aw_led led = g_aw_leds[index]; |
123 | |||
155 | g_pwm_buffer[led.driver][led.r] = red; | 124 | g_pwm_buffer[led.driver][led.r] = red; |
156 | g_pwm_buffer[led.driver][led.g] = green; | 125 | g_pwm_buffer[led.driver][led.g] = green; |
157 | g_pwm_buffer[led.driver][led.b] = blue; | 126 | g_pwm_buffer[led.driver][led.b] = blue; |
158 | g_pwm_buffer_update_required[led.driver] = true; | 127 | g_pwm_buffer_update_required[led.driver] = true; |
159 | return; | ||
160 | } | 128 | } |
129 | |||
161 | void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | 130 | void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { |
162 | for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { | 131 | for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { |
163 | AW20216_set_color(i, red, green, blue); | 132 | AW20216_set_color(i, red, green, blue); |
164 | } | 133 | } |
165 | return; | ||
166 | } | ||
167 | |||
168 | void AW20216_write_pwm_buffer(pin_t slave_pin, uint8_t buffer_idx) { | ||
169 | AW_SPI_START(slave_pin); | ||
170 | spi_write((AWINIC_ID | AW_PAGE_PWM | AW_WRITE)); | ||
171 | spi_write(0); | ||
172 | spi_transmit(g_pwm_buffer[buffer_idx], AW_PWM_REGISTER_COUNT); | ||
173 | spi_stop(); | ||
174 | } | 134 | } |
175 | 135 | ||
176 | void AW20216_update_pwm_buffers(void) { | 136 | void AW20216_update_pwm_buffers(pin_t cs_pin, uint8_t index) { |
177 | AW20216_write_pwm_buffer(DRIVER_1_CS, 0); | 137 | if (g_pwm_buffer_update_required[index]) { |
178 | #ifdef DRIVER_2_CS | 138 | AW20216_write(cs_pin, AW_PAGE_PWM, 0, g_pwm_buffer[index], AW_PWM_REGISTER_COUNT); |
179 | AW20216_write_pwm_buffer(DRIVER_2_CS, 1); | 139 | } |
180 | #endif | 140 | g_pwm_buffer_update_required[index] = false; |
181 | return; | ||
182 | } | 141 | } |
diff --git a/drivers/awinic/aw20216.h b/drivers/awinic/aw20216.h index 9c6865cc8..c55d9605f 100644 --- a/drivers/awinic/aw20216.h +++ b/drivers/awinic/aw20216.h | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <stdint.h> | 19 | #include <stdint.h> |
20 | #include <stdbool.h> | 20 | #include <stdbool.h> |
21 | #include "gpio.h" | ||
21 | 22 | ||
22 | typedef struct aw_led { | 23 | typedef struct aw_led { |
23 | uint8_t driver : 2; | 24 | uint8_t driver : 2; |
@@ -28,10 +29,10 @@ typedef struct aw_led { | |||
28 | 29 | ||
29 | extern const aw_led g_aw_leds[DRIVER_LED_TOTAL]; | 30 | extern const aw_led g_aw_leds[DRIVER_LED_TOTAL]; |
30 | 31 | ||
31 | void AW20216_init(void); | 32 | void AW20216_init(pin_t cs_pin, pin_t en_pin); |
32 | void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | 33 | void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); |
33 | void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | 34 | void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue); |
34 | void AW20216_update_pwm_buffers(void); | 35 | void AW20216_update_pwm_buffers(pin_t cs_pin, uint8_t index); |
35 | 36 | ||
36 | #define CS1_SW1 0x00 | 37 | #define CS1_SW1 0x00 |
37 | #define CS2_SW1 0x01 | 38 | #define CS2_SW1 0x01 |