/* USER CODE BEGIN Header */
/* you can remove the copyright */
/*
 *  Copyright 2020-2024 Yuntu Microelectronics co.,ltd
 *  All rights reserved.
 * 
 *  YUNTU Confidential. This software is owned or controlled by YUNTU and may only be
 *  used strictly in accordance with the applicable license terms. By expressly
 *  accepting such terms or by downloading, installing, activating and/or otherwise
 *  using the software, you are agreeing that you have read, and that you agree to
 *  comply with and are bound by, such license terms. If you do not agree to be
 *  bound by the applicable license terms, then you may not retain, install,
 *  activate or otherwise use the software. The production use license in
 *  Section 2.3 is expressly granted for this software.
 * 
 * @file main.c
 * @brief 
 * 
 */

/* USER CODE END Header */
#include "sdk_project_config.h"
/* Includes ------------------------------------------------------------------*/

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "osire_driver.h"
#include "peripherals_osire_config.h"
#include "osif.h"
#include <string.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
uint8_t data[8];

static uint16_t colorRED[7] =
  { 0x1fff, 0x0000, 0x0000, 0x1fff, 0x0000, 0x1fff, 0x1fff };
static uint16_t colorGREEN[7] =
  { 0x0000, 0x1fff, 0x0000, 0x0000, 0x1fff, 0x1fff, 0x1fff };
static uint16_t colorBLUE[7] =
  { 0x0000, 0x0000, 0x1fff, 0x1fff, 0x1fff, 0x0000, 0x1fff };

OSIRE_PwmDataType dataPwm, dataPwmReturn, dataPwmBlank;

volatile OSIRE_CommEventType appState = IDLE;
volatile uint8_t stripCallback, ServiceNumber = 0, strip = 0;
uint8_t LedStatus, LedTemp;
uint16_t address = 0, ledCount[3];
OSIRE_ReturnType state;
OSIRE_FrameType rspFrame;
volatile uint32_t timer10ms = 0;
/* USER CODE END PV */

/* Private function declare --------------------------------------------------*/
/* USER CODE BEGIN PFDC */
void OSIRE_Callback(OSIRE_CommEventType state, uint8_t stripNr);
void FreemasterStateMachine(void);
void lightShowMode0(void);
/* USER CODE END PFDC */
static void Board_Init(void);

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void OSIRE_Callback(OSIRE_CommEventType state, uint8_t stripNr)
{
    switch (state)
    {
        case TRANSMISSION_COMPLETE:
            appState = state;
            break;
        case RECEPTION_COMPLETE:
            appState = state;
            break;
        case RECEPTION_TIMEOUT:
            appState = state;
            break;
        case CRC_ERROR:
            appState = state;
            break;
        case CHAINLENGTH_ERROR:
            appState = state;
            break;
        default:
            break;
    }
    stripCallback = stripNr;
}

void FreemasterStateMachine(void)
{
    appState = IDLE;
    switch (ServiceNumber)
    {
        case 0:
            ServiceNumber = 0;
            return;
        case 1:
            state |= OSIRE_Reset(strip, 0);
            break;
        case 2:
            state |= OSIRE_GoActive(strip, 0);
            break;
        case 3:
            // CRC check enabled, ADC ~2.4kHz,OT Flag+Sleep
            state |= OSIRE_SetSetup(strip, 0, 0x32);
            break;
        case 4:
            state |= OSIRE_SetPwm(strip, address, dataPwm);
            break;
        case 5:
            state |= OSIRE_SetPwm(strip, 0, dataPwmBlank);
            break;
        case 6:
            state |= OSIRE_ClearError(strip, 0);
            break;
        case 7:
            state |= OSIRE_GoSleep(strip, 0);
            break;
        case 8:
            state |= OSIRE_GoDeepSleep(strip, 0);
            break;
        case 20:
            memset((uint8_t *)&rspFrame, 0, sizeof(rspFrame));
            state |= OSIRE_InitBidir(strip, &rspFrame);
            while(appState != RECEPTION_COMPLETE);
            ledCount[strip] =  rspFrame.bit.address;
            return;
        case 21:
            memset((uint8_t *)&rspFrame, 0, sizeof(rspFrame));
            rspFrame.bit.address = ledCount[strip];
            state |= OSIRE_ReadSetup(strip, &rspFrame);
            while(appState != RECEPTION_COMPLETE);
            return;
        case 22:
            memset((uint8_t *)&rspFrame, 0, sizeof(rspFrame));
            state |= OSIRE_ReadPwm(strip, &rspFrame);
            rspFrame.bit.address = ledCount[strip];
            while(appState != RECEPTION_COMPLETE);
            for(uint8_t i = 0; i < 6; i++)
            {
                dataPwmReturn.pwmData[i] = rspFrame.bit.data[5-i];
            }
            return;
        case 23:
            memset((uint8_t *)&rspFrame, 0, sizeof(rspFrame));
            rspFrame.bit.address = ledCount[strip];
            state |= OSIRE_ReadTempStatus(strip, &rspFrame);
            while(appState != RECEPTION_COMPLETE);
            LedTemp = rspFrame.bit.data[0] - 113;
            LedStatus = rspFrame.bit.data[1];
            return;
        case 24:
            memset((uint8_t *)&rspFrame, 0, sizeof(rspFrame));
            rspFrame.bit.address = ledCount[strip];
            state |= OSIRE_ReadStatus(strip, &rspFrame);
            while(appState != RECEPTION_COMPLETE);
            LedStatus = rspFrame.bit.data[0];
            return;
        case 25:
            memset((uint8_t *)&rspFrame, 0, sizeof(rspFrame));
            rspFrame.bit.address = ledCount[strip];
            state |= OSIRE_ReadComStatus(strip, &rspFrame);
            while(appState != RECEPTION_COMPLETE);
            LedStatus = rspFrame.bit.data[0];
            return;
        case 26:
            memset((uint8_t *)&rspFrame, 0, sizeof(rspFrame));
            rspFrame.bit.address = ledCount[strip];
            state |= OSIRE_ReadLedStatus(strip, &rspFrame);
            while(appState != RECEPTION_COMPLETE);
            LedStatus = rspFrame.bit.data[0];
            return;
        case 27:
            memset((uint8_t *)&rspFrame, 0, sizeof(rspFrame));
            rspFrame.bit.address = ledCount[strip];
            state |= OSIRE_ReadTemp(strip, &rspFrame);
            while(appState != RECEPTION_COMPLETE);
            LedTemp = rspFrame.bit.data[0] - 113;
            return;
        case 28:
            memset((uint8_t *)&rspFrame, 0, sizeof(rspFrame));
            rspFrame.bit.address = ledCount[strip];
            state |= OSIRE_ReadOtp(strip, 0x0A, &rspFrame);
            while(appState != RECEPTION_COMPLETE);
            return;              
        default:
            break;
    }
    while(appState != TRANSMISSION_COMPLETE);
    if (state != OSIRE_OK)
        while(1);
}

