295 lines
8.9 KiB
C
295 lines
8.9 KiB
C
#include "pico/stdlib.h"
|
|
#include "hardware/pio.h"
|
|
#include "ws2812.h"
|
|
#include "ws2812.pio.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#define WS2812_PIN 15
|
|
#define IS_RGBW false
|
|
#define NB_WS2812 5
|
|
|
|
|
|
uint32_t couleur[13];
|
|
uint32_t buffer_couleur[12];
|
|
|
|
struct ws2812_type_gestion_t
|
|
{
|
|
enum led_type_gestion_t led_type_gestion;
|
|
uint32_t couleur;
|
|
} ws2812_type_gestion[NB_WS2812];
|
|
|
|
void ws2812_set_buffer(uint32_t couleur, uint8_t index_led);
|
|
static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b);
|
|
|
|
void ws2812_init(){
|
|
couleur[0]=0x000200;
|
|
couleur[1]=0x010200;
|
|
couleur[2]=0x020200;
|
|
couleur[3]=0x020100;
|
|
couleur[4]=0x020000;
|
|
couleur[5]=0x020001;
|
|
couleur[6]=0x020002;
|
|
couleur[7]=0x010002;
|
|
couleur[8]=0x000002;
|
|
couleur[9]=0x000102;
|
|
couleur[10]=0x000202;
|
|
couleur[11]=0x000201;
|
|
couleur[12]=0x000200;
|
|
|
|
/*couleur[0]=0x002000;
|
|
couleur[1]=0x102000;
|
|
couleur[2]=0x202000;
|
|
couleur[3]=0x201000;
|
|
couleur[4]=0x200000;
|
|
couleur[5]=0x200010;
|
|
couleur[6]=0x200020;
|
|
couleur[7]=0x100020;
|
|
couleur[8]=0x000020;
|
|
couleur[9]=0x001020;
|
|
couleur[10]=0x002020;
|
|
couleur[11]=0x002010;
|
|
couleur[12]=0x002000;*/
|
|
|
|
/*couleur[0]=0x00FF00;
|
|
couleur[1]=0x80FF00;
|
|
couleur[2]=0xFFFF00;
|
|
couleur[3]=0xFF8000;
|
|
couleur[4]=0xFF0000;
|
|
couleur[5]=0xFF0080;
|
|
couleur[6]=0xFF00FF;
|
|
couleur[7]=0x8000FF;
|
|
couleur[8]=0x0000FF;
|
|
couleur[9]=0x0080FF;
|
|
couleur[10]=0x00FFFF;
|
|
couleur[11]=0x00FF80;
|
|
couleur[12]=0x00FF00;*/
|
|
|
|
// initialisation du PIO
|
|
PIO pio = pio0;
|
|
int sm = 0;
|
|
uint offset = pio_add_program(pio, &ws2812_program);
|
|
|
|
ws2812_program_init(pio, sm, offset, WS2812_PIN, 800000, IS_RGBW);
|
|
|
|
// Tout rouge !
|
|
for(uint32_t i = 0; i<12; i++){
|
|
ws2812_set_buffer_rgb(ORANGE_24BITS, i);
|
|
ws2812_type_gestion[NB_WS2812].couleur = urgb_u32(ORANGE_24BITS);
|
|
ws2812_type_gestion[NB_WS2812].led_type_gestion = PAS_DE_GESTION;
|
|
}
|
|
ws2812_affiche_buffer();
|
|
}
|
|
|
|
|
|
void ws2812_arc_en_ciel(){
|
|
while(1){
|
|
uint32_t i;
|
|
sleep_ms(50);
|
|
|
|
// Affichage
|
|
for(i = 0; i<12; i++){
|
|
ws2812_set_buffer(couleur[i], i);
|
|
}
|
|
ws2812_affiche_buffer();
|
|
|
|
// Décalage des couleurs
|
|
for(i = 0; i<12; i++){
|
|
couleur[i] = couleur[i+1];
|
|
}
|
|
couleur[12]=couleur[0];
|
|
}
|
|
}
|
|
|
|
static inline void put_pixel(uint32_t pixel_grb) {
|
|
pio_sm_put_blocking(pio0, 0, pixel_grb << 8u);
|
|
}
|
|
|
|
static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) {
|
|
return
|
|
((uint32_t) (r) << 8) |
|
|
((uint32_t) (g) << 16) |
|
|
(uint32_t) (b);
|
|
}
|
|
|
|
void ws2812_affiche_buffer(){
|
|
for(uint32_t i = 0; i<12; i++){
|
|
put_pixel(buffer_couleur[i]);
|
|
}
|
|
}
|
|
|
|
void ws2812_set_buffer_rgb(uint8_t rouge, uint8_t vert, uint8_t bleu, uint8_t index_led){
|
|
ws2812_set_buffer(urgb_u32(rouge, vert,bleu), index_led);
|
|
}
|
|
|
|
void ws2812_set_rgb(uint8_t rouge, uint8_t vert, uint8_t bleu, uint8_t index_led){
|
|
ws2812_set_buffer(urgb_u32(rouge, vert,bleu), index_led);
|
|
ws2812_affiche_buffer();
|
|
sleep_us(500);
|
|
}
|
|
|
|
//Bit 7 6 5 4 3 2 1 0
|
|
//Data R R R G G G B B
|
|
void ws2812_set_buffer_8bits(uint8_t couleur, uint8_t index_led){
|
|
ws2812_set_buffer(urgb_u32(couleur >> 5, (couleur >> 2) & 0x07, couleur & 0x03), index_led);
|
|
}
|
|
|
|
/// @brief Rempli le buffer à envoyer au LED, necessite d'appeler la fonction ws2812_affiche_buffer() ensuite
|
|
/// @param couleur : couleur en RVB
|
|
/// @param index_led : index entre 0 et 11
|
|
void ws2812_set_buffer(uint32_t couleur, uint8_t index_led){
|
|
if(index_led <12){
|
|
buffer_couleur[index_led] = couleur;
|
|
}
|
|
}
|
|
|
|
void ws2812_set_led(uint8_t led, uint32_t couleur){
|
|
ws2812_set_buffer(couleur, led);
|
|
ws2812_affiche_buffer();
|
|
|
|
}
|
|
|
|
uint32_t ws2812_mix_color(uint32_t couleur1, uint32_t couleur2, float facteur){
|
|
uint8_t r, g, b;
|
|
b = (couleur1 & 0xFF) * (1 - facteur) + (couleur2 & 0xFF) * facteur;
|
|
r = ((couleur1 & 0xFF00)>> 8) * (1 - facteur) + ((couleur2 & 0xFF00)>> 8) * facteur;
|
|
g = ((couleur1 & 0xFF0000)>> 16) * (1 - facteur) + ((couleur2 & 0xFF0000)>> 16) * facteur;
|
|
return urgb_u32(r, g, b);
|
|
}
|
|
|
|
void ws2812_set_mode(uint8_t led_id, enum led_type_gestion_t led_type_gestion, uint32_t couleur){
|
|
if(led_id < NB_WS2812){
|
|
ws2812_type_gestion[led_id].couleur = couleur;
|
|
ws2812_type_gestion[led_id].led_type_gestion = led_type_gestion;
|
|
}
|
|
}
|
|
|
|
void ws2812_gestion(void){
|
|
uint32_t temps_ref;
|
|
uint8_t nb_cli;
|
|
uint8_t phase_led;
|
|
|
|
float f;
|
|
for(int led_id = 0; led_id < NB_WS2812; led_id++){
|
|
switch (ws2812_type_gestion[led_id].led_type_gestion)
|
|
{
|
|
case PAS_DE_GESTION:
|
|
break;
|
|
|
|
case LED_STABLE:
|
|
ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id);
|
|
break;
|
|
|
|
case LED_CLI_RAPIDE:
|
|
if((get_absolute_time() / 50000) % 2){
|
|
ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id);
|
|
}else{
|
|
ws2812_set_buffer(0x000000, led_id);
|
|
}
|
|
break;
|
|
|
|
case LED_CLI_NORMAL:
|
|
if((get_absolute_time() / 200000) % 2){
|
|
ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id);
|
|
}else{
|
|
ws2812_set_buffer(0x000000, led_id);
|
|
}
|
|
break;
|
|
|
|
case LED_CLI_LENT:
|
|
if((get_absolute_time() / 1000000) % 2){
|
|
ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id);
|
|
}else{
|
|
ws2812_set_buffer(0x000000, led_id);
|
|
}
|
|
break;
|
|
|
|
case LED_CLI_PANIQUE_1:
|
|
temps_ref =100000;
|
|
nb_cli = 1;
|
|
phase_led =(get_absolute_time() / temps_ref) % (nb_cli*2 + 4) ;
|
|
printf(">l:%d\n", phase_led);
|
|
if(phase_led >= nb_cli*2){
|
|
ws2812_set_buffer(0x000000, led_id);
|
|
}else{
|
|
printf(">l1:%d\n",phase_led );
|
|
|
|
if(phase_led % 2){
|
|
ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id);
|
|
}else{
|
|
ws2812_set_buffer(0x000000, led_id);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LED_CLI_PANIQUE_2:
|
|
temps_ref =100000;
|
|
nb_cli = 2;
|
|
phase_led =(get_absolute_time() / temps_ref) % (nb_cli*2 + 4) ;
|
|
if(phase_led >= nb_cli*2){
|
|
ws2812_set_buffer(0x000000, led_id);
|
|
}else{
|
|
if(phase_led % 2){
|
|
ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id);
|
|
}else{
|
|
ws2812_set_buffer(0x000000, led_id);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LED_CLI_PANIQUE_3:
|
|
temps_ref =100000;
|
|
nb_cli = 3;
|
|
phase_led =(get_absolute_time() / temps_ref) % (nb_cli*2 + 4) ;
|
|
if(phase_led >= nb_cli*2){
|
|
ws2812_set_buffer(0x000000, led_id);
|
|
}else{
|
|
if(phase_led % 2){
|
|
ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id);
|
|
}else{
|
|
ws2812_set_buffer(0x000000, led_id);
|
|
}
|
|
}
|
|
break;
|
|
|
|
|
|
case LED_PULSE_LENT:
|
|
temps_ref = 3000000;
|
|
if((get_absolute_time() / temps_ref) % 2){
|
|
f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref;
|
|
ws2812_set_buffer(ws2812_mix_color(0, ws2812_type_gestion[led_id].couleur, f), led_id);
|
|
}else{
|
|
f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref;
|
|
ws2812_set_buffer(ws2812_mix_color(ws2812_type_gestion[led_id].couleur, 0, f), led_id);
|
|
}
|
|
break;
|
|
|
|
case LED_PULSE_NORMAL:
|
|
temps_ref = 1000000;
|
|
if((get_absolute_time() / temps_ref) % 2){
|
|
f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref;
|
|
ws2812_set_buffer(ws2812_mix_color(0, ws2812_type_gestion[led_id].couleur, f), led_id);
|
|
}else{
|
|
f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref;
|
|
ws2812_set_buffer(ws2812_mix_color(ws2812_type_gestion[led_id].couleur, 0, f), led_id);
|
|
}
|
|
break;
|
|
|
|
case LED_PULSE_RAPIDE:
|
|
temps_ref = 200000;
|
|
if((get_absolute_time() / temps_ref) % 2){
|
|
f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref;
|
|
ws2812_set_buffer(ws2812_mix_color(0, ws2812_type_gestion[led_id].couleur, f), led_id);
|
|
}else{
|
|
f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref;
|
|
ws2812_set_buffer(ws2812_mix_color(ws2812_type_gestion[led_id].couleur, 0, f), led_id);
|
|
}
|
|
break;
|
|
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
} |