/*
* Copyright (c) 2023-2028, SpaceTouch Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date          Author      Notes
* 2024-08-21    yongchaoz   the first version
*/


#include "platform.h"
#include "hal_log.h"
#include "hal_gpio.h"
#include "hal_common.h"
#include "hal_cmu.h"
#include "hal_spi.h"
#include "board.h"
#include "hal_psram.h"

void MySPI_W_SS(uint8_t BitValue)
{
    if(BitValue)
       DEV_GPIO->CTL[GPIO33] = 0X210;
    else
       DEV_GPIO->CTL[GPIO33] = 0X010;
}

void MySPI_W_SCK(uint8_t BitValue)
{
    if(BitValue)
       DEV_GPIO->CTL[GPIO32] = 0X210;
    else
       DEV_GPIO->CTL[GPIO32] = 0X010;
}

void MySPI_W_MOSI(uint8_t BitValue)
{
	if(BitValue)
       DEV_GPIO->CTL[GPIO34] = 0X210;
    else
       DEV_GPIO->CTL[GPIO34] = 0X010;
}

uint8_t MySPI_R_MISO(void)
{
    return ((DEV_GPIO->IN1 & (1UL << (GPIO35 - GPIO32))) ? (SET) : (RESET));
}

void MySPI_Start(void)
{
	MySPI_W_SS(0);				//拉低SS，开始时序
}

void MySPI_Stop(void)
{
	MySPI_W_SS(1);				//拉高SS，终止时序
}

uint8_t MySPI_SwapByte(uint8_t ByteSend)
{
	uint8_t i, ByteReceive = 0x00;					//定义接收的数据，并赋初值0x00，此处必须赋初值0x00，后面会用到
	
	for (i = 0; i < 8; i ++)						//循环8次，依次交换每一位数据
	{
		MySPI_W_MOSI(ByteSend & (0x80 >> i));		//使用掩码的方式取出ByteSend的指定一位数据并写入到MOSI线
		MySPI_W_SCK(1);								//拉高SCK，上升沿移出数据
		if (MySPI_R_MISO() == 1)
        {
            ByteReceive |= (0x80 >> i);
        }	//读取MISO数据，并存储到Byte变量
													//当MISO为1时，置变量指定位为1，当MISO为0时，不做处理，指定位为默认的初值0
		MySPI_W_SCK(0);								//拉低SCK，下降沿移入数据
	}
	
	return ByteReceive;								//返回接收到的一个字节数据
}

#if 0
void psram_init(void)
{
    uint8_t spi_txd_buff[40]={0x9f,0xff,0xff,0xff};
    uint8_t spi_rxd_buff[40]={0xff,0xff,0xff,0xff};
    
    cmu_psram_set_clk(CMU_Clock_SYS,CMU_Clk_Div_1);


    DEV_GPIO->CTL[GPIO32] = 0X010;//SCK
    DEV_GPIO->CTL[GPIO33] = 0X210;//SS  
    DEV_GPIO->CTL[GPIO34] = 0X210;//MOSI
    DEV_GPIO->CTL[GPIO35] = (1<<5);//MISO
    DEV_GPIO->CTL[GPIO36] = 0X210;
    DEV_GPIO->CTL[GPIO37] = 0X210;
    MySPI_Start();
    (void)MySPI_SwapByte(0x66);
    (void)MySPI_SwapByte(0x99);
    MySPI_Stop();   
    DEV_GPIO->CTL[GPIO32] = 5;
    DEV_GPIO->CTL[GPIO33] = 5;
    DEV_GPIO->CTL[GPIO34] = 5;
    DEV_GPIO->CTL[GPIO35] = 5;
    DEV_GPIO->CTL[GPIO36] = 5;
    DEV_GPIO->CTL[GPIO37] = 5;

    PSRAM_RWC->PSRAM_RWC_CFG1 = (0<<0)| /*MODE 0(CPOL=0, CPHA=0)*/
							    (6<<1)| /*PSRAM burst length(1024 byte)*/
							    (0<<5)| /*QUAD_EN disable*/
							    (0<<6)| /*TX_HOLD_CYC disable*/
							    (0<<8)| /*RX_HOLD_CYC*/
							    (8<<10)|/*DELAY_CHIAN_SEL t= 8*0.5 = 4ns*/
							    (0<<16)|
							    (0<<17)|
							    (0<<18)|
							    ((480-1)<<19);//psram cfg1 single  //192  //clk*8 //0x0600502a

	PSRAM_RWC->PSRAM_RWC_CFG2 = (8<<0)|  /*SPI read wait cycle*/
						 	    (1<<8)|  /*0x0b fast read*/
								(0<<11)| /*0x02, write*/
								(0<<13);//psram cfg2 single
}
#endif
#if 0
void psram_init(void)
{
    uint8_t spi_txd_buff[40]={0x9f,0xff,0xff,0xff};
    uint8_t spi_rxd_buff[40]={0xff,0xff,0xff,0xff};
    
    cmu_psram_set_clk(CMU_Clock_PLL_USB,CMU_Clk_Div_4);

    DEV_GPIO->CTL[GPIO32] = 0X010;//SCK
    DEV_GPIO->CTL[GPIO33] = 0X210;//SS  
    DEV_GPIO->CTL[GPIO34] = 0X210;//MOSI
    DEV_GPIO->CTL[GPIO35] = (1<<5);//MISO
    DEV_GPIO->CTL[GPIO36] = 0X210;
    DEV_GPIO->CTL[GPIO37] = 0X210;
    MySPI_Start();
    (void)MySPI_SwapByte(0x66);
    (void)MySPI_SwapByte(0x99);
    MySPI_Stop();   

    MySPI_Start();
    (void)MySPI_SwapByte(0x35);
    MySPI_Stop(); 

    //rt_thread_mdelay(1);
    DEV_GPIO->CTL[GPIO32] = 5;
    DEV_GPIO->CTL[GPIO33] = 5;
    DEV_GPIO->CTL[GPIO34] = 5;
    DEV_GPIO->CTL[GPIO35] = 5;
    DEV_GPIO->CTL[GPIO36] = 5;
    DEV_GPIO->CTL[GPIO37] = 5;

    PSRAM_RWC->PSRAM_RWC_CFG1 = (0<<0)| /*MODE 0(CPOL=0, CPHA=0)*/
							    (6<<1)| /*PSRAM burst length(1024 byte)*/
							    (1<<5)| /*QUAD_EN enable*/
							    (0<<6)| /*TX_HOLD_CYC disable*/
							    (0<<8)| /*RX_HOLD_CYC*/
							    (20<<10)|/*DELAY_CHIAN_SEL t= 8*0.5 = 4ns*/
							    (0<<16)|
							    (0<<17)|
							    (0<<18)|
							    ((120*8-1)<<19);//psram cfg1 single
	PSRAM_RWC->PSRAM_RWC_CFG2 = (6<<0)|  /*SPI read wait cycle*/
						 	    (2<<8)|  /*0x0b fast read*/
								(0<<11)| /*0x02, write*/
								(0<<13);//psram cfg2 single
}
#endif

