zynq SPI 參數配置


/*
 * Create the table of options which are processed to get/set the device
 * options. These options are table driven to allow easy maintenance and
 * expansion of the options.
 */
typedef struct 
{
    u32 Option;
    u32 Mask;
} OptionsMap;

static OptionsMap OptionsTable[] = 
{
    // 主機模式選項
    {XSPIPS_MASTER_OPTION, XSPIPS_CR_MSTREN_MASK},
    // 極性(CLK_POL)配置選項
    // CPOL的高低決定串行同步時鍾的空閑狀態電平,CPOL = 0,為低電平
    {XSPIPS_CLK_ACTIVE_LOW_OPTION, XSPIPS_CR_CPOL_MASK},
    // 時鍾相位(CLK_PH)配置選項
    // CPHA的高低決定串行同步時鍾是在第一時鍾跳變沿還是第二個時鍾跳變沿數據被采集,當CPHL = 0,在第一個跳變沿進行數據采集;
    {XSPIPS_CLK_PHASE_1_OPTION, XSPIPS_CR_CPHA_MASK},
    // 是否使用 3/8 譯碼器 ,從3個SS信號擴展到8個SS信號 配置選項
    {XSPIPS_DECODE_SSELECT_OPTION, XSPIPS_CR_SSDECEN_MASK},
    // 強制選擇模式,通過調用發送函數來強制選擇CS來使CS有效。
    {XSPIPS_FORCE_SSELECT_OPTION, XSPIPS_CR_SSFORCE_MASK},
    //  手動觸發選項
    {XSPIPS_MANUAL_START_OPTION, XSPIPS_CR_MANSTRTEN_MASK}
};

s32 XSpiPs_SetOptions(XSpiPs *InstancePtr, u32 Options)
{
    u32 ConfigReg;
    u32 Index;
    u32 CurrentConfigReg;
    s32 Status;

    Xil_AssertNonvoid(InstancePtr != NULL);
    Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

    /*
     * Do not allow the slave select to change while a transfer is in
     * progress. Not thread-safe.
     */
     
     // 在傳輸過程中,不允許該改變從機選擇,線程不安全
    if (InstancePtr->IsBusy == TRUE) 
    {
        Status = (s32)XST_DEVICE_BUSY;
    }
    else 
    {

        // 讀取當前寄存器配置信息
        ConfigReg = XSpiPs_ReadReg( InstancePtr->Config.BaseAddress, XSPIPS_CR_OFFSET );
        
        // 將當前配置賦值給 CurrentConfigReg
        CurrentConfigReg = ConfigReg;

        /*
         * Loop through the options table, turning the option on or off
         * depending on whether the bit is set in the incoming options flag.
         */
        // 循環遍歷選項表,打開或關閉選項
        // 取決於是否在傳入選項標志中設置了位
        for (Index = 0U; Index < XSPIPS_NUM_OPTIONS; Index++) 
        {
            if ((Options & OptionsTable[Index].Option) != (u32)0U) 
            {
                /* Turn it on */
                ConfigReg |= OptionsTable[Index].Mask;
            }
            else 
            {
                /* Turn it off */
                ConfigReg &= ~(OptionsTable[Index].Mask);
            }
        }


        /*
         * If CPOL-CPHA bits are toggled from previous state,
         * disable before writing the configuration register and then enable.
         */
         // 配置 CPOL/CPHA 選項時,先禁止 SPI 再使能 
        if( ((CurrentConfigReg & XSPIPS_CR_CPOL_MASK) !=
            (ConfigReg & XSPIPS_CR_CPOL_MASK)) ||
            ((CurrentConfigReg & XSPIPS_CR_CPHA_MASK) !=
            (ConfigReg & XSPIPS_CR_CPHA_MASK)) ) 
            {
                XSpiPs_Disable(InstancePtr);
            }

        /*
         * Now write the Config register. Leave it to the upper layers
         * to restart the device.
         */
         // 將配置寫入到寄存器,請在 應用層 重啟 SPI
        XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
                    XSPIPS_CR_OFFSET, ConfigReg);

        /*
         * Enable
         */
        // 配置 CPOL/CPHA 選項時,先禁止 SPI 再使能 
        if( ((CurrentConfigReg & XSPIPS_CR_CPOL_MASK) !=
            (ConfigReg & XSPIPS_CR_CPOL_MASK)) ||
            ((CurrentConfigReg & XSPIPS_CR_CPHA_MASK) !=
            (ConfigReg & XSPIPS_CR_CPHA_MASK)) ) 
{
                XSpiPs_Enable(InstancePtr);
            }

        Status = (s32)XST_SUCCESS;
    }
    return Status;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM