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