/*
 * Copyright 2025 NXP
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <fsl_inputmux.h>
#include "board.h"
#include "app.h"
#include "fsl_debug_console.h"
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "fsl_clock.h"
#include "fsl_smartdma.h"
#include "smartdma_keyscan.h"
#include "string.h"
#include "light_effect.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*******************************************************************************
 * Prototypes
 ******************************************************************************/
extern void SMARTDMA_AccessShareRAM(uint8_t flag);
extern const uint8_t s_smartdmaKeyscanFirmware[];

/*******************************************************************************
 * Variables
 ******************************************************************************/
/* Whether the SW button is pressed */
volatile bool g_ButtonPress = false;
smartdma_keyscan_4x4_param_t smartdmaParam;                  /*!< SMARTDMA function parameters. */
volatile uint8_t g_samrtdma_stack[32];

volatile uint32_t g_keyscan_gpio_register[KEY_ROW_COUNT + KEY_COL_COUNT] = {

		0x5009E000 + 0x60 + 6,/*ROW1, P4_6,Pin Data security Register*/
		0x5009E000 + 0x60 + 15,/*ROW2, P4_15,Pin Data security Register*/
		0x5009E000 + 0x60 + 16,/*ROW3, P4_16,Pin Data security Register*/
		0x5009E000 + 0x60 + 17,/*ROW4, P4_17,Pin Data security Register*/
		0x5009E000 + 0x60 + 12,/*ROW5, P4_12,Pin Data security Register*/
		0x5009E000 + 0x60 + 13,/*ROW6, P4_13,Pin Data security Register*/

		0x50098000 + 0x60 + 17, /*COL1, P1_17,Pin Data security Register */
		0x50098000 + 0x60 + 16,/*COL2, P1_16,Pin Data security Register*/
		0x50098000 + 0x60 + 1,/*COL3, P1_1,Pin Data security Register*/
		0x50098000 + 0x60 + 2,/*COL4, P1_2,Pin Data security Register*/

		0x50098000 + 0x60 + 3, /*COL5, P1_3,Pin Data security Register */
		0x5009C000 + 0x60 + 14,/*COL6, P3_14,Pin Data security Register*/
		0x50096000 + 0x60 + 23,/*COL7, P0_23,Pin Data security Register*/
		0x50096000 + 0x60 + 22,/*COL8, P0_22,Pin Data security Register*/

		0x5009C000 + 0x60 + 17, /*COL9, P3_17,Pin Data security Register */
		0x5009A000 + 0x60 + 7,/*COL10, P2_7,Pin Data security Register*/
		0x50096000 + 0x60 + 21,/*COL11, P0_21,Pin Data security Register*/
		0x5009C000 + 0x60 + 12,/*COL12, P3_12,Pin Data security Register*/

		0x5009A000 + 0x60 + 0, /*COL13, P2_0,Pin Data security Register */
		0x5009E000 + 0x60 + 2,/*COL114, P4_2,Pin Data security Register*/
		0x5009E000 + 0x60 + 3,/*COL115, P4_3,Pin Data security Register*/
};

volatile uint32_t g_KeyValue[8]={0,0,0,0,0};
volatile uint32_t g_KeyValueSharedRAM[8]={0,0,0,0,0,0,0,0};

/* Need wait for at least 800 clocks for 6x15 keyboard,79.8us */
volatile uint32_t g_keyscan_interval = 800;
volatile uint32_t g_keyscan_complete_flag=0;
uint8_t g_keyscan_value_updating = 0;
extern bool g_lightEffectEnable;
extern uint8_t g_lightEffectIndex;
extern const uint8_t s_smartdmaKeyscanFirmware_6x15[];
extern const uint32_t s_smartdmaKeyscanFirmwareSize_6x15;
/*******************************************************************************
 * Code
 ******************************************************************************/
