예제 #1
0
/*
*******************************************************************************
* void SpiClrFifoCounter( SPI_MemMapPtr base)
*******************************************************************************
* Input         : base : Pointer to SPI0/ SPI1 /SPI2 Register Base 	
* Output        : void
* Description   : Clear RX and TX FIFO counters for respective SPI module
*******************************************************************************
*/
void SpiClrFifoCounter( SPI_MemMapPtr base)
{
	//-->Clear RX and TX FIFO counters
	SPI_MCR_REG(base) |=(SPI_CLR_TXFIFO<<SPI_MCR_CLR_TXF_SHIFT);
	SPI_MCR_REG(base) |=(SPI_CLR_RXFIFO<<SPI_MCR_CLR_RXF_SHIFT);
	
}// End of  SpiClrFifoCounter
예제 #2
0
/*
*******************************************************************************
* void SpiDisable( SPI_MemMapPtr base );
*******************************************************************************
* Input         : base : Pointer to SPI0/ SPI1 /SPI2 Register Base 	
* Output        : void
* Description   : Disable respective SPI module
*******************************************************************************
*/
void SpiDisable( SPI_MemMapPtr base)
{
	//-->Disable SPI
	SPI_MCR_REG(base) |=SPI_DISABLE;
	
	SPI_MCR_REG(base) &= (~SPI_MCR_MDIS_MASK);

}// End of SpiDisable
예제 #3
0
/*
*******************************************************************************
* void SpiSetMode( SPI_MemMapPtr base, uint8_t mode)
*******************************************************************************
* Input         : base : Pointer to SPI0/ SPI1 /SPI2 Register Base
* 				  mode : 1=> Master
* 				  		 0=> Slave    		
* Output        : void
* Description   : Enable Master or Slave mode for respective SPI module
*******************************************************************************
*/
void SpiSetMode( SPI_MemMapPtr base , uint8_t mode)
{
	if(SPI_MASTER_MODE == mode)
	{
		//-->SPI in Master mode 
		SPI_MCR_REG(base) |= (SPI_MASTER_MODE <<SPI_MCR_MSTR_SHIFT );
	}
	else
	{
		//-->SPI in Slave mode 
		SPI_MCR_REG(base) |= (SPI_SLAVE_MODE <<SPI_MCR_MSTR_SHIFT );
	}
	
}// End of SpiSetMode
예제 #4
0
/*
*******************************************************************************
* void SpiSetTxFifo( SPI_MemMapPtr base, uint8_t tx_fifo_enable)
*******************************************************************************
* Input         : base : Pointer to SPI0/ SPI1 /SPI2 Register Base 
* 				  tx_fifo_enable: 1=> FIFO disabled
* 				  				  0=> FIFO Enabled		
* Output        : void
* Description   : Enable  or disable Tx Fifo for respective SPI module
*******************************************************************************
*/
void SpiSetTxFifo( SPI_MemMapPtr base, uint8_t tx_fifo_enable)
{
	if(SPI_DISABLE_RXFIFO == tx_fifo_enable)
	{
		//--> Disable Tx FIFO
		SPI_MCR_REG(base) |=(SPI_DISABLE_TXFIFO <<SPI_MCR_DIS_TXF_SHIFT);
	}
	else
	{
		//--> Disable Tx FIFO
		SPI_MCR_REG(base) |=(SPI_ENABLE_TXFIFO <<SPI_MCR_DIS_TXF_SHIFT);
	}
		
}//End of SpiSetTxFifo
예제 #5
0
OSStatus spi_deinit( spi_driver_t* spi_driver )
{
    clear_spi_fifos( spi_driver->spi_peripheral );

    /* Halt transfer */
    SPI_MCR_REG( spi_driver->spi_peripheral ) |=  (uint32_t) ( SPI_MCR_HALT_MASK );

    /* Disable module */
    SPI_MCR_REG( spi_driver->spi_peripheral ) &= ~(uint32_t) ( SPI_MCR_MDIS_MASK );

    /* Disable SPI peripheral clock */
    set_spi_peripheral_clock( spi_driver->spi_peripheral, false );
    return kNoErr;
}
예제 #6
0
//=========================================================================
//函数名称:spi_re
//函数参数:spin:SPI通道号。
//          data[]:需要接收的数据。
//函数返回:返回接收到字节的长度
//功能概要:SPI接收数据。
//=========================================================================
u32 spi_re(SPIn spin,u8 data[])
{
    u32   n=0;

    while(SPI_SR_REG(SPIN[spin]) & SPI_SR_RFDF_MASK)    //RFDF为1,Rx FIFO is not empty.
    {
        data[n++] = (u8)SPI_POPR_REG(SPIN[spin]);    //保存接收到的数据            
        SPI_SR_REG(SPIN[spin]) |= SPI_SR_RFDF_MASK;
    }
     
    /*************  清标志位  ***************/
    SPI_SR_REG(SPIN[spin]) = (SPI_SR_EOQF_MASK
                       | SPI_SR_TFUF_MASK
                       | SPI_SR_TFFF_MASK
                       | SPI_SR_RFOF_MASK
                       | SPI_SR_RFDF_MASK
                       );
    
    /************** 清FIFO计数器 **************/
    SPI_MCR_REG(SPIN[spin])  |=  (SPI_MCR_CLR_TXF_MASK     //Clear the Tx FIFO counter.
                                |SPI_MCR_CLR_RXF_MASK     //Clear the Rx FIFO counter.
                                );

    return n; //n为0,则没接收到数据
}
예제 #7
0
static void spi_status_print(SPI_MemMapPtr p)
{
#define CTAR_REG_USED       (0)

    printf("MCR %x, TCR %x, CTAR %x, SR %x, RSER %x\r\n",
        SPI_MCR_REG(p), SPI_TCR_REG(p), SPI_CTAR_REG( p, CTAR_REG_USED ), SPI_SR_REG(p), SPI_RSER_REG(p));
}
예제 #8
0
//=========================================================================
//函数名称:spi_send
//函数参数:spin:SPI通道号。
//          data[]:需要发送的数据。
//          len:数据长度。
//函数返回:无
//功能概要:SPI发送数据。
//=========================================================================
void spi_send(SPIn spin,u8 data[],u32 len)
{
    u32 i = 0;
    u8 temp;
    SPI_TX_WAIT(spin);

    do
    {
        /*************  清标志位  ***************/
        SPI_SR_REG(SPIN[spin]) = (SPI_SR_EOQF_MASK
                                | SPI_SR_TFUF_MASK
                                | SPI_SR_TFFF_MASK
                                | SPI_SR_RFOF_MASK
                                | SPI_SR_RFDF_MASK
                                );
    
        /************** 清FIFO计数器 **************/
        SPI_MCR_REG(SPIN[spin])    |=  (SPI_MCR_CLR_TXF_MASK     //Clear TX FIFO.写1清 Tx FIFO counter
                                   |SPI_MCR_CLR_RXF_MASK     //Clear RX FIFO. 写1清 the Rx FIFO counter.
                                   );
        //SPI_SR_REG(SPIN[spin]) |= SPI_SR_RFDF_MASK;
    }while( (SPI_SR_REG(SPIN[spin]) & SPI_SR_RFDF_MASK));   //如果 Rx FIFO 非空,则清FIFO.

    /***************** 发送len-1个数据 *******************/                                                ;
    for(i = 0;i < (len-1);i++)
    {
        //DELAY_MS(1); 
        SPI_PUSHR_REG(SPIN[spin]) = 0 
                                | SPI_PUSHR_CONT_MASK   //Continuous Peripheral Chip Select Enable,1为 传输期间保持PCSn信号 ,即继续传输数据
                                | SPI_PUSHR_CTAS(0)
                                | SPI_PUSHR_TXDATA(data[i]);    //要传输的数据
        
        while( !(SPI_SR_REG(SPIN[spin]) & SPI_SR_RFDF_MASK));    //RFDF为1,Rx FIFO is not empty.
        temp = (u8)SPI_POPR_REG(SPIN[spin]);    //读取一次接收的数据    
        SPI_SR_REG(SPIN[spin]) |= SPI_SR_RFDF_MASK;
    }

    /***************** 发送最后一个数据 *******************/    
    SPI_PUSHR_REG(SPIN[spin]) = 0 
                   | SPI_PUSHR_CTAS(0)
                   | SPI_PUSHR_EOQ_MASK         //End Of Queue,1为 传输SPI最后的数据
                   | SPI_PUSHR_TXDATA(data[i]); 
    
    SPI_EOQF_WAIT(spin);    //要及时把RX FIFO的东西清掉,不然这里就无限等待
    
    while( !(SPI_SR_REG(SPIN[spin]) & SPI_SR_RFDF_MASK));    //RFDF为1,Rx FIFO is not empty.
    temp = (u8)SPI_POPR_REG(SPIN[spin]);    //读取一次接收的数据          
    //SPI_SR_REG(SPIN[spin]) |= SPI_SR_RFDF_MASK;
    

}
예제 #9
0
파일: spi.c 프로젝트: aarzho/k60
/**
 *    @brief   SPI接收数据
 * 
 *    @param   spino   SPI通道号
 *    @param   data[]  需要发送的数据  
 *    
 *    @return  1     成功
 *    @return  0     失败
 */
