NXP iMX8MM Cortex-M4 核心 GPT Capture 測試

By Toradex秦海

1). 簡介

NXP i.MX8 系列處理器均為異構(gòu)多核架構(gòu) SoC弛槐,除了可以運(yùn)行 Linux 等復(fù)雜操作系統(tǒng)的 Cortax-A 核心,還包含了可以運(yùn)行實時操作系統(tǒng)比如 FreeRTOS 的 Cortex-M 核心醉箕,本文就演示通過 NXP i.MX8MM 處理器集成的 Cortex-M4 核心來運(yùn)行 GPT (General Purpose Timer) 輸入采集功能模塊的測試。


I.MX8M Mini 處理器 GPT 模塊硬件比較簡單脓恕,如下框圖躬拢,可以實現(xiàn) Capture 捕獲輸入功能和 Compare 定時輸出功能。



本文所演示的ARM平臺來自于Toradex 基于NXP i.MX8M Mini ARM處理器的Verdin iMX8MM ARM嵌入式平臺念秧。



2. 準(zhǔn)備

a). Verdin i.MX8MMARM核心版配合Verdin Development Board淤井,連接調(diào)試串口(載板X66)到開發(fā)主機(jī)方便調(diào)試,X66 連接了4個串口摊趾,其中第三個是 Cortex-M4 核心的默認(rèn)調(diào)試串口币狠,第四個是 Cortex-A53 核心的默認(rèn)調(diào)試串口。


b). 為了測試 GPT 輸入捕獲砾层, 相應(yīng)的需要一個PWM 波發(fā)生設(shè)備漩绵,這里使用Toradex 基于NXP i.MX8M Plus ARM處理器的Verdin i.MX8MP核心板配合Dahlia Board作為PWM output使用。同樣連接調(diào)試串口(載板X18)到開發(fā)主機(jī)方便調(diào)試肛炮。


c). Verdin i.MX8MP Cortex-A53 核心系統(tǒng)使用Toradex Yocto Linux BSP6, 更多說明請參考這里止吐。


d). 參考如下將 Verdin i.MX8MP PWM1 連接到 Verdin i.MX8MM GPT1 Capture 管腳,同時為了阻斷載板其他電路干擾侨糟,將 Verdin Development Board X6 Pin_24 的跳線帽去掉碍扔。

Dahlia Board X20 Pin_9 -> Verdin Development Board X5Pin_24 SODIMM_252



3). Verdin?i.MX8MM M4核心FreeRTOS基本資料

a). Verdin i.MX8MM?HMP(Heterogeneous Multi-core Processing) 架構(gòu)基本說明請參考如下:

https://developer.toradex.cn/software/cortex-m/hmp-memory-areas-on-toradex-soms/?


b). 參考如下說明下載配置NXP 用于開發(fā) Cortex-M 核心的 MCUXpresso SDK

https://developer.toradex.cn/software/cortex-m/setting-up-sdk-toolchain/?


c). Verdin i.MX8MM 編譯運(yùn)行 M4 firmware 操作流程請參考如下文章

https://developer.toradex.cn/software/real-time/freertos/freertos-on-the-cortex-m4-of-a-verdin-imx8mm


d). MCUXpresso SDK 包含的 sample 示例應(yīng)用可以參考如下 SDK 源位置

-----------------------------

$cd <SDK_root>/boards/evkmimx8mm/

$ tree -L 2

.

├── cmsis_driver_examples

│?? ├── ecspi

│?? ├── enet

│?? ├── i2c

│?? └── uart

├── demo_apps

│?? ├── hello_world

│?? └── sai_low_power_audio

├── driver_examples

│?? ├── ecspi

│?? ├── enet

│?? ├── gpio

│?? ├── gpt

│?? ├── i2c

│?? ├── pdm

│?? ├── pwm

│?? ├── rdc

│?? ├── sai

│?? ├── sdma

│?? ├── sema4

│?? ├── tmu

