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; }