/*
* leds.c
*
* Created on: 7 Jul 2019
* Author: Mike
*/
#include "main.h"
#include "leds.h"
// Target clock rate 800 kHz
#define SPICLOCK 9000000UL
// one clock of SPI is 166nS
#define TSPI (1000000000UL/SPICLOCK)
// reset period is 50000nS
#define TRESET 50000
// stop period is 20000nS
#define TSTOP 50000
// total bit period is 1250nS or 1/800kHz
#define TBIT 1250
// to produce '0' value go high for 400nS, low for 850nS
#define T0H 400
#define T0L 850
// to produce '1' value go high for 850nS, low for 400nS
#define T1H 850
#define T1L 400
// DMX state variables
DMX_State_t DMX_State = DMX_IDLE;
uint8_t DMX_Buffer[512];
uint32_t DMX_Pointer;
#define BUFFER_SIZE 1000
uint8_t buffer [BUFFER_SIZE];
// byte pointer
unsigned bufPtr;
// bit index pointer
uint8_t bitPtr;
// bit transmission time offset from start of transmission
unsigned SPItime = 0;
unsigned RealTime = 0;
static volatile uint8_t busy = 0;
void initCode(void)
{
bufPtr = 0;
bitPtr = 0;
SPItime = 0;
RealTime = 0;
}
// send a '1' or '0' on SPI bus
void codeBit(uint8_t val, unsigned until)
{
// calculate true limit time
RealTime += until;
while(SPItime<= RealTime)
{
if(val)
buffer[bufPtr] |= (1<<bitPtr);
else
buffer[bufPtr] &= ~(1<<bitPtr);
bitPtr++;
if(bitPtr == 8)
{
bitPtr = 0;
bufPtr ++;
}
// accumulate transmission time on SPI bus
SPItime += TSPI;
if(bufPtr >= BUFFER_SIZE)
bufPtr = BUFFER_SIZE-1; // limit
}
}
void codeReset (void)
{
codeBit(0,TRESET);
}
void codeStop (void)
{
codeBit(0,TSTOP);
}
// send a single Run Length code bit
void codeRL(uint8_t bit)
{
unsigned lim = bit ? T1H : T0H;
codeBit(1,lim);
codeBit(0,TBIT-lim);
}
// code a byte using the RL code
void codeRLByte(uint8_t val)
{
uint8_t i;
for (i=0; i<8; i++)
{
codeRL(val & 0x80);
val<<=1;
}
}
void codeFRGBW(frgbw_t led )
{
codeRLByte(((uint16_t)(led.green) * led.fader)/256);
codeRLByte(((uint16_t)(led.red) * led.fader)/256);
codeRLByte(((uint16_t)(led.blue) * led.fader)/256);
codeRLByte(((uint16_t)(led.white) * led.fader)/256);
}
frgbw_t led0 = { 128, 0, 0, 0, 0 };
frgbw_t led1 = { 128, 0, 0, 0, 2 };
frgbw_t ledZ = { 0,0,0,0 };
void sendLeds()
{
initCode();
codeReset();
led0.green++;
/// led0.fader++;
led1.red++;
// led1.fader--;
codeFRGBW(led0);
codeFRGBW(led1);
// send terminal
codeStop();
busy= 1;
HAL_SPI_Transmit_DMA(&hspi1,buffer,bufPtr);
//
while(busy) {};
}
void HAL_SPI_TxCpltCallback( SPI_HandleTypeDef * hspi)
{
(void ) hspi;
busy = 0;
}