│?? ├── uart

│?? └── wdog

├── evkmimx8mm.png

├── freertos_examples

│?? ├── freertos_event

│?? ├── freertos_generic

│?? ├── freertos_hello

│?? ├── freertos_mutex

│?? ├── freertos_queue

│?? ├── freertos_sem

│?? ├── freertos_swtimer

│?? └── freertos_tickless

├── multicore_examples

│?? ├── rpmsg_lite_pingpong_rtos

│?? └── rpmsg_lite_str_echo_rtos

└── project_template

├── board.c

├── board.h

├── BOARD_Project_Template_evkmimx8mm.cmake

├── clock_config.c

├── clock_config.h

├── peripherals.c

├── peripherals.h

├── pin_mux.c

└── pin_mux.h

-----------------------------



4). Verdin i.MX8MM?Cortex-M4核心FreeRTOS GPT Capture示例驅(qū)動開發(fā)

a). Verdin i.MX8MM MCUXpresso SDK 已經(jīng)包含一個簡單的 GPT Capture sample驅(qū)動,本文基于此sample 進(jìn)行修改測試秕重。

-----------------------------

$cd <SDK_root>/boards/evkmimx8mm/driver_examples/gpt/capture

$ tree -L 1

.

├── armgcc

├── board.c

├── board.h

├── clock_config.c

├── clock_config.h

├── empty_rsc_table.c

├── fsl_iomuxc.h

├── gpt_capture.c

├── gpt_capture_v3_14.xml

├── pin_mux.c

├── pin_mux.h

└── readme.md

-----------------------------



b). 首先先確認(rèn)?pin_mux 定義以及其他i.MX8MM 初始化基本配置不同,如果需要可以進(jìn)行修改

./ pin_mux.h/pin_mux.c 用于確定項目中使用的管腳定義,本文中使用的正好就是示例默認(rèn)的 GPT1 Capture1 管腳,因此無需修改二拐。如果用到其他管腳服鹅,就需要進(jìn)行修改,支持的所有管腳定義可以參考 fsl_iomuxc.h 文件卓鹿。

-----------------------------

/* FUNCTION ************************************************************************************************************

*

* Function Name : BOARD_InitPins

* Description ??: Configures pin routing and optionally pin electrical features.

*

* END ****************************************************************************************************************/

void BOARD_InitPins(void) { ???????????????????????????????/*!< Function assigned for the core: Cortex-M4[m4] */

????IOMUXC_SetPinMux(IOMUXC_SAI3_RXFS_GPT1_CAPTURE1, 0U);

IOMUXC_SetPinMux(IOMUXC_UART4_RXD_UART4_RX, 0U);

...

-----------------------------


./ board.h/board.c 用于 i.MX8MM M4 核心基本初始化配置菱魔,本文不做修改留荔。


./ clock_config.h/clock_config.c 用于 i.MX8MM M4 核心基本時鐘配置吟孙,本文不做修改。


c). GPT Capture 功能實現(xiàn)

./ 本文 GPT Capture 功能定義

GPT1 capture1 管腳輸入一個給定頻率(如 1k Hz )和占空比(如 ?50% ) 的PWM 信號聚蝶,通過捕獲輸入上升/下降沿中斷杰妓,分別獲得相鄰兩次中斷的 GPT Counter 計數(shù)器的計數(shù),并以此來計算輸入 PWM 信號的半波周期碘勉。


./ GPT Capture 功能基本都是通過 gpt_capture.c 文件代碼來實現(xiàn)巷挥,默認(rèn) sample 是捕獲上升沿中斷后,打印中斷當(dāng)時的 GPT Counter 計數(shù)數(shù)值验靡。


./ 為了實現(xiàn)本文定義的捕獲功能倍宾,首先增加如下全局變量定義

-----------------------------

/*******************************************************************************

* Variables

******************************************************************************/

volatile bool gptIsrFlag_Start = false;

volatile bool gptIsrFlag_Finish = false;

