@@ -50,10 +50,28 @@ busio_spi_obj_t status_apa102;
5050#endif
5151#endif
5252
53- #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK ))
53+ #if defined(CP_RGB_STATUS_R ) || defined(CP_RGB_STATUS_G ) || defined(CP_RGB_STATUS_B )
54+ #define CP_RGB_STATUS_LED
55+
56+ #include "shared-bindings/pulseio/PWMOut.h"
57+ #include "shared-bindings/microcontroller/Pin.h"
58+
59+ pulseio_pwmout_obj_t rgb_status_r ;
60+ pulseio_pwmout_obj_t rgb_status_g ;
61+ pulseio_pwmout_obj_t rgb_status_b ;
62+
63+ uint8_t rgb_status_brightness = 0xFF ;
64+
65+ uint16_t status_rgb_color [3 ] = {
66+ 0 /* red */ , 0 /* green */ , 0 /* blue */
67+ };
68+ #endif
69+
70+ #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK )) || (defined(CP_RGB_STATUS_LED ))
5471static uint32_t current_status_color = 0 ;
5572#endif
5673
74+
5775void rgb_led_status_init () {
5876 #ifdef MICROPY_HW_NEOPIXEL
5977 common_hal_digitalio_digitalinout_construct (& status_neopixel , MICROPY_HW_NEOPIXEL );
@@ -93,7 +111,34 @@ void rgb_led_status_init() {
93111 #endif
94112 #endif
95113
96- #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK ))
114+
115+ #if defined(CP_RGB_STATUS_LED )
116+ if (common_hal_mcu_pin_is_free (CP_RGB_STATUS_R )) {
117+ pwmout_result_t red_result = common_hal_pulseio_pwmout_construct (& rgb_status_r , CP_RGB_STATUS_R , 0 , 50000 , false);
118+
119+ if (PWMOUT_OK == red_result ) {
120+ common_hal_pulseio_pwmout_never_reset (& rgb_status_r );
121+ }
122+ }
123+
124+ if (common_hal_mcu_pin_is_free (CP_RGB_STATUS_G )) {
125+ pwmout_result_t green_result = common_hal_pulseio_pwmout_construct (& rgb_status_g , CP_RGB_STATUS_G , 0 , 50000 , false);
126+
127+ if (PWMOUT_OK == green_result ) {
128+ common_hal_pulseio_pwmout_never_reset (& rgb_status_g );
129+ }
130+ }
131+
132+ if (common_hal_mcu_pin_is_free (CP_RGB_STATUS_B )) {
133+ pwmout_result_t blue_result = common_hal_pulseio_pwmout_construct (& rgb_status_b , CP_RGB_STATUS_B , 0 , 50000 , false);
134+
135+ if (PWMOUT_OK == blue_result ) {
136+ common_hal_pulseio_pwmout_never_reset (& rgb_status_b );
137+ }
138+ }
139+ #endif
140+
141+ #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK )) || (defined(CP_RGB_STATUS_LED ))
97142 // Force a write of the current status color.
98143 uint32_t rgb = current_status_color ;
99144 current_status_color = 0x1000000 ; // Not a valid color
@@ -109,10 +154,13 @@ void reset_status_led() {
109154 reset_pin_number (MICROPY_HW_APA102_MOSI -> number );
110155 reset_pin_number (MICROPY_HW_APA102_SCK -> number );
111156 #endif
157+ #if defined(CP_RGB_STATUS_LED )
158+ // TODO: Support sharing status LED with user.
159+ #endif
112160}
113161
114162void new_status_color (uint32_t rgb ) {
115- #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK ))
163+ #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK )) || (defined( CP_RGB_STATUS_LED ))
116164 if (current_status_color == rgb ) {
117165 return ;
118166 }
@@ -143,10 +191,30 @@ void new_status_color(uint32_t rgb) {
143191 common_hal_busio_spi_write (& status_apa102 , status_apa102_color , 8 );
144192 #endif
145193 #endif
194+
195+ #if defined(CP_RGB_STATUS_LED )
196+ uint8_t red_u8 = (rgb_adjusted >> 16 ) & 0xFF ;
197+ uint8_t green_u8 = (rgb_adjusted >> 8 ) & 0xFF ;
198+ uint8_t blue_u8 = rgb_adjusted & 0xFF ;
199+
200+ #if defined(CP_RGB_STATUS_INVERTED_PWM )
201+ status_rgb_color [0 ] = (1 << 16 ) - 1 - ((uint16_t ) (red_u8 << 8 ) + red_u8 );
202+ status_rgb_color [1 ] = (1 << 16 ) - 1 - ((uint16_t ) (green_u8 << 8 ) + green_u8 );
203+ status_rgb_color [2 ] = (1 << 16 ) - 1 - ((uint16_t ) (blue_u8 << 8 ) + blue_u8 );
204+ #else
205+ status_rgb_color [0 ] = (uint16_t ) (red_u8 << 8 ) + red_u8 ;
206+ status_rgb_color [1 ] = (uint16_t ) (green_u8 << 8 ) + green_u8 ;
207+ status_rgb_color [2 ] = (uint16_t ) (blue_u8 << 8 ) + blue_u8 ;
208+ #endif
209+
210+ common_hal_pulseio_pwmout_set_duty_cycle (& rgb_status_r , status_rgb_color [0 ]);
211+ common_hal_pulseio_pwmout_set_duty_cycle (& rgb_status_g , status_rgb_color [1 ]);
212+ common_hal_pulseio_pwmout_set_duty_cycle (& rgb_status_b , status_rgb_color [2 ]);
213+ #endif
146214}
147215
148216void temp_status_color (uint32_t rgb ) {
149- #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK ))
217+ #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK )) || (defined( CP_RGB_STATUS_LED ))
150218 uint32_t rgb_adjusted = rgb ;
151219 rgb_adjusted = color_brightness (rgb , rgb_status_brightness );
152220 #endif
@@ -168,6 +236,27 @@ void temp_status_color(uint32_t rgb) {
168236 common_hal_busio_spi_write (& status_apa102 , colors , 12 );
169237 #endif
170238 #endif
239+ #if defined(CP_RGB_STATUS_LED )
240+ uint8_t red_u8 = (rgb_adjusted >> 16 ) & 0xFF ;
241+ uint8_t green_u8 = (rgb_adjusted >> 8 ) & 0xFF ;
242+ uint8_t blue_u8 = rgb_adjusted & 0xFF ;
243+
244+ uint16_t temp_status_color_rgb [3 ] = {0 };
245+
246+ #if defined(CP_RGB_STATUS_INVERTED_PWM )
247+ temp_status_color_rgb [0 ] = (1 << 16 ) - 1 - ((uint16_t ) (red_u8 << 8 ) + red_u8 );
248+ temp_status_color_rgb [1 ] = (1 << 16 ) - 1 - ((uint16_t ) (green_u8 << 8 ) + green_u8 );
249+ temp_status_color_rgb [2 ] = (1 << 16 ) - 1 - ((uint16_t ) (blue_u8 << 8 ) + blue_u8 );
250+ #else
251+ temp_status_color_rgb [0 ] = (uint16_t ) (red_u8 << 8 ) + red_u8 ;
252+ temp_status_color_rgb [1 ] = (uint16_t ) (green_u8 << 8 ) + green_u8 ;
253+ temp_status_color_rgb [2 ] = (uint16_t ) (blue_u8 << 8 ) + blue_u8 ;
254+ #endif
255+
256+ common_hal_pulseio_pwmout_set_duty_cycle (& rgb_status_r , temp_status_color_rgb [0 ]);
257+ common_hal_pulseio_pwmout_set_duty_cycle (& rgb_status_g , temp_status_color_rgb [1 ]);
258+ common_hal_pulseio_pwmout_set_duty_cycle (& rgb_status_b , temp_status_color_rgb [2 ]);
259+ #endif
171260}
172261
173262void clear_temp_status () {
@@ -181,10 +270,30 @@ void clear_temp_status() {
181270 common_hal_busio_spi_write (& status_apa102 , status_apa102_color , 8 );
182271 #endif
183272 #endif
273+ #if defined(CP_RGB_STATUS_LED )
274+
275+ uint16_t red = 0 ;
276+ uint16_t green = 0 ;
277+ uint16_t blue = 0 ;
278+
279+ #if defined(CP_RGB_STATUS_INVERTED_PWM )
280+ red = (1 << 16 ) - 1 - status_rgb_color [0 ];
281+ green = (1 << 16 ) - 1 - status_rgb_color [1 ];
282+ blue = (1 << 16 ) - 1 - status_rgb_color [2 ];
283+ #else
284+ red = status_rgb_color [0 ];
285+ green = status_rgb_color [1 ];
286+ blue = status_rgb_color [2 ];
287+ #endif
288+
289+ common_hal_pulseio_pwmout_set_duty_cycle (& rgb_status_r , red );
290+ common_hal_pulseio_pwmout_set_duty_cycle (& rgb_status_g , green );
291+ common_hal_pulseio_pwmout_set_duty_cycle (& rgb_status_b , blue );
292+ #endif
184293}
185294
186295uint32_t color_brightness (uint32_t color , uint8_t brightness ) {
187- #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK ))
296+ #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK )) || (defined( CP_RGB_STATUS_LED ))
188297 uint32_t result = ((color & 0xff0000 ) * brightness / 255 ) & 0xff0000 ;
189298 result += ((color & 0xff00 ) * brightness / 255 ) & 0xff00 ;
190299 result += ((color & 0xff ) * brightness / 255 ) & 0xff ;
@@ -195,7 +304,7 @@ uint32_t color_brightness(uint32_t color, uint8_t brightness) {
195304}
196305
197306void set_rgb_status_brightness (uint8_t level ){
198- #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK ))
307+ #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK )) || (defined( CP_RGB_STATUS_LED ))
199308 rgb_status_brightness = level ;
200309 uint32_t current_color = current_status_color ;
201310 // Temporarily change the current color global to force the new_status_color call to update the
@@ -210,7 +319,7 @@ void prep_rgb_status_animation(const pyexec_result_t* result,
210319 bool found_main ,
211320 safe_mode_t safe_mode ,
212321 rgb_status_animation_t * status ) {
213- #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK ))
322+ #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK )) || (defined( CP_RGB_STATUS_LED ))
214323 new_status_color (ALL_DONE );
215324 status -> pattern_start = ticks_ms ;
216325 status -> safe_mode = safe_mode ;
@@ -256,7 +365,7 @@ void prep_rgb_status_animation(const pyexec_result_t* result,
256365}
257366
258367void tick_rgb_status_animation (rgb_status_animation_t * status ) {
259- #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK ))
368+ #if defined(MICROPY_HW_NEOPIXEL ) || (defined(MICROPY_HW_APA102_MOSI ) && defined(MICROPY_HW_APA102_SCK )) || (defined( CP_RGB_STATUS_LED ))
260369 uint32_t tick_diff = ticks_ms - status -> pattern_start ;
261370 if (status -> ok ) {
262371 // All is good. Ramp ALL_DONE up and down.
0 commit comments