void lpTMR0_IRQHandler(void)
{
    /* Clear compare flag */
    lpTMR_DRV_ClearCompareFlag(0);
    /* Combine to timeout service */
    OSIRE_Timeout_Service(strip);
    timer10ms++;
}

void lightShowMode0(void)
{
    dataPwm.bit.blue_curr = 0;
    dataPwm.bit.green_curr = 0;
    dataPwm.bit.red_curr = 0;
    memset((uint8_t *)&dataPwmBlank, 0, sizeof(dataPwmBlank));
    for(strip = 0; strip < 1; strip++)
    {
        ServiceNumber = 5;
        FreemasterStateMachine();
    }

    uint8_t count = 0, addr = 2;

    while (1)
    {
        /* Set color */
        dataPwm.bit.blue_pwm = colorBLUE[count];
        dataPwm.bit.green_pwm = colorGREEN[count];
        dataPwm.bit.red_pwm = colorRED[count];
        count = (count >= 6) ? 0 : (count + 1);

        for(strip = 0; strip < 1; strip++)
        {
            /* Light off all leds and light one led */
            ServiceNumber = 5;
            FreemasterStateMachine();
            if(strip == 2)
            {
                address = addr;
                ServiceNumber = 4;
                FreemasterStateMachine();

                address = addr + 10;
                ServiceNumber = 4;
                FreemasterStateMachine();

                address = addr + 20;
                ServiceNumber = 4;
                FreemasterStateMachine();
            }else{
                address = addr;
                ServiceNumber = 4;
                FreemasterStateMachine();
            }
        }
        addr = (addr >= 11) ? 2 : (addr + 1);
        OSIF_TimeDelay(100);
    }
}
/* USER CODE END 0 */


/**
 * @brief  The application entry point.
 * @retval int
 */
int main(void)
{
    /* USER CODE BEGIN 1 */
    /* USER CODE END 1 */ 
    Board_Init();
    /* USER CODE BEGIN 2 */
    OSIF_TimeDelay(2000);
    lpTMR_DRV_StartCounter(0);
    /* Init interface of osire */
    OSIRE_InitInterface(NUMBER_OF_INTERFACES, osire);

    for(strip = 0; strip < 1; strip++)
    {
        /* Reset strip and init bidir */
        ServiceNumber = 1;
        FreemasterStateMachine();
        OSIF_TimeDelay(10);
        ServiceNumber = 20;
        FreemasterStateMachine();

        /* Go active */
        ServiceNumber = 2;
        FreemasterStateMachine();

        /* Set setup and read the setup of last led */
        ServiceNumber = 3;
        FreemasterStateMachine();
        ServiceNumber = 21;
        FreemasterStateMachine();

        /* Read status */
        ServiceNumber = 24;
        FreemasterStateMachine();

        /* Read temp */
        ServiceNumber = 27;
        FreemasterStateMachine();

        /* Read Temp and status */
        ServiceNumber = 23;
        FreemasterStateMachine();

        /* Read com status */
        ServiceNumber = 25;
        FreemasterStateMachine();

        /* Read led status */
        ServiceNumber = 26;
        FreemasterStateMachine();

        /* Read otp */
        ServiceNumber = 28;
        FreemasterStateMachine();
    }

    lightShowMode0();
    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
        /* USER CODE END WHILE */
        /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
}

static void Board_Init(void)
{
    CLOCK_SYS_Init(g_clockManConfigsArr,CLOCK_MANAGER_CONFIG_CNT,g_clockManCallbacksArr,CLOCK_MANAGER_CALLBACK_CNT);
    CLOCK_SYS_UpdateConfiguration(CLOCK_MANAGER_ACTIVE_INDEX,CLOCK_MANAGER_POLICY_AGREEMENT);
    PINS_DRV_Init(NUM_OF_CONFIGURED_PINS0,g_pin_mux_InitConfigArr0);
    DMA_DRV_Init(&dmaState,&dmaController_InitConfig,dmaChnState,dmaChnConfigArray,NUM_OF_CONFIGURED_DMA_CHANNEL);
    INT_SYS_ConfigInit();
    lpTMR_DRV_Init(0,&LPTMR_Config,false);
}

/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