volatile uint8_t gptIsrFlag_Overflow = 0;

volatile uint32_t captureVal = 0;

volatile uint32_t captureVal_Last = 0;

-----------------------------


// gptIsrFlag_Start 定義為第一次捕獲中斷開始標(biāo)志

// gptIsrFlag_Finish 定義為第二次捕獲中斷結(jié)束標(biāo)志

// gptIsrFlag_Overflow 定義為 GPT Counter 溢出標(biāo)志計數(shù)

// captureVal 定義為第二次中斷 GPT Counter 數(shù)值

// captureVal_Last 定義為第一次中斷 GPT Counter 數(shù)值


./ GPT Interrupt 函數(shù)修改如下:

首先處理計數(shù)器溢出情況,如果中斷發(fā)生時候已經(jīng)發(fā)生溢出胜嗓,則增加gptIsrFlag_Overflow 溢出標(biāo)志計數(shù)的數(shù)值高职;然后通過 gptIsrFlag_Start / gptIsrFlag_Finish 標(biāo)志位來分別處理第一次和第二次中斷,獲取第一次和第二次中斷時候的 GPT Counter 數(shù)值辞州,同時分別翻轉(zhuǎn) GPT Capture Interrupt 模式怔锌。

-----------------------------

void EXAMPLE_GPT_CAPTURE_IRQHandler(void)

{

/* GPT Counter Overflow processing */

if (GPT_GetStatusFlags(DEMO_GPT_BASE, kGPT_RollOverFlag) != false)

{

if (gptIsrFlag_Start == true)

{

gptIsrFlag_Overflow ++;

}

GPT_ClearStatusFlags(DEMO_GPT_BASE, kGPT_RollOverFlag);

}


if (GPT_GetStatusFlags(DEMO_GPT_BASE, kGPT_InputCapture1Flag) != false)

{

if(gptIsrFlag_Finish != true)

{

/* First time IRQ */

if (gptIsrFlag_Start == false)

{

captureVal_Last = GPT_GetInputCaptureValue(DEMO_GPT_BASE, BOARD_GPT_INPUT_CAPTURE_CHANNEL);

/* Switch Interrupt mode to falling edge */

GPT_SetInputOperationMode(DEMO_GPT_BASE, BOARD_GPT_INPUT_CAPTURE_CHANNEL, kGPT_InputOperation_FallEdge);

gptIsrFlag_Start = true;

}

/* Second time IRQ */

else

{

captureVal = GPT_GetInputCaptureValue(DEMO_GPT_BASE, BOARD_GPT_INPUT_CAPTURE_CHANNEL);

/* Switch Interrupt mode to rising edge */

GPT_SetInputOperationMode(DEMO_GPT_BASE, BOARD_GPT_INPUT_CAPTURE_CHANNEL, kGPT_InputOperation_RiseEdge);

gptIsrFlag_Start = false;

gptIsrFlag_Finish = true;

}

}

GPT_ClearStatusFlags(DEMO_GPT_BASE, BOARD_GPT_CHANNEL_FLAG);

}

SDK_ISR_EXIT_BARRIER;

}

-----------------------------


./ Main 主函數(shù)修改如下:

-----------------------------

int main(void)

