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.

CC3100: Firmware get stuck in _SlNonOsSemGet function

Part Number: CC3100

Hi, I have a firmware (non OS) which is configured as AP mode. Every second, this application sends a message to a device using UDP.
The problem is sometimes the firmware got stuck on _SlNonOsSemGet function.

I`m already calling _SlNonOsMainLoopTask() in every loop I think it is important.

Following you can find my configuration:

        ...
        /* Configure CC3100 in a default state */
        if (CC3100_SetupSTAMode() != 0)
          PeriphInitFail(WIFI_STATION_MODE_ERR);
        /*
         * “CC3100_SetupAPMode()” function is
         * called which configures the WiFi module as an access point, to
         * allow the app to connect to it and start the provisioning process
         */
        if (CC3100_SetupAPMode(ssid) != 0) {
          PeriphInitFail(WIFI_AP_MODE_ERR);
        }
        CC3100_WaitClients();
        ...
CC3100_SetupSTAMode():
signed long CC3100_SetupSTAMode(void)
{
  signed long ret_val = -1;

  ret_val = InitializeAppVariables();
  ASSERT_ON_ERROR(ret_val);

  /*
   * Following function configures the device to default state by cleaning
   * the persistent settings stored in NVMEM (viz. connection profiles &
   * policies, power policy etc)
   *
   * Applications may choose to skip this step if the developer is sure
   * that the device is in its default state at start of application
   *
   * Note that all profiles and persistent settings that were done on the
   * device will be lost
   */
  ret_val = ConfigureSimpleLinkToDefaultState();
  ASSERT_ON_ERROR(ret_val);

  return SUCCESS;
}

CC3100_SetupAPMode(ssid):

signed long CC3100_SetupAPMode(char* ssid)
{
  signed long ret_val = -1;
  _i32 mode = ROLE_STA;
  _u8 sec_type = 0;
  /* Password calculation */
  char network_password[16] = "";

  /* Starts to blink power LED */
  PowerLedBlink(ENABLE);

  /*
   * Assumption is that the device is configured in station mode already
   * and it is in its default state
   */
  mode = sl_Start(0, 0, 0);
  if (mode == ROLE_AP) {
    /*
     * If the device is in AP mode, we need to wait for this event before doing
     * anything
     */
    while (!IS_IP_ACQUIRED(g_Status)) {
      _SlNonOsMainLoopTask();
    }
  } else {
    /* Configure CC3100 to start in AP mode */
    ret_val = sl_WlanSetMode(ROLE_AP);
    ASSERT_ON_ERROR(ret_val);

    /* Configure the SSID of the CC3100 */
    ret_val = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID,
                         pal_Strlen(ssid), (_u8*) ssid);
    ASSERT_ON_ERROR(ret_val);

    sec_type = SEC_TYPE_AP_MODE;
    /* Configure the Security parameter of AP mode */
    ret_val = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, 1,
                         (_u8 *) &sec_type);
    ASSERT_ON_ERROR(ret_val);

    ret_val = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD,
                         pal_Strlen(network_password),
                         (_u8 *) network_password);
    ASSERT_ON_ERROR(ret_val);

    ret_val = sl_Stop(SL_STOP_TIMEOUT);
    ASSERT_ON_ERROR(ret_val);

    CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED);

    mode = sl_Start(0, 0, 0);
    if (ROLE_AP == mode) {
      /* If the device is in AP mode, we need to wait for this event
       * before doing anything */
      while (!IS_IP_ACQUIRED(g_Status)) {
        _SlNonOsMainLoopTask();
      }
    } else {
      return -(ECONNABORTED);
    }
  }

  return ret_val;
}

In the past, I could see it happening when I had a code where a interruption was sending some data and at the same time was reading a socket. However, I'm not enabling that interruption anymore to avoid that problem.

From the SPI point of view, I`m using a STM32F4 microcontroller family, with the CC3100 is connected to the SPI1 and uses a preescale of 8 (45MHz/8 = 5.625MHz). Following you can find the code to configure the SPI pins.

