Timing synchronization with GPIO controller

Hi support team,

I'm trying to simulate the BDM protocol of the 9s12 chip series. Basically the protocol is as follows: Communication on 1 GPIO pin, output open-drain mode and input floating, clock base 5MHz.

Transmission of logic like picture below

Chapter 7 - BDM Serial Interface

Doing this work by writing the delay function (loops and commands _nop) with optimize O0 (the entire project is configured as O3).
To make sure the delay run time is exactly (which is important because the communication signal dose not have synchronize signal) must disable interrupt when making the transmission, I know that it is only prohibited interrupt below 6us, tranmit a bit of communication is only about 4us, everything is still under control.

static volatile uint8_t *GPIO = (uint8_t *)0x50000000UL;

/*...............................................................................*/
static __inline void gpio_pin_write(uint8_t pin_num, uint8_t pin_level)
{
  if (pin_level)
    *((uint32_t *)(GPIO + GPIO_PIN_OUTSET_OFFSET)) = 1 << pin_num;
  else
    *((uint32_t *)(GPIO + GPIO_PIN_OUTCLR_OFFSET)) = 1 << pin_num;
}
/*...............................................................................*/
static __inline void gpio_cfg_input(uint32_t pin_num)
{
  NRF_GPIO_Type *reg = nrf_gpio_pin_port_decode(&pin_num);

  reg->PIN_CNF[pin_num] = ((uint32_t)NRF_GPIO_PIN_DIR_INPUT << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t)NRF_GPIO_PIN_INPUT_CONNECT << GPIO_PIN_CNF_INPUT_Pos);
}

/* ============================== 9S12 Interface =============================== */
#pragma GCC push_options
#pragma GCC optimize ("O0")
static __inline void eeprom_9s12_delay_tc(uint32_t num)
{
  uint32_t overflow = num * 4; /* Caculate clock cycle */
  num = 0;
  while (num <= overflow)
    num += 4; /* Loop takes 4 clock cycles */
}
#pragma GCC pop_options
/*...............................................................................*/
#pragma GCC push_options
#pragma GCC optimize ("O0")
static void eeprom_9s12_send_cmd(uint8_t cmd, uint8_t ack)
{
  nrf_gpio_cfg_output(EEPROM_9S12_BDM_PIN);

  for (uint8_t i = 0; i < 8; i++)
  {
    __disable_irq();
    if (cmd & 0x80)
    {
      gpio_pin_write(EEPROM_9S12_BDM_PIN, 0);
      eeprom_9s12_delay_tc(4);
      gpio_pin_write(EEPROM_9S12_BDM_PIN, 1);
      eeprom_9s12_delay_tc(12);
    }

    else
    {
      gpio_pin_write(EEPROM_9S12_BDM_PIN, 0);
      eeprom_9s12_delay_tc(12);
      gpio_pin_write(EEPROM_9S12_BDM_PIN, 1);
      eeprom_9s12_delay_tc(4);
    }
    __enable_irq();
    cmd = cmd << 1;
  }

  if (ack) {
    gpio_cfg_input(EEPROM_9S12_BDM_PIN);
    nrf_delay_us(25);
  }

}
#pragma GCC pop_options
/*...............................................................................*/
#pragma GCC push_options
#pragma GCC optimize ("O0")
static uint8_t eeprom_9s12_rx(void)
{
  uint8_t byte = 1;
  __disable_irq();
  nrf_gpio_cfg_output(EEPROM_9S12_BDM_PIN);

  gpio_pin_write(EEPROM_9S12_BDM_PIN, 0);
  gpio_cfg_input(EEPROM_9S12_BDM_PIN);

  byte = nrf_gpio_pin_read(EEPROM_9S12_BDM_PIN);
  eeprom_9s12_delay_tc(12);
  __enable_irq();

  return byte;
}
#pragma GCC pop_options


