This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

按键值的问题。

Other Parts Discussed in Thread: CC2540

你好,Yan

    求解一个问题,就是按键值都是单字节,我跟踪发现static uint8 skKeyPressed = 0,不能改成双字节。keyfobapp_HandleKeys的SK_SetParameter( SK_KEY_ATTR, sizeof ( uint8 ), &SK_Keys ); 确定了每按一次键,只能是1个字节的键值。我想按一次产生双字节键值,怎么办?还有sk_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr, uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen )中读两个字节     case SK_KEYPRESSED_UUID:
        *pLen = 2;            
         pValue[0] = *pAttr->pValue;  
         pValue[1] ????如何表示,
        break;

谢了。万分感谢!!!!

  • lincoln,

    SK_SetParameter( SK_KEY_ATTR, 2, &SK_Keys ); 表示可以发送两个字节。

    读两个字节, pValue[1]  =  *(pAttr->pValue+1);

    读两个字节的前提是,你必须修改simplekeys.c中skKeyPressed的定义,改成两字节的数组,同时修改 simplekeysAttrTbl[] 中的skKeyPressed 引用,去掉“&”

    最后,如果编译有错,请对应的一一修改。

  • 谢了,yan。按你的要求做了如下改动,能编译通过。

    1)SK_SetParameter( SK_KEY_ATTR, sizeof ( uint8 ), &SK_Keys );
            *skKeyPressed = *((uint8*)pValue);    
            // See if Notification/Indication has been enabled
           GATTServApp_ProcessCharCfg( skConfig, skKeyPressed, FALSE,
                                       simplekeysAttrTbl, GATT_NUM_ATTRS( simplekeysAttrTbl ),
                                       INVALID_TASK_ID );

    2)static uint8 sk_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen )
          case SK_KEYPRESSED_UUID:
            *pLen = 2;        
            pValue[0] = *pAttr->pValue;         
            pValue[1] = *(pAttr->pValue+1);

    改成数组了,编译ok,结果跟uint16定义一样也只得到1个字节内容是对的。另一个00或FF。也没得到。

    可能哪里还有问题。

    还有几个问题请教:

    1)
    GATTServApp_ReadCharCfg(0, skConfig);//handle为0,是否只是单机相连接才有效。
    GATT_Notification(0, &noti, FALSE);//handle为0,是否只是单机相连接才有效。

    static uint16 gapConnHandle;

    GATTServApp_ReadCharCfg(gapConnHandle, skConfig);

    GATT_Notification(gapConnHandle, &noti, FALSE);
    GAPRole_GetParameter( GAPROLE_CONNHANDLE, &gapConnHandle );//gapConnHandle是否是通过这个函数取得

    2)

    我用packet sniffer抓包,把广播单独设成37,38,39频道还是抓不到包。(按你讲设置数值1,2,4等)
    clock mulitiplier 为1.0是否要修改。
    connect to initiator address:设置成被抓包地址,dongle地址

    怎能都只是广告包,数据包抓不到,是否可能还有其它什么原因。

    万分感谢!

    祝好!

    Lincoln

  • yan,你好,*skKeyPressed = *((uint8*)pValue);   >>>用osalmemcpy函数能得到2个正确字节了。按键值,在keyfobapp_handlekeys函数得到了。弹起时的键值在哪个函数能得到。其它几个问题也帮我回下。谢了。

    lincoln

  • yan,你好,还一个问题,就是用lightblue测试,总能发现第一个16byte的service uuid。但程序中好象找不到,不知是哪里来的。谢了。

    祝好

    lincoln

  • Yan,你好!

            帮我一下,除了前面的一太堆问题,还有几个问题:

    1)如果自己单独定义service uuid,charateristic uuid,是否要写_readattrcb(****),_writeattrcb(****),还要写其它什么函数吗?

    2)我用lightblue能看到manufacturer data,这个是干什么的。

    万分感谢。

    祝好

    lincoln

  • hi lincon,

    1, handle 为0,的确是单连接状态。作为slave,目前也不会有多连接状态。如果作为master的话,连接上多个slave之后,这个数字就会累加。

    connection handle可以通过GAPRole_GetParameter( GAPROLE_CONNHANDLE, &gapConnHandle );得到。

    2.clock multiplier不需要改,代码里面改成37, 38, 或39之后,packet sniffer里面也要设置成相应的频道。

  • 好的,谢了。

       1) 是按你讲的在代码与sniffer同时设置的,还是抓不着。不知什么原因,难道很难抓吗?

       2)按你所讲,GATTServApp_ProcessCharCfg与GATT_Notification 的区别,GATTServApp_ProcessCharCfg最终会导致master那边调用一个read请求, 然后调用到keyfob这边的sk_ReadAttrCB()。GATT_Notification判断Notification 打开就发给master。我用btool测试,uuid找到handle,加1,在下面写入01:00,抓到的数据是对的。如果不写。好像GATT_Notification也没反应。

      3)如果直接跟app通讯。我们这边用GATTServApp_ProcessCharCfg与GATT_Notification 。我们在keyfob这边如何知道app那边是否打开notification了。是在sk_writeAttrCB()回调函数中拦截吗?在keyfob这边有什么办法确认在与手机app通讯后,手机那端notification是打开的。因为app是另一家公司写。我现在这边按你的方式送给它的数据,用btool测试是对的。但跟手机app对不上。因此我想从我这边来判断。

    4)蓝牙协议栈1.3.2是否支持android4.3.

    谢了

    祝好

    lincoln


  • lincon,

    1, 很奇怪,我这样设置每次都是能抓到包的。

    2. 你说的没错,notification必须被使能之后才能起作用。

    3. BTool正常,说明你的代码是正确的。第三方的手机app, 对方并不确定你的notification使能的handle的位置,因此应该无法使能你的notification.  你可以在writeAttrCB()中进行拦截判断是否notification的使能请求被收到。

  • 谢了,yan

         确认是app没使能notification,我们有什么办法设置成它需要的handle。

    谢谢。

    祝好

    lincoln

  • 你好,yan

         GATTServApp_ProcessCharCfg 最终会导致master那边调用一个read请求, 然后调用sk_ReadAttrCB()。它是靠performperiodicktask()这个函数还是靠sk_writeAttrCB()来处理master的read请求?

    谢了。

    祝好

    lincoln

  • lincoln,

    你需要修改app的代码,能手动修改Handle或者自动搜索到相应handle,进行修改。

  • lincoln,

    GATTServApp_ProcessCharCfg ()是靠 sk_ReadAttrCB()来处理。

  • 谢了,yan 

        客户想做些功能要求,比如通过读rssi调距离报警开关控制,断开后一直报警或不报警开关控制,按键取消报警开关控制,app那边进行这些设置。我这边想单独用定义service uuid,charateristic uuid来完成这些要求,但不知要写那些相关函数,才能与app那边通讯。是否有类似的例程。

    谢谢

    祝好

    lincoln

  • 你好,yan

           app那边没办法stop notify可能是固件这边什么原因。谢了

    祝好

    lincoln

  • 你好,yan。

          客户要求按键时间长短不同,做不同功能要求。我用定时器来判断时间,如下:

    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))    /* Key is active low */
      {
        keys |= HAL_KEY_SW_6;
      }

      if ((HAL_KEY_JOY_MOVE_PORT & HAL_KEY_JOY_MOVE_BIT))  /* Key is active HIGH */
      {
        keys = halGetJoyKeyInput();
      }
    #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;
        InitT4();//add
        }
      }

      /* 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);
      }
    }

    //add

    int  PRESS_KEY_TIME=0

    void InitT4()
    {

     T4CTL &= ~0x10;             // 起止控制位 先停中断,假如开
     T4CTL |= 0x08 ; //开溢出中断
     T4IE = 1; //开总中断和 T4中断
     T4CTL|=0XE0; //128 分频,128/16000000*N=0.5S,N=65200
     T4CTL &= ~0X03; //自动重装 00->0xff 65200/256=254(次)
     T4CTL |=0X10; //启动
     EA = 1; //开总中断
    }

    #pragma vector = T4_VECTOR //定时器 T4
    __interrupt void T4_ISR(void)
    {
      IRCON = 0x00; //清中断标志, 也可由硬件自动完成
    if(++count>254) //254 次中断后,约为 0.5 秒
    {
      count = 0; // 计数清零
      PRESS_KEY_TIME++;
    }
    }//0.5s

    void OnBoard_KeyCallback ( uint8 keys, uint8 state )
    {
      uint8 shift;
      (void)state;

      // shift key (S1) is used to generate key interrupt
      // applications should not use S1 when key interrupt is enabled
      shift = (OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE) ? false : ((keys & HAL_KEY_SW_6) ? true : false);

      if ( OnBoard_SendKeys( keys, shift ) != SUCCESS )
      {
        // Process SW1 here
        if ( keys & HAL_KEY_SW_1 )  // Switch 1
        {
        }
        // Process SW2 here
        if ( keys & HAL_KEY_SW_2 )  // Switch 2
        {
        }
        // Process SW3 here
        if ( keys & HAL_KEY_SW_3 )  // Switch 3
        {
        }
        // Process SW4 here
        if ( keys & HAL_KEY_SW_4 )  // Switch 4
        {
        }
        // Process SW5 here
        if ( keys & HAL_KEY_SW_5 )  // Switch 5
        {
        }
        // Process SW6 here
        if ( keys & HAL_KEY_SW_6 )  // Switch 6
        {
        }
      }

      /* If any key is currently pressed down and interrupt
         is still enabled, disable interrupt and switch to polling */
      if( keys != 0 )
      {
        if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE )
        {
          OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;
          HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
        }
      }
      /* If no key is currently pressed down and interrupt/
         is disabled, enable interrupt and turn off polling */
      else
      {
        if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_DISABLE )
        {
          OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;
          HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
        }
    //add
            T4CTL &= 0xf7;//if need to close interrupt
            T4CTL &= ~0x10;     
            T4IE = 0;
            EA = 0;
     
      }
    }

    帮我看下,我追踪PRESS_KEY_TIME变量,发现没变化。那就是中断没起作用。

    我担心定时器耗电,我在按键弹起来时,关掉中断,不知是否正确。

    谢了

    祝好

    lincoln

  • lincoln,

    TI提供了Android 和iOS 端的源码提供参考,是基于sensortag的,对你来说是非常好的参考,但是没有你要求的那么具体的需求,你说的功能应该是都能实现的,但是需要你做些工作。