一.介紹
本文介紹如何配置 GINT (GPIO Input Interrupt) 配置,SDK 提供的範例為 Falling Edge Trigger,當使用省電模式 Low Power mode 時僅有 GINT 可用於喚醒,有時需要 both edge 觸發,本文補充說明如何配置 both edge。
二.GINT 功能簡介
LPC55S GINT 有五大特性
l 可以使用任意數量的 GPIO Pin 以 Group 為單位成一個中斷
l 以 Group 為單位組配置為 High/Rising 或 Low/falling 觸發
l Enable 的中斷可以透過 AND/OR 運算組合
l 二個 Group 中斷可配置為不同的中斷行為
l GINT 可喚醒 sleep, deep-sleep, power down 等省電模式
從特性第一點來看,只要是 GPIO 皆可以配置為 GINT,在使用上提供許多便利,在 LPC55S1x 提供二組 GPIO,在使用上提供了一定的便利性。
三.目標
l 配置 Port 0 Pin 5 為 Falling trigger,Port 1 Pin 18 & 9 及 Port 0 Pin5 為 Rising trigger
NXP SDK 提供的關於 GINT 範例範例當中 Pin 特性的配置如下所示
/* Setup GINT0 for edge trigger, "OR" mode */
GINT_SetCtrl(GINT0, kGINT_CombineOr, kGINT_TrigEdge, gint0_callback);
/* Setup GINT1 for edge trigger, "AND" mode */
#if defined(FSL_FEATURE_SOC_GINT_COUNT) && (FSL_FEATURE_SOC_GINT_COUNT > 1)
GINT_SetCtrl(GINT1, kGINT_CombineAnd, kGINT_TrigEdge, gint1_callback);
#endif
/* Select pins & polarity for GINT0 */
GINT_ConfigPins(GINT0, DEMO_GINT0_PORT, DEMO_GINT0_POL_MASK, DEMO_GINT0_ENA_MASK);
/* Select pins & polarity for GINT1 */
#if defined(FSL_FEATURE_SOC_GINT_COUNT) && (FSL_FEATURE_SOC_GINT_COUNT > 1)
GINT_ConfigPins(GINT1, DEMO_GINT1_PORT, DEMO_GINT1_POL_MASK, DEMO_GINT1_ENA_MASK);
#endif
從配置上可以看到透過 GINT_SetCtrl 配置 kGINT_TrigEdge模式,那 kGINT_TrigEdge 到底是 rising 還是 falling ?
從下一個 API 命令 GINT_ConfigPins 的註解可以看到此 API 是配置 polarity,API當中有三個參數 DEMO_GINT0_PORT, DEMO_GINT0_POL_MASK, DEMO_GINT0_ENA_MASK,從命名規則上可以看到分別代表 GINT1 Port,POL,ENA
從 define 上可以確認相關的參數名稱,當中可以看到當需要配置 low/falling 時需要將暫存器 POL 對應的 Pin 配置為 0 ,比如 Pin 5 則是 bit 5並將對應的 ENA 對應的 bit 配置為 1 啟動該 Pin。
/*******************************************************************************
* Definitions
******************************************************************************/
#define DEMO_GINT0_PORT kGINT_Port0
#define DEMO_GINT1_PORT kGINT_Port1
/* Select one input, active low for GINT0 */
#define DEMO_GINT0_POL_MASK ~(1U << BOARD_SW1_GPIO_PIN)
#define DEMO_GINT0_ENA_MASK (1U << BOARD_SW1_GPIO_PIN)
/* Select two inputs, active low for GINT1. SW2 & SW3 must be connected to the same port */
#define DEMO_GINT1_POL_MASK ~((1U << BOARD_SW2_GPIO_PIN) | (1U << BOARD_SW3_GPIO_PIN))
#define DEMO_GINT1_ENA_MASK ((1U << BOARD_SW2_GPIO_PIN) | (1U << BOARD_SW3_GPIO_PIN))
從 SDK 範例來看僅有配置 Falling 配置,如果需要配置 both edge trigger 該如何配置?
筆者在此就陷入一個誤區,以為 kGINT_Port0 是 GINT 的 Port 配置,實際上此處的 Port 指的是 GPIO 的 Port。
將範例的 SDK 調整一下如下測試,在原本 GINT1 配置調整為 Rising 及新增配置 SW4 多偵測 Rising
/* Select two inputs, active low for GINT1. SW1 & SW3 must be connected to the same port */
#define DEMO_GINT1_POL_MASK ((1U << BOARD_SW1_GPIO_PIN) | (1U << BOARD_SW3_GPIO_PIN))
…
#if defined(FSL_FEATURE_SOC_GINT_COUNT) && (FSL_FEATURE_SOC_GINT_COUNT > 1)
GINT_ConfigPins(GINT1, DEMO_GINT1_PORT, DEMO_GINT1_POL_MASK, DEMO_GINT1_ENA_MASK);
//added
GINT_ConfigPins(GINT1, kGINT_Port0, (1U << BOARD_SW4_GPIO_PIN), DEMO_GINT0_ENA_MASK);
#endif
實際測試單獨按按壓 EVK 上 SW4 , SW1 , SW3 無法看到觸發中斷,但將前述三個按鈕同時按壓的情況下卻可以正確觸發 Rising
做個測試將 GINT1 改為 kGINT_CombineAnd ,如下所示
GINT_SetCtrl(GINT1, kGINT_CombineAnd, kGINT_TrigEdge, gint1_callback);
運行後,每個中斷觸發就可以單獨觸發!!!
這點有點反直覺,以 SDK 範例預設的狀態 kGINT_CombineAnd 應該是所有配置的 pin 符合配置的觸發後以 AND 運算所有 Pin 符合則觸發中斷,以現在的觸發的狀態,似乎與 And 運算不同,分析一下原因!!
先確認 EVK 上的硬體電路的設計!
從硬體電路來看,所有硬體設計通常狀態均配置為 Pull High,也就是當按鈕按下時該 Pin 電壓為 Low,放開時為 High。
再將對應的電氣狀態及觸發整理成表形式,灰底的部分代表電器特性狀態,當 1 時為 High,如下所示
COMB |
POL |
SW2 |
SW3 |
SW4 |
Result |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 | ||
0 |
1 |
0 |
0 | ||
1 |
0 |
0 |
0 | ||
1 |
1 |
0 |
0 | ||
1 |
0 |
1 |
0 | ||
0 |
1 |
1 |
0 | ||
1 |
1 |
1 |
1 | ||
| |||||
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 | ||
0 |
1 |
0 |
1 | ||
1 |
0 |
0 |
1 | ||
1 |
1 |
0 |
0 | ||
1 |
0 |
1 |
0 | ||
0 |
1 |
1 |
0 | ||
1 |
1 |
1 |
0 |
從上表來看似乎 COMB 配置為影響,不是想像中 AND 及 OR 運算,這點與 API 參數名稱不符。
關於此點在 NXP論壇有討論,官方有提出解答如下圖,如此一來再比對測試結果,就可以確認實際 AND 及 OR 取決於暫存器 COMB 及暫存器 POL 組合
結論!
1. 當使用 GINT 時須注意外部電路設計是否與配置搭配
2. COMB 及 POL 組合實際影響 GINT 中斷觸發運作邏輯
四.參考文獻
l NXP Community