uint8_t spi_rcv(uint8_t spino, uint8_t data[])
{
      SPI_MemMapPtr base_addr = spi_get_base_address(spino);

      if(SPI_SR_REG(base_addr) & SPI_SR_RFDF_MASK)    /* Rx FIFO is not empty */
      {
              data[0] = (uint8_t)SPI_POPR_REG(base_addr);      /* Received Data */           
              SPI_SR_REG(base_addr) |= SPI_SR_RFDF_MASK;       /* The RFDF bit can be cleared by writing 1  */
              return 1;
      }
      SPI_SR_REG(base_addr) = (SPI_SR_EOQF_MASK
               | SPI_SR_TFUF_MASK
               | SPI_SR_TFFF_MASK
               | SPI_SR_RFOF_MASK
               | SPI_SR_RFDF_MASK);

      SPI_MCR_REG(base_addr) |= SPI_MCR_CLR_TXF_MASK     /* Clear the Tx FIFO counter. */
                             | SPI_MCR_CLR_RXF_MASK;     /* Clear the Rx FIFO counter. */
      
      return 0;
}
예제 #10
0
파일: spi.c 프로젝트: aarzho/k60
/**
 *    @brief  SPI发送数据
 * 
 *    @param   spino   SPI通道号
 *    @param   data[]  需要发送的数据  
 *    @param   len     需要发送的数据 
 */
