// reset default value void MVDRestoreDefault(mico_Context_t* const context) { // start a thread to reset device info on EasyCloud mico_rtos_init_semaphore(&_reset_cloud_info_sem, 1); mico_rtos_create_thread(NULL, MICO_APPLICATION_PRIORITY, "MVD resetCloudInfo", MVDDevCloudInfoResetThread, 0x800, context ); mico_rtos_get_semaphore(&_reset_cloud_info_sem, 5000); // 5s timeout // reset all MVD config params memset((void*)&(context->flashContentInRam.appConfig.virtualDevConfig), 0, sizeof(virtual_device_config_t)); context->flashContentInRam.appConfig.virtualDevConfig.USART_BaudRate = 115200; context->flashContentInRam.appConfig.virtualDevConfig.isActivated = false; sprintf(context->flashContentInRam.appConfig.virtualDevConfig.deviceId, DEFAULT_DEVICE_ID); sprintf(context->flashContentInRam.appConfig.virtualDevConfig.masterDeviceKey, DEFAULT_DEVICE_KEY); sprintf(context->flashContentInRam.appConfig.virtualDevConfig.romVersion, DEFAULT_ROM_VERSION); sprintf(context->flashContentInRam.appConfig.virtualDevConfig.loginId, DEFAULT_LOGIN_ID); sprintf(context->flashContentInRam.appConfig.virtualDevConfig.devPasswd, DEFAULT_DEV_PASSWD); //sprintf(context->flashContentInRam.appConfig.virtualDevConfig.userToken, context->micoStatus.mac); }
void MVDMainThread(void *arg) { OSStatus err = kUnknownErr; mico_Context_t *inContext = (mico_Context_t *)arg; bool connected = false; MVDOTARequestData_t devOTARequestData; MVDActivateRequestData_t devDefaultActivateData; mvd_log("MVD main thread start."); while(kNoErr != mico_rtos_get_semaphore(&_wifi_station_on_sem, MICO_WAIT_FOREVER)); /* check reset cloud info */ if((inContext->flashContentInRam.appConfig.virtualDevConfig.needCloudReset) && (inContext->flashContentInRam.appConfig.virtualDevConfig.isActivated)){ // start a thread to reset device info on EasyCloud mico_rtos_init_semaphore(&_reset_cloud_info_sem, 1); mico_rtos_create_thread(NULL, MICO_APPLICATION_PRIORITY, "MVDResetCloudInfo", MVDDevCloudInfoResetThread, 0x800, inContext ); err = mico_rtos_get_semaphore(&_reset_cloud_info_sem, MICO_WAIT_FOREVER); if(kNoErr == err){ mico_rtos_lock_mutex(&inContext->flashContentInRam_mutex); inContext->flashContentInRam.appConfig.virtualDevConfig.needCloudReset = false; inContext->flashContentInRam.appConfig.virtualDevConfig.isActivated = false; err = MICOUpdateConfiguration(inContext); mico_rtos_unlock_mutex(&inContext->flashContentInRam_mutex); mvd_log("MVD Cloud reset success!"); } else{ mvd_log("MVD Cloud reset failed!"); } mvd_log("Press reset button..."); goto exit; // do nothing after reset, please press reset button. } /* OTA check */ //mvd_log(DEFAULT_MVD_OTA_CHECK_MSG_2MCU); MVDDevInterfaceSend(DEFAULT_MVD_OTA_CHECK_MSG_2MCU, strlen(DEFAULT_MVD_OTA_CHECK_MSG_2MCU)); memset((void*)&devOTARequestData, 0, sizeof(devOTARequestData)); strncpy(devOTARequestData.loginId, inContext->flashContentInRam.appConfig.virtualDevConfig.loginId, MAX_SIZE_LOGIN_ID); strncpy(devOTARequestData.devPasswd, inContext->flashContentInRam.appConfig.virtualDevConfig.devPasswd, MAX_SIZE_DEV_PASSWD); strncpy(devOTARequestData.user_token, inContext->micoStatus.mac, MAX_SIZE_USER_TOKEN); err = MVDCloudInterfaceDevFirmwareUpdate(inContext, devOTARequestData); if(kNoErr == err){ if(inContext->appStatus.virtualDevStatus.RecvRomFileSize > 0){ //mvd_log(DEFAULT_MVD_OTA_UPDATE_MSG_2MCU); MVDDevInterfaceSend(DEFAULT_MVD_OTA_UPDATE_MSG_2MCU, strlen(DEFAULT_MVD_OTA_UPDATE_MSG_2MCU)); // set bootloader to reboot && update app fw memset(&inContext->flashContentInRam.bootTable, 0, sizeof(boot_table_t)); inContext->flashContentInRam.bootTable.length = inContext->appStatus.virtualDevStatus.RecvRomFileSize; inContext->flashContentInRam.bootTable.start_address = UPDATE_START_ADDRESS; inContext->flashContentInRam.bootTable.type = 'A'; inContext->flashContentInRam.bootTable.upgrade_type = 'U'; if(inContext->flashContentInRam.micoSystemConfig.configured != allConfigured) inContext->flashContentInRam.micoSystemConfig.easyLinkByPass = EASYLINK_SOFT_AP_BYPASS; MICOUpdateConfiguration(inContext); inContext->micoStatus.sys_state = eState_Software_Reset; if(inContext->micoStatus.sys_state_change_sem != NULL ); mico_rtos_set_semaphore(&inContext->micoStatus.sys_state_change_sem); mico_thread_sleep(MICO_WAIT_FOREVER); } else{ //mvd_log(DEFAULT_MVD_OTA_UP_TO_DATE_MSG_2MCU); MVDDevInterfaceSend(DEFAULT_MVD_OTA_UP_TO_DATE_MSG_2MCU, strlen(DEFAULT_MVD_OTA_UP_TO_DATE_MSG_2MCU)); } } else{ //mvd_log(DEFAULT_MVD_OTA_DOWNLOAD_FAILED_MSG_2MCU); MVDDevInterfaceSend(DEFAULT_MVD_OTA_DOWNLOAD_FAILED_MSG_2MCU, strlen(DEFAULT_MVD_OTA_DOWNLOAD_FAILED_MSG_2MCU)); } /* activate when wifi on */ while(false == inContext->flashContentInRam.appConfig.virtualDevConfig.isActivated){ // auto activate, using default login_id/dev_pass/user_token //mvd_log(DEFAULT_MVD_DEV_ACTIVATE_START_MSG_2MCU); MVDDevInterfaceSend(DEFAULT_MVD_DEV_ACTIVATE_START_MSG_2MCU, strlen(DEFAULT_MVD_DEV_ACTIVATE_START_MSG_2MCU)); memset((void*)&devDefaultActivateData, 0, sizeof(devDefaultActivateData)); strncpy(devDefaultActivateData.loginId, inContext->flashContentInRam.appConfig.virtualDevConfig.loginId, MAX_SIZE_LOGIN_ID); strncpy(devDefaultActivateData.devPasswd, inContext->flashContentInRam.appConfig.virtualDevConfig.devPasswd, MAX_SIZE_DEV_PASSWD); strncpy(devDefaultActivateData.user_token, inContext->micoStatus.mac, MAX_SIZE_USER_TOKEN); err = MVDCloudInterfaceDevActivate(inContext, devDefaultActivateData); if(kNoErr == err){ //mvd_log("device activate success!"); MVDDevInterfaceSend(DEFAULT_MVD_DEV_ACTIVATE_OK_MSG_2MCU, strlen(DEFAULT_MVD_DEV_ACTIVATE_OK_MSG_2MCU)); } else{ //mvd_log("device activate failed, err = %d, retry in %d s ...", err, 1); MVDDevInterfaceSend(DEFAULT_MVD_DEV_ACTIVATE_FAILED_MSG_2MCU, strlen(DEFAULT_MVD_DEV_ACTIVATE_FAILED_MSG_2MCU)); } mico_thread_sleep(1); } mvd_log("[MVD]device already activated."); /* start EasyCloud service */ err = MVDCloudInterfaceStart(inContext); require_noerr_action(err, exit, mvd_log("ERROR: MVDCloudInterfaceStart failed!") ); /* loop connect status */ while(1) { if(inContext->appStatus.virtualDevStatus.isCloudConnected){ if (!connected){ connected = true; // set LED to blue means cloud connected, data: on/off,H,S,B LedControlMsgHandler("1,240,100,100", strlen("1,240,100,100")); //mvd_log("[MVD]Cloud: connected"); MVDDevInterfaceSend(DEFAULT_MVD_CLOUD_CONNECTED_MSG_2MCU, strlen(DEFAULT_MVD_CLOUD_CONNECTED_MSG_2MCU)); MVDCloudInterfaceSendtoChannel(PUBLISH_TOPIC_CHANNEL_STATUS, DEFAULT_MVD_CLOUD_CONNECTED_MSG_2CLOUD, strlen(DEFAULT_MVD_CLOUD_CONNECTED_MSG_2CLOUD)); } } else{ if (connected){ connected = false; // white means cloud disconnect. LedControlMsgHandler("1,0,0,10", strlen("1,0,0,10")); mvd_log("[MVD]cloud service disconnected!"); //mvd_log("[MVD]Cloud: disconnected"); MVDDevInterfaceSend(DEFAULT_MVD_CLOUD_DISCONNECTED_MSG_2MCU, strlen(DEFAULT_MVD_CLOUD_DISCONNECTED_MSG_2MCU)); } } mico_thread_sleep(1); } exit: mvd_log("[MVD]MVDMainThread exit err=%d.", err); mico_rtos_delete_thread(NULL); return; }
static OSStatus FUartRecv( platform_uart_driver_t* driver, void* data, uint32_t size, uint32_t timeout ) { if ( driver->rx_buffer != NULL ) { while (size != 0) { uint32_t transfer_size = MIN( driver->rx_buffer->size/2, size ); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > ring_buffer_used_space( driver->rx_buffer ) ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ driver->rx_size = transfer_size; #ifndef NO_MICO_RTOS if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout) != kNoErr ) { driver->rx_size = 0; return kTimeoutErr; } #else driver->rx_complete = false; int delay_start = mico_get_time_no_os(); while(driver->rx_complete == false){ if(mico_get_time_no_os() >= delay_start + timeout && timeout != MICO_NEVER_TIMEOUT){ driver->rx_size = 0; return kTimeoutErr; } } #endif /* Reset rx_size to prevent semaphore being set while nothing waits for the data */ driver->rx_size = 0; } size -= transfer_size; // Grab data from the buffer do { uint8_t* available_data; uint32_t bytes_available; ring_buffer_get_data( driver->rx_buffer, &available_data, &bytes_available ); bytes_available = MIN( bytes_available, transfer_size ); memcpy( data, available_data, bytes_available ); transfer_size -= bytes_available; data = ( (uint8_t*) data + bytes_available ); ring_buffer_consume( driver->rx_buffer, bytes_available ); } while ( transfer_size != 0 ); } if ( size != 0 ) { return kGeneralErr; } else { return kNoErr; } } else { mico_thread_msleep(timeout); return kNoMemoryErr; } }
/** * @brief Configures TIM5 to measure the LSI oscillator frequency. * @param None * @retval LSI Frequency */ uint32_t GetLSIFrequency(void) { NVIC_InitTypeDef NVIC_InitStructure; TIM_ICInitTypeDef TIM_ICInitStructure; RCC_ClocksTypeDef RCC_ClockFreq; mico_rtos_init_semaphore(&_measureLSIComplete_SEM, 1); /* Enable the LSI oscillator ************************************************/ RCC_LSICmd(ENABLE); /* Wait till LSI is ready */ while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {} /* TIM5 configuration *******************************************************/ /* Enable TIM5 clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); /* Connect internally the TIM5_CH4 Input Capture to the LSI clock output */ TIM_RemapConfig(TIM5, TIM5_LSI); /* Configure TIM5 presclaer */ TIM_PrescalerConfig(TIM5, 0, TIM_PSCReloadMode_Immediate); /* TIM5 configuration: Input Capture mode --------------------- The LSI oscillator is connected to TIM5 CH4 The Rising edge is used as active edge, The TIM5 CCR4 is used to compute the frequency value ------------------------------------------------------------ */ TIM_ICInitStructure.TIM_Channel = TIM_Channel_4; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV8; TIM_ICInitStructure.TIM_ICFilter = 0; TIM_ICInit(TIM5, &TIM_ICInitStructure); /* Enable TIM5 Interrupt channel */ NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 8; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable TIM5 counter */ TIM_Cmd(TIM5, ENABLE); /* Reset the flags */ TIM5->SR = 0; /* Enable the CC4 Interrupt Request */ TIM_ITConfig(TIM5, TIM_IT_CC4, ENABLE); /* Wait until the TIM5 get 2 LSI edges (refer to TIM5_IRQHandler()) *********/ mico_rtos_get_semaphore(&_measureLSIComplete_SEM, MICO_WAIT_FOREVER); /* Deinitialize the TIM5 peripheral registers to their default reset values */ TIM_ITConfig(TIM5, TIM_IT_CC4, DISABLE); TIM_DeInit(TIM5); NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 8; NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; NVIC_Init(&NVIC_InitStructure); /* Compute the LSI frequency, depending on TIM5 input clock frequency (PCLK1)*/ /* Get SYSCLK, HCLK and PCLKx frequency */ RCC_GetClocksFreq(&RCC_ClockFreq); /* Get PCLK1 prescaler */ if ((RCC->CFGR & RCC_CFGR_PPRE1) == 0) { /* PCLK1 prescaler equal to 1 => TIMCLK = PCLK1 */ return ((RCC_ClockFreq.PCLK1_Frequency / PeriodValue) * 8); } else { /* PCLK1 prescaler different from 1 => TIMCLK = 2 * PCLK1 */ return (((2 * RCC_ClockFreq.PCLK1_Frequency) / PeriodValue) * 8) ; } }
OSStatus MicoUartRecv( mico_uart_t uart, void* data, uint32_t size, uint32_t timeout ) { #if RING_BUFF_ON if (uart_interfaces[uart].rx_buffer != NULL) { while (size != 0) { uint32_t transfer_size = MIN(uart_interfaces[uart].rx_buffer->size / 2, size); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > ring_buffer_used_space( uart_interfaces[uart].rx_buffer ) ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ uart_interfaces[uart].rx_size = transfer_size; #ifndef NO_MICO_RTOS if ( mico_rtos_get_semaphore( &uart_interfaces[uart].rx_complete, timeout) != kNoErr ) { uart_interfaces[uart].rx_size = 0; return kTimeoutErr; } #else uart_interfaces[uart].rx_complete = false; int delay_start = mico_get_time_no_os(); while(uart_interfaces[uart].rx_complete == false){ if(mico_get_time_no_os() >= delay_start + timeout && timeout != MICO_NEVER_TIMEOUT){ uart_interfaces[uart].rx_size = 0; return kTimeoutErr; } } #endif /* Reset rx_size to prevent semaphore being set while nothing waits for the data */ uart_interfaces[uart].rx_size = 0; } size -= transfer_size; // Grab data from the buffer do { uint8_t* available_data; uint32_t bytes_available; //platform_log("uart receive 03"); ring_buffer_get_data( uart_interfaces[uart].rx_buffer, &available_data, &bytes_available ); bytes_available = MIN( bytes_available, transfer_size ); memcpy( data, available_data, bytes_available ); transfer_size -= bytes_available; data = ( (uint8_t*) data + bytes_available ); ring_buffer_consume( uart_interfaces[uart].rx_buffer, bytes_available ); } while ( transfer_size != 0 ); } if ( size != 0 ) { return kGeneralErr; } else { return kNoErr; } } else { return platform_uart_receive_bytes( uart, data, size, timeout ); } #else return platform_uart_receive_bytes( uart, data, size, timeout ); #endif // return kNoErr; }
void NTPClient_thread(void *inContext) { ntp_log_trace(); OSStatus err = kUnknownErr; mico_Context_t *Context = inContext; int Ntp_fd = -1; fd_set readfds; struct timeval_t t ; struct sockaddr_t addr; socklen_t addrLen; char ipstr[16]; unsigned int trans_sec, current; struct NtpPacket outpacket ,inpacket; socklen_t sockLen; char timeString[40]; /* Regisist notifications */ err = MICOAddNotification( mico_notify_WIFI_STATUS_CHANGED, (void *)ntpNotify_WifiStatusHandler ); require_noerr( err, exit ); memset(&outpacket,0x0,sizeof(outpacket)); memset(&inpacket,0x0,sizeof(inpacket)); outpacket.flags = NTP_Flags; outpacket.stratum = NTP_Stratum; outpacket.poll = NTP_Poll; outpacket.precision = NTP_Precision; outpacket.root_delay = NTP_Root_Delay; outpacket.root_dispersion = NTP_Root_Dispersion; if(_wifiConnected == false){ mico_rtos_get_semaphore(&_wifiConnected_sem, MICO_WAIT_FOREVER); mico_thread_msleep(50); } Ntp_fd = socket(AF_INET, SOCK_DGRM, IPPROTO_UDP); require_action(IsValidSocket( Ntp_fd ), exit, err = kNoResourcesErr ); addr.s_ip = INADDR_ANY; addr.s_port = 45000; err = bind(Ntp_fd, &addr, sizeof(addr)); err = kNoErr; require_noerr(err, exit); while(1) { err = gethostbyname(NTP_Server, (uint8_t *)ipstr, 16); require_noerr(err, ReConnWithDelay); ntp_log("NTP server address: %s",ipstr); break; ReConnWithDelay: mico_thread_sleep(5); } addr.s_ip = inet_addr(ipstr); addr.s_port = NTP_Port; t.tv_sec = 5; t.tv_usec = 0; while(1) { require_action(sendto(Ntp_fd, &outpacket,sizeof(outpacket), 0, &addr, sizeof(addr)), exit, err = kNotWritableErr); FD_ZERO(&readfds); FD_SET(Ntp_fd, &readfds); select(1, &readfds, NULL, NULL, &t); if(FD_ISSET(Ntp_fd, &readfds)) { require_action(recvfrom(Ntp_fd, &inpacket, sizeof(struct NtpPacket), 0, &addr, &addrLen)>=0, exit, err = kNotReadableErr); trans_sec = inpacket.trans_ts_sec; trans_sec = ntohl(trans_sec); current = trans_sec - UNIX_OFFSET; ntp_log("Time Synchronoused, %s",asctime(localtime(¤t))); PlatformRTCWrite( localtime(¤t) ); goto exit; } } exit: if( err!=kNoErr )ntp_log("Exit: NTP client exit with err = %d", err); MICORemoveNotification( mico_notify_WIFI_STATUS_CHANGED, (void *)ntpNotify_WifiStatusHandler ); if(_wifiConnected_sem) mico_rtos_deinit_semaphore(&_wifiConnected_sem); SocketClose(&Ntp_fd); mico_rtos_delete_thread(NULL); return; }
int application_start(void) { OSStatus err = kNoErr; IPStatusTypedef para; struct tm currentTime; mico_rtc_time_t time; char wifi_ver[64]; mico_log_trace(); #if 1 /*Read current configurations*/ context = ( mico_Context_t *)malloc(sizeof(mico_Context_t) ); require_action( context, exit, err = kNoMemoryErr ); memset(context, 0x0, sizeof(mico_Context_t)); mico_rtos_init_mutex(&context->flashContentInRam_mutex); mico_rtos_init_semaphore(&context->micoStatus.sys_state_change_sem, 1); MICOReadConfiguration( context ); err = MICOInitNotificationCenter ( context ); err = MICOAddNotification( mico_notify_READ_APP_INFO, (void *)micoNotify_ReadAppInfoHandler ); require_noerr( err, exit ); err = MICOAddNotification( mico_notify_WIFI_CONNECT_FAILED, (void *)micoNotify_ConnectFailedHandler ); require_noerr( err, exit ); err = MICOAddNotification( mico_notify_WIFI_Fatal_ERROR, (void *)micoNotify_WlanFatalErrHandler ); require_noerr( err, exit ); err = MICOAddNotification( mico_notify_Stack_Overflow_ERROR, (void *)micoNotify_StackOverflowErrHandler ); require_noerr( err, exit ); #endif /*wlan driver and tcpip init*/ MicoInit(); MicoSysLed(true); /**********************add ethernet**********************/ add_ethernet(); //sleep(5000); /*********************************************************/ mico_log("Free memory %d bytes", MicoGetMemoryInfo()->free_memory) ; /* Enter test mode, call a build-in test function amd output on STDIO */ if(MicoShouldEnterMFGMode()==true) mico_mfg_test(); /*Read current time from RTC.*/ MicoRtcGetTime(&time); currentTime.tm_sec = time.sec; currentTime.tm_min = time.min; currentTime.tm_hour = time.hr; currentTime.tm_mday = time.date; currentTime.tm_wday = time.weekday; currentTime.tm_mon = time.month - 1; currentTime.tm_year = time.year + 100; mico_log("Current Time: %s",asctime(¤tTime)); micoWlanGetIPStatus(¶, Station); formatMACAddr(context->micoStatus.mac, (char *)¶.mac); MicoGetRfVer(wifi_ver, sizeof(wifi_ver)); mico_log("%s mxchipWNet library version: %s", APP_INFO, MicoGetVer()); mico_log("Wi-Fi driver version %s, mac %s", wifi_ver, context->micoStatus.mac); /*Start system monotor thread*/ err = MICOStartSystemMonitor(context); require_noerr_action( err, exit, mico_log("ERROR: Unable to start the system monitor.") ); err = MICORegisterSystemMonitor(&mico_monitor, APPLICATION_WATCHDOG_TIMEOUT_SECONDS*1000); require_noerr( err, exit ); mico_init_timer(&_watchdog_reload_timer,APPLICATION_WATCHDOG_TIMEOUT_SECONDS*1000 - 100, _watchdog_reload_timer_handler, NULL); mico_start_timer(&_watchdog_reload_timer); /* Regisist notifications */ err = MICOAddNotification( mico_notify_WIFI_STATUS_CHANGED, (void *)micoNotify_WifiStatusHandler ); require_noerr( err, exit ); /*************add ethernet********Why add twice?***********/ //add_ethernet(); if(context->flashContentInRam.micoSystemConfig.configured != allConfigured){ mico_log("Empty configuration. Starting configuration mode..."); #if (MICO_CONFIG_MODE == CONFIG_MODE_EASYLINK) || (MICO_CONFIG_MODE == CONFIG_MODE_EASYLINK_WITH_SOFTAP) err = startEasyLink( context ); require_noerr( err, exit ); #elif (MICO_CONFIG_MODE == CONFIG_MODE_SOFT_AP) err = startEasyLinkSoftAP( context ); require_noerr( err, exit ); #elif (MICO_CONFIG_MODE == CONFIG_MODE_AIRKISS) err = startAirkiss( context ); require_noerr( err, exit ); #elif (MICO_CONFIG_MODE == CONFIG_MODE_WPS) || MICO_CONFIG_MODE == defined (CONFIG_MODE_WPS_WITH_SOFTAP) err = startWPS( context ); require_noerr( err, exit ); #elif ( MICO_CONFIG_MODE == CONFIG_MODE_WAC) WACPlatformParameters_t* WAC_Params = NULL; WAC_Params = calloc(1, sizeof(WACPlatformParameters_t)); require(WAC_Params, exit); str2hex((unsigned char *)para.mac, WAC_Params->macAddress, 6); WAC_Params->isUnconfigured = 1; WAC_Params->supportsAirPlay = 0; WAC_Params->supportsAirPrint = 0; WAC_Params->supports2_4GHzWiFi = 1; WAC_Params->supports5GHzWiFi = 0; WAC_Params->supportsWakeOnWireless = 0; WAC_Params->firmwareRevision = FIRMWARE_REVISION; WAC_Params->hardwareRevision = HARDWARE_REVISION; WAC_Params->serialNumber = SERIAL_NUMBER; WAC_Params->name = context->flashContentInRam.micoSystemConfig.name; WAC_Params->model = MODEL; WAC_Params->manufacturer = MANUFACTURER; WAC_Params->numEAProtocols = 1; WAC_Params->eaBundleSeedID = BUNDLE_SEED_ID; WAC_Params->eaProtocols = (char **)eaProtocols; err = startMFiWAC( context, WAC_Params, 1200); free(WAC_Params); require_noerr( err, exit ); #else #error "Wi-Fi configuration mode is not defined"? #endif } else{ mico_log("Available configuration. Starting Wi-Fi connection..."); err = MICOAddNotification( mico_notify_WiFI_PARA_CHANGED, (void *)micoNotify_WiFIParaChangedHandler ); require_noerr( err, exit ); err = MICOAddNotification( mico_notify_DHCP_COMPLETED, (void *)micoNotify_DHCPCompleteHandler ); require_noerr( err, exit ); if(context->flashContentInRam.micoSystemConfig.rfPowerSaveEnable == true){ micoWlanEnablePowerSave(); } if(context->flashContentInRam.micoSystemConfig.mcuPowerSaveEnable == true){ MicoMcuPowerSaveConfig(true); } /*Local configuration server*/ if(context->flashContentInRam.micoSystemConfig.configServerEnable == true){ err = MICOStartConfigServer(context); require_noerr_action( err, exit, mico_log("ERROR: Unable to start the local server thread.") ); } err = MICOStartNTPClient(context); require_noerr_action( err, exit, mico_log("ERROR: Unable to start the NTP client thread.") ); /*Start mico application*/ err = MICOStartApplication( context ); require_noerr( err, exit ); _ConnectToAP( context ); } mico_log("Free memory %d bytes", MicoGetMemoryInfo()->free_memory) ; /*System status changed*/ while(mico_rtos_get_semaphore(&context->micoStatus.sys_state_change_sem, MICO_WAIT_FOREVER)==kNoErr){ switch(context->micoStatus.sys_state){ case eState_Normal: break; case eState_Software_Reset: sendNotifySYSWillPowerOff(); mico_thread_msleep(500); MicoSystemReboot(); break; case eState_Wlan_Powerdown: sendNotifySYSWillPowerOff(); mico_thread_msleep(500); micoWlanPowerOff(); break; case eState_Standby: mico_log("Enter standby mode"); sendNotifySYSWillPowerOff(); mico_thread_msleep(200); micoWlanPowerOff(); MicoSystemStandBy(MICO_WAIT_FOREVER); break; default: break; } } require_noerr_action( err, exit, mico_log("Closing main thread with err num: %d.", err) ); exit: mico_rtos_delete_thread(NULL); return kNoErr; }
OSStatus MicoUartSend( mico_uart_t uart, const void* data, uint32_t size ) { // /* Reset DMA transmission result. The result is assigned in interrupt handler */ uart_interfaces[uart].tx_dma_result = kGeneralErr; uart = MICO_UART_1; //test #ifndef NO_MICO_RTOS mico_rtos_lock_mutex(&uart_interfaces[uart].tx_mutex); #endif MicoMcuPowerSaveConfig(false); #ifdef UART_IRQ_APP if (UART_DRV_SendData(BOARD_APP_UART_INSTANCE, data, size) == kStatus_UART_Success){ #else if (UART_DRV_EdmaSendData(BOARD_APP_UART_INSTANCE, data, size) == kStatus_UART_Success){ #endif #if ADD_OS_CODE #ifndef NO_MICO_RTOS mico_rtos_set_semaphore( &uart_interfaces[ uart ].tx_complete ); #else uart_interfaces[ uart ].rx_complete = true; #endif #endif } #if ADD_OS_CODE #ifndef NO_MICO_RTOS mico_rtos_get_semaphore( &uart_interfaces[ uart ].tx_complete, MICO_NEVER_TIMEOUT ); #else while(uart_interfaces[ uart ].tx_complete == false); uart_interfaces[ uart ].tx_complete = false; #endif #endif // return uart_interfaces[uart].tx_dma_result; MicoMcuPowerSaveConfig(true); #ifndef NO_MICO_RTOS mico_rtos_unlock_mutex(&uart_interfaces[uart].tx_mutex); #endif return kNoErr; } void UART_DRV_CompleteReceiveData(uint32_t instance) { assert(instance < HW_UART_INSTANCE_COUNT); uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; uint32_t baseAddr = g_uartBaseAddr[instance]; mico_uart_t uart; if(instance == BOARD_APP_UART_INSTANCE) uart = MICO_UART_1; /* Disable receive data full interrupt */ UART_HAL_SetRxDataRegFullIntCmd(baseAddr, false); /* Signal the synchronous completion object. */ if (uartState->isRxBlocking) { OSA_SemaPost(&uartState->rxIrqSync); mico_rtos_set_semaphore(&uart_interfaces[uart].rx_complete); //OSA_SemaPost(&uartState->rxIrqSync); } /* Update the information of the module driver state */ uartState->isRxBusy = false; }
void remoteTcpClient_thread(void *inContext) { client_log_trace(); OSStatus err = kUnknownErr; int len; mico_Context_t *Context = inContext; struct sockaddr_t addr; fd_set readfds; fd_set writeSet; char ipstr[16]; struct timeval_t t; int remoteTcpClient_fd = -1; uint8_t *inDataBuffer = NULL; int eventFd = -1; mico_queue_t queue; socket_msg_t *msg; LinkStatusTypeDef wifi_link; int sent_len, errno; mico_rtos_init_semaphore(&_wifiConnected_sem, 1); /* Regisist notifications */ err = MICOAddNotification( mico_notify_WIFI_STATUS_CHANGED, (void *)clientNotify_WifiStatusHandler ); require_noerr( err, exit ); inDataBuffer = malloc(wlanBufferLen); require_action(inDataBuffer, exit, err = kNoMemoryErr); err = micoWlanGetLinkStatus( &wifi_link ); require_noerr( err, exit ); if( wifi_link.is_connected == true ) _wifiConnected = true; while(1) { if(remoteTcpClient_fd == -1 ) { if(_wifiConnected == false){ require_action_quiet(mico_rtos_get_semaphore(&_wifiConnected_sem, 200000) == kNoErr, Continue, err = kTimeoutErr); } err = gethostbyname((char *)Context->flashContentInRam.appConfig.remoteServerDomain, (uint8_t *)ipstr, 16); require_noerr(err, ReConnWithDelay); remoteTcpClient_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); addr.s_ip = inet_addr(ipstr); addr.s_port = Context->flashContentInRam.appConfig.remoteServerPort; err = connect(remoteTcpClient_fd, &addr, sizeof(addr)); require_noerr_quiet(err, ReConnWithDelay); client_log("Remote server connected at port: %d, fd: %d", Context->flashContentInRam.appConfig.remoteServerPort, remoteTcpClient_fd); err = socket_queue_create(Context, &queue); require_noerr( err, exit ); eventFd = mico_create_event_fd(queue); if (eventFd < 0) { client_log("create event fd error"); socket_queue_delete(Context, &queue); goto ReConnWithDelay; } }else{ FD_ZERO(&readfds); FD_SET(remoteTcpClient_fd, &readfds); FD_SET(eventFd, &readfds); FD_ZERO(&writeSet ); FD_SET(remoteTcpClient_fd, &writeSet ); t.tv_sec = 4; t.tv_usec = 0; select(1, &readfds, &writeSet, NULL, &t); /* send UART data */ if ((FD_ISSET( eventFd, &readfds )) && (FD_ISSET(remoteTcpClient_fd, &writeSet ))) {// have data and can write if (kNoErr == mico_rtos_pop_from_queue( &queue, &msg, 0)) { sent_len = write(remoteTcpClient_fd, msg->data, msg->len); if (sent_len <= 0) { len = sizeof(errno); getsockopt(remoteTcpClient_fd, SOL_SOCKET, SO_ERROR, &errno, &len); socket_msg_free(msg); if (errno != ENOMEM) { client_log("write error, fd: %d, errno %d", remoteTcpClient_fd,errno ); goto ReConnWithDelay; } } else { socket_msg_free(msg); } } } /*recv wlan data using remote client fd*/ if (FD_ISSET(remoteTcpClient_fd, &readfds)) { len = recv(remoteTcpClient_fd, inDataBuffer, wlanBufferLen, 0); if(len <= 0) { client_log("Remote client closed, fd: %d", remoteTcpClient_fd); goto ReConnWithDelay; } sppWlanCommandProcess(inDataBuffer, &len, remoteTcpClient_fd, Context); } Continue: continue; ReConnWithDelay: if (eventFd >= 0) { mico_delete_event_fd(eventFd); eventFd = -1; socket_queue_delete(Context, &queue); } if(remoteTcpClient_fd != -1){ SocketClose(&remoteTcpClient_fd); } sleep(CLOUD_RETRY); } } exit: if(inDataBuffer) free(inDataBuffer); client_log("Exit: Remote TCP client exit with err = %d", err); mico_rtos_delete_thread(NULL); return; }
OSStatus host_platform_sdio_transfer( bus_transfer_direction_t direction, sdio_command_t command, sdio_transfer_mode_t mode, sdio_block_size_t block_size, uint32_t argument, /*@null@*/ uint32_t* data, uint16_t data_size, sdio_response_needed_t response_expected, /*@out@*/ /*@null@*/ uint32_t* response ) { UNUSED_PARAMETER(mode); OSStatus result = kNoErr; uint16_t attempts = 0; uint8_t response_full[6]; uint32_t blockNumber, blockIdx; bool status; check_string(!((command == SDIO_CMD_53) && (data == NULL)), "Bad args" ); if ( response != NULL ) { *response = 0; } MCU_CLOCKS_NEEDED(); restart: // SDIO->ICR = (uint32_t) 0xFFFFFFFF; ++attempts; /* Check if we've tried too many times */ if (attempts >= (uint16_t) BUS_LEVEL_MAX_RETRIES) { result = kGeneralErr; platform_log("SDIO error!"); mico_thread_sleep(0xFFFFFFFF); goto exit; } /* Prepare the data transfer register */ if ( command == SDIO_CMD_53 ) { if ( direction == BUS_READ ) { if(mode == SDIO_BYTE_MODE) SdioStartReciveData((uint8_t*)data, data_size); else SdioStartReciveData((uint8_t*)data, block_size); //require_noerr_quiet(SdioSendCommand(command, argument, 2), restart); SdioDataInterruptEn(); waiting = true; status = SdioSendCommand(command, argument, 1); if(status != 0){ goto restart; } result = mico_rtos_get_semaphore( &sdio_transfer_finished_semaphore, (uint32_t) 50 ); waiting = false; if ( result != kNoErr ) { printf("@@, %d", data_size); //SdioDataInterruptDis(); goto restart; } //while(!SdioIsDatTransDone()); if(mode == SDIO_BLOCK_MODE){ blockNumber = argument & (uint32_t) ( 0x1FF ) ; for( blockIdx = 1; blockIdx < blockNumber; blockIdx++ ){ SdioStartReciveData( (uint8_t *)data + blockIdx * block_size, block_size); waiting = true; result = mico_rtos_get_semaphore( &sdio_transfer_finished_semaphore, (uint32_t) 50 ); waiting = false; if ( result != kNoErr ) { printf("@, %d", data_size); //SdioDataInterruptDis(); goto restart; } //while(!SdioIsDatTransDone()); } } SdioEndDatTrans(); SdioDataInterruptDis(); //memcpy( data, temp_dma_buffer, (size_t) data_size ); }else{ //memcpy(temp_dma_buffer, data, data_size); //require_noerr_quiet(SdioSendCommand(command, argument, 2), restart); status = SdioSendCommand(command, argument, 1); if(status != 0){ goto restart; } SdioDataInterruptEn(); if(mode == SDIO_BYTE_MODE){ waiting = true; SdioStartSendData((uint8_t *)data, data_size); result = mico_rtos_get_semaphore( &sdio_transfer_finished_semaphore, (uint32_t) 50 ); waiting = false; if ( result != kNoErr ) { printf("$, %d", data_size); //SdioDataInterruptDis(); goto restart; } //while(!SdioIsDatTransDone()); }else{ blockNumber = argument & (uint32_t) ( 0x1FF ) ; for( blockIdx = 0; blockIdx < blockNumber; blockIdx++ ){ SdioStartSendData( (uint8_t *)data + blockIdx * block_size, block_size); waiting = true; result = mico_rtos_get_semaphore( &sdio_transfer_finished_semaphore, (uint32_t) 50 ); waiting = false; if ( result != kNoErr ) { printf("-, %d", data_size); //SdioDataInterruptDis(); goto restart; } //while(!SdioIsDatTransDone()); } } SdioEndDatTrans(); SdioDataInterruptDis(); } } else { status = SdioSendCommand(command, argument, 50); if( response_expected == RESPONSE_NEEDED && status != 0 ) { goto restart; } } if ( response != NULL ) { SdioGetCmdResp(response_full, 6); *response = hton32(*(uint32_t *)&response_full[1]); } result = kNoErr; exit: MCU_CLOCKS_NOT_NEEDED(); return result; }
OSStatus BUartRecv( mico_uart_t uart, void* data, uint32_t size, uint32_t timeout ) { while (size != 0) { uint32_t transfer_size = MIN(uart_interfaces[uart].rx_buffer->size / 2, size); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0) ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ uart_interfaces[uart].rx_size = transfer_size; BuartIOctl(BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, uart_interfaces[uart].rx_size-1); BuartIOctl(UART_IOCTL_RXINT_SET, 1); #ifndef NO_MICO_RTOS if ( mico_rtos_get_semaphore( &uart_interfaces[uart].rx_complete, timeout) != kNoErr ) { //BuartIOctl(UART_IOCTL_RXINT_SET, 0); uart_interfaces[uart].rx_size = 0; return kTimeoutErr; } #else uart_interfaces[uart].rx_complete = false; int delay_start = mico_get_time_no_os(); while(uart_interfaces[uart].rx_complete == false){ if(mico_get_time_no_os() >= delay_start + timeout && timeout != MICO_NEVER_TIMEOUT){ uart_interfaces[uart].rx_size = 0; return kTimeoutErr; } } #endif /* Reset rx_size to prevent semaphore being set while nothing waits for the data */ uart_interfaces[uart].rx_size = 0; } size -= transfer_size; // Grab data from the buffer do { uint32_t bytes_available; bytes_available = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); bytes_available = MIN( bytes_available, transfer_size ); BuartRecv(data, bytes_available, 0); transfer_size -= bytes_available; data = ( (uint8_t*) data + bytes_available ); } while ( transfer_size != 0 ); } if ( size != 0 ) { return kGeneralErr; } else { return kNoErr; } }
// Magicoe OSStatus platform_spi_transfer( const platform_spi_t* spi, const platform_spi_config_t* config, const platform_spi_message_segment_t* segments, uint16_t number_of_segments ) OSStatus platform_spi_transfer( platform_spi_driver_t* driver, const platform_spi_config_t* config, const platform_spi_message_segment_t* segments, uint16_t number_of_segments ) { OSStatus err = kNoErr; uint32_t count = 0; uint32_t i; const platform_spi_message_segment_t *pSeg; uint32_t dmaXferLen; DMA_CHDESC_T *pTxDesc, *pRxDesc; LPC_SPI_T *pSPI; uint32_t dmaRxChnNdx, dmaTxChnNdx; const uint8_t *pcTx; uint8_t *pRx; require_action_quiet( ( driver != NULL ) && ( config != NULL ) && ( segments != NULL ) && ( number_of_segments != 0 ), exit, err = kParamErr); // save the driver pointer so that in DMA IRQ callback we can access its members platform_mcu_powersave_disable(); pSeg = segments; pTxDesc = (DMA_CHDESC_T *) g_pDMA->SRAMBASE + driver->peripheral->dmaTxChnNdx; pRxDesc = (DMA_CHDESC_T *) g_pDMA->SRAMBASE + driver->peripheral->dmaRxChnNdx; pSPI = driver->peripheral->port; if (pSPI == LPC_SPI0) s_pSPIDrvs[0] = driver; dmaRxChnNdx = driver->peripheral->dmaRxChnNdx , dmaTxChnNdx = driver->peripheral->dmaTxChnNdx; driver->xferErr = 0; /* Activate chip select */ platform_gpio_output_low( config->chip_select ); for ( i = 0; i < number_of_segments; i++, pSeg++ ) { // transfer one seg count = pSeg->length; if (0 == count) continue; pcTx = pSeg->tx_buffer , pRx = pSeg->rx_buffer; do { dmaXferLen = count > DMA_MAX_XFER_CNT ? DMA_MAX_XFER_CNT : count; count -= dmaXferLen; driver->isRxDone = driver->isTxDone = 0; #if 0 { if (pRx != 0) { pSPI->TXCTRL &= ~(1UL<<22); if (pSPI->STAT & SPI_STAT_RXRDY) pSPI->RXDAT; while (dmaXferLen--) { while (!(pSPI->STAT & SPI_STAT_TXRDY)); pSPI->TXDAT = *pcTx++; while (!(pSPI->STAT & SPI_STAT_RXRDY)); *pRx++ = (uint8_t) pSPI->RXDAT; } } else { pSPI->TXCTRL |= (1UL<<22); while (dmaXferLen--) { while (!(pSPI->STAT & SPI_STAT_TXRDY)); pSPI->TXDAT = *pcTx++; } } while (!(pSPI->STAT & SPI_STAT_TXRDY)); } #else pTxDesc->next = 0; pTxDesc->dest = DMA_ADDR(&pSPI->TXDAT); pTxDesc->source = DMA_ADDR(pcTx) + dmaXferLen - 1; pTxDesc->xfercfg = DMA_XFERCFG_CFGVALID | DMA_XFERCFG_SETINTA | DMA_XFERCFG_SWTRIG | DMA_XFERCFG_WIDTH_8 | DMA_XFERCFG_SRCINC_1 | DMA_XFERCFG_DSTINC_0 | DMA_XFERCFG_XFERCOUNT(dmaXferLen); if (pRx != 0) { pSPI->TXCTRL &= ~(1UL<<22); driver->isRx = 1; pRxDesc->next = 0; pRxDesc->source = DMA_ADDR(&pSPI->RXDAT); pRxDesc->dest = DMA_ADDR(pRx) + dmaXferLen - 1; pRxDesc->xfercfg = DMA_XFERCFG_CFGVALID | DMA_XFERCFG_SETINTA | DMA_XFERCFG_SWTRIG | DMA_XFERCFG_WIDTH_8 | DMA_XFERCFG_DSTINC_1 | DMA_XFERCFG_SRCINC_0 | DMA_XFERCFG_XFERCOUNT(dmaXferLen); // start RX DMA g_pDMA->DMACH[dmaRxChnNdx].XFERCFG = pRxDesc->xfercfg; } else { driver->isRx = 0; pSPI->TXCTRL |= (1UL<<22); } // start TX DMA g_pDMA->DMACH[dmaTxChnNdx].XFERCFG = pTxDesc->xfercfg; #ifndef NO_MICO_RTOS mico_rtos_get_semaphore(&driver->sem_xfer_done, MICO_WAIT_FOREVER); #else while(1) { if (driver->isTxDone) { if (!driver->isRx || driver->isRxDone) break; } __WFI(); } #endif #endif if (driver->xferErr) { err = kGeneralErr; break; } // >>> update read and/or write pointers pcTx += dmaXferLen; if (pRx != 0) pRx += dmaXferLen; // <<< } while (count); } platform_gpio_output_high( config->chip_select ); exit: platform_mcu_powersave_enable( ); return err; }
static OSStatus BUartRecv( platform_uart_driver_t* driver, void* data, uint32_t size, uint32_t timeout ) { int next_trigger; uint32_t recved_data_len = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); uint32_t delay_start = 0; while (size != 0) { uint32_t transfer_size = MIN( BUART_RX_FIFO_SIZE / 2, size ); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > recved_data_len ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ driver->rx_size = transfer_size; next_trigger = (driver->buart_fifo_head + driver->rx_size - 1)% BUART_RX_FIFO_SIZE; /* */ if( next_trigger < driver->buart_fifo_head && (driver->buart_fifo_head + recved_data_len) < BUART_RX_FIFO_SIZE ){ BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, BUART_RX_FIFO_SIZE - 1 ); BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl(UART_IOCTL_RXINT_SET, 1); #ifndef NO_MICO_RTOS #if 0 if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout) != kNoErr ) { driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } #else delay_start = mico_get_time(); while(1){ mico_rtos_get_semaphore( &driver->rx_complete, 50); if( (BUART_RX_FIFO_SIZE - driver->buart_fifo_head) <= (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0) ) break; if( mico_get_time() - delay_start > timeout ){ driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } #endif #else driver->rx_complete = false; int delay_start = mico_get_time_no_os(); while(driver->rx_complete == false){ if(mico_get_time_no_os() >= delay_start + timeout && timeout != MICO_NEVER_TIMEOUT){ driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } #endif mico_thread_msleep(20); } #ifndef NO_MICO_RTOS #if 1 recved_data_len = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); if ( transfer_size > recved_data_len ){ BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_SET, 1); if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout) != kNoErr ) { driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } else{ driver->rx_size = 0; } #else //platform_log( "Waiting...,head:%d expext:%d trigger:%d", driver->buart_fifo_head, driver->rx_size, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_SET, 1); delay_start = mico_get_time(); while(1){ mico_rtos_get_semaphore( &driver->rx_complete, 50); if( driver->rx_size <= (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0) ) break; if( mico_get_time() - delay_start > timeout ){ driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } #endif #else BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_SET, 1); driver->rx_complete = false; delay_start = mico_get_time_no_os(); while(driver->rx_complete == false){ if(mico_get_time_no_os() >= delay_start + timeout && timeout != MICO_NEVER_TIMEOUT){ driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } #endif /* Reset rx_size to prevent semaphore being set while nothing waits for the data */ driver->rx_size = 0; } size -= transfer_size; // Grab data from the buffer do { uint32_t bytes_available; bytes_available = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); bytes_available = MIN( bytes_available, transfer_size ); BuartRecv(data, bytes_available, 0); driver->buart_fifo_head = (driver->buart_fifo_head + bytes_available)% BUART_RX_FIFO_SIZE; transfer_size -= bytes_available; } while ( transfer_size != 0 ); } if ( size != 0 ) { return kGeneralErr; } else { return kNoErr; } }
void easylink_thread(void *inContext) { OSStatus err = kNoErr; mico_Context_t *Context = inContext; fd_set readfds; struct timeval_t t; int reConnCount = 0; easylink_log_trace(); require_action(easylink_sem, threadexit, err = kNotPreparedErr); if(Context->flashContentInRam.micoSystemConfig.easyLinkEnable != false){ OpenEasylink2_withdata(EasyLink_TimeOut); easylink_log("Start easylink"); mico_rtos_get_semaphore(&easylink_sem, MICO_WAIT_FOREVER); if(EasylinkFailed == false) _easylinkConnectWiFi(Context); else{ _easylinkStartSoftAp(Context); mico_rtos_delete_thread(NULL); return; } }else{ mico_rtos_lock_mutex(&Context->flashContentInRam_mutex); Context->flashContentInRam.micoSystemConfig.easyLinkEnable = true; MICOUpdateConfiguration(Context); mico_rtos_unlock_mutex(&Context->flashContentInRam_mutex); _easylinkConnectWiFi_fast(Context); } err = mico_rtos_get_semaphore(&easylink_sem, ConnectFTC_Timeout); require_noerr(err, reboot); httpHeader = HTTPHeaderCreate(); require_action( httpHeader, threadexit, err = kNoMemoryErr ); HTTPHeaderClear( httpHeader ); t.tv_sec = 100; t.tv_usec = 0; while(1){ if(easylinkClient_fd == -1){ err = _connectFTCServer(inContext, &easylinkClient_fd); require_noerr(err, Reconn); }else{ FD_ZERO(&readfds); FD_SET(easylinkClient_fd, &readfds); err = select(1, &readfds, NULL, NULL, &t); if(FD_ISSET(easylinkClient_fd, &readfds)){ err = SocketReadHTTPHeader( easylinkClient_fd, httpHeader ); switch ( err ) { case kNoErr: // Read the rest of the HTTP body if necessary err = SocketReadHTTPBody( easylinkClient_fd, httpHeader ); require_noerr(err, Reconn); PrintHTTPHeader(httpHeader); // Call the HTTPServer owner back with the acquired HTTP header err = _FTCRespondInComingMessage( easylinkClient_fd, httpHeader, Context ); require_noerr( err, Reconn ); // Reuse HTTPHeader HTTPHeaderClear( httpHeader ); break; case EWOULDBLOCK: // NO-OP, keep reading break; case kNoSpaceErr: easylink_log("ERROR: Cannot fit HTTPHeader."); goto Reconn; break; case kConnectionErr: // NOTE: kConnectionErr from SocketReadHTTPHeader means it's closed easylink_log("ERROR: Connection closed."); goto threadexit; //goto Reconn; break; default: easylink_log("ERROR: HTTP Header parse internal error: %d", err); goto Reconn; } } } continue; Reconn: HTTPHeaderClear( httpHeader ); SocketClose(&easylinkClient_fd); easylinkClient_fd = -1; require(reConnCount < 6, threadexit); reConnCount++; sleep(5); } /*Module is ignored by FTC server, */ threadexit: ConfigWillStop( Context ); _cleanEasyLinkResource( Context ); /*Roll back to previous settings (if it has) and reboot*/ mico_rtos_lock_mutex(&Context->flashContentInRam_mutex); if(Context->flashContentInRam.micoSystemConfig.configured != unConfigured){ Context->flashContentInRam.micoSystemConfig.configured = allConfigured; MICOUpdateConfiguration( Context ); PlatformSoftReboot(); } mico_rtos_unlock_mutex(&Context->flashContentInRam_mutex); wifi_power_down(); mico_rtos_delete_thread( NULL ); return; /*SSID or Password is not correct, module cannot connect to wlan, so reboot and enter EasyLink again*/ reboot: ConfigWillStop( Context ); PlatformSoftReboot(); return; }
void acaUartInterface_thread(void *inContext) { client_log_trace(); OSStatus err = kUnknownErr; arrayent_net_status_t arg; arrayent_return_e ret; //int8_t retry = 0; uint16_t len = 0; static char property[150]; mico_rtos_init_semaphore(&_wifiConnected_sem, 1);//初始化信号量 /* Regisist notifications */ err = mico_system_notify_register( mico_notify_WIFI_STATUS_CHANGED, (void *)notify_WifiStatusHandler, (void *)inContext);//??? require_noerr( err, exit ); while(_wifiConnected == false){//after few time connected wifi success.??? mico_rtos_get_semaphore(&_wifiConnected_sem, 200000); client_log("Waiting for Wi-Fi network..."); mico_thread_sleep(1); } user_modules_init(); OLED_ShowString(OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_2, "Arrayent "); OLED_ShowString(OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_3, " Connecting... "); OLED_ShowString(OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_4, " "); configureArrayent(inContext); //Initialize Arrayent stack client_log("Initializing Arrayent daemon..."); ret = ArrayentInit(); if(ret != ARRAYENT_SUCCESS) { client_log("Failed to initialize Arrayent daemon.%d", ret); return; } client_log("Arrayent daemon successfully initialized!"); //Wait for Arrayent to finish connecting to the server do { ret = ArrayentNetStatus(&arg);//get connecting status to server if(ret != ARRAYENT_SUCCESS) { client_log("Failed to connect to Arrayent network."); } client_log("Waiting for good network status."); mico_thread_sleep(1); } while(!(arg.connected_to_server));//after few time connected server success. client_log("Connected to Arrayent network!\r\n"); _connection_lost = false; OLED_ShowString(OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_2, "Connected "); OLED_ShowString(OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_3, " Arrayent! "); OLED_ShowString(OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_4, " "); ArrayentSetProperty("DC","0"); mico_thread_msleep(200); ArrayentSetProperty("RGB","off"); err = mico_rtos_create_thread(NULL, MICO_DEFAULT_LIBRARY_PRIORITY, "update", update_property, STACK_SIZE_UART_RECV_THREAD, (void*)inContext); require_noerr_action( err, exit, client_log("ERROR: Unable to start the update_property thread.") ); err = mico_rtos_create_thread(NULL, MICO_APPLICATION_PRIORITY, "except", except_handle, STACK_SIZE_UART_RECV_THREAD, (void*)inContext); require_noerr_action( err, exit, client_log("ERROR: Unable to start the except_handle thread.") ); while(1) { //sure wifi connected. if(_wifiConnected == false){ mico_rtos_get_semaphore(&_wifiConnected_sem, 200000); continue; } //sure server connected. if(_connection_lost && _wifiConnected){ do { ret = ArrayentNetStatus(&arg);//get connecting status to server if(ret != ARRAYENT_SUCCESS) { client_log("Failed to connect to Arrayent network."); } client_log("Waiting for good network status."); mico_thread_sleep(1); } while(!(arg.connected_to_server)); _connection_lost = false; } len = sizeof(property); if(ARRAYENT_SUCCESS==ArrayentRecvProperty(property,&len,10000)){//receive property data from server client_log("property = %s\n\r",property); if(0!=checkCmd(property, inContext)){//parse cmd success //_response = false; //retry = 1; client_log("%s", property); } } } exit: client_log("Exit: ACA App exit with err = %d", err); mico_rtos_delete_thread(NULL); return; }
void remoteTcpClient_thread(void *inContext) { client_log_trace(); OSStatus err = kUnknownErr; int len; mico_Context_t *Context = inContext; struct sockaddr_t addr; fd_set readfds; char ipstr[16]; struct timeval_t t; int remoteTcpClient_loopBack_fd = -1; int remoteTcpClient_fd = -1; uint8_t *inDataBuffer = NULL; uint8_t *outDataBuffer = NULL; mico_rtos_init_semaphore(&_wifiConnected_sem, 1); /* Regisist notifications */ err = MICOAddNotification( mico_notify_WIFI_STATUS_CHANGED, (void *)clientNotify_WifiStatusHandler ); require_noerr( err, exit ); inDataBuffer = malloc(wlanBufferLen); require_action(inDataBuffer, exit, err = kNoMemoryErr); outDataBuffer = malloc(wlanBufferLen); require_action(inDataBuffer, exit, err = kNoMemoryErr); /*Loopback fd, recv data from other thread */ remoteTcpClient_loopBack_fd = socket( AF_INET, SOCK_DGRM, IPPROTO_UDP ); require_action(IsValidSocket( remoteTcpClient_loopBack_fd ), exit, err = kNoResourcesErr ); addr.s_ip = IPADDR_LOOPBACK; addr.s_port = REMOTE_TCP_CLIENT_LOOPBACK_PORT; err = bind( remoteTcpClient_loopBack_fd, &addr, sizeof(addr) ); require_noerr( err, exit ); t.tv_sec = 4; t.tv_usec = 0; while(1) { if(remoteTcpClient_fd == -1 ) { if(_wifiConnected == false){ require_action_quiet(mico_rtos_get_semaphore(&_wifiConnected_sem, 200000) == kNoErr, Continue, err = kTimeoutErr); } err = gethostbyname((char *)Context->flashContentInRam.appConfig.remoteServerDomain, (uint8_t *)ipstr, 16); require_noerr(err, ReConnWithDelay); remoteTcpClient_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); addr.s_ip = inet_addr(ipstr); addr.s_port = Context->flashContentInRam.appConfig.remoteServerPort; err = connect(remoteTcpClient_fd, &addr, sizeof(addr)); require_noerr_quiet(err, ReConnWithDelay); Context->appStatus.isRemoteConnected = true; client_log("Remote server connected at port: %d, fd: %d", Context->flashContentInRam.appConfig.remoteServerPort, remoteTcpClient_fd); }else{ FD_ZERO(&readfds); FD_SET(remoteTcpClient_fd, &readfds); FD_SET(remoteTcpClient_loopBack_fd, &readfds); select(1, &readfds, NULL, NULL, &t); /*recv UART data using loopback fd*/ if (FD_ISSET( remoteTcpClient_loopBack_fd, &readfds) ) { len = recv( remoteTcpClient_loopBack_fd, outDataBuffer, wlanBufferLen, 0 ); SocketSend( remoteTcpClient_fd, outDataBuffer, len ); } /*recv wlan data using remote client fd*/ if (FD_ISSET(remoteTcpClient_fd, &readfds)) { len = recv(remoteTcpClient_fd, inDataBuffer, wlanBufferLen, 0); if(len <= 0) { client_log("Remote client closed, fd: %d", remoteTcpClient_fd); Context->appStatus.isRemoteConnected = false; goto ReConnWithDelay; } sppWlanCommandProcess(inDataBuffer, &len, remoteTcpClient_fd, Context); } Continue: continue; ReConnWithDelay: if(remoteTcpClient_fd != -1){ SocketClose(&remoteTcpClient_fd); } sleep(CLOUD_RETRY); } } exit: if(inDataBuffer) free(inDataBuffer); if(outDataBuffer) free(outDataBuffer); if(remoteTcpClient_loopBack_fd != -1) SocketClose(&remoteTcpClient_loopBack_fd); client_log("Exit: Remote TCP client exit with err = %d", err); mico_rtos_delete_thread(NULL); return; }
void NTPClient_thread(void *arg) { ntp_log_trace(); OSStatus err = kUnknownErr; UNUSED_PARAMETER( arg ); int Ntp_fd = -1; fd_set readfds; struct timeval_t t ; struct sockaddr_t addr; socklen_t addrLen; char ipstr[16]; unsigned int trans_sec, current; struct NtpPacket outpacket ,inpacket; struct tm *currentTime; mico_rtc_time_t time; LinkStatusTypeDef wifi_link; int contry = 0; /* Regisist notifications */ err = mico_system_notify_register( mico_notify_WIFI_STATUS_CHANGED, (void *)ntpNotify_WifiStatusHandler, NULL ); require_noerr( err, exit ); memset(&outpacket,0x0,sizeof(outpacket)); memset(&inpacket,0x0,sizeof(inpacket)); outpacket.flags = NTP_Flags; outpacket.stratum = NTP_Stratum; outpacket.poll = NTP_Poll; outpacket.precision = NTP_Precision; outpacket.root_delay = NTP_Root_Delay; outpacket.root_dispersion = NTP_Root_Dispersion; err = micoWlanGetLinkStatus( &wifi_link ); require_noerr( err, exit ); if( wifi_link.is_connected == true ) _wifiConnected = true; if(_wifiConnected == false) mico_rtos_get_semaphore(&_wifiConnected_sem, MICO_WAIT_FOREVER); Ntp_fd = socket(AF_INET, SOCK_DGRM, IPPROTO_UDP); require_action(IsValidSocket( Ntp_fd ), exit, err = kNoResourcesErr ); addr.s_ip = INADDR_ANY; addr.s_port = 45000; err = bind(Ntp_fd, &addr, sizeof(addr)); err = kNoErr; require_noerr(err, exit); contry=0; while(1) { //err = gethostbyname((char *)NTP_Server, (uint8_t *)ipstr, 16); err = gethostbyname(NTP_Server, (uint8_t *)ipstr, 16); contry+=1; if (contry > 4) { require_noerr(err, exit); } else { require_noerr(err, ReConnWithDelay); } ntp_log("NTP server address: %s",ipstr); break; ReConnWithDelay: mico_thread_sleep(5); } addr.s_ip = inet_addr(ipstr); addr.s_port = NTP_Port; t.tv_sec = 5; t.tv_usec = 0; while(1) { require_action(sendto(Ntp_fd, &outpacket,sizeof(outpacket), 0, &addr, sizeof(addr)), exit, err = kNotWritableErr); FD_ZERO(&readfds); FD_SET(Ntp_fd, &readfds); select(1, &readfds, NULL, NULL, &t); if(FD_ISSET(Ntp_fd, &readfds)) { require_action(recvfrom(Ntp_fd, &inpacket, sizeof(struct NtpPacket), 0, &addr, &addrLen)>=0, exit, err = kNotReadableErr); trans_sec = inpacket.trans_ts_sec; trans_sec = ntohl(trans_sec); current = trans_sec - UNIX_OFFSET + (ntp_time_zone*3600); ntp_log("Time Synchronised, %s, tz=%d, from %s\n\r",asctime(gmtime(¤t)),ntp_time_zone, NTP_Server); //currentTime = localtime(¤t); currentTime = gmtime(¤t); time.sec = currentTime->tm_sec; time.min = currentTime->tm_min ; time.hr = currentTime->tm_hour; time.date = currentTime->tm_mday; time.weekday = currentTime->tm_wday; time.month = currentTime->tm_mon + 1; time.year = (currentTime->tm_year + 1900)%100; MicoRtcSetTime( &time ); goto exit; } } exit: if( err!=kNoErr )ntp_log("Exit: NTP client exit with err = %d", err); mico_system_notify_remove( mico_notify_WIFI_STATUS_CHANGED, (void *)ntpNotify_WifiStatusHandler ); if(_wifiConnected_sem) mico_rtos_deinit_semaphore(&_wifiConnected_sem); SocketClose(&Ntp_fd); mico_rtos_delete_thread(NULL); return; }
void micokit_ext_mfg_test(mico_Context_t *inContext) { OSStatus err = kUnknownErr; char str[64] = {'\0'}; char mac[6]; int rgb_led_hue = 0; uint8_t dht11_ret = 0; uint8_t dht11_temp_data = 0; uint8_t dht11_hum_data = 0; int light_ret = 0; uint16_t light_sensor_data = 0; int infrared_ret = 0; uint16_t infrared_reflective_data = 0; int32_t bme280_temp = 0; uint32_t bme280_hum = 0; uint32_t bme280_press = 0; UNUSED_PARAMETER(inContext); mico_rtos_init_semaphore(&mfg_test_state_change_sem, 1); err = MICOAddNotification( mico_notify_WIFI_SCAN_COMPLETED, (void *)mico_notify_WifiScanCompleteHandler ); require_noerr( err, exit ); while(1){ switch(mfg_test_module_number){ case 0: // mfg mode start { sprintf(str, "%s\r\nStart:\r\n%s\r\n%s", "TEST MODE", " next: Key2", " prev: Key1"); mf_printf(str); while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, MICO_WAIT_FOREVER)); break; } case 1: // OLED { while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, 0)) { sprintf(str, "%s OLED\r\n", OLED_MFG_TEST_PREFIX); mf_printf(str); mico_thread_msleep(300); mf_printf(mfg_test_oled_test_string); mico_thread_msleep(300); } OLED_Clear(); break; } case 2: // RGB_LED { sprintf(str, "%s RGB LED\r\nBlink: \r\n R=>G=>B", OLED_MFG_TEST_PREFIX); mf_printf(str); while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, 0)) { hsb2rgb_led_open(rgb_led_hue, 100, 50); rgb_led_hue += 120; if(rgb_led_hue >= 360){ rgb_led_hue = 0; } mico_thread_msleep(300); } hsb2rgb_led_open(0, 0, 0); break; } case 3: // infrared sensor { while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, 0)) { infrared_ret = infrared_reflective_read(&infrared_reflective_data); if(0 == infrared_ret){ sprintf(str, "%s Infrared\r\nInfrared: %d", OLED_MFG_TEST_PREFIX, infrared_reflective_data); mf_printf(str); } mico_thread_msleep(300); } break; } case 4: // DC Motor { sprintf(str, "%s DC Motor\r\nRun:\r\n on : 500ms\r\n off: 500ms", OLED_MFG_TEST_PREFIX); mf_printf(str); while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, 0)) { dc_motor_set(1); mico_thread_msleep(500); dc_motor_set(0); mico_thread_msleep(500); } dc_motor_set(0); break; } case 5: // BME280 { while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, 0)) { err = bme280_sensor_init(); if(kNoErr != err){ sprintf(str, "%s BME280\r\nMoule not found!", OLED_MFG_TEST_PREFIX); mf_printf(str); // goto next mdoule mico_thread_msleep(500); mfg_test_module_number = (mfg_test_module_number+1)%(MFG_TEST_MAX_MODULE_NUM+1); break; } else{ err = bme280_data_readout(&bme280_temp, &bme280_press, &bme280_hum); if(kNoErr == err){ sprintf(str, "%s BME280\r\nT: %3.1fC\r\nH: %3.1f%%\r\nP: %5.2fkPa", OLED_MFG_TEST_PREFIX, (float)bme280_temp/100, (float)bme280_hum/1024, (float)bme280_press/1000); mf_printf(str); } else{ sprintf(str, "%s BME280\r\nRead error!", OLED_MFG_TEST_PREFIX); mf_printf(str); } } mico_thread_msleep(500); } break; } case 6: // DHT11 { while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, 0)) { dht11_ret = DHT11_Read_Data(&dht11_temp_data, &dht11_hum_data); if(0 == dht11_ret){ sprintf(str, "%s DHT11\r\nT: %3.1fC\r\nH: %3.1f%%", OLED_MFG_TEST_PREFIX, (float)dht11_temp_data, (float)dht11_hum_data); mf_printf(str); } mico_thread_sleep(1); // DHT11 must >= 1s } break; } case 7: // Light sensor { while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, 0)) { light_ret = light_sensor_read(&light_sensor_data); if(0 == light_ret){ sprintf(str, "%s Light\r\nLight: %d", OLED_MFG_TEST_PREFIX, light_sensor_data); mf_printf(str); } mico_thread_msleep(300); } break; } case 8: // wifi { wlan_get_mac_address(mac); sprintf(str, "%s Wi-Fi\r\nMAC:\r\n %02X%02X%02X%02X%02X%02X", OLED_MFG_TEST_PREFIX, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); mf_printf(str); //mico_thread_msleep(500); scanap_done = false; micoWlanStartScan(); while((!scanap_done) || (kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, MICO_WAIT_FOREVER))); break; } default: goto exit; // error break; } } exit: mico_thread_sleep(MICO_NEVER_TIMEOUT); }
/* MP3音乐处理线程 */ void MP3_handleThread(void *inContext) { SD_sizeInfo sdSizeInfo; u32 ret = 0; u8 *pBuf = NULL; /* 检测是否插上SD卡 */ if (MP3_sdCardDetect() == 0) { while(1) { printf( "sdCard not insert !!!!!\r\n"); mico_thread_sleep( 1 ); } } /* MP3初始化 */ if (MP3_init() == 0) { while(1) { printf( "mp3 init failed !!!!!\r\n"); mico_thread_sleep( 1 ); } } /* 获取SD卡容量信息 */ MP3_getSdSize(&sdSizeInfo); printf("%d MB total drive space.\r\n" "%d MB available.\r\n", sdSizeInfo.totalSize, sdSizeInfo.availableSize); /* 获取MP3文件总数 */ ret = MP3_getMp3FileNum("0:/MUSIC"); printf("mp3FileNum=%d\r\n", ret); #if 0 /* 写文件 */ pBuf = malloc(512); if (pBuf != NULL) { memset(pBuf, 0x5a, 512); ret = MP3_writeSong("0:/MUSIC/hujg.mp3", 0, pBuf, 512); printf("ret0=%d\r\n", ret); memset(pBuf, 0xa5, 512); ret = MP3_writeSong("0:/MUSIC/hujg.mp3", 512, pBuf, 512); printf("ret1=%d\r\n", ret); free(pBuf); } /* 删除文件 */ ret = MP3_removeSong("0:/MUSIC/hujg_bak.mp3"); if (ret == 1) { printf("remove mp3 file success!\r\n"); } else { printf("remove mp3 file failed !\r\n"); } #endif /* 播放指定歌曲和音量设置 */ while(mico_rtos_get_semaphore(&cupTimeObj.playMp3_sem, MICO_WAIT_FOREVER) == kNoErr) { if (cupTimeObj.playMode != PLAY_ONLY_LED) //如果不是单单灯提醒喝水时 { MP3_setVolume(20); printf("MP3_getVolume=%d\r\n", MP3_getVolume()); ret = MP3_playSong("0:/MUSIC/水晶闹钟.mp3"); //播放指定歌曲 printf("play over!!!!ret=%d\r\n", ret); mico_rtos_set_semaphore(&cupTimeObj.stopLed_sem); //通知停止亮LED灯 } // mp3_play(); } }
int application_start(void) { OSStatus err = kNoErr; net_para_st para; Platform_Init(); /*Read current configurations*/ context = ( mico_Context_t *)malloc(sizeof(mico_Context_t) ); require_action( context, exit, err = kNoMemoryErr ); memset(context, 0x0, sizeof(mico_Context_t)); mico_rtos_init_mutex(&context->flashContentInRam_mutex); mico_rtos_init_semaphore(&context->micoStatus.sys_state_change_sem, 1); MICOReadConfiguration( context ); err = MICOInitNotificationCenter ( context ); err = MICOAddNotification( mico_notify_READ_APP_INFO, (void *)micoNotify_ReadAppInfoHandler ); require_noerr( err, exit ); /*wlan driver and tcpip init*/ mxchipInit(); getNetPara(¶, Station); formatMACAddr(context->micoStatus.mac, (char *)¶.mac); mico_log_trace(); mico_log("%s mxchipWNet library version: %s", APP_INFO, system_lib_version()); /*Start system monotor thread*/ err = MICOStartSystemMonitor(context); require_noerr_action( err, exit, mico_log("ERROR: Unable to start the system monitor.") ); err = MICORegisterSystemMonitor(&mico_monitor, APPLICATION_WATCHDOG_TIMEOUT_SECONDS*1000); require_noerr( err, exit ); mico_init_timer(&_watchdog_reload_timer,APPLICATION_WATCHDOG_TIMEOUT_SECONDS*1000-100, _watchdog_reload_timer_handler, NULL); mico_start_timer(&_watchdog_reload_timer); if(context->flashContentInRam.micoSystemConfig.configured != allConfigured){ mico_log("Empty configuration. Starting configuration mode..."); #ifdef CONFIG_MODE_EASYLINK err = startEasyLink( context ); require_noerr( err, exit ); #endif #ifdef CONFIG_MODE_WAC WACPlatformParameters_t* WAC_Params = NULL; WAC_Params = calloc(1, sizeof(WACPlatformParameters_t)); require(WAC_Params, exit); str2hex((unsigned char *)para.mac, WAC_Params->macAddress, 6); WAC_Params->isUnconfigured = 1; WAC_Params->supportsAirPlay = 0; WAC_Params->supportsAirPrint = 0; WAC_Params->supports2_4GHzWiFi = 1; WAC_Params->supports5GHzWiFi = 0; WAC_Params->supportsWakeOnWireless = 0; WAC_Params->firmwareRevision = FIRMWARE_REVISION; WAC_Params->hardwareRevision = HARDWARE_REVISION; WAC_Params->serialNumber = SERIAL_NUMBER; WAC_Params->name = context->flashContentInRam.micoSystemConfig.name; WAC_Params->model = MODEL; WAC_Params->manufacturer = MANUFACTURER; WAC_Params->numEAProtocols = 1; WAC_Params->eaBundleSeedID = BUNDLE_SEED_ID; WAC_Params->eaProtocols = (char **)eaProtocols;; err = startMFiWAC( context, WAC_Params, 1200); free(WAC_Params); require_noerr( err, exit ); #endif } else{ mico_log("Available configuration. Starting Wi-Fi connection..."); /* Regisist notifications */ err = MICOAddNotification( mico_notify_WIFI_STATUS_CHANGED, (void *)micoNotify_WifiStatusHandler ); require_noerr( err, exit ); err = MICOAddNotification( mico_notify_WiFI_PARA_CHANGED, (void *)micoNotify_WiFIParaChangedHandler ); require_noerr( err, exit ); err = MICOAddNotification( mico_notify_DHCP_COMPLETED, (void *)micoNotify_DHCPCompleteHandler ); require_noerr( err, exit ); if(context->flashContentInRam.micoSystemConfig.rfPowerSaveEnable == true){ ps_enable(); } if(context->flashContentInRam.micoSystemConfig.mcuPowerSaveEnable == true){ mico_mcu_powersave_config(true); } /*Bonjour service for searching*/ // if(context->flashContentInRam.micoSystemConfig.bonjourEnable == true){ // err = MICOStartBonjourService( Station, context ); // require_noerr( err, exit ); // } err = mico_rtos_create_thread(NULL, MICO_APPLICATION_PRIORITY, "mDNSResponder", mDNSResponder_thread, 0x1000, (void*)context ); require_noerr_action( err, exit, mico_log("ERROR: Unable to start mDNSResponder thread.") ); /*Local configuration server*/ if(context->flashContentInRam.micoSystemConfig.configServerEnable == true){ err = MICOStartConfigServer(context); require_noerr_action( err, exit, mico_log("ERROR: Unable to start the local server thread.") ); } /*Start mico application*/ err = MICOStartApplication( context ); require_noerr( err, exit ); _ConnectToAP( context ); } /*System status changed*/ while(mico_rtos_get_semaphore(&context->micoStatus.sys_state_change_sem, MICO_WAIT_FOREVER)==kNoErr){ switch(context->micoStatus.sys_state){ case eState_Normal: break; case eState_Software_Reset: sendNotifySYSWillPowerOff(); mico_thread_msleep(500); PlatformSoftReboot(); break; case eState_Wlan_Powerdown: sendNotifySYSWillPowerOff(); mico_thread_msleep(500); wifi_power_down(); break; case eState_Standby: mico_log("Enter standby mode"); sendNotifySYSWillPowerOff(); mico_thread_msleep(200); wifi_power_down(); Platform_Enter_STANDBY(); break; default: break; } } require_noerr_action( err, exit, mico_log("Closing main thread with err num: %d.", err) ); exit: mico_rtos_delete_thread(NULL); return kNoErr; }
OSStatus host_platform_sdio_transfer( bus_transfer_direction_t direction, sdio_command_t command, sdio_transfer_mode_t mode, sdio_block_size_t block_size, uint32_t argument, /*@null@*/ uint32_t* data, uint16_t data_size, sdio_response_needed_t response_expected, /*@out@*/ /*@null@*/ uint32_t* response ) { uint32_t loop_count = 0; OSStatus result; uint16_t attempts = 0; check_string(!((command == SDIO_CMD_53) && (data == NULL)), "Bad args" ); if ( response != NULL ) { *response = 0; } platform_mcu_powersave_disable(); /* Ensure the bus isn't stuck half way through transfer */ DMA2_Stream3->CR = 0; restart: SDIO->ICR = (uint32_t) 0xFFFFFFFF; sdio_transfer_failed = false; ++attempts; /* Check if we've tried too many times */ if (attempts >= (uint16_t) BUS_LEVEL_MAX_RETRIES) { result = kGeneralErr; goto exit; } /* Prepare the data transfer register */ current_command = command; if ( command == SDIO_CMD_53 ) { sdio_enable_bus_irq(); /* Dodgy STM32 hack to set the CMD53 byte mode size to be the same as the block size */ if ( mode == SDIO_BYTE_MODE ) { block_size = find_optimal_block_size( data_size ); if ( block_size < SDIO_512B_BLOCK ) { argument = ( argument & (uint32_t) ( ~0x1FF ) ) | block_size; } else { argument = ( argument & (uint32_t) ( ~0x1FF ) ); } } /* Prepare the SDIO for a data transfer */ current_transfer_direction = direction; sdio_prepare_data_transfer( direction, block_size, (uint8_t*) data, data_size ); /* Send the command */ SDIO->ARG = argument; SDIO->CMD = (uint32_t) ( command | SDIO_Response_Short | SDIO_Wait_No | SDIO_CPSM_Enable ); /* Wait for the whole transfer to complete */ result = mico_rtos_get_semaphore( &sdio_transfer_finished_semaphore, (uint32_t) 50 ); if ( result != kNoErr ) { goto exit; } if ( sdio_transfer_failed == true ) { goto restart; } /* Check if there were any SDIO errors */ require(( SDIO->STA & ( SDIO_STA_DTIMEOUT | SDIO_STA_CTIMEOUT ) ) == 0, restart); require_string(( SDIO->STA & ( SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | SDIO_STA_TXUNDERR | SDIO_STA_RXOVERR ) ) == 0, restart, "SDIO communication failure"); /* Wait till complete */ loop_count = (uint32_t) SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS; do { loop_count--; if ( loop_count == 0 || ( ( SDIO->STA & SDIO_ERROR_MASK ) != 0 ) ) { goto restart; } } while ( ( SDIO->STA & ( SDIO_STA_TXACT | SDIO_STA_RXACT ) ) != 0 ); if ( direction == BUS_READ ) { memcpy( user_data, dma_data_source, (size_t) user_data_size ); } } else { uint32_t temp_sta; /* Send the command */ SDIO->ARG = argument; SDIO->CMD = (uint32_t) ( command | SDIO_Response_Short | SDIO_Wait_No | SDIO_CPSM_Enable ); loop_count = (uint32_t) COMMAND_FINISHED_CMD52_TIMEOUT_LOOPS; do { temp_sta = SDIO->STA; loop_count--; if ( loop_count == 0 || ( ( response_expected == RESPONSE_NEEDED ) && ( ( temp_sta & SDIO_ERROR_MASK ) != 0 ) ) ) { goto restart; } } while ( ( temp_sta & SDIO_FLAG_CMDACT ) != 0 ); } if ( response != NULL ) { *response = SDIO->RESP1; } result = kNoErr; exit: platform_mcu_powersave_enable(); #ifndef SDIO_1_BIT SDIO->MASK = SDIO_MASK_SDIOITIE; #endif return result; }
int application_start(void) { OSStatus err = kNoErr; net_para_st para; Platform_Init(); /*Read current configurations*/ context = ( mico_Context_t *)malloc(sizeof(mico_Context_t) ); require_action( context, exit, err = kNoMemoryErr ); memset(context, 0x0, sizeof(mico_Context_t)); mico_rtos_init_mutex(&context->flashContentInRam_mutex); mico_rtos_init_semaphore(&context->micoStatus.sys_state_change_sem, 1); MICOReadConfiguration( context ); err = MICOInitNotificationCenter ( context ); err = MICOAddNotification( mico_notify_READ_APP_INFO, (void *)micoNotify_ReadAppInfoHandler ); require_noerr( err, exit ); /*wlan driver and tcpip init*/ mxchipInit(); getNetPara(¶, Station); formatMACAddr(context->micoStatus.mac, (char *)¶.mac); mico_log_trace(); mico_log("%s mxchipWNet library version: %s", APP_INFO, system_lib_version()); /*Start system monotor thread*/ err = MICOStartSystemMonitor(context); require_noerr_action( err, exit, mico_log("ERROR: Unable to start the system monitor.") ); err = MICORegisterSystemMonitor(&mico_monitor, APPLICATION_WATCHDOG_TIMEOUT_SECONDS*1000); require_noerr( err, exit ); mico_init_timer(&_watchdog_reload_timer,APPLICATION_WATCHDOG_TIMEOUT_SECONDS*1000-100, _watchdog_reload_timer_handler, NULL); mico_start_timer(&_watchdog_reload_timer); if(context->flashContentInRam.micoSystemConfig.configured != allConfigured){ mico_log("Empty configuration. Starting configuration mode..."); #ifdef CONFIG_MODE_EASYLINK err = startEasyLink( context ); require_noerr( err, exit ); #endif #ifdef CONFIG_MODE_WAC err = startMfiWac( context ); require_noerr( err, exit ); #endif } else{ mico_log("Available configuration. Starting Wi-Fi connection..."); /* Regisist notifications */ err = MICOAddNotification( mico_notify_WIFI_STATUS_CHANGED, (void *)micoNotify_WifiStatusHandler ); require_noerr( err, exit ); err = MICOAddNotification( mico_notify_WiFI_PARA_CHANGED, (void *)micoNotify_WiFIParaChangedHandler ); require_noerr( err, exit ); err = MICOAddNotification( mico_notify_DHCP_COMPLETED, (void *)micoNotify_DHCPCompleteHandler ); require_noerr( err, exit ); if(context->flashContentInRam.micoSystemConfig.rfPowerSaveEnable == true){ ps_enable(); } if(context->flashContentInRam.micoSystemConfig.mcuPowerSaveEnable == true){ mico_mcu_powersave_config(true); } /*Bonjour service for searching*/ if(context->flashContentInRam.micoSystemConfig.bonjourEnable == true){ err = MICOStartBonjourService( Station, context ); require_noerr( err, exit ); } /*Local configuration server*/ if(context->flashContentInRam.micoSystemConfig.configServerEnable == true){ err = MICOStartConfigServer(context); require_noerr_action( err, exit, mico_log("ERROR: Unable to start the local server thread.") ); } /*Start mico application*/ err = MICOStartApplication( context ); require_noerr( err, exit ); _ConnectToAP( context ); } /*System status changed*/ while(mico_rtos_get_semaphore(&context->micoStatus.sys_state_change_sem, MICO_WAIT_FOREVER)==kNoErr){ switch(context->micoStatus.sys_state){ case eState_Normal: break; case eState_Software_Reset: sendNotifySYSWillPowerOff(); mico_thread_msleep(500); PlatformSoftReboot(); break; case eState_Wlan_Powerdown: sendNotifySYSWillPowerOff(); mico_thread_msleep(500); wifi_power_down(); break; case eState_Standby: mico_log("Enter standby mode"); sendNotifySYSWillPowerOff(); mico_thread_msleep(100); wifi_power_down(); Platform_Enter_STANDBY(); break; default: break; } } require_noerr_action( err, exit, mico_log("Closing main thread with err num: %d.", err) ); exit: mico_rtos_delete_thread(NULL); return kNoErr; }
void easylink_thread(void *inContext) { OSStatus err = kNoErr; mico_Context_t *Context = inContext; fd_set readfds; int reConnCount = 0; int clientFdIsSet; easylink_log_trace(); require_action(easylink_sem, threadexit, err = kNotPreparedErr); if(Context->flashContentInRam.micoSystemConfig.easyLinkByPass == EASYLINK_BYPASS){ Context->flashContentInRam.micoSystemConfig.easyLinkByPass = EASYLINK_BYPASS_NO; MICOUpdateConfiguration(Context); _easylinkConnectWiFi_fast(Context); }else if(Context->flashContentInRam.micoSystemConfig.easyLinkByPass == EASYLINK_SOFT_AP_BYPASS){ ConfigWillStop( Context ); _easylinkStartSoftAp(Context); mico_rtos_delete_thread(NULL); return; }else{ #ifdef EasyLink_Plus easylink_log("Start easylink plus mode"); micoWlanStartEasyLinkPlus(EasyLink_TimeOut/1000); #else easylink_log("Start easylink V2"); micoWlanStartEasyLink(EasyLink_TimeOut/1000); #endif mico_rtos_get_semaphore(&easylink_sem, MICO_WAIT_FOREVER); if(EasylinkFailed == false) _easylinkConnectWiFi(Context); else{ msleep(20); _cleanEasyLinkResource( Context ); ConfigWillStop( Context ); _easylinkStartSoftAp(Context); mico_rtos_delete_thread(NULL); return; } } err = mico_rtos_get_semaphore(&easylink_sem, EasyLink_ConnectWlan_Timeout); require_noerr(err, reboot); httpHeader = HTTPHeaderCreate(); require_action( httpHeader, threadexit, err = kNoMemoryErr ); HTTPHeaderClear( httpHeader ); while(1){ if(easylinkClient_fd == -1){ err = _connectFTCServer(inContext, &easylinkClient_fd); require_noerr(err, Reconn); }else{ FD_ZERO(&readfds); FD_SET(easylinkClient_fd, &readfds); if(httpHeader->len == 0){ err = select(1, &readfds, NULL, NULL, NULL); require(err>=1, threadexit); clientFdIsSet = FD_ISSET(easylinkClient_fd, &readfds); } if(clientFdIsSet||httpHeader->len){ err = SocketReadHTTPHeader( easylinkClient_fd, httpHeader ); switch ( err ) { case kNoErr: // Read the rest of the HTTP body if necessary do{ err = SocketReadHTTPBody( easylinkClient_fd, httpHeader ); require_noerr(err, Reconn); PrintHTTPHeader(httpHeader); // Call the HTTPServer owner back with the acquired HTTP header err = _FTCRespondInComingMessage( easylinkClient_fd, httpHeader, Context ); require_noerr( err, Reconn ); if(httpHeader->contentLength == 0) break; } while( httpHeader->chunkedData == true || httpHeader->dataEndedbyClose == true); // Reuse HTTPHeader HTTPHeaderClear( httpHeader ); break; case EWOULDBLOCK: // NO-OP, keep reading break; case kNoSpaceErr: easylink_log("ERROR: Cannot fit HTTPHeader."); goto Reconn; case kConnectionErr: // NOTE: kConnectionErr from SocketReadHTTPHeader means it's closed easylink_log("ERROR: Connection closed."); /*Roll back to previous settings (if it has) and reboot*/ if(Context->flashContentInRam.micoSystemConfig.configured == wLanUnConfigured ){ Context->flashContentInRam.micoSystemConfig.configured = allConfigured; MICOUpdateConfiguration( Context ); MicoSystemReboot(); }else{ micoWlanPowerOff(); msleep(20); } goto threadexit; default: easylink_log("ERROR: HTTP Header parse internal error: %d", err); goto Reconn; } } } continue; Reconn: HTTPHeaderClear( httpHeader ); SocketClose(&easylinkClient_fd); easylinkClient_fd = -1; require(reConnCount < 6, reboot); reConnCount++; sleep(5); } /*Module is ignored by FTC server, */ threadexit: _cleanEasyLinkResource( Context ); ConfigWillStop( Context ); mico_rtos_delete_thread( NULL ); return; /*SSID or Password is not correct, module cannot connect to wlan, so reboot and enter EasyLink again*/ reboot: MicoSystemReboot(); return; }
OSStatus platform_uart_receive_bytes( platform_uart_driver_t* driver, uint8_t* data_in, uint32_t expected_data_size, uint32_t timeout_ms ) { OSStatus err = kNoErr; //platform_mcu_powersave_disable(); require_action_quiet( ( driver != NULL ) && ( data_in != NULL ) && ( expected_data_size != 0 ), exit, err = kParamErr); if ( driver->rx_buffer != NULL) { while ( expected_data_size != 0 ) { uint32_t transfer_size = MIN( driver->rx_buffer->size / 2, expected_data_size ); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > ring_buffer_used_space( driver->rx_buffer ) ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ driver->last_receive_result = kNoErr; driver->rx_size = transfer_size; #ifndef NO_MICO_RTOS err = mico_rtos_get_semaphore( &driver->rx_complete, timeout_ms ); /* Reset rx_size to prevent semaphore being set while nothing waits for the data */ driver->rx_size = 0; if( err != kNoErr ) goto exit; #else driver->rx_complete = false; int delay_start = mico_get_time_no_os(); while(driver->rx_complete == false) { if(mico_get_time_no_os() >= delay_start + timeout_ms && timeout_ms != MICO_NEVER_TIMEOUT) { driver->rx_size = 0; err = kTimeoutErr; goto exit; } } driver->rx_size = 0; #endif } err = driver->last_receive_result; expected_data_size -= transfer_size; // Grab data from the buffer do { uint8_t* available_data; uint32_t bytes_available; ring_buffer_get_data( driver->rx_buffer, &available_data, &bytes_available ); bytes_available = MIN( bytes_available, transfer_size ); memcpy( data_in, available_data, bytes_available ); transfer_size -= bytes_available; data_in = ( (uint8_t*) data_in + bytes_available ); ring_buffer_consume( driver->rx_buffer, bytes_available ); } while ( transfer_size != 0 ); } } else { err = receive_bytes( driver, data_in, expected_data_size, timeout_ms ); } exit: //platform_mcu_powersave_enable(); return err; }
static void health_thread(void* arg) { app_context_t *app_context = (app_context_t *)arg; user_log_trace(); EKey ot; #if 0 u8 cup_status_temp, cup_status; cup_status = cup_status_temp = KEY_getValue(); #endif /* thread loop */ while(1){ #if 1 ot = GetOuterTriggerStatus(); if(OUTERTRIGGER_PICKUP == ot) { SetDrinkPutStatus(true); if(IsDrinkPutStatusChanged()) { SendJsonBool(app_context, "HEALTH-1/DrinkPutStatus", GetDrinkPutStatus()); if(!NoDisturbing() && IsPickupSetting()) { u8 type; u16 track_id; FindPickupTrack(&type, &track_id); AaSysLogPrint(LOGLEVEL_DBG, "track type %d index %d will be played", type, track_id); // stop last track before play new song SendQuitReq(); SendPlayReq(type, track_id); } } } else if(OUTERTRIGGER_PUTDOWN == ot) { SetDrinkPutStatus(false); if(IsDrinkPutStatusChanged()) { SendJsonBool(app_context, "HEALTH-1/DrinkPutStatus", GetDrinkPutStatus()); if(!NoDisturbing() && IsPutDownSetting()) { startPutDownTimerGroup(); } } } mico_thread_msleep(100); #elif if(mico_rtos_get_semaphore(&semaphore_getup, CHECK_CUPSTATUS_TIMEOUT)) { // key fliter cup_status_temp = KEY_getValue(); if(cup_status != cup_status_temp) { cup_status = cup_status_temp; SetDrinkStamp(true); if(!NoDisturbing() && IsPickupSetting()) { PlayingSong(FindPickupTrack()); } } } if(mico_rtos_get_semaphore(&semaphore_putdown, CHECK_CUPSTATUS_TIMEOUT)) { // key fliter cup_status_temp = KEY_getValue(); if(cup_status != cup_status_temp) { cup_status = cup_status_temp; SetPutDownStamp(true); if(!NoDisturbing() && IsPutDownSetting()) { startPutDownTimerGroup(); } } } #endif } }
OSStatus host_platform_spi_transfer( bus_transfer_direction_t dir, uint8_t* buffer, uint16_t buffer_length ) { OSStatus result; uint8_t *junk; MCU_CLOCKS_NEEDED(); #ifdef USE_OWN_SPI_DRV pdc_packet_t pdc_spi_packet; pdc_spi_packet.ul_addr = (uint32_t)buffer; pdc_spi_packet.ul_size = buffer_length; pdc_tx_init(spi_m_pdc, &pdc_spi_packet, NULL); if ( dir == BUS_READ ) { pdc_spi_packet.ul_addr = (uint32_t)buffer; pdc_spi_packet.ul_size = buffer_length; } if ( dir == BUS_WRITE ) { junk = malloc(buffer_length); pdc_spi_packet.ul_addr = (uint32_t)junk; pdc_spi_packet.ul_size = buffer_length; } pdc_rx_init(spi_m_pdc, &pdc_spi_packet, NULL); #if 0 if ( dir == BUS_WRITE ) { spi_enable_interrupt(SPI_MASTER_BASE, SPI_IER_ENDTX); NVIC_EnableIRQ(SPI_IRQn); } else { spi_enable_interrupt(SPI_MASTER_BASE, SPI_IER_ENDRX); NVIC_EnableIRQ(SPI_IRQn); } #endif //platform_log("dir = %d, len = %d",dir, buffer_length);//TBD #ifndef HARD_CS_NSS0 mico_gpio_output_low( MICO_GPIO_15 ); #endif /* Enable the RX and TX PDC transfer requests */ pdc_enable_transfer(spi_m_pdc, PERIPH_PTCR_TXTEN | PERIPH_PTCR_RXTEN);//pdc buffer address increase automatic. //platform_log("pdc status = 0x%x",pdc_read_status(spi_m_pdc)); #ifndef NO_MICO_RTOS result = mico_rtos_get_semaphore( &spi_transfer_finished_semaphore, 100 ); #else /* Waiting transfer done*/ while((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RXBUFF) == 0) { __asm("wfi"); } #endif if ( dir == BUS_WRITE ) { if (junk) free(junk); } /* Disable the RX and TX PDC transfer requests */ pdc_disable_transfer(spi_m_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); #ifndef HARD_CS_NSS0 mico_gpio_output_high( MICO_GPIO_15 ); #endif #if 1 //clear PDC Perph Status flags pdc_spi_packet.ul_addr = NULL; pdc_spi_packet.ul_size = 3; pdc_tx_init(spi_m_pdc, &pdc_spi_packet, NULL); pdc_rx_init(spi_m_pdc, &pdc_spi_packet, NULL); #endif #else //spi_master_vec : tx_dscr[0].data = buffer; tx_dscr[0].length = buffer_length; tx_dscr[1].data = NULL; tx_dscr[1].length = 0; //if ( dir == BUS_READ ) { rx_dscr[0].data = buffer; rx_dscr[0].length = buffer_length; //} else { // rx_dscr[0].data = &junk; // rx_dscr[0].length = 0; //} rx_dscr[1].data = NULL; rx_dscr[1].length = 0; #ifndef HARD_CS_NSS0 mico_gpio_output_low( MICO_GPIO_15 ); #endif if (spi_master_vec_transceive_buffer_wait(&spi_master, tx_dscr, rx_dscr) != STATUS_OK) { platform_log("STATUS = -1"); return kGeneralErr; } #ifndef HARD_CS_NSS0 mico_gpio_output_high( MICO_GPIO_15 ); #endif #endif /* USE_OWN_SPI_DR */ MCU_CLOCKS_NOT_NEEDED(); #ifdef USE_OWN_SPI_DRV return result; #else return 0; #endif }
void user2_upstream_thread(void* arg) { user_log_trace(); OSStatus err = kUnknownErr; app_context_t *app_context = (app_context_t *)arg; json_object *send_json_object = NULL; const char *upload_data = NULL; // user_log("ip address is :%s", ip_address); mico_rtos_init_semaphore( &switch_change_sem, 1); require(app_context, exit); /* thread loop */ while(1){ mico_rtos_get_semaphore(&switch_change_sem, MICO_WAIT_FOREVER); // create json object to format upload data send_json_object = json_object_new_object(); if(NULL == send_json_object){ user_log("create json object error!"); err = kNoMemoryErr; } else{ switch (msg_id ) { case 1: { json_object_object_add(send_json_object, "lamp_switch", json_object_new_boolean(lamp_switch)); break; } case 2: { json_object_object_add(send_json_object, "pump_switch", json_object_new_boolean(pump_switch)); break; } case 3: { json_object_object_add(send_json_object, "ip_address", json_object_new_string(app_context->mico_context->micoStatus.localIp)); break; } case 4: { json_object_object_add(send_json_object, "hasImage", json_object_new_boolean(true)); break; } default: { break; } } // add temperature/humidity data into a json oject upload_data = json_object_to_json_string(send_json_object); if(NULL == upload_data){ user_log("create upload data string error!"); err = kNoMemoryErr; } else{ // check fogcloud connect status if(app_context->appStatus.fogcloudStatus.isCloudConnected){ // upload data string to fogcloud, the seconde param(NULL) means send to defalut topic: '<device_id>/out' MiCOFogCloudMsgSend(app_context, NULL, (unsigned char*)upload_data, strlen(upload_data)); // user_log("upload data success! \t topic=%s/out \t dht11_temperature=%d, dht11_humidity=%d", // app_context->appConfig->fogcloudConfig.deviceId, // dht11_temperature, dht11_humidity); err = kNoErr; } } } // free json object memory json_object_put(send_json_object); send_json_object = NULL; } exit: if(kNoErr != err){ user_log("ERROR: user_uptream exit with err=%d", err); } mico_rtos_delete_thread(NULL); // delete current thread }