STM32 SPI Library for APA102 RGB LED

STM32 SPI Library for APA102 RGB LED

Please read Liability Disclaimer and License Agreement CAREFULLY

This library is adapted for a APA102 LED strip with 30 LEDs.

Read this article to have a better understanding Ambient light with APA102 and MQTT

APA102.h

 

#ifndef __APA102_H
#define __APA102_H
#ifdef __cplusplus
 extern "C" {
    #endif

        #include <stdint.h>
        #define     LED_INIT            0xE0
        #define     LED_GLOBAL            0x1F    
        #define     LED_COUNT            30                        //Number of LEDs in strip
        #define     FirstThird            LED_COUNT/3                //LED end position of first third of the strip
        #define     SecondThird            2*FirstThird            //LED end position of second third of the strip
        #define     FRAME_SIZE            4*LED_COUNT                //Number of LEDs in strip
        #define     START_FRAME_SIZE    4                            //0x00, 0x00, 0x00, 0x00
    //    #define        bits                            (FRAME_SIZE + 1)/2    //Number of bits we need (with rounding)
    //    #define     b1                                 bits / 8        //Number of bytes we need
    //    #define        rem                                bits % 8        //
        //final number of bytes we need
        #define END_FRAME_SIZE            2
        #define START_END_FRAME            START_FRAME_SIZE + FRAME_SIZE
        #define LED_FRAME_SIZE            START_FRAME_SIZE + FRAME_SIZE + END_FRAME_SIZE
    //    #if rem
    //        #define        END_FRAME_SIZE (b1 + 1)
    //    #else
    //        #define        END_FRAME_SIZE        b1    
    //    #endif
        //#define        END_FRAME_SIZE        rem ? (b1 + 1) : b1    //final numbero of bytes we need
        #define TIME_OUT                    500
        #define getPosition(pos) (4 + 4 * pos)

        extern volatile uint8_t effectDone;
        void APA_init(void);
        void APA_setColor(uint8_t led, uint8_t red, uint8_t green, uint8_t blue);
        void APA_setColorBright(uint8_t led, uint8_t red, uint8_t green, uint8_t blue, uint8_t bright);
        void APA_setAllColor(uint8_t red, uint8_t green, uint8_t blue);
        void APA_setRGB(uint8_t led, uint32_t rgb, uint8_t bright);
        void APA_setAllRGB(uint32_t rgb, uint8_t bright);
        void APA_setllumination(uint8_t intensity);
        void APA_setLedIllumination(uint8_t led, uint8_t intensity);
        void APA_setAllBrightness(uint8_t intensity);
        void APA_setLedOff(uint8_t led);
        void APA_setLedOn(uint8_t led);
        void APA_update(uint8_t crtLED_Strip);
        //Light effects functions
        void ColorWheel(uint8_t WheelPos, uint8_t *r, uint8_t *g, uint8_t *b);
        void SnowFlakes(void);
        void RandomSparkle(void);
        void RainbowCycle(void);
    #ifdef __cplusplus
}
#endif
#endif /*__ APA102_H */

 

The APA102.c

The SPI is using only the clock and data lines

#include "APA102.h"
#include "spi.h"
#include <stdlib.h>
uint8_t SpiSendFrame[LED_FRAME_SIZE];
volatile uint8_t effectDone = 1;
void APA_init(void) {
    uint8_t led;
    //Fixed frame, will not change
    for (led = 0; led < START_FRAME_SIZE; led++) {
        SpiSendFrame[led] = 0x00;
    }
    
    for (led = START_FRAME_SIZE; led < START_END_FRAME; led+=4)    {
        SpiSendFrame[led] = LED_INIT;// | (LED_GLOBAL & brightness);
        //SpiSendFrame[led + 1] = 0x00;
        //SpiSendFrame[led + 2] = 0x00;
        //SpiSendFrame[led + 3] = 0x00;
    }
    //Fixed frame, will not change
    for (led = START_END_FRAME; led < LED_FRAME_SIZE; led++) {
        SpiSendFrame[led] = 0xFF;
    }    
}

void APA_setColor(uint8_t led, uint8_t red, uint8_t green, uint8_t blue){
    uint8_t pos = getPosition(led) + 1;
    SpiSendFrame[pos] = blue;
    SpiSendFrame[pos + 1] = green;
    SpiSendFrame[pos + 2] = red;
}