void spi_snd(uint8_t spino, uint8_t data[], uint32_t len)
{
    uint32_t i = 0;
    SPI_MemMapPtr base_addr = spi_get_base_address(spino);
        
    SPI_SR_REG(base_addr) = (SPI_SR_EOQF_MASK
         | SPI_SR_TFUF_MASK
         | SPI_SR_TFFF_MASK
         | SPI_SR_RFOF_MASK
         | SPI_SR_RFDF_MASK);
    
    SPI_MCR_REG(base_addr) |= SPI_MCR_CLR_TXF_MASK    /* Clear TX FIFO */
                            | SPI_MCR_CLR_RXF_MASK;   /* Clears the RX Counter */
    
    for (i = 0; i < len; i++)
    {
        if (i == (len - 1))
        {
            SPI_PUSHR_REG(base_addr) = 0 
                    | SPI_PUSHR_CTAS(0)            /* Clock and Transfer Attributes Select */
                    | SPI_PUSHR_EOQ_MASK           /* End Of Queue */
                    | SPI_PUSHR_TXDATA(data[i]);   /* Transmit Data */
        }
        else
        {
            SPI_PUSHR_REG(base_addr) = 0 
                    | SPI_PUSHR_CONT_MASK
                    | SPI_PUSHR_CTAS(0) 
                    | SPI_PUSHR_TXDATA(data[i]);
        }
    }
    
    /* 等待数据发送完毕 */
    while((SPI_SR_REG(base_addr) & SPI_SR_TCF_MASK)==0);
    SPI_SR_REG(base_addr) |= SPI_SR_TCF_MASK;
}
예제 #11
0
static void clear_spi_fifos( SPI_MemMapPtr spi_peripheral  )
{
    SPI_MCR_REG( spi_peripheral ) |= (uint32_t)( SPI_MCR_CLR_RXF_MASK | SPI_MCR_CLR_TXF_MASK );
    SPI_SR_REG ( spi_peripheral ) |= (uint32_t)( SPI_SR_RFOF_MASK );
}
예제 #12
0
OSStatus spi_init( spi_driver_t* spi_driver, SPI_MemMapPtr spi_peripheral, uint32_t baud_rate_bps, uint8_t chip_select, bool polarity, bool phase, bool use_dma )
{
    uint8_t br = get_baud_rate_scaler_register_value( baud_rate_bps );

    spi_driver->spi_peripheral = spi_peripheral;
    spi_driver->baud_rate_bps  = baud_rate_bps;
    spi_driver->chip_select    = chip_select;
    spi_driver->polarity       = polarity;
    spi_driver->phase          = phase;
    spi_driver->use_dma        = use_dma;

    /* Enable SPI peripheral clock */
    set_spi_peripheral_clock( spi_peripheral, true );

    /* Enable SPI peripheral and clean up (stop) any previous transfer
     * MDIS     = 0 to enable
     * HALT     = 1 to stop transfer
     * MSTR     = 1 for master mode
     * DCONF    = 0 for SPI
     * PCSIS[x] = 1 for CS active low
     */
    SPI_MCR_REG( spi_peripheral ) &= ~(uint32_t) ( SPI_MCR_MDIS_MASK | SPI_MCR_DCONF(0) );
    SPI_MCR_REG( spi_peripheral ) |=  (uint32_t) ( (0x1<<24)|SPI_MCR_HALT_MASK | SPI_MCR_MSTR_MASK | SPI_MCR_PCSIS( 1 << chip_select ) );

    /* Select Clock and Transfer Attributes Register (CTAR). Always use CTAR0 */
    SPI_PUSHR_REG( spi_peripheral ) &= ~(uint32_t) SPI_PUSHR_CTAS(CTAR_REG_USED);

    /* Reset Clock and Transfer Attributes (CTAR) register */
    SPI_CTAR_REG( spi_peripheral, CTAR_REG_USED ) = 0;

    /* Set SPI configuration
     * FMSZ   = 7. Set frame size to 8-bit. frame size = FMSZ + 1
     * CPOL   = phase
     * CPHA   = polarity
     * DBR    = 00
     * PBR    = 2
     * BR     = calculate based on baud_rate_Mbps
     * PCSSCK = 0
     * PASC   = 0
     * PDT    = 0
     * CSSCK  = BR - 1
     * ASC    = BR - 1
     * DT     = 0
     */
    SPI_CTAR_REG( spi_peripheral, CTAR_REG_USED ) |= (uint32_t) ( SPI_CTAR_CPOL_MASK & (uint32_t)( polarity << SPI_CTAR_CPOL_SHIFT ) ) |
                                                     (uint32_t) ( SPI_CTAR_CPHA_MASK & (uint32_t)( phase    << SPI_CTAR_CPHA_SHIFT ) ) |
                                                     (uint32_t) ( SPI_CTAR_FMSZ( 8 - 1 ) ) |
                                                     (uint32_t) ( SPI_CTAR_DBR_MASK & ( DOUBLE_BAUD_RATE << SPI_CTAR_DBR_SHIFT ) ) |
                                                     (uint32_t) ( SPI_CTAR_PBR( CTAR_PBR ) ) |
                                                     (uint32_t) ( SPI_CTAR_BR( br ) ) |
                                                     (uint32_t) ( SPI_CTAR_CSSCK( br - 1 ) ) |
                                                     (uint32_t) ( SPI_CTAR_ASC( br - 1 ) );

    clear_spi_fifos( spi_peripheral );
        
    /* Enable the start transfer bit */
    SPI_MCR_REG( spi_peripheral ) &= ~(uint32_t) ( SPI_MCR_HALT_MASK );

	if(use_dma)
	{
		SPI_RSER_REG( spi_peripheral ) |= (0x3<<24)|(0x3<<16);
		DMA_init();
	}

    spi_status_print(spi_peripheral);
    return kNoErr;
}
예제 #13
0
/*
*******************************************************************************
* void SpiEnableReceiver( SPI_MemMapPtr base)
*******************************************************************************
* Input         : base : Pointer to SPI0/ SPI1 /SPI2 Register Base    		
* Output        : void
* Description   : Enable Receiver for respective SPI module
*******************************************************************************
*/
void SpiEnableReceiver( SPI_MemMapPtr base)
{

	SPI_MCR_REG(base) |= (SPI_RECV_ENABLE <<SPI_MCR_ROOE_SHIFT );

}//End of SpiEnableREeceiver
예제 #14
0
/*
*******************************************************************************
* void SpiSetPCS( SPI_MemMapPtr base , uint8_t peri_chip_sel)
*******************************************************************************
* Input         : base : Pointer to SPI0/ SPI1 /SPI2 Register Base 	
*				  peri_chip_sel: 0=> Low
*				  				 1=> High
* Output        : void
* Description   : Set Peripheral Chip Select for respective SPI module
*******************************************************************************
*/
void SpiSetPCS( SPI_MemMapPtr base, uint8_t peri_chip_sel)
{
	//-->Peripheral Chip Select is Inactive Low
	SPI_MCR_REG(base) |=SPI_MCR_PCSIS(peri_chip_sel);
	
}// End of SpiSetPCS
예제 #15
0
//=========================================================================
//函数名称:spi_init
//函数参数:spin:SPI通道号。
//          Master:是否是主机。
//函数返回:无
//功能概要:SPI初始化。
//=========================================================================
void spi_init(SPIn spin,SPI_CFG master)
{
    
    //使能SPI模块时钟,配置SPI引脚功能
    if(spin == 0)
    {
        SIM_SCGC6 |= SIM_SCGC6_DSPI0_MASK;
        //PORTA_PCR14 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK;//PCS0   //DSE=1:输出时高驱动能力
        PORTA_PCR15 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK;//SCK
        PORTA_PCR16 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK;//SOUT
        PORTA_PCR17 = 0 | PORT_PCR_MUX(0x2);//SIN
    }
    else if(spin == 1)
    {
        SIM_SCGC6 |= SIM_SCGC6_SPI1_MASK;
        PORTE_PCR1 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; //SOUT
        PORTE_PCR2 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; //SCK
        PORTE_PCR3 = 0 | PORT_PCR_MUX(0x2);                     //SIN
        PORTE_PCR4 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; //PCS0
    }
    else 
    {   
        SIM_SCGC3 |= SIM_SCGC3_SPI2_MASK;
        PORTD_PCR13 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; //SOUT
        PORTD_PCR12 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; //SCK
        PORTD_PCR14 = 0 | PORT_PCR_MUX(0x2)/* | PORT_PCR_DSE_MASK*/;                     //SIN
        //PORTD_PCR15 = 0 | PORT_PCR_MUX(0x2)/* | PORT_PCR_DSE_MASK*/; //PCS1     
    }
    
    SPI_MCR_REG(SPIN[spin]) = 0 
                 | SPI_MCR_CLR_TXF_MASK     //Clear the Tx FIFO counter.
                 | SPI_MCR_CLR_RXF_MASK     //Clear the Rx FIFO counter.
                 //| SPI_MCR_PCSIS_MASK
                 | SPI_MCR_HALT_MASK;

    
    //根据主从机模式设置工作模式。MCU提供最大主机频率是1/2主频,最大从机频率是1/4主频
    if(master == MASTER)
    {
        SPI_MCR_REG(SPIN[spin]) =  (0
                                    |  SPI_MCR_MSTR_MASK //Master,主机模式
                                   // |   SPI_MCR_PCSIS(2) //PCS1
                                    );      
        SPI_CTAR_REG(SPIN[spin],0) = (0
                       //| SPI_CTAR_DBR_MASK          //双波特率 ,这里设 DBR=1,CPHA=1,PBR=00,得SCK Duty Cycle 为 50/50
                       //| SPI_CTAR_CPHA_MASK         //数据在SCK上升沿改变(输出),在下降沿被捕捉(输入读取)。如果是0,则反之。  w25x16在上升沿读取数据;NRF24L01在上升沿读取数据
                        | SPI_CTAR_PBR(1)            //波特率分频器 ,0~3 对应的分频值Prescaler为 2、3、5、7
                         
                        | SPI_CTAR_PDT(0x00)         //延时因子为 PDT*2+1 ,这里PDT为3,即延时因子为7。PDT为2bit
                        | SPI_CTAR_BR(0)             //波特率计数器值 ,当BR<=3,分频Scaler 为 2*(BR+1) ,当BR>=3,分频Scaler 为 2^BR  。BR为4bit
                                                    //SCK 波特率 = (fSYS/Prescaler) x [(1+DBR)/Scaler ]          fSYS 为 Bus clock
                                                    //              100M  2          1    2   = 50M   这里以最大的来算
                                                    //              100M   5          1    2   =20M
                         
                       //| SPI_CTAR_CPOL_MASK         //时钟极性,1表示 SCK 不活跃状态为高电平,   NRF24L01 不活跃为低电平
                        | SPI_CTAR_FMSZ(0x07)        //每帧传输 7bit+1 ,即8bit (FMSZ默认就是8)  
                      // | SPI_CTAR_LSBFE_MASK        //1为低位在前。
                        //| SPI_CTAR_CSSCK(1)          //
                        //|SPI_CTAR_PCSSCK(2)         //设置片选信号有效到时钟第一个边沿出现的延时的预分频值。tcsc延时预分频 2*x+1;
                       ); 
                        //LSBFE 为 0 ,数据在前
    }
    else
    {
        //默认从机模式
        SPI_CTAR_SLAVE_REG(SPIN[spin],0) = 0 
                            | SPI_CTAR_SLAVE_FMSZ(0x07)
                            | SPI_CTAR_SLAVE_CPOL_MASK 
                            | SPI_CTAR_SLAVE_CPHA_MASK; 
   }
    //DELAY_MS(100);
   /*************  清标志位  ***************/
    SPI_SR_REG(SPIN[spin]) = (SPI_SR_EOQF_MASK     //End of Queue Flag,发送队列空了,发送完毕
                         | SPI_SR_TFUF_MASK     //Transmit FIFO Underflow Flag,传输FIFO下溢标志位,SPI为从机模式,Tx FIFO为空,而外部SPI主机模式启动传输,标志位就会置1,写1清0
                         | SPI_SR_TFFF_MASK     //Transmit FIFO Fill Flag,传输FIFO满标志位。 写1或者DMA控制器发现传输FIFO满了就会清0。 0表示Tx FIFO满了
                         | SPI_SR_RFOF_MASK     //Receive FIFO Overflow Flag,接收FIFO溢出标志位。
                         | SPI_SR_RFDF_MASK);   //Receive FIFO Drain Flag,接收FIFO损耗标志位,写1或者DMA控制器发现传输FIFO空了就会清0。0表示Rx FIFO空
    
    
    SPI_MCR_REG(SPIN[spin]) &= ~SPI_MCR_HALT_MASK;     //启动SPI传输。1为暂停,0为启动
    
    DELAY_MS(1);
}
예제 #16
0
/*
*******************************************************************************
* void SpiEnable( SPI_MemMapPtr base )
*******************************************************************************
* Input         : base : Pointer to SPI0/ SPI1 /SPI2 Register Base 	
* Output        : void
* Description   : Enable The SPI module
*******************************************************************************
*/
void SpiEnable( SPI_MemMapPtr base )
{
	SPI_MCR_REG(base) &= SPI_ENABLE; 

}//End of SpiEnable
예제 #17
0
파일: spi.c 프로젝트: aarzho/k60
/**
 *    @brief  SPI初始化
 * 
 *    @param   spino   SPI通道号
 *    @param   master  是否是主机  
 *    
 *    @return  E_ID    输入序号错误
 *    @return  E_OK    初始化正常
 */
