Radio stops working after disable softdevice. No receiver interrupts.

nRF51822QFAC SDK v10 S130

In the completed project it was necessary to make an update. It is necessary to switch off the softdevice and switch to its own Rx protocol. After performing the standard shutdown procedure, Radio interrupts stop coming. All other interrupts work. If do not initialise the stack, Radio works. As far as I understand correctly, Radio interrupts are not forwarded to the application table.

BLE_disable() run without errors. How fix the problem? Without preliminary BLE connection it is not possible to accept parameters of next connection protocol.

void BLE_disable(void)
{  
  int error;
 
  //Stopping advertising
  if (is_advertising_active)
  {
    error = sd_ble_gap_adv_stop();
    APP_ERROR_CHECK(error);
    is_advertising_active = false;
  }
 
  //BLE_GAP_EVT_DISCONNECT should be waited for after the call. Disconnect
  if(connection_handle != BLE_CONN_HANDLE_INVALID)
  {
    // Disconnect  
    error = sd_ble_gap_disconnect(connection_handle,
                                  BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
    if (error != NRF_SUCCESS && error != BLE_ERROR_INVALID_CONN_HANDLE)
    {
      APP_ERROR_CHECK(error);
    }

    // Waiting for the disconnect event BLE_GAP_EVT_DISCONNECT
    for(int i = 0; i < 10; i++)
    {
      if(BLE_connected == false) break;

      // waiting for the tripping event to be triggered
      nrf_delay_ms(10);
    }
  }  
  
  //forward interrupt vectors to the application (it don`t help)
  //error = sd_softdevice_vector_table_base_set(0x1C000);
  //APP_ERROR_CHECK(error);
 
  //Deactivating SoftDevice
  error = softdevice_handler_sd_disable();
  APP_ERROR_CHECK(error);
 
  SoftDev_enabled = softdevice_handler_isEnabled();
}

//-----------

Debug here. If comment BLE_Peripheral_ini() the reception will work.

But if you switch the stack on and then switch it off, it's over. 

//Bluetooth radio ini
BLE_Peripheral_ini();

sleep(100);

BLE_disable();

RADIO_RxCustom_Ini();

Parents Reply Children
  • Timeslot API will not working here . Because the connection is established via a standard BLE dongle, where there is no access to code changes. So when switching to Timeslot another node breaks the connection. About of the vector table transfer. I stop all interrupts before transferring by the function sd_softdevice_vector_table_base_set(). Clear all pending ones. I check it visually in debugger in NVIC registers settings. Everything is restored as it was before using the stack. Then I reinitialise and enable the interrupts used in the program. All of them work fine except Radio. It doesn't come in.  Even running the stack once breaks the reception irrevocably.  

    error = softdevice_handler_sd_disable();
    APP_ERROR_CHECK(error); //no err
    
    SoftDev_enabled = softdevice_handler_isEnabled();
    
    //----
    NVIC_DisableIRQ(RADIO_IRQn);
    NVIC_ClearPendingIRQ(RADIO_IRQn);
    
    NVIC_DisableIRQ(TIMER0_IRQn);
    NVIC_ClearPendingIRQ(TIMER0_IRQn);
    
    NVIC_DisableIRQ(TIMER1_IRQn);
    NVIC_ClearPendingIRQ(TIMER1_IRQn);
    
    NVIC_DisableIRQ(TIMER2_IRQn);
    NVIC_ClearPendingIRQ(TIMER2_IRQn);
    
    NVIC_DisableIRQ(RTC0_IRQn);
    NVIC_ClearPendingIRQ(RTC0_IRQn);
    
    NVIC_DisableIRQ(RTC1_IRQn);
    NVIC_ClearPendingIRQ(RTC1_IRQn);
    
    NVIC_DisableIRQ(UART0_IRQn);
    NVIC_ClearPendingIRQ(UART0_IRQn);
    
    NVIC_DisableIRQ(SPI1_TWI1_IRQn);
    NVIC_ClearPendingIRQ(SPI1_TWI1_IRQn);
    
    NVIC_DisableIRQ(ADC_IRQn);
    NVIC_ClearPendingIRQ(ADC_IRQn);
    
    // NVIC->ICER[0] = 0xffffffff;
    
    error = sd_softdevice_vector_table_base_set(0x1C000);
    APP_ERROR_CHECK(error); //no error
    
    //then init application irq and run..

    Interrupts initially arrive at the beginning of the original vectors address in the memory begin. If there is no code there that throws them into the application's interrupt section, they will not arrive. I suspect that the interrupt transfer for Radio is defective. Or something corrupts the code that does the forwarding during stack shutdown.

    How can I view the integrity of the code for forwarding with the IAR disassembler debugger? Could you please tell me which code does it at which addresses?

    I tried disabling stack interrupts before shutting it down. But it causes softdevice_handler_sd_disable() execution error; This is a very strange way of doing it. And judging by the number of problems other people have with disabling it, it is done crookedly.

    Checked the projects you linked to as an example. There are no softdevice_handler_sd_disable() calls anywhere; Therefore, these examples are about other things and do not fit my case.

    Probably a tested example where a softdevice_handler_sd_disable() call is made will help me. And then the radio is re-initialised and it works after that.

  • Was this line an indication that the SoftDevice has been re-enabled at this point, or was it for some other use in your application?

    SoftDev_enabled = softdevice_handler_isEnabled();

    Have you tried running only softdevice_handler_init() or sd_softdevice_enable(), and then sd_softdevice_vector_table_base_set() to see if the interrupt forwarding works?

    sevstels said:
    Timeslot API will not working here . Because the connection is established via a standard BLE dongle, where there is no access to code changes.

    I am a little confused about this statement. Could you elaborate why Timeslot API does not work? It is used to implement multiprotocol co-existence in the nRF5 SDK. In your opening post, you wrote:

    It is necessary to switch off the softdevice and switch to its own Rx protocol.

    The timeslot API will let the application run a proprietary RX protocol. If BLE is not necessary, the application can simply turn off all BLE activities, and not worry about disabling the SoftDevice.

    Besides the example I linked, please also see the docs: Radio Timeslot API.

    sevstels said:
    How can I view the integrity of the code for forwarding with the IAR disassembler debugger? Could you please tell me which code does it at which addresses?

    Do you want to see the SoftDevice forwarding the interrupt? I am afraid debugging the SoftDevice is not possible, as it is proprietary, and we don't release source code or .elf files.

    I honestly am not very well versed at the very low-level interrupt and vector table handling topic and also not experienced with the IAR environment either. Thus, please overlook it if my questions were obvious.

  • >>I honestly am not very well versed at the very low-level interrupt and vector table handling topic and also not experienced with the IAR environment either. Thus, please overlook it if my questions were obvious.

    Hmm... sounds like a battle against common sense! So as not to waste your time. I'd like the advice of someone who knows how this works. Do you have any such experts? Thank you. I'm not asking because I want your secrets. I want this piece of *** to work right.

    >>Could you elaborate why Timeslot API does not work?

    We're not talking about yours API. We are saying that other companies' stacks do not support Timeslot. Therefore, it's useless. The second device we have is running on the TI stack. And it doesn't. It's not in the BLE standard at all.

    I get along fine without Timeslot using my own protocol. And I transmit synchro through a normal BLE channel. The only thing I need is that the Softdevice does not spoil the work of the radio when switched off. Make my job easier. Tell me the address where the forwarder is. And I'll give it a hard hack to make it work right.

  • I ran the case through a couple of people more knowledgeable. One tried to reproduce your issue but couldn't. Interrupts work as expected.

    sevstels said:
    We're not talking about yours API. We are saying that other companies' stacks do not support Timeslot. Therefore, it's useless. The second device we have is running on the TI stack. And it doesn't. It's not in the BLE standard at all.

    We are not sure you understand the Timeslot API correctly. It is just there to tell the application when the radio is free, so that the application can implement another protocol without radio-usage conflict with the SoftDevice.

    Therefore, if you disable all BLE functionalities, the Timeslot API should basically let you do anything, as if the SoftDevice isn't there.

    But in any cases, even with the SoftDevice disabled, we cannot reproduce your issue.

    Do you have a minimal project where the issue can be reproduced?

Related