#if 1
void psram_init(void)
{
    uint8_t spi_txd_buff[40]={0x9f,0xff,0xff,0xff};
    uint8_t spi_rxd_buff[40]={0xff,0xff,0xff,0xff};
    
    cmu_psram_set_clk(CMU_Clock_PLL_USB,CMU_Clk_Div_4);

    DEV_GPIO->CTL[GPIO32] = 0X010;//SCK
    DEV_GPIO->CTL[GPIO33] = 0X210;//SS  
    DEV_GPIO->CTL[GPIO34] = 0X210;//MOSI
    DEV_GPIO->CTL[GPIO35] = (1<<5);//MISO
    DEV_GPIO->CTL[GPIO36] = 0X210;
    DEV_GPIO->CTL[GPIO37] = 0X210;
    MySPI_Start();
    (void)MySPI_SwapByte(0x66);
    (void)MySPI_SwapByte(0x99);
    MySPI_Stop();   

    MySPI_Start();
    (void)MySPI_SwapByte(0x35);
    MySPI_Stop(); 

    //rt_thread_mdelay(1);
    DEV_GPIO->CTL[GPIO32] = 5;
    DEV_GPIO->CTL[GPIO33] = 5;
    DEV_GPIO->CTL[GPIO34] = 5;
    DEV_GPIO->CTL[GPIO35] = 5;
    DEV_GPIO->CTL[GPIO36] = 5;
    DEV_GPIO->CTL[GPIO37] = 5;

    PSRAM_RWC->PSRAM_RWC_CFG1 = (0<<0)| /*MODE 0(CPOL=0, CPHA=0)*/
							    (6<<1)| /*PSRAM burst length(1024 byte)*/
							    (1<<5)| /*QUAD_EN enable*/
							    (0<<6)| /*TX_HOLD_CYC disable*/
							    (0<<8)| /*RX_HOLD_CYC*/
							    (20<<10)|/*DELAY_CHIAN_SEL t= 8*0.5 = 4ns*/
							    (0<<16)|
							    (0<<17)|
							    (0<<18)|
							    ((120*8-1)<<19);//psram cfg1 single
	PSRAM_RWC->PSRAM_RWC_CFG2 = (6<<0)|  /*SPI read wait cycle*/
						 	    (2<<8)|  /*0x0b fast read*/
								(0<<11)| /*0x02, write*/
								(0<<13);//psram cfg2 single
}
#endif



#ifdef BSP_USING_EXFLASH
#include "quad_flash.h"

void ex_flash_set_quad_mode(void)
{

	qflash_pin_info_t  qflash_pin;
	qflash_pin.dat0 =	GPIO34;
	qflash_pin.dat1 =	GPIO35;
	qflash_pin.dat2 =	GPIO36;
	qflash_pin.dat3 =	GPIO37;
	qflash_pin.nss =	GPIO33;
	qflash_pin.sck=		GPIO32;
	qflash_pin.nor_mfp = 11;
	qflash_pin.spi_mfp = 1;

	NORCTRL_QuadSPIinit(0,&qflash_pin);
	uint32_t nor_ctrl_data = DEV_NORC->CTL;
	nor_ctrl_data &= ~(3<<30);
	nor_ctrl_data |=  (1<<30);
	DEV_NORC->CTL = nor_ctrl_data;
//	debug("addr:0x48800000 data:%08x\r\n",*(volatile uint32_t*)0x48800000);
//	debug("addr:0x48800004 data:%08x\r\n",*(volatile uint32_t*)0x48800004);
//	debug("addr:0x6c800000 data:%08x\r\n",*(volatile uint32_t*)0x6c800000);
//	debug("addr:0x6c800004 data:%08x\r\n",*(volatile uint32_t*)0x6c800004);
}
#endif