void APA_setColorBright(uint8_t led, uint8_t red, uint8_t green, uint8_t blue, uint8_t bright){
    uint8_t pos = getPosition(led);
    SpiSendFrame[pos] = LED_INIT | bright;
    APA_setColor(led, red, green, blue);
}

void APA_setAllColor(uint8_t red, uint8_t green, uint8_t blue){
    for (uint8_t led = 0; led < LED_COUNT; led++)    {
        APA_setColor(led, red, green, blue);
    }
}

void APA_setRGB(uint8_t led, uint32_t rgb, uint8_t bright) {
    uint8_t pos = getPosition(led);
    SpiSendFrame[pos] = LED_INIT | bright;
    SpiSendFrame[pos + 1] = (uint8_t)(rgb);
    SpiSendFrame[pos + 2] = (uint8_t)(rgb >> 8);
    SpiSendFrame[pos + 3] = (uint8_t)(rgb >> 16);
}

void APA_setAllRGB(uint32_t rgb, uint8_t bright){
    for (uint8_t led = 0; led < LED_COUNT; led++)    {
        APA_setRGB(led, rgb, bright);
    }
}

void APA_setLedBrightness(uint8_t led, uint8_t bright) {
    SpiSendFrame[getPosition(led)] = LED_INIT | bright;
}

void APA_setAllBrightness(uint8_t intensity) {
    for (uint8_t led = 0; led < LED_COUNT; led++)    {
        APA_setLedBrightness(led, intensity);
    }
}

void APA_setLedOff(uint8_t led) {
    SpiSendFrame[getPosition(led)] =  LED_INIT;
}

void APA_setLedOn(uint8_t led) {
    SpiSendFrame[getPosition(led)] =  LED_GLOBAL;
}

void APA_update(uint8_t crtLED_Strip) {
        SPI_HandleTypeDef crtSPI;
        if(crtLED_Strip) {
            crtSPI = hspi1;
        } else {
            crtSPI = hspi2;
        }
        // send spi frame with all led values
        HAL_SPI_Transmit(&crtSPI, SpiSendFrame, LED_FRAME_SIZE, TIME_OUT);;
}

//Color wheel function
void ColorWheel(uint8_t WheelPos, uint8_t *r, uint8_t *g, uint8_t *b) {
    WheelPos = 255 - WheelPos;
    if(WheelPos < 85)
    {
        *r = 255 - WheelPos * 3;
        *g = 0;
        *b = WheelPos * 3;
    }
    if(WheelPos < 170)
    {
        WheelPos -= 85;
        *r = 0;
        *g = WheelPos * 3;
        *b =255 - WheelPos * 3;
    }
    WheelPos -= 170;
    *r = WheelPos * 3;
    *g = 255 - WheelPos * 3;
    *b = 0;
}

void SnowFlakes(void) {
    uint16_t arr_rand[LED_COUNT];
    for(uint8_t i=0; i< LED_COUNT; i++) {
        arr_rand[i] = rand()% LED_COUNT;
        APA_setColor(arr_rand[i], 255, 255, 255);
    }
    APA_update(0);
    APA_update(1);
    HAL_Delay(50);
    for(uint8_t i=0; i< LED_COUNT; i++) {
        APA_setColor(arr_rand[i], 0, 0, 0);
    }
    APA_update(0);
    APA_update(1);
    HAL_Delay(50);
    effectDone = 1;
}

void RandomSparkle(void) {
    uint16_t arr_rand[LED_COUNT];
    for(uint8_t i=0; i< LED_COUNT; i++) {
        arr_rand[i] = rand()% LED_COUNT;
        APA_setColor(arr_rand[i], rand()%256, rand()%256, rand()%256);
    }
    APA_update(0);
    APA_update(1);
    HAL_Delay(50);
    for(uint8_t i=0; i< LED_COUNT; i++) {
        APA_setColor(arr_rand[i], 0, 0, 0);
    }
    APA_update(0);
    APA_update(1);
    HAL_Delay(50);
    effectDone = 1;
}

void RainbowCycle(void) {
    uint16_t j;
    uint8_t i, r, g, b;
    for(j=0; j< 512; j++)    {
        for(i=0; i< LED_COUNT; i++)    {
            ColorWheel(((i * 256 / LED_COUNT) + j) & 255, &r, &g, &b);
            APA_setColor(i, r, g, b);
        }
        APA_update(0);
        APA_update(1);
        HAL_Delay(10);
    }
    effectDone = 1;
}

Comments powered by CComment

Who’s online

We have 67 guests and no members online