加入星計劃,您可以享受以下權益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 相關推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

快速定位i.MXRT600啟動引腳上電時序問題

2021/06/02
484
閱讀需 9 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

大家好,我是痞子衡,是正經(jīng)搞技術的痞子。今天痞子衡給大家介紹的是一種快速定位i.MXRT600板級設計ISP[2-0]啟動模式引腳上電時序問題的方法。

我們知道恩智浦i.MXRT600是主打音頻市場的MCU產(chǎn)品,其也是i.MXRT三位數(shù)平臺的第一款型號。這顆MCU已被眾多知名國際大廠客戶選用,在項目中作為協(xié)處理器負責音頻相關子功能。不少客戶都已經(jīng)到了量產(chǎn)階段,最近痞子衡在支持其中一個量產(chǎn)客戶,客戶遇到了同一批次某幾個板卡無法正常啟動的問題。痞子衡和同事一起排查,最終發(fā)現(xiàn)是ISP[2:0]啟動引腳電平上電時序問題。這其實是個典型問題,痞子衡今天教你一招快速定位此類問題的方法:

一、引出上電時序問題

我們先來看看客戶的問題,下面是客戶板卡簡圖,i.MXRT600是負責音頻功能的協(xié)處理器,它的啟動引腳ISP[2:0]與主應用處理器(AP)連接了起來(客戶項目設計里,AP并不負責控制i.MXRT600的啟動模式),為了防止對i.MXRT600上電ISP引腳采樣有影響,客戶還特地在中間加了一層反向隔離電路。

  • 注:其實i.MXRT600支持Serial Boot模式,這種模式下i.MXRT600作為協(xié)處理器,其應用程序數(shù)據(jù)可直接由AP通過指定的UART/I2C/SPI/USB下載進i.MXRT600的內(nèi)部RAM運行,能省去一顆外部Flash。

客戶量產(chǎn)過程中,同一批次幾百塊板卡,有一兩塊板卡上i.MXRT600無法啟動??蛻糇隽松倭緼BA實驗:將無法啟動板卡上的i.MXRT600芯片吹下來,換到能正常啟動板卡上,依然無法啟動。反過來,能正常啟動板卡上的i.MXRT600芯片換到無法正常啟動的板卡上,這塊板卡就能正常啟動了。

從上面ABA實驗來看,似乎不是板級設計問題,像是出問題的板卡上i.MXRT600芯片自身問題。痞子衡拿到一塊出問題的板子,上電后測量了ISP[2:0]引腳電平,其值是3'b011 - FlexSPI Boot from Port A,上電穩(wěn)定后ISP設置是沒問題的,但剛上電時i.MXRT600 BootROM到底采樣到的是什么ISP電平值沒人知道。

下面是客戶板卡上ISP部分反向隔離設計,為了驗證是ISP采樣時機問題,我們特意對電路進行改造將RT600_BOOT0和RT600_BOOT2分別強行拉高和拉低,然后給板卡重新上電,終于板卡能正常啟動了。

所以我們可以得出初步結論,對于i.MXRT600從上電到BootROM進行ISP采樣,這段時間不是一個嚴格固定值,因芯片制造差異,這個時間應該是在一定范圍內(nèi),板級供電設計時上電時間應留有足夠余量??蛻暨@個項目里上電時間余量留得不足,導致無法滿足個別i.MXRT600芯片ISP采樣時間要求。

 

二、BootROM中對于啟動模式的處理

在介紹快速定位ISP采樣時機問題方法前,痞子衡先帶大家了解下i.MXRT600 BootROM中關于啟動模式的處理流程。

咱們先回顧下痞子衡的舊文 《Boot配置(ISP_Pin/OTP)》,每次i.MXRT600芯片硬復位,OTP中的部分關于系統(tǒng)配置的值會被自動加載到OCOTP模塊相應Shadow Register里(關于OCOTP外設基礎知識可參考 《OTP及其燒寫方法》),BootROM中主要用如下 get_runtime_boot_device_info() 函數(shù)來獲取最終啟動模式,并將其存在全局變量 s_bootDeviceInfo 中。

  • 注:代碼中 OCOTP->OTP_SHADOW[0x60] 寄存器低四位即芯片參考手冊里提及的 PRIMARY_BOOT_SRC[3:0]
