
/*
 * 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;
}