static void SmartDMA_keyscan_callback(void *param){
	g_keyscan_complete_flag = 1;
	SMARTDMA_AccessShareRAM(1) ;
//	PRINTF("%x\r\n", g_KeyValueSharedRAM[0]);
//	PRINTF("%x\r\n", g_KeyValueSharedRAM[1]);
//	PRINTF("%x\r\n", g_KeyValueSharedRAM[2]);
//	PRINTF("%x\r\n", g_KeyValueSharedRAM[3]);
//	PRINTF("\r\n");
    memcpy((void *)g_KeyValue,(void *)g_KeyValueSharedRAM,sizeof(g_KeyValueSharedRAM));

	SMARTDMA_AccessShareRAM(0);

	/* key combination detection, Fn + Home: light effect switch */
	/* bit 29: Home, bit 24: Fn */
	if(g_KeyValue[0] == 0x20000000 && g_KeyValue[2] == 0x1000000)
	{
		g_lightEffectEnable = g_lightEffectEnable ^ 1;
	}

	/* Fn + Page up */
	if(g_KeyValue[1] == 0x4000 && g_KeyValue[2] == 0x1000000)
	{
		if(g_lightEffectEnable)
		{
			if(g_lightEffectIndex == kLIGHT_EFFECT_COUNT - 1)
			{
				g_lightEffectIndex = 0;
			}
			else
			{
			    g_lightEffectIndex ++;
			}
		}
	}
	else if (g_KeyValue[1] == 0x20000000 && g_KeyValue[2] == 0x1000000)
	{
		if(g_lightEffectEnable)
		{
			if(g_lightEffectIndex == 0)
			{
				g_lightEffectIndex = kLIGHT_EFFECT_COUNT - 1;
			}
			else
			{
			    g_lightEffectIndex --;
			}
		}
	}

 }


/*!
 * @brief Main function
 */
int smartdma_init(void)
{
    //PRINTF("\r\n SmartDMA init.\r\n");
    /*give smartdma role with secure user and non-privilege*/
 	AHBSC->MASTER_SEC_LEVEL = (AHBSC->MASTER_SEC_LEVEL) | (0x2<<4);
 	AHBSC->MASTER_SEC_ANTI_POL_REG = (AHBSC->MASTER_SEC_ANTI_POL_REG) & (~(0x2<<4));
    /*set GPIO pins user permission with secure user and non-privilege*/
 	GPIO4->PCNP = (1 << 2)|(1 << 3)|(1 << 6)|(1 << 15)|(1 << 16)|(1 << 17)|(1 << 12)|(1 << 13);
 	GPIO0->PCNP = (1 << 22)|(1 << 21)|(1 << 23);
 	GPIO1->PCNP = (1 << 17)|(1 << 16)|(1 << 1)|(1 << 2)|(1 << 3);
 	GPIO2->PCNP = (1 << 0)|(1 << 7);
 	GPIO3->PCNP = (1 << 12)|(1 << 17)|(1 << 14);

    SMARTDMA_InitWithoutFirmware();
    SMARTDMA_InstallFirmware(SMARTDMA_KEYSCAN_MEM_ADDR,s_smartdmaKeyscanFirmware_6x15,
    		s_smartdmaKeyscanFirmwareSize_6x15);
	SMARTDMA_InstallCallback(SmartDMA_keyscan_callback, NULL);
    NVIC_EnableIRQ(SMARTDMA_IRQn);
    NVIC_SetPriority(SMARTDMA_IRQn, 3);
	smartdmaParam.smartdma_stack 	 = (uint32_t*)g_samrtdma_stack;
	smartdmaParam.p_gpio_reg  		 = (uint32_t*)g_keyscan_gpio_register;
	smartdmaParam.p_keyvalue  		 = (uint32_t*)g_KeyValueSharedRAM;
	smartdmaParam.p_keycan_interval  = (uint32_t*)&g_keyscan_interval;
	SMARTDMA_Boot(kSMARTDMA_Keyscan_4x4, &smartdmaParam, 0x2);

}
