//============================================================================
//文件名称：spi.c
//功能概要：KW01 spi底层驱动程序源文件
//版权所有：苏州大学飞思卡尔嵌入式中心(sumcu.suda.edu.cn)
//版    本：V3.0(WYH),20140909
//============================================================================

#include "spi.h"

//============================================================================
//函数名称：MKW01Drv_SpiInit()
//函数返回：val      
//参数说明：addr：无线模块寄存器地址
//功能概要：读取无线模块寄存器 
//============================================================================
void MKW01Drv_SPI0_Init()
{
    /* Enable Reset PORT clock */
    SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK;//(1<<13); /*Reset Radio Clock Gate Control enable*/ 
    
    //使能复位引脚，复位引脚E30复用GPIO功能,【输出】RF硬件复位，
    //以便于软件取得完全控制，否则无法启动MCU（它会一直检测REST_RF是否被拉高）
    PORTE_PCR30 &= ~PORT_PCR_MUX_MASK;
    PORTE_PCR30 |= PORT_PCR_MUX(1);//复用GPIO功能
    GPIOE_PDDR |= (1<<30);//输出
    
    /* 使能SPI端口时钟 */
    SIM_SCGC5 |= (1<<11);         /*SPI Port Clock Gate Control enable*/
    
    /* 打开SPI0时钟门*/
    SIM_SCGC4 |=  (1<<22);        /*SPI Clock Gate Control enable*/
    
    /*初始化化SPI控制寄存器*/
    PORTD_PCR0&= ~PORT_PCR_MUX_MASK;      //D0----PCS
    PORTD_PCR0|= PORT_PCR_MUX(1);         //PTD0 作为从机选择线
    GPIOD_PDDR|=(1<<0);                   //引脚定义为输出
    
    PORTC_PCR5  &= ~PORT_PCR_MUX_MASK;    //C5----SCK
    PORTC_PCR5  |= PORT_PCR_MUX(2);
    PORTC_PCR6 &= ~PORT_PCR_MUX_MASK;     //C6----MOSI
    PORTC_PCR6 |= PORT_PCR_MUX(2);
    PORTC_PCR7 &= ~PORT_PCR_MUX_MASK;     //C7----MISO
    PORTC_PCR7 |= PORT_PCR_MUX(2); 
    
    //保持射频芯片处于复位状态（即E口的30号脚数据输出寄存器始终置1，即输出高电平，复位RF）
    MKW01DRV_ASSERTRESET(); //Keep Radio in reset
    
    /* Initialize the SPI peripheral base address */  
    SPI0_BASE_PTR->C1 = CSPIC1_INIT;//控制寄存器1
    SPI0_BASE_PTR->C2 = CSPIC2_INIT;//控制寄存器2
    SPI0_BR = CSPIBR_INIT;
    SPI0_BASE_PTR->C1 |= (uint_8)(SPI_C1_SPE_MASK | SPI_C1_MSTR_MASK) ; //enable SPI system
    SPIS_DUMMYREAD;
    DEASSERTSS
}


//============================================================================
//函数名称：MKW01Drv_ReadRegister
//函数返回：val      
//参数说明：addr：无线模块寄存器地址
//功能概要：读取无线模块寄存器 
//============================================================================
uint_8 MKW01Drv_ReadRegister(uint_8 addr)
{
    uint_8 val;
    uint_32 CCR;

    CCR = IntDisableAll();//关中断

    SPIS_DUMMYREAD;  //空读SPI0状态寄存器
    ASSERTSS;       //片选，配置C口的第4号脚的清输出寄存器为1，则清除对应数据输出寄存器PDOR的位
    SPI0_BASE_PTR->DL = (unsigned char)(addr);                         
    WAIT_SPITX_BUFFER_EMPTY; //等待SPI0发送缓冲区为空
    SPID_DUMMYREAD;    //空读SPI0数据寄存器
    SPI0_BASE_PTR->DL = 0x00;   
    WAIT_SPITX_BUFFER_EMPTY;  //等待SPI0发送缓冲区为空
    SPID_DUMMYREAD;     //空读SPI0数据寄存器
    WAIT_SPIRX_BUFFER_FULL;   //等待接收缓冲区为满   （保证主机已将数据发出，并且从机收到）
    val = SPI0_BASE_PTR->DL;   //读取数据寄存器中的值                                 
    DEASSERTSS;      //片选，配置C口的PDOR寄存器第4位为1
    IntRestoreAll(CCR);  //开中断
    return val;
}

//============================================================================
//函数名称：MKW01Drv_WriteRegister
//函数返回：无      
//参数说明：addr：无线模块寄存器地址；val：待写入的值
//功能概要：设置无线模块寄存器 
//============================================================================
void MKW01Drv_WriteRegister(uint_8 addr, uint_8 val)
{
    uint_32 CCR;
    CCR = IntDisableAll();    
    SPIS_DUMMYREAD;
    ASSERTSS;                    //从机片选信号（低电压选中从机，）
    SPI0_BASE_PTR->DL = (unsigned char)(addr | 0x80);      
    WAIT_SPITX_BUFFER_EMPTY;      //等待，直到发送缓冲区为空
    SPID_DUMMYREAD;
    SPI0_BASE_PTR->DL = (unsigned char)(val);         
    WAIT_SPITX_BUFFER_EMPTY;     //等待，直到发送缓冲区为空
    SPID_DUMMYREAD;
    WAIT_SPIRX_BUFFER_FULL;    //等待，直到移位缓冲区接收到从机发来的数据，这可以用来保证TX发送的数据已被从机已经接收到
    DEASSERTSS;
    IntRestoreAll(CCR);
}

//============================================================================
//函数名称：MKW01Drv_WriteRegisterFast
//函数返回：不安全的函数,只有在禁止中断时才可使用
//参数说明：addr：无线模块寄存器地址；val：待写入的值
//功能概要：设置无线模块寄存器 
//============================================================================
void MKW01Drv_WriteRegisterFast(uint_8 addr, uint_8 val)
{
    SPIS_DUMMYREAD;
    ASSERTSS;
    SPI0_BASE_PTR->DL = (unsigned char)(addr | 0x80);  // 写目的地址           
    WAIT_SPITX_BUFFER_EMPTY;                        //等待发送缓冲区为空
    SPID_DUMMYREAD;
//    SPI0_BASE_PTR->DL = (unsigned char)(val);    //写数据            
    WAIT_SPITX_BUFFER_EMPTY;
    SPID_DUMMYREAD;
    WAIT_SPIRX_BUFFER_FULL;                        //等待，直到移位缓冲区接收到从机发来的数据，这可以用来保证TX发送的数据已被从机已经接收到
    DEASSERTSS;
}
