Ejemplo n.º 1
0
/*********************************************************
* Name: SPI_Send_byte
* Desc: Send one byte 
* Parameter: The byte to be sent
* Return: None
**********************************************************/
void SPI_Send_byte(uint_8 u8Data)
{
    /*Body*/
    /* Check the status flag */
    if(SPI1_SR & SPI_SR_EOQF_MASK)
    {
        /* Clear the EOQF by writting a 1 to it */
        SPI1_SR |= SPI_SR_EOQF_MASK;
    }/*Endif*/

    /* Write the DSPI_PUSHR register */
    SPI1_PUSHR = (  SPI_PUSHR_CTAS(0)        | 
                    SPI_PUSHR_EOQ_MASK       |
                    SPI_PUSHR_CTCNT_MASK     |
                    SPI_PUSHR_PCS(1)         |
                    SPI_PUSHR_TXDATA(u8Data)); 
    /* Write the clock and transfer attributes: master clock and frame size (8 bits) */
    SPI1_CTAR0 = (  SPI_CTAR_SLAVE_FMSZ(7)      | 
                    gSPI_BeforeTransfDelay      |
                    gSPI_AfterTransfDelay       |
                    gSPI_InterTransfDelay       |
                    gSPI_BaudRate);

    /* Start the transfer */
    SPI1_MCR &= ~SPI_MCR_HALT_MASK;
    
    /* Wait until the transfer has been finished */
    while(!(SPI1_SR & SPI_SR_EOQF_MASK))
    {
        Watchdog_Reset();
    }/*EndWhile*/
    /* Clear the EOQF by writting a 1 to it */
    SPI1_SR |= SPI_SR_EOQF_MASK;
}/*EndBody*/
Ejemplo n.º 2
0
Archivo: spi.c Proyecto: 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);
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
0
int spi_init_slave(spi_t dev, spi_conf_t conf, char(*cb)(char data))
{
    SPI_Type *spi_dev;

    switch (dev) {
#if SPI_0_EN

        case SPI_0:
            spi_dev = SPI_0_DEV;
            /* enable clocks */
            SPI_0_CLKEN();
            SPI_0_PCS0_PORT_CLKEN();
            SPI_0_SCK_PORT_CLKEN();
            SPI_0_SOUT_PORT_CLKEN();
            SPI_0_SIN_PORT_CLKEN();
            /* Set PORT to AF mode */
            SPI_0_PCS0_PORT->PCR[SPI_0_PCS0_PIN] = PORT_PCR_MUX(SPI_0_PCS0_AF);
            SPI_0_SCK_PORT->PCR[SPI_0_SCK_PIN] = PORT_PCR_MUX(SPI_0_SCK_AF);
            SPI_0_SOUT_PORT->PCR[SPI_0_SOUT_PIN] = PORT_PCR_MUX(SPI_0_SOUT_AF);
            SPI_0_SIN_PORT->PCR[SPI_0_SIN_PIN] = PORT_PCR_MUX(SPI_0_SIN_AF);
            break;
#endif /* SPI_0_EN */

        default:
            return -1;
    }

    /* set frame size, slave mode always uses CTAR0 */
    spi_dev->CTAR[0] = SPI_CTAR_SLAVE_FMSZ(7);

    /* Set clock polarity and phase. */
    switch (conf) {
        case SPI_CONF_FIRST_RISING:
            spi_dev->CTAR[0] &= ~(SPI_CTAR_CPHA_MASK | SPI_CTAR_CPOL_MASK);
            break;

        case SPI_CONF_SECOND_RISING:
            spi_dev->CTAR[0] &= ~(SPI_CTAR_CPOL_MASK);
            spi_dev->CTAR[0] |= SPI_CTAR_CPHA_MASK;
            break;

        case SPI_CONF_FIRST_FALLING:
            spi_dev->CTAR[0] &= ~(SPI_CTAR_CPHA_MASK);
            spi_dev->CTAR[0] |= SPI_CTAR_CPOL_MASK;
            break;

        case SPI_CONF_SECOND_FALLING:
            spi_dev->CTAR[0] |= SPI_CTAR_CPHA_MASK | SPI_CTAR_CPOL_MASK;
            break;

        default:
            return -2;
    }

    /* enable SPI */
    spi_dev->MCR = SPI_MCR_DOZE_MASK
                   | SPI_MCR_PCSIS(SPI_0_PCS0_ACTIVE_LOW << 0)
                   | SPI_MCR_CLR_TXF_MASK
                   | SPI_MCR_CLR_RXF_MASK;

    spi_dev->RSER = (uint32_t)0;

    /* set callback */
    spi_config[dev].cb = cb;

    return 0;
}