SoftDevice clock source as below
//==========================================================
    // <o> NRF_SDH_CLOCK_LF_SRC  - SoftDevice clock source.
    
    // <0=> NRF_CLOCK_LF_SRC_RC 
    // <1=> NRF_CLOCK_LF_SRC_XTAL 
    // <2=> NRF_CLOCK_LF_SRC_SYNTH 

    #ifndef NRF_SDH_CLOCK_LF_SRC
    #define NRF_SDH_CLOCK_LF_SRC 1
    #endif

    // <o> NRF_SDH_CLOCK_LF_RC_CTIV - SoftDevice calibration timer interval. 
    #ifndef NRF_SDH_CLOCK_LF_RC_CTIV
    #define NRF_SDH_CLOCK_LF_RC_CTIV 0
    #endif

    // <o> NRF_SDH_CLOCK_LF_RC_TEMP_CTIV - SoftDevice calibration timer interval under constant temperature. 
    // <i> How often (in number of calibration intervals) the RC oscillator shall be calibrated
    // <i>  if the temperature has not changed.

    #ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
    #define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 0
    #endif

    // <o> NRF_SDH_CLOCK_LF_ACCURACY  - External clock accuracy used in the LL to compute timing.
    
    // <0=> NRF_CLOCK_LF_ACCURACY_250_PPM 
    // <1=> NRF_CLOCK_LF_ACCURACY_500_PPM 
    // <2=> NRF_CLOCK_LF_ACCURACY_150_PPM 
    // <3=> NRF_CLOCK_LF_ACCURACY_100_PPM 
    // <4=> NRF_CLOCK_LF_ACCURACY_75_PPM 
    // <5=> NRF_CLOCK_LF_ACCURACY_50_PPM 
    // <6=> NRF_CLOCK_LF_ACCURACY_30_PPM 
    // <7=> NRF_CLOCK_LF_ACCURACY_20_PPM 
    // <8=> NRF_CLOCK_LF_ACCURACY_10_PPM 
    // <9=> NRF_CLOCK_LF_ACCURACY_5_PPM 
    // <10=> NRF_CLOCK_LF_ACCURACY_2_PPM 
    // <11=> NRF_CLOCK_LF_ACCURACY_1_PPM 

    #ifndef NRF_SDH_CLOCK_LF_ACCURACY
    #define NRF_SDH_CLOCK_LF_ACCURACY 7
    #endif

I was able to communicate to 9s12, read data from eeprom. But when compared to the original file, I discovered that there were several randomly wrong bytes, This means that something has impacted the delay time when transmitting.
I tested on my board, or with nrf52840DK, got the same problem. Had try to change calibration timer interval to 8s, 0.5 degree but got same issue.

I was not able to fix this issue. maybe it come from the hardware? Do you have any suggestions for the cause? Any suggestion is appreciated.

Sorry my English is not good, I used Translate to post the question. 

Parents
  • Hi 

    Which version of the SDK and SoftDevice are you using?

    I am know sure where you found this 6us limitation documented, but later versions of the SoftDevice generally won't allow you to disable the SoftDevice interrupts at all. 

    Is there any BLE activity when this issue occurs?

    If so could you test again without BLE activity, to verify if this is the cause of the issue?

    There is a so called timeslot API in the SoftDevice which allows you to reserve a timeslot during which you will not be interrupted by the SoftDevice. As long as you are the master on the bus, and the one initiating the transfers, then you can use this API to avoid interrupts during the transaction, 

    Best regards
    Torbjørn

Reply
  • Hi 

    Which version of the SDK and SoftDevice are you using?

    I am know sure where you found this 6us limitation documented, but later versions of the SoftDevice generally won't allow you to disable the SoftDevice interrupts at all. 

    Is there any BLE activity when this issue occurs?

    If so could you test again without BLE activity, to verify if this is the cause of the issue?

    There is a so called timeslot API in the SoftDevice which allows you to reserve a timeslot during which you will not be interrupted by the SoftDevice. As long as you are the master on the bus, and the one initiating the transfers, then you can use this API to avoid interrupts during the transaction, 

    Best regards
    Torbjørn

Children
  • Hi,
    I tested on nrf52840DK with SDK 17.0.2, project base on blink example, not using softdevice. However, I would like to add some codes for BLE communication that connects to the mobile phone so softdevice will be used later.
    By using timeslot API, I think it's exactly what I'm looking for.
    We will have 4 days holiday, so I'll update the test results later.
    Thank you for the suggestion.

  • Hi 

    Dien Nguyen said:
    I tested on nrf52840DK with SDK 17.0.2, project base on blink example, not using softdevice.

    So you mean to say that even without the SoftDevice running you are still having issues?

    If that is the case it implies that there is something else in your project that is affecting the serial communication. 

    Have you tried to connect an oscilloscope or logic analyzer to the interface lines to see if you can spot any delays or other forms of data corruption?

    Dien Nguyen said:
    By using timeslot API, I think it's exactly what I'm looking for.

    The timeslot API works great when you are in charge of the timing, and can decide when the communication should be run. 

    The timeslot API is not so great if the timing is controlled by some other chip, since you are not guaranteed that the timeslot will be accepted if you need it to happen at a particular time. 

    Best regards
    Torbjørn

Related