static boot_device_info_t s_bootDeviceInfo;

void get_runtime_boot_device_info(void)
{
    // 從OTP Shadow Register獲取啟動模式
    uint32_t bootSrc = OCOTP->OTP_SHADOW[0x60] & 0x0f;
    boot_device_info_t bootDeviceInfo = { 0 };

    if (bootSrc == 0) // Isp Pin
    {
        // 從ISP[2:0]引腳獲取啟動模式 
        bootSrc = get_bootpin_mode();
        // 對 bootDeviceInfo 成員進一步賦值
    }
    else
    {
        // 對 bootDeviceInfo 成員進一步賦值
    }
    s_bootDeviceInfo = bootDeviceInfo;
}

每一次i.MXRT600系統(tǒng)軟復位去重新執(zhí)行BootROM時,ISP[2:0]引腳狀態(tài)都會被重新采樣,這完全是軟件采樣。ROM中ISP采樣功能函數(shù)如下面 get_bootpin_mode() 所示,代碼中做了IO電平去抖處理:

#define BOOT_PIN_DEBOUNCE_READ_COUNT 500

uint32_t get_bootpin_mode(void)
{
    uint32_t bootSrc = 0;

    // 使能GPIO外設
    CLOCK_EnableClock(kCLOCK_HsGpio1);
    RESET_PeripheralReset(kHSGPIO1_RST_SHIFT_RSTn);

    // 設置ISP引腳為GPIO模式,并使能上拉.
    IOPCTL->PIO[1][15] = IOPCTL_PIO_FSEL(0) | IOPCTL_PIO_PUPDENA(1) | IOPCTL_PIO_PUPDSEL(1) | IOPCTL_PIO_IBENA(1);
    IOPCTL->PIO[1][16] = IOPCTL_PIO_FSEL(0) | IOPCTL_PIO_PUPDENA(1) | IOPCTL_PIO_PUPDSEL(1) | IOPCTL_PIO_IBENA(1);
    IOPCTL->PIO[1][17] = IOPCTL_PIO_FSEL(0) | IOPCTL_PIO_PUPDENA(1) | IOPCTL_PIO_PUPDSEL(1) | IOPCTL_PIO_IBENA(1);

    // 配置ISP引腳GPIO屬性為數(shù)字輸入模式.
    GPIO->DIR[1] &= ~((1U << 15) | (1U << 16) | (1U << 17));

    // Note1: 管腳默認上拉是disable的,ROM需要使能管腳上拉.
    // Note2: 從使能管腳上拉到讀取管腳值之間應間隔10us以上.
    sw_delay_us(10);

    // 采樣ISP引腳值
    for (uint32_t pin = 17; pin >= 15; pin--)
    {
        uint32_t readCount = 0;
        for (uint32_t i = 0; i < BOOT_PIN_DEBOUNCE_READ_COUNT; i++)
        {
            readCount += GPIO->B[1][pin] & 0x1;
        }
        if (readCount >= BOOT_PIN_DEBOUNCE_READ_COUNT / 2)
        {
            bootSrc |= 0x1;
        }
        if (pin != 15)
        {
            bootSrc <<= 1;
        }
    }

    return bootSrc;
}

上面就是BootROM中關于啟動模式的處理代碼。那么有沒有方法掛上調(diào)試器通過查后門方式直接讀取到 s_bootDeviceInfo 變量值呢?很抱歉,不可以!即使痞子衡也做不到,雖然痞子衡能通過查BootROM map文件得知這個變量放在 0x10012d38 地址處。但是i.MXRT600 BootROM中集成了 《Debug Mailbox機制》,我們無法通過調(diào)試器讀取正常運行后的ROM狀態(tài),這條路行不通。

三、快速定位ISP[2:0]電平采樣問題

第一小節(jié)介紹的客戶項目啟動問題,其實還算比較好定位,因為有ABA實驗在先,基本可以明確問題就出在ISP采樣時機上。但更多時候,在客戶項目研發(fā)階段,沒有ABA實驗的條件,可能僅有一塊板卡,并且Flash配置以及App里啟動頭是否正確都尚待驗證。這種情況下,我們就需要一種快速甄別是否是ISP采樣時機因素導致的啟動問題。

當芯片無法啟動時,我們第一想法肯定是要得知第二小節(jié)介紹里 s_bootDeviceInfo 到底是什么值,這樣我們就能反推ISP引腳到底在ROM里是什么采樣值,但這條路行不通。換個角度想,我們能不能不讓BootROM去采樣ISP引腳,換一種替代方式來決定啟動模式,如果這種情況下能按替代設置去啟動,就也可以反證ISP引腳采樣時機有問題。

這種啟動模式替代設置方法就是痞子衡今天要教大家的方法,利用調(diào)試器臨時改寫OCOTP->OTP_SHADOW[0x60]值(對的,我們可以不燒寫OTP),改寫完成后對芯片做一次軟復位即可。OCOTP->OTP_SHADOW寄存器組僅芯片硬件復位或者執(zhí)行OCOTP更新命令其值才會被重新加載,軟復位不會影響其值。

四、在MIMXRT685-EVK上做一次實驗

讓我們在MIMXRT685-EVK上做一次實驗,這塊板卡上Flash連到了FlexSPI0 Port B上,我們隨意下載一個SDK XIP工程,并將ISP引腳撥碼設為3'b010 - FlexSPI Boot from Port B,復位后芯片能正常啟動,工程運行正常。

現(xiàn)在我們將ISP引腳撥碼設為3'b110 - Serial ISP,軟復位后芯片進入了ISP下載模式,不會從Flash啟動。查芯片頭文件得知 OCOTP->OTP_SHADOW[0x60] 寄存器地址是 0x50130180,我們現(xiàn)在嘗試改寫這個寄存器。

/** OCOTP - Register Layout Typedef */
typedef struct {
  __IO uint32_t OTP_SHADOW[496];                   /**< OTP shadow register N, array offset: 0x0, array step: 0x4 */
       uint8_t RESERVED_0[64];
  __IO uint32_t OTP_CTRL;                          /**< Control/address register, offset: 0x800 */
  // 省略...
} OCOTP_Type;

/** Peripheral OCOTP base address */
#define OCOTP_BASE                               (0x50130000u)
/** Peripheral OCOTP base address */
#define OCOTP_BASE_NS                            (0x40130000u)
/** Peripheral OCOTP base pointer */
#define OCOTP                                    ((OCOTP_Type *)OCOTP_BASE)
/** Peripheral OCOTP base pointer */
#define OCOTP_NS                                 ((OCOTP_Type *)OCOTP_BASE_NS)

掛上J-Link調(diào)試器,打開J-Link Commander,連接芯片,注意選擇"MIMXRT685_M33",然后使用w4命令在0x50130180地址處寫入0x00000005(在PRIMARY_BOOT_SRC[3:0]定義里,4'b0101是QSPI_B_BOOT)。

 

繼續(xù)執(zhí)行reset和go命令(或者按一下板載軟復位按鈕RESET BUTTON SW3),這時候你可以看到芯片從Flash正常啟動了,SDK XIP工程又運行起來了,顯然這時候ISP引腳電平設置被忽略了,因此我們找到了有效的啟動模式替代設置方法。

 

最后有一點要注意,在使用J-Link軟復位時,如果看到如下log,得檢查下配套JLinkScript里的ResetTarget()函數(shù)具體功能,要確保內(nèi)核真的被復位了。

 

至此,快速定位i.MXRT600板級設計ISP[2-0]啟動模式引腳上電時序問題的方法痞子衡便介紹完畢了,掌聲在哪里~~~

相關推薦

電子產(chǎn)業(yè)圖譜

碩士畢業(yè)于蘇州大學電子信息學院,目前就職于恩智浦(NXP)半導體MCU系統(tǒng)部門,擔任嵌入式系統(tǒng)應用工程師。痞子衡會定期分享嵌入式相關文章