Fd_t CC3100_SpiOpen(char *if_name, unsigned long flags)
{
  /* Set variables used */
  GPIO_InitTypeDef  GPIO_InitStructure;
  SPI_InitTypeDef   SPI_InitStructure;
  EXTI_InitTypeDef  EXTI_InitStructure;
  NVIC_InitTypeDef  NVIC_InitStructure;

  /* Enable clock for GPIOA, GPIOB, GPIOC */
  RCC_AHB1PeriphClockCmd(CC3100_CS_PERIPH, ENABLE);
  RCC_AHB1PeriphClockCmd(CC3100_RST_PERIPH, ENABLE);

  /* Configure nHIB(PA3) pin as output floating */
  GPIO_InitStructure.GPIO_Pin   = CC3100_NHIB_PIN;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_Init(CC3100_NHIB_PORT, &GPIO_InitStructure);
  GPIO_ResetBits(CC3100_NHIB_PORT, CC3100_NHIB_PIN); /* Assert nHIB */

  /* Configure CS(PA4) pin as output floating */
  GPIO_InitStructure.GPIO_Pin   = CC3100_CS_PIN;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_Init(CC3100_CS_PORT, &GPIO_InitStructure);
  GPIO_SetBits(CC3100_CS_PORT, CC3100_CS_PIN); /* Deassert CS */

  /* Configure RST(PC4) pin as output floating */
  GPIO_InitStructure.GPIO_Pin   = CC3100_RST_PIN;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_Init(CC3100_RST_PORT, &GPIO_InitStructure);
  /* Trogle reset */
  GPIO_ResetBits(CC3100_RST_PORT, CC3100_RST_PIN); /* Assert RST */
  Delay_ms(250);
  GPIO_SetBits(CC3100_RST_PORT, CC3100_RST_PIN); /* Deassert RST */
  Delay_ms(300);

  /* Configuring pins used by SPI1 PA5(SCK), PA6(MISO), PA7(MOSI) */
  GPIO_InitStructure.GPIO_Pin = CC3100_SPI_CLK |
                                CC3100_SPI_MISO |
                                CC3100_SPI_MOSI;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(CC3100_SPI_PORT, &GPIO_InitStructure);

  /* Connect SPI1 pins to SPI alternate function */
  GPIO_PinAFConfig(CC3100_SPI_PORT, CC3100_SPI_CLK_PINSRC, CC3100_SPI_AF);
  GPIO_PinAFConfig(CC3100_SPI_PORT, CC3100_SPI_MISO_PINSRC, CC3100_SPI_AF);
  GPIO_PinAFConfig(CC3100_SPI_PORT, CC3100_SPI_MOSI_PINSRC, CC3100_SPI_AF);

  /* Enable SPI1 clock */
  RCC_APB2PeriphClockCmd(CC3100_SPI_PERIPH, ENABLE);

  SPI_DeInit(CC3100_SPI);

  /* Configure SPI1 in Mode 0 = CLK is low when idle, data is sampled at the first edge */
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
  SPI_InitStructure.SPI_Direction         = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode              = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize          = SPI_DataSize_8b;
  SPI_InitStructure.SPI_NSS               = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;
  SPI_InitStructure.SPI_CPOL              = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA              = SPI_CPHA_1Edge;
  SPI_InitStructure.SPI_FirstBit          = SPI_FirstBit_MSB;
  SPI_Init(CC3100_SPI, &SPI_InitStructure);

  SPI_Cmd(CC3100_SPI, ENABLE);

  /* Configure host IRQ line */
  /* Enable clock for SYSCFG */
  RCC_APB2PeriphClockCmd(CC3100_IRQ_PERIPH_CFG, ENABLE);

  /* Configure PC5 pin as input floating */
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_Pin   = CC3100_IRQ_PIN;
  GPIO_Init(CC3100_IRQ_PORT, &GPIO_InitStructure);

  /* Tell system that you will use PC5 for EXTI_Line5 */
  SYSCFG_EXTILineConfig(CC3100_IRQ_EXTI_SRC, CC3100_IRQ_PINSRC);

  /* Configure EXTI Line5 */
  EXTI_InitStructure.EXTI_Line     = CC3100_IRQ_LINE;     /* PC5 is connected to EXTI_Line5 */
  EXTI_InitStructure.EXTI_Mode     = EXTI_Mode_Interrupt; /* Interrupt mode */
  EXTI_InitStructure.EXTI_Trigger  = EXTI_Trigger_Rising; /* Triggers on rising and falling edge */
  EXTI_InitStructure.EXTI_LineCmd  = ENABLE;              /* Enable interrupt */
  /* Add to EXTI */
  EXTI_Init(&EXTI_InitStructure);

  /* Add IRQ vector to NVIC */
  /* PC5 is connected to EXTI_Line5, which has EXTI9_5_IRQn vector */
  NVIC_InitStructure.NVIC_IRQChannel                    = CC3100_IRQ_CHANNEL;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority  = 0x01; /* Set priority */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority         = 0x01; /* Set sub priority */
  NVIC_InitStructure.NVIC_IRQChannelCmd                 = ENABLE;   /* Enable interrupt */
  /* Add to NVIC */
  NVIC_Init(&NVIC_InitStructure);

  EXTI_ClearITPendingBit(CC3100_IRQ_LINE);

  Delay_ms(50);

  return NONOS_RET_OK;
}



  • Hi Felipe,

    Are you using the sl_SyncObj or sl_LockObj (or directly to _SlNonOsSemGet) in your application code?
    - You shouldn't (this is for the host driver exclusively ).

    Are you calling any SL command from an interrupt/event context?
    - You shouldn't (interrupt/event context should only be used to signal the main execution thread which may issue new SL commands).

    br,
    Kobi