{

? ? uint64_t int_Peroid = 0;

? ? ? ? uint32_t time_Ms = 0;

? ? ? ? uint32_t time_Us = 0;

gpt_config_t gptConfig;

...

GPT_GetDefaultConfig(&gptConfig);

????/* Initialize GPT module */

????GPT_Init(DEMO_GPT_BASE, &gptConfig);

...

/* Setup input capture on a gpt channel */

GPT_SetInputOperationMode(DEMO_GPT_BASE, BOARD_GPT_INPUT_CAPTURE_CHANNEL, kGPT_InputOperation_RiseEdge);

...

/* Enable GPT Overflow interrupt */

GPT_EnableInterrupts(DEMO_GPT_BASE, kGPT_RollOverFlagInterruptEnable);

...

while (true)

????{

????????/* Check whether occur 2nd interupt */

????????if (true == gptIsrFlag_Finish)

????????{

????????????/* GPT counter diff value between 2 IRQs */

????????????int_Peroid = gptIsrFlag_Overflow * (uint64_t) 0xffffffff;

????????????int_Peroid = int_Peroid + captureVal;

????????????int_Peroid = int_Peroid - captureVal_Last;

????????????/* transfer counter value to peroid */

????????????time_Us = (uint32_t) ((int_Peroid / 24) % 1000);

????????????time_Ms = (uint32_t) ((int_Peroid / 24) / 1000);

????????????PRINTF("\r\n interval between 2 rising edge =%u ms and %u us\r\n", time_Ms, time_Us);

????????????gptIsrFlag_Overflow = 0;

????????????gptIsrFlag_Finish = false;

????????}

????????else

????????{

????????????__WFI();

????????}

????}

}

-----------------------------


// 通過 GPT_GetDefaultConfig函數(shù)獲取默認(rèn)的GPT Capture 配置催束,參考 docs 目錄下的 MCUXpresso SDK API Reference Manual_MIMX8MM6.pdf 文檔冈敛,可以查到默認(rèn)配置如下懊纳,如果需要也可以修改這個配置

-----------------------------

config->clockSource = kGPT_ClockSource_Periph;

config->divider = 1U;

config->enableRunInStop = true;

config->enableRunInWait = true;

config->enableRunInDoze = false;

config->enableRunInDbg = false;

config->enableFreeRun = false;

config->enableMode = true;

-----------------------------

// 通過 GPT_SetInputOperationMode函數(shù)將GPT Capture 模式初始配置為上升沿觸發(fā)

// 為了處理 GPT Counter Overflow叉抡,使能對應(yīng)中斷

// while 函數(shù)循環(huán)執(zhí)行當(dāng) ?gptIsrFlag_Finish第二次中斷采集結(jié)束標(biāo)志位聲明后备恤,打印捕獲的輸入PWM 波的半波周期型檀。如果有溢出發(fā)生躯嫉,則需要考慮增加相應(yīng)的 0xffffffff 溢出計數(shù)次數(shù)壶唤。這里需要說明下崭孤,由于 NXP iMX8MM SoC 也受到如下 Errata 影響楞件,因此 GPT Clock Source 只能使用內(nèi)部 24M Hz 時鐘源,所以這里直接使用 24M 來算出半波周期是多少 ms 和 us 裳瘪。

https://www.nxp.com.cn/docs/en/errata/IMX8X_C0_0N99Z_ER.pdf?



5).Verdin i.MX8MM?Cortex-M4核心FreeRTOS GPT Capture示例部署測試

a). 將上述修改后的項目參考章節(jié)3 的相關(guān)資料編譯后土浸,復(fù)制 gpt_capture.bin 可執(zhí)行文件到 Verdin i.MX8MM 核心板 Linux /home/root 目錄下保存。


b). 對Verdin i.MX8MM 模塊進(jìn)入 U-boot 命令行彭羹,通過如下命令配置 Cortex-M4 核心 Firmware 下載和運(yùn)行

-----------------------------

# setenv load_cmd "ext4load mmc 0:2"

#setenv m4image "/home/root/gpt_capture.bin"

> setenv m4image_size 17000

> setenv loadm4image "${load_cmd} ${loadaddr} ${m4image}"

> setenv m4boot "${loadm4image}; cp.b ${loadaddr} 0x7e0000 ${m4image_size}; dcache flush; bootaux 0x7e0000"

> saveenv

> run m4boot

-----------------------------


c). Verdin i.MX8MM Cortex-M4 核心運(yùn)行后其調(diào)試串口打印信息

-----------------------------

GPT input capture example


Once the input signal is received the input capture half peroid is printed

-----------------------------


d). 此時在Verdin i.MX8MP 平臺通過如下腳本使能 1kHz 50% 占空比 PWM 輸出 10s 時間

-----------------------------

#!/bin/sh

cd /sys/class/pwm/pwmchip0/

echo 0 > export

echo 1000000 > pwm0/period

echo 500000 > pwm0/duty_cycle

echo "normal" > pwm0/polarity

echo 1 > pwm0/enable

sleep 10

echo 0 > pwm0/enable

-----------------------------


e). 這時Verdin i.MX8MM Cortex-M4 調(diào)試串口就會打印出對應(yīng)的半波周期

-----------------------------

...

Input Capture Half Period Value = 0ms and 500us


Input Capture Half Period Value = 0ms and 500us


Input Capture Half Period Value = 0ms and 500us


Input Capture Half Period Value = 0ms and 500us

...

-----------------------------


f). 嘗試將Verdin i.MX8MP PWM 修改為 10kHz 80%/20% 占空比

-----------------------------

...

echo 100000 > pwm0/period

echo 80000 > pwm0/duty_cycle

...

-----------------------------


g). Verdin i.MX8MM Cortex-M4 輸出周期會對應(yīng)變化

-----------------------------

Input Capture Half Period Value = 0ms and 80us


Input Capture Half Period Value = 0ms and 80us


Input Capture Half Period Value = 0ms and 80us


Input Capture Half Period Value = 0ms and 80us

-----------------------------


h). 最后黄伊,由于Verdin i.MX8MM GPT1 CAPTURE1 管腳在 Cortex-A53 核心 Linux 下默認(rèn)是用于 WAKEUP GPIO 使用,如果需要同時運(yùn)行 Verdin i.MX8MM Cortex-A53 核心和 Cortex-M4 核心派殷,就需要在 Linux device-tree 文件中將 WAKEUP gpio-key 功能替換為其他 GPIO 管腳資源还最。

https://git.toradex.cn/cgit/linux-toradex.git/tree/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi?h=toradex_5.15-2.2.x-imx#n40?



6). 總結(jié)

本文簡單示例了基于i.MX8MM?Cortex-M4 核心GPT Capture 功能供參考墓阀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市拓轻,隨后出現(xiàn)的幾起案子斯撮,更是在濱河造成了極大的恐慌,老刑警劉巖扶叉,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件勿锅,死亡現(xiàn)場離奇詭異,居然都是意外死亡枣氧,警方通過查閱死者的電腦和手機(jī)溢十,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來达吞,“玉大人张弛,你說我怎么就攤上這事±医伲” “怎么了吞鸭?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長覆糟。 經(jīng)常有香客問我刻剥,道長,這世上最難降的妖魔是什么搪桂? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任透敌,我火速辦了婚禮,結(jié)果婚禮上踢械,老公的妹妹穿的比我還像新娘酗电。我一直安慰自己,他們只是感情好内列,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布撵术。 她就那樣靜靜地躺著,像睡著了一般话瞧。 火紅的嫁衣襯著肌膚如雪嫩与。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天交排,我揣著相機(jī)與錄音划滋,去河邊找鬼。 笑死埃篓,一個胖子當(dāng)著我的面吹牛处坪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼同窘,長吁一口氣:“原來是場噩夢啊……” “哼玄帕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起想邦,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤裤纹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后丧没,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鹰椒,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年骂铁,在試婚紗的時候發(fā)現(xiàn)自己被綠了吹零。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罩抗。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡拉庵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出套蒂,到底是詐尸還是另有隱情钞支,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布操刀,位于F島的核電站烁挟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏骨坑。R本人自食惡果不足惜撼嗓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望欢唾。 院中可真熱鬧且警,春花似錦、人聲如沸礁遣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽祟霍。三九已至杏头,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沸呐,已是汗流浹背醇王。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留崭添,地道東北人寓娩。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親根暑。 傳聞我的和親對象是個殘疾皇子力试,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容