5 Replies Latest reply on Mar 3, 2020 6:42 AM by PY_21

    strange CyBle_GattsNotification behaviour

    maze_1672671

      Hello all,

       

      My code sends a command to a cyble-214015-1 writing a characteristic and then waits for a notification on the same char

       

      mtu is 70 bytes and notify is 3 bytes: 32 2E 9B

       

      Sometimes it works but sometimes it fails: after a timeout of 5 s I pause psoc creator 4.2 and I find this:

       

      notify.png

       

      The timeout happens on my pc because the command is not syncronized with events, but I receive EVT_CONNECTION_TERMINATED_NOTIFICATION from cy5677, that is CYBLE_EVT_GAP_DEVICE_DISCONNECTED.

       

      The device seems stucked

       

      The function that sends the notification is:

       

      void BLE_notify(uint16_t h, void * v, uint16_t lenght)

      {

          if (connesso) {

              CYBLE_GATTS_HANDLE_VALUE_NTF_T hvntf = {

                  .attrHandle = h

              } ;

              uint8_t * dati = (uint8_t *) v ;

       

              while (lenght) {

                  if (CYBLE_STACK_STATE_BUSY == CyBle_GattGetBusyStatus()) {

                      CyBle_ProcessEvents() ;

                      continue ;

                  }

       

                  uint16_t dim = lenght ;

                  if (dim > mtu-3)

                      dim = mtu-3 ;

       

                  hvntf.value.len = dim ;

                  hvntf.value.val = dati ;

       

                  CYBLE_API_RESULT_T ris = CyBle_GattsNotification(cyBle_connHandle, &hvntf) ;

       

                  CyBle_ProcessEvents() ;

       

                  switch (ris) {

                  case CYBLE_ERROR_OK:

                      DBG_PRINT_HEX("notif ", dati, dim) ;

                      lenght -= dim ;

                      dati += dim ;

                      break ;

       

                  case CYBLE_ERROR_MEMORY_ALLOCATION_FAILED:

                      // Bisogna aspettare che lo stack spedisca i dati

                      CyBle_ProcessEvents() ;

                      break ;

       

                  default:

                      // ??? esco

                      DBG_PRINTF("ERR %s %d ris = 0x%04X\n", __FILE__, __LINE__, ris) ;

                      lenght = 0 ;

                      break ;

       

                  case CYBLE_ERROR_INVALID_PARAMETER:

                      // notifiche disabilitate

                      DBG_ERR ;

                      lenght = 0 ;

                      break ;

       

                  case CYBLE_ERROR_INVALID_OPERATION:

                      // Riprovo

                      DBG_ERR ;

                      CyBle_ProcessEvents() ;

                      break ;

                  }

              }

          }

          else {

              DBG_ERR ;

          }

      }

       

      What am I doing wrong?

        • 1. Re: strange CyBle_GattsNotification behaviour
          PY_21

          Hello,

           

          1. Please ensure that the BLE subsystem (BLESS) interrupt has the highest priority.
          2. CyBle_ProcessEvents() needs to be called at least once every interval 't' where 't' is equal to connection interval or advertisement interval, whichever is smaller, if the device is in GAP Peripheral mode of operation. If a custom function consumes more time for execution, please call CyBle_ProcessEvents inside it.

          3. Latest version of BLE component available is v3.63. Could you update the BLE component to latest version and test ? (In PSoC Creator, Goto 'Project' --> 'Update components').

           

          Thanks,

          P Yugandhar.

          • 2. Re: strange CyBle_GattsNotification behaviour
            maze_1672671

            Hello Yugandhar,

             

            thank you for your answer

             

            How can I fulfill (1)? Which function must I call ?

             

            Can I find macros with the times in (2)? That is, if I choose 1000 ms for my advertisement min time, can I find something like

            #define CYBLE_MIN_ADV     1000

             

            BLE_notify is kind of a "frankenstein": I collected info from various posts on the community and put them there. The function must cope with mtu when sending the advertisement. Is it correct?

            • 3. Re: strange CyBle_GattsNotification behaviour
              PY_21

              Hello,

               

              Q1) How can I fulfill (1)? Which function must I call ?
              Ans: In the project, Goto 'Design Wide Resources' --> click on 'Interrupts' -->Set 'BLE_bless_isr' priority to 0.

               

              Q2) Can I find macros with the times in (2)? That is, if I choose 1000 ms for my advertisement min time, can I find something like
              #define CYBLE_MIN_ADV    1000
              Ans: In BLE.h file, you can find the macros for Advertisement intervals (which was set in the BLE component) as shown in attached image.
              After the connection got established, central device will decide the connection parameters. The event 'CYBLE_EVT_GAP_DEVICE_CONNECTED' will be generated at the GAP Peripheral end after connection is completed. 'CYBLE_EVT_GAP_ENHANCE_CONN_COMPLETE' event will be triggered instead of 'CYBLE_EVT_GAP_DEVICE_CONNECTED', if Link Layer Privacy is enabled in component customizer. The event parameter of this events will give the current connection parameters.

               

              The amount of data that can be send/receive by the connected BLE devices depends on the negotiated MTU size. When you connect BLE device with the central device, negotiated GATT MTU will be Min of (MTU of client device, MTU of server device). The valid range for the negotiated MTU size for a Cypress BLE connection is from 23 to 512 bytes. Please check the negotiated MTU value during Exchange MTU procedure and update the Length of the value accordingly for sending the notification data.

               

              Please let me know if this helps. If you are still facing the issue, then please share your project so that we can check at our end.

               

              Thanks,
              P Yugandhar.

              • 4. Re: strange CyBle_GattsNotification behaviour
                maze_1672671

                Hello Yugandhar,

                 

                in the attachment you can find my project with a lot of disabled schematic pages, so that you can run it un a pioneer board (you should change ucol pins to direct logs to the pioneer serial port)

                 

                To reproduce the issue, you must write 03:00 to the Client Characteristic Configuration and then write 32:2B:33:39:33:34:37:35:31:31:31:30:34:39:F2:F0 to the related characteristic. cysmart receives a disconnect. When you pause the debugger you will find the call stack that I posted previously

                 

                You can breakpoint in scrivi_numtel (in config.c, it is invoked when you write the char). PRM_numtel_s writes to a user flash row and then AUT_risposta compose the response and calls BLE_notify, that calls  CyBle_GattsNotification that never returns

                 

                I put 0 to the ble isr priority but this does not risolve the issue

                 

                The last ble version that I see is 3.60. I can have a proxy problem, but I don't know how to change the proxy settings in PSoC Creator  4.2 (4.2.0.641)

                 

                Thank you very much for your help

                 

                Massimo

                • 5. Re: strange CyBle_GattsNotification behaviour
                  PY_21

                  Hello,

                   

                  If there is any continuous flash writes during the BLE connected state. This may result in processing of BLE events to be pending and can cause disconnection. So, please call the flash write only if the BLESS state is in CYBLE_BLESS_STATE_EVENT_CLOSE. Before doing any flash write, wait for 'CYBLE_BLESS_STATE_EVENT_CLOSE' state and then call as shown in below code.

                   

                  **********************************

                  while(CyBle_GetBleSsState()!=CYBLE_BLESS_STATE_EVENT_CLOSE)

                  {

                      DBG_PRINTF("\r\n waiting ");

                          }

                    if(CyBle_GetBleSsState()==CYBLE_BLESS_STATE_EVENT_CLOSE)

                      {

                          CySysSFlashWriteUserRow(uint32 rowNum, const uint8 rowData[]);    //calling SFlash write

                          }

                  **********************************

                   

                  Please refer to the below modified project. Please let me know if this helps.

                   

                  Thanks,

                  P Yugandhar.