Fork of WS2812 library for experimenting with Nucleo board

Fork of WS2812 by Brian Daniels

Committer:
ALeggeUp
Date:
Fri Sep 23 14:57:15 2016 +0000
Revision:
3:5e65b629b49d
Parent:
1:aadbf08c62a2
Initialise j in the for loops or it will not loop the expected number of times (j will start with the end value of the loop above)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bridadan 0:0b79cafcb387 1 #include "WS2812.h"
bridadan 0:0b79cafcb387 2
bridadan 1:aadbf08c62a2 3 WS2812::WS2812(PinName pin, int size, int zeroHigh, int zeroLow, int oneHigh, int oneLow) : __gpo(pin)
bridadan 0:0b79cafcb387 4 {
bridadan 0:0b79cafcb387 5 __size = size;
bridadan 0:0b79cafcb387 6 __transmitBuf = new bool[size * FRAME_SIZE];
bridadan 1:aadbf08c62a2 7 __use_II = OFF;
bridadan 0:0b79cafcb387 8 __II = 0xFF; // set global intensity to full
bridadan 1:aadbf08c62a2 9 __outPin = pin;
bridadan 0:0b79cafcb387 10
bridadan 0:0b79cafcb387 11 // Default values designed for K64f. Assumes GPIO toggle takes ~0.4us
bridadan 1:aadbf08c62a2 12 setDelays(zeroHigh, zeroLow, oneHigh, oneLow);
bridadan 0:0b79cafcb387 13 }
bridadan 0:0b79cafcb387 14
bridadan 0:0b79cafcb387 15
bridadan 0:0b79cafcb387 16 WS2812::~WS2812()
bridadan 0:0b79cafcb387 17 {
bridadan 0:0b79cafcb387 18 delete[] __transmitBuf;
bridadan 0:0b79cafcb387 19 }
bridadan 0:0b79cafcb387 20
bridadan 0:0b79cafcb387 21 void WS2812::setDelays(int zeroHigh, int zeroLow, int oneHigh, int oneLow) {
bridadan 0:0b79cafcb387 22 __zeroHigh = zeroHigh;
bridadan 0:0b79cafcb387 23 __zeroLow = zeroLow;
bridadan 0:0b79cafcb387 24 __oneHigh = oneHigh;
bridadan 0:0b79cafcb387 25 __oneLow = oneLow;
bridadan 0:0b79cafcb387 26 }
bridadan 0:0b79cafcb387 27
bridadan 0:0b79cafcb387 28 void WS2812::__loadBuf(int buf[],int r_offset, int g_offset, int b_offset) {
bridadan 0:0b79cafcb387 29 for (int i = 0; i < __size; i++) {
bridadan 0:0b79cafcb387 30 int color = 0;
bridadan 0:0b79cafcb387 31
bridadan 0:0b79cafcb387 32 color |= ((buf[(i+g_offset)%__size] & 0x0000FF00));
bridadan 0:0b79cafcb387 33 color |= ((buf[(i+r_offset)%__size] & 0x00FF0000));
bridadan 0:0b79cafcb387 34 color |= (buf[(i+b_offset)%__size] & 0x000000FF);
bridadan 0:0b79cafcb387 35 color |= (buf[i] & 0xFF000000);
bridadan 0:0b79cafcb387 36
bridadan 0:0b79cafcb387 37 // Outut format : GGRRBB
bridadan 0:0b79cafcb387 38 // Inout format : IIRRGGBB
bridadan 0:0b79cafcb387 39 unsigned char agrb[4] = {0x0, 0x0, 0x0, 0x0};
bridadan 0:0b79cafcb387 40
bridadan 0:0b79cafcb387 41 unsigned char sf; // scaling factor for II
bridadan 0:0b79cafcb387 42
bridadan 0:0b79cafcb387 43 // extract colour fields from incoming
bridadan 0:0b79cafcb387 44 // 0 = green, 1 = red, 2 = blue, 3 = brightness
bridadan 0:0b79cafcb387 45 agrb[0] = (color & 0x0000FF00) >> 8;
bridadan 0:0b79cafcb387 46 agrb[1] = (color & 0x00FF0000) >> 16;
bridadan 0:0b79cafcb387 47 agrb[2] = color & 0x000000FF;
bridadan 0:0b79cafcb387 48 agrb[3] = (color & 0xFF000000) >> 24;
bridadan 0:0b79cafcb387 49
bridadan 1:aadbf08c62a2 50 // set the intensity scaling factor (global, per pixel, none)
bridadan 1:aadbf08c62a2 51 if (__use_II == GLOBAL) {
bridadan 0:0b79cafcb387 52 sf = __II;
bridadan 1:aadbf08c62a2 53 } else if (__use_II == PER_PIXEL) {
bridadan 0:0b79cafcb387 54 sf = agrb[3];
bridadan 0:0b79cafcb387 55 } else {
bridadan 0:0b79cafcb387 56 sf = 0xFF;
bridadan 0:0b79cafcb387 57 }
bridadan 0:0b79cafcb387 58
bridadan 0:0b79cafcb387 59 // Apply the scaling factor to each othe colour components
bridadan 0:0b79cafcb387 60 for (int clr = 0; clr < 3; clr++) {
bridadan 0:0b79cafcb387 61 agrb[clr] = ((agrb[clr] * sf) >> 8);
bridadan 0:0b79cafcb387 62
bridadan 0:0b79cafcb387 63 for (int j = 0; j < 8; j++) {
bridadan 0:0b79cafcb387 64 if (((agrb[clr] << j) & 0x80) == 0x80) {
bridadan 0:0b79cafcb387 65 // Bit is set (checks MSB fist)
bridadan 0:0b79cafcb387 66 __transmitBuf[(i * FRAME_SIZE) + (clr * 8) + j] = 1;
bridadan 0:0b79cafcb387 67 } else {
bridadan 0:0b79cafcb387 68 // Bit is clear
bridadan 0:0b79cafcb387 69 __transmitBuf[(i * FRAME_SIZE) + (clr * 8) + j] = 0;
bridadan 0:0b79cafcb387 70 }
bridadan 0:0b79cafcb387 71 }
bridadan 0:0b79cafcb387 72 }
bridadan 0:0b79cafcb387 73 }
bridadan 0:0b79cafcb387 74 }
bridadan 0:0b79cafcb387 75
bridadan 0:0b79cafcb387 76 void WS2812::write(int buf[]) {
bridadan 0:0b79cafcb387 77 write_offsets(buf, 0, 0, 0);
bridadan 0:0b79cafcb387 78 }
bridadan 0:0b79cafcb387 79
bridadan 0:0b79cafcb387 80 void WS2812::write_offsets (int buf[],int r_offset, int g_offset, int b_offset) {
bridadan 0:0b79cafcb387 81 int i, j;
bridadan 0:0b79cafcb387 82
bridadan 1:aadbf08c62a2 83 // Load the transmit buffer
bridadan 0:0b79cafcb387 84 __loadBuf(buf, r_offset, g_offset, b_offset);
bridadan 0:0b79cafcb387 85
bridadan 1:aadbf08c62a2 86 // Entering timing critical section, so disabling interrupts
bridadan 1:aadbf08c62a2 87 __disable_irq();
bridadan 1:aadbf08c62a2 88
bridadan 1:aadbf08c62a2 89 // Begin bit-banging
bridadan 0:0b79cafcb387 90 for (i = 0; i < FRAME_SIZE * __size; i++) {
bridadan 0:0b79cafcb387 91 if (__transmitBuf[i]){
bridadan 0:0b79cafcb387 92 __gpo = 1;
ALeggeUp 3:5e65b629b49d 93 for (j = 0; j < __oneHigh; j++) {
bridadan 0:0b79cafcb387 94 __nop();
bridadan 0:0b79cafcb387 95 }
bridadan 0:0b79cafcb387 96 __gpo = 0;
ALeggeUp 3:5e65b629b49d 97 for (j = 0; j < __oneLow; j++) {
bridadan 0:0b79cafcb387 98 __nop();
bridadan 0:0b79cafcb387 99 }
bridadan 0:0b79cafcb387 100 } else {
bridadan 0:0b79cafcb387 101 __gpo = 1;
ALeggeUp 3:5e65b629b49d 102 for (j = 0; j < __zeroHigh; j++) {
bridadan 0:0b79cafcb387 103 __nop();
bridadan 0:0b79cafcb387 104 }
bridadan 0:0b79cafcb387 105 __gpo = 0;
ALeggeUp 3:5e65b629b49d 106 for (j = 0; j < __zeroLow; j++) {
bridadan 0:0b79cafcb387 107 __nop();
bridadan 0:0b79cafcb387 108 }
bridadan 0:0b79cafcb387 109 }
bridadan 0:0b79cafcb387 110 }
bridadan 1:aadbf08c62a2 111
bridadan 1:aadbf08c62a2 112 // Exiting timing critical section, so enabling interrutps
bridadan 1:aadbf08c62a2 113 __enable_irq();
bridadan 0:0b79cafcb387 114 }
bridadan 0:0b79cafcb387 115
bridadan 0:0b79cafcb387 116
bridadan 1:aadbf08c62a2 117 void WS2812::useII(BrightnessControl bc)
bridadan 0:0b79cafcb387 118 {
bridadan 1:aadbf08c62a2 119 if (bc > OFF) {
bridadan 1:aadbf08c62a2 120 __use_II = bc;
bridadan 0:0b79cafcb387 121 } else {
bridadan 1:aadbf08c62a2 122 __use_II = OFF;
bridadan 0:0b79cafcb387 123 }
bridadan 0:0b79cafcb387 124 }
bridadan 0:0b79cafcb387 125
bridadan 0:0b79cafcb387 126 void WS2812::setII(unsigned char II)
bridadan 0:0b79cafcb387 127 {
bridadan 0:0b79cafcb387 128 __II = II;
bridadan 0:0b79cafcb387 129 }
bridadan 0:0b79cafcb387 130
bridadan 0:0b79cafcb387 131
bridadan 0:0b79cafcb387 132
bridadan 0:0b79cafcb387 133
bridadan 0:0b79cafcb387 134
bridadan 0:0b79cafcb387 135