【CC2541】CC2541之HAL层KEY分析
来源:互联网 发布:美国本科预科 知乎 编辑:程序博客网 时间:2024/05/21 11:28
在CC2541BLE协议栈中,KEY测试是由HAL层来进行抽象和管理的。关于按键的的测试代码和配置主要集中在hal_drivers.c 、hal_drivers.h 、hal_key.c、hal_key.h、hal_board_cfg.h、Onboard.c几个文件中。
初始化:
main
函数HAL层的KEY
初始化主要是调用HalDriverInit();
和InitBoard( OB_READY );
,代码如下:int main(void){ /* Initialize hardware */ HAL_BOARD_INIT(); // Initialize board I/O InitBoard( OB_COLD ); /* Initialze the HAL driver */ HalDriverInit(); // Final board initialization InitBoard( OB_READY ); /* Initialize NV system */ osal_snv_init(); /*Initialize LL*/ /* Initialize the operating system x*/ osal_init_system(); /* Enable interrupts */ HAL_ENABLE_INTERRUPTS(); // Final board initialization InitBoard( OB_READY ); #if defined ( POWER_SAVING ) osal_pwrmgr_device( PWRMGR_BATTERY ); #if defined (WDT_USED) WD_INIT(); #endif /* Start OSAL */ osal_start_system(); // No Return from here return 0;}
hal_drivers.c中HalDriverInit()
定义如下,其中调用HalKeyInit();
进行按键的初始化处理,代码如下:
void HalDriverInit (void){ /* TIMER */#if (defined HAL_TIMER) && (HAL_TIMER == TRUE)#endif /* ADC */#if (defined HAL_ADC) && (HAL_ADC == TRUE) HalAdcInit();#endif /* DMA */#if (defined HAL_DMA) && (HAL_DMA == TRUE) // Must be called before the init call to any module that uses DMA. HalDmaInit();#endif /* AES */#if (defined HAL_AES) && (HAL_AES == TRUE) HalAesInit();#endif /* LCD */#if (defined HAL_LCD) && (HAL_LCD == TRUE) HalLcdInit();#endif /* LED */#if (defined HAL_LED) && (HAL_LED == TRUE) HalLedInit();#endif /* UART */#if (defined HAL_UART) && (HAL_UART == TRUE) HalUARTInit();#endif /* KEY */#if (defined HAL_KEY) && (HAL_KEY == TRUE) HalKeyInit();#endif /* HID */#if (defined HAL_HID) && (HAL_HID == TRUE) usbHidInit();#endif#if (defined HAL_BAT) && (HAL_BAT == TRUE) //HalBatteryInit();#endif}
hal_key.c中的HalKeyInit( void )
定义如下:
变量说明:
halKeySavedKeys
:在轮训模式下用于保存上次按键的状态。pHalKeyProcessFunction
:用于回调处理的函数指针。初始化时,指向为NULL
,其结构如下:- 定义:
static halKeyCBack_t pHalKeyProcessFunction;
- 类型:
typedef void (*halKeyCBack_t) (uint8 keys, uint8 state);
- 定义:
HalKeyConfigured
:按键配置参数,初始化为FALSE
。
void HalKeyInit( void ){ halKeySavedKeys = 0; // Initialize previous key to 0. #if defined ( CC2540_MINIDK ) HAL_KEY_SW_1_SEL &= ~(HAL_KEY_SW_1_BIT); /* Set pin function to GPIO */ HAL_KEY_SW_1_DIR &= ~(HAL_KEY_SW_1_BIT); /* Set pin direction to Input */ HAL_KEY_SW_2_SEL &= ~(HAL_KEY_SW_2_BIT); /* Set pin function to GPIO */ HAL_KEY_SW_2_DIR &= ~(HAL_KEY_SW_2_BIT); /* Set pin direction to Input */ #else HAL_KEY_SW_6_SEL &= ~(HAL_KEY_SW_6_BIT); /* Set pin function to GPIO */ HAL_KEY_SW_6_DIR &= ~(HAL_KEY_SW_6_BIT); /* Set pin direction to Input */ HAL_KEY_SW_7_SEL &= ~(HAL_KEY_SW_7_BIT); /* Set pin function to GPIO*/ HAL_KEY_SW_7_DIR &= ~(HAL_KEY_SW_7_BIT); /* Set pin direction to Input*/ #endif #endif /* Initialize callback function */ pHalKeyProcessFunction = NULL; /* Start with key is not configured */ HalKeyConfigured = FALSE;}
在OnBoard.c中:InitBoard(uint8 level)
函数中选择了按键的触发方式(中断方式、非中断方式);HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
配置按键服务,传入参数包括中断的是否使能参数以及回调函数。代码如下:
变量说明: OnboardKeyIntEnable
:按键中断的方式的使能开关。赋值HAL_KEY_INTERRUPT_DISABLE
非中断方式(即轮训的方式),赋值HAL_KEY_INTERRUPT_ENABLE
中断方式。
void InitBoard( uint8 level ){ if ( level == OB_COLD ) { osal_int_disable( INTS_ALL ); HalLedSet( HAL_LED_ALL, HAL_LED_MODE_OFF ); } else//!OB_COLD { OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE; HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback); }}
在hal_key.c中的HalKeyConfig (bool interruptEnable, halKeyCBack_t cback)
用于传入按键方式参数(中断方式或者非中断方式),以及传入回调函数。
变量说明: Hal_KeyIntEnable
:用于记录按键的的方式(中断方式和非中断方式)。 pHalKeyProcessFunction
:指向回调函数,上述已经有提到。
void HalKeyConfig (bool interruptEnable, halKeyCBack_t cback){ /* Enable/Disable Interrupt or */ Hal_KeyIntEnable = interruptEnable; /* Register the callback fucntion */ pHalKeyProcessFunction = cback; /* Determine if interrupt is enable or not */ if (Hal_KeyIntEnable) { #if defined ( CC2540_MINIDK ) /* Rising/Falling edge configuratinn */ PICTL |= HAL_KEY_SW_1_EDGEBIT; /* Set the edge bit to set falling edge to give int */ HAL_KEY_SW_1_ICTL |= HAL_KEY_SW_1_ICTLBIT; /* enable interrupt generation at port */ HAL_KEY_SW_1_IEN |= HAL_KEY_SW_1_IENBIT; /* enable CPU interrupt */ HAL_KEY_SW_1_PXIFG = ~(HAL_KEY_SW_1_BIT); /* Clear any pending interrupt */ HAL_KEY_SW_2_ICTL |= HAL_KEY_SW_2_ICTLBIT; /* enable interrupt generation at port */ HAL_KEY_SW_2_IEN |= HAL_KEY_SW_2_IENBIT; /* enable CPU interrupt */ HAL_KEY_SW_2_PXIFG = ~(HAL_KEY_SW_2_BIT); /* Clear any pending interrupt */ #else /* ************************* * Interrupt configuration: * - Enable interrupt generation at the port * - Enable CPU interrupt * - Clear any pending interrupt ***************************/ HAL_KEY_SW_6_ICTL |= HAL_KEY_SW_6_ICTLBIT;//Port0_1 HAL_KEY_SW_6_PXIFG = ~(HAL_KEY_SW_6_BIT); //flag BV(1) HAL_KEY_SW_7_ICTL |= HAL_KEY_SW_7_ICTLBIT;//Port1_0 HAL_KEY_SW_7_PXIFG = ~(HAL_KEY_SW_7_BIT); //flag BV(0); #endif // !CC2540_MINIDK /* Do this only after the hal_key is configured - to work with sleep stuff */ if (HalKeyConfigured == TRUE) { osal_stop_timerEx(Hal_TaskID, HAL_KEY_EVENT); /* Cancel polling if active */ } } else /* Interrupts NOT enabled */ { #if defined ( CC2540_MINIDK ) HAL_KEY_SW_1_ICTL &= ~(HAL_KEY_SW_1_ICTLBIT); /* don't generate interrupt */ HAL_KEY_SW_1_IEN &= ~(HAL_KEY_SW_1_IENBIT); /* Clear interrupt enable bit */ HAL_KEY_SW_2_ICTL &= ~(HAL_KEY_SW_2_ICTLBIT); /* don't generate interrupt */ HAL_KEY_SW_2_IEN &= ~(HAL_KEY_SW_2_IENBIT); /* Clear interrupt enable bit */ #else //HAL_KEY_SW_6_ICTL &= ~(HAL_KEY_SW_6_ICTLBIT); /* don't generate interrupt */ //HAL_KEY_SW_6_IEN &= ~(HAL_KEY_SW_6_IENBIT); /* Clear interrupt enable bit */ //HAL_KEY_SW_BIT_ICTL &= ~HAL_KEY_SW_ICTLBIT; #endif // !CC2540_MINIDK osal_set_event(Hal_TaskID, HAL_KEY_EVENT); } /* Key now is configured */ HalKeyConfigured = TRUE;}
按键触发的处理:
hal_key.c中断处理函数halProcessKeyInterrupt (void)
,如果按键触发了函数中会触发HAL_KEY_EVENT
的任务的处理:
void halProcessKeyInterrupt (void){ bool valid=FALSE;#if defined ( CC2540_MINIDK ) if( HAL_KEY_SW_1_PXIFG & HAL_KEY_SW_1_BIT) /* Interrupt Flag has been set by SW1 */ { HAL_KEY_SW_1_PXIFG = ~(HAL_KEY_SW_1_BIT); /* Clear Interrupt Flag */ valid = TRUE; } if (HAL_KEY_SW_2_PXIFG & HAL_KEY_SW_2_BIT) /* Interrupt Flag has been set by SW2 */ { HAL_KEY_SW_2_PXIFG = ~(HAL_KEY_SW_2_BIT); /* Clear Interrupt Flag */ valid = TRUE; }#else if(HAL_KEY_SW_6_PXIFG&HAL_KEY_SW_6_BIT) { HAL_KEY_SW_6_PXIFG = ~(HAL_KEY_SW_6_BIT); /*Clear Interrupt Flag */ valid = TRUE; } if(HAL_KEY_SW_7_PXIFG&HAL_KEY_SW_7_BIT) { HAL_KEY_SW_7_PXIFG = ~(HAL_KEY_SW_7_BIT); /*Clear Interrupt Flag*/ valid = TRUE; }#endif //ev_queue_event(EV_KEY_1_PRESS);//this section is removed by tony 20160617 if (valid) { osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE);//25ms }}
hal_drivers.c中关于HAL_KEY_EVENT
任务的处理:
if (events & HAL_KEY_EVENT) { #if (defined HAL_KEY) && (HAL_KEY == TRUE) /* Check for keys */ HalKeyPoll(); /* if interrupt disabled, do next polling */ #if 1 if (!Hal_KeyIntEnable) { // if(lcd_sleep_flag == 1) { osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, 200); } } #endif #endif return events ^ HAL_KEY_EVENT; }
hal_key.c
void HalKeyPoll (void){ uint8 keys = 0; uint8 notify = 0;#if defined (CC2540_MINIDK) if (!(HAL_KEY_SW_1_PORT & HAL_KEY_SW_1_BIT)) /* Key is active low */ { keys |= HAL_KEY_SW_1; } if (!(HAL_KEY_SW_2_PORT & HAL_KEY_SW_2_BIT)) /* Key is active low */ { keys |= HAL_KEY_SW_2; }#else if(!(HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT)){ keys |= HAL_KEY_1; } if(!(HAL_KEY_SW_7_PORT&HAL_KEY_SW_7_BIT)){ keys |= HAL_KEY_2; } //keys = read_adc_key_value();#endif /* If interrupts are not enabled, previous key status and current key status * are compared to find out if a key has changed status. */ if (!Hal_KeyIntEnable) { if (keys == halKeySavedKeys){ /* Exit - since no keys have changed */ return; }else{ notify = 1; } } else { /* Key interrupt handled here */ if (keys){ notify = 1; } } /* Store the current keys for comparation next time */ halKeySavedKeys = keys; /* Invoke Callback if new keys were depressed */ if (notify && (pHalKeyProcessFunction)) { (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL); }}
- 【CC2541】CC2541之HAL层KEY分析
- CC2541之SimpleBLEPeripheral程序流程分析 -- 02.App层初始化
- CC2541之SimpleBLEPeripheral程序流程分析 -- 03.App层事务处理
- CC2541
- 【BLE】-CC2541 HAL层控制LED的实验
- CC2540/CC2541/CC254x之硬件抽象层
- 【BLE】CC2541之notify
- 【BLE】CC2541之按键
- 【BLE】CC2541之RSSI
- 【BLE】CC2541之OLED
- 【BLE】CC2541之indicate
- 【BLE】CC2541之timer3
- 【BLE】CC2541之看门狗
- 【BLE】CC2541之SNV
- 【BLE】CC2541之OAD
- 【BLE】CC2541之PWM
- 【BLE】CC2541之OAD
- 【BLE】CC2541之BTool
- 【项目管理和构建】—— Maven简介(一)
- ios 图片处理( 1.按比例缩放 2.指定宽度按比例缩放)
- 广播包里加MAC地址
- Redis的基本操作
- ubuntu设置root密码及 Xftp连接linux(ubuntu)时提示ssh服务器拒绝了密码,请再试一次
- 【CC2541】CC2541之HAL层KEY分析
- 【整理】Android-Recovery Mode(recover模式详解)
- Javaweb
- C++中static用法总结
- 最简单的基于FFmpeg的视频编码器-更新版(YUV编码为HEVC(H.265))
- opencv2,找轮廓,用周长筛选
- 2016年的年终总结吧
- SQL查询、排序(mysql下)
- P2P打洞原理