/*
 * sk_led.c
 *
 *  Created on: July 17, 2023
 *      Author: true
 *
 * communicates with SK68xx LEDs using bitbang.
 *
 * not yet implemented.
 */


#include <led_sk.h>
#include <stdint.h>

#include "hk32f030m.h"



#define SPI_TX_PORT		GPIOD
#define SPI_MOSI_PINSRC	GPIO_PinSource2
#define SK_SET()		SK6X_PORT->BSRR = SK6X_PIN;
#define SK_CLR()		SK6X_PORT->BRR  = SK6X_PIN;

#define SK_SEND_BIT1()	__NOP();  __NOP(); SK_CLR(); __NOP();
#define SK_SEND_BIT0()	SK_CLR(); __NOP(); __NOP();  __NOP();



uint8_t sk6x_led[SK6X_LED_COUNT][3] = {0};	// G-R-B order

const uint8_t adxl_cmds[] = {0x80, 0x80, 0x80};



#ifdef USE_SK_LEDS

void led_init()
{
	uint8_t idx;

	// enable SPI with appropriate settings to talk to ADXL
	GPIO_PinAFConfig(SPI_TX_PORT, SPI_MOSI_PINSRC, GPIO_AF_2);

	// disable ADXL interrupts, configure INT1 pin active low (so idle high)
	volatile uint8_t *spi_dr = (volatile uint8_t *)((uint32_t)SPI1 + 0x0c);

	// transfer all of our data
	idx = 0;
	while (idx < sizeof(adxl_cmds)) {
		// transmit FIFO has space? if so, send byte
		if ((SPI1->SR & SPI_SR_FTLVL) != SPI_SR_FTLVL) {
			*spi_dr = adxl_cmds[idx];
			idx++;
		}
	}
}

void led_tx()
{
	uint8_t i;
	uint16_t j;

	uint8_t b;
	uint8_t *p;

	p = sk6x_led[0];

	for (i = 0; i < SK6X_LED_COUNT; i++) {
		b = *p;
		p++;

		j = 0x100;

		do {
			j >>= 1;
			SK_SET();
			if (!(b & j)) { SK_SEND_BIT0(); } else { SK_SEND_BIT1(); }
		} while (j);
	}
}


void led_set(uint8_t idx, uint8_t r, uint8_t g, uint8_t b)
{
	sk6x_led[idx][0] = g;
	sk6x_led[idx][1] = r;
	sk6x_led[idx][2] = b;
}

void led_set_all(uint8_t r, uint8_t g, uint8_t b)
{
	uint8_t i;

	for (i = 0; i < SK6X_LED_COUNT; i++) {
		led_set(i, r, g, b);
	}
}

#endif