ER spi_init(uint8_t spino, uint8_t master)
{
    if((spino < 0) || (spino > SPI_NO_GET(SPI2)))
    {
        return (E_ID);
    }
    
    SPI_MemMapPtr base_addr = spi_get_base_address(spino);
    
    /* 使能SPI模块时钟,配置SPI引脚功能 */
    if(SPI_MOD_SET(spino) == SPI0)
    {
        SIM_SCGC6 |= SIM_SCGC6_DSPI0_MASK;
        
        /* PORT_PCR_MUX(0x2) : SPI功能
         * PORT_PCR_DSE_MASK : Drive Strength Enable */
        gpio_init(PORT_NO_GET(SD_CS), PIN_NO_GET(SD_CS), OUT_PUT, HIGH_POWER);   /* PCS0 */
        PORTA_PCR15 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; /* SCK */
        PORTA_PCR16 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; /* SOUT */
        PORTA_PCR17 = 0 | PORT_PCR_MUX(0x2);                     /* SIN */
    }
    else if(SPI_MOD_SET(spino) == SPI1)
    {
        SIM_SCGC6 |= SIM_SCGC6_SPI1_MASK;
        PORTE_PCR4 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; /* PCS0 */
        PORTE_PCR2 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; /* SCK */
        PORTE_PCR1 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK; /* SOUT */
        PORTE_PCR3 = 0 | PORT_PCR_MUX(0x2);                     /* SIN */
    }
    else 
    {
        SIM_SCGC3 |= SIM_SCGC3_SPI2_MASK;
    }
    
    SPI_MCR_REG(base_addr) = 0 
                 | SPI_MCR_CLR_TXF_MASK     /* Clear the Tx FIFO counter. */
                 | SPI_MCR_CLR_RXF_MASK     /* Clear the Rx FIFO counter. */
                 | SPI_MCR_HALT_MASK;       /* Starts and stops DSPI transfers */

    /* 根据主从机模式设置工作模式 */
    if(master == MASTER)
    {
        SPI_MCR_REG(base_addr) |= SPI_MCR_MSTR_MASK;   /* Master/Slave Mode Select */
     
        SPI_CTAR_REG(base_addr,0) = 0
                       | SPI_CTAR_DBR_MASK         /* Double Baud Rate */
                       | SPI_CTAR_FMSZ(0x07)       /* Frame Size: 8bit */
                       | SPI_CTAR_PDT_MASK         /* 延时因子为7 */
                       | SPI_CTAR_BR(0x8);         /* Selects the scaler value for the baud rate.  */
                       //| SPI_CTAR_CPOL_MASK;     /* Clock Polarity */
                       //| SPI_CTAR_CPHA_MASK;     /* Clock Phase */
    }
    else
    {
        SPI_CTAR_SLAVE_REG(base_addr,0) = 0 
                            | SPI_CTAR_SLAVE_FMSZ(0x07)
                            | SPI_CTAR_SLAVE_CPOL_MASK 
                            | SPI_CTAR_SLAVE_CPHA_MASK; 
   }
 
   SPI_SR_REG(base_addr) = SPI_SR_EOQF_MASK    /* End of Queue Flag */
                         | SPI_SR_TFUF_MASK      /* Transmit FIFO Underflow Flag */
                         | SPI_SR_TFFF_MASK      /* Transmit FIFO Fill Flag */
                         | SPI_SR_RFOF_MASK      /* Receive FIFO Overflow Flag */
                         | SPI_SR_RFDF_MASK;    /* Receive FIFO Drain Flag */
    
    SPI_MCR_REG(base_addr) &= ~SPI_MCR_HALT_MASK;   /* start */
    
    return (E_OK);
}