/**************************************************************************** * * Copy right: 2017-, Copyrigths of EigenComm Ltd. * File name: app.c * Description: EC616 onenet demo app source file * History: Rev1.0 2018-10-12 * ****************************************************************************/ #include "bsp.h" #include "bsp_custom.h" #include "osasys.h" #include "ostask.h" #include "queue.h" #include "ps_event_callback.h" #include "app.h" #include "cmisim.h" #include "cmimm.h" #include "cmips.h" #include "sockets.h" #include "psifevent.h" #include "ps_lib_api.h" #include "lwip/netdb.h" #include #include "debug_log.h" #include "slpman_ec616.h" #include "plat_config.h" // app task static stack and control block #define PROC_TASK_STACK_SIZE (1024) #define ONENET_TASK_STACK_SIZE (1024) #define RECV_BUFFER_LEN (16) #define RTE_UART_RX_IO_MODE RTE_UART1_RX_IO_MODE extern ARM_DRIVER_USART Driver_USART1; static ARM_DRIVER_USART *USARTdrv = &Driver_USART1; /** \brief usart receive buffer */ uint8_t recBuffer[RECV_BUFFER_LEN]; /** \brief usart send buffer */ uint8_t sendBuffer[RECV_BUFFER_LEN]; /** \brief receive timeout flag */ volatile bool isRecvTimeout = false; /** \brief receive complete flag */ volatile bool isRecvComplete = false; typedef enum { PROCESS_STATE_IDLE = 0, PROCESS_STATE_WORK, PROCESS_STATE_SLEEP }processSM; static StaticTask_t gOnenetTask; static uint8_t gOnenetTaskStack[ONENET_TASK_STACK_SIZE]; static StaticTask_t gProcessTask; static UINT8 gProcessTaskStack[PROC_TASK_STACK_SIZE]; static StaticTask_t gProcessTask2; static UINT8 gProcessTaskStack2[PROC_TASK_STACK_SIZE]; static processSM gProcState = PROCESS_STATE_IDLE; #define PROC_STATE_SWITCH(a) (gProcState = a) static UINT8 gImsi[16] = {0}; static UINT32 gCellID = 0; static NmAtiSyncRet gNetworkInfo; static appRunningState_t stateMachine = APP_INIT_STATE; uint8_t onenetASlpHandler = 0xff; uint8_t processSlpHandler = 0xff; static INT32 onenetPSUrcCallback(urcID_t eventID, void *param, UINT32 paramLen) { UINT8 rssi = 0; CmiSimImsiStr *imsi = NULL; CmiPsCeregInd *cereg = NULL; NmAtiNetifInfo *netif = NULL; switch(eventID) { case NB_URC_ID_SIM_READY: { imsi = (CmiSimImsiStr *)param; //memcpy(gImsi, imsi->contents, imsi->length); //DEBUG_TRACE(APP, TRACE_LEVEL_INFO,"SIM ready(imsi=%s len=%d)", imsi->contents, imsi->length); break; } case NB_URC_ID_MM_SIGQ: { rssi = *(UINT8 *)param; ECOMM_TRACE(UNILOG_PLA_APP, onenetPSUrcCallback_1, P_INFO, 1, "URCCallBack:RSSI signal=%d", rssi); break; } case NB_URC_ID_PS_BEARER_ACTED: { ECOMM_TRACE(UNILOG_PLA_APP, onenetPSUrcCallback_2, P_INFO, 0, "URCCallBack:Default bearer activated"); break; } case NB_URC_ID_PS_BEARER_DEACTED: { ECOMM_TRACE(UNILOG_PLA_APP, onenetPSUrcCallback_3, P_INFO, 0, "URCCallBack:Default bearer Deactivated"); break; } case NB_URC_ID_PS_CEREG_CHANGED: { cereg = (CmiPsCeregInd *)param; gCellID = cereg->celId; ECOMM_TRACE(UNILOG_PLA_APP, onenetPSUrcCallback_4, P_INFO, 4, "URCCallBack:CEREG changed act:%d celId:%d locPresent:%d tac:%d", cereg->act, cereg->celId, cereg->locPresent, cereg->tac); break; } case NB_URC_ID_PS_NETINFO: { netif = (NmAtiNetifInfo *)param; if (netif->netStatus == NM_NETIF_ACTIVATED) { stateMachine = APP_IPREADY_STATE; ECOMM_TRACE(UNILOG_PLA_APP, onenetPSUrcCallback_5, P_INFO, 0, "URCCallBack:PSIF network active"); } else if (netif->netStatus == NM_NETIF_OOS) { ECOMM_TRACE(UNILOG_PLA_APP, onenetPSUrcCallback_6, P_INFO, 0, "URCCallBack:PSIF network OOS"); } else if (netif->netStatus == NM_NO_NETIF_OR_DEACTIVATED || netif->netStatus == NM_NO_NETIF_NOT_DIAL) { stateMachine = APP_DEACTIVE_STATE; ECOMM_TRACE(UNILOG_PLA_APP, onenetPSUrcCallback_7, P_INFO, 0, "URCCallBack:PSIF network deactive"); } break; } } return 0; } static void onenetAppTask(void *arg) { cis_version_t ver; UINT8 cid[CMI_PS_CID_NUM] = {0}; UINT8 cidlen = 0; INT8 ret; UINT8 psmMode = 0, actType = 0, edrxModeValue = 0; UINT16 tac = 0; UINT32 tauTime = 0, activeTime = 0, cellID = 0, nwEdrxValueMs = 0, nwPtwMs = 0, reqEdrxValueMs = 0; UINT8 csq = 0, regstate = 0; INT8 snr = 0; INT8 rsrp = 0; cis_version(&ver); #ifdef USING_PRINTF printf("[%d]CIS SDK Version:%d.%d.%d",__LINE__,ver.major,ver.minor,ver.micro); #else ECOMM_TRACE(UNILOG_PLA_APP, onenetAppTask_0, P_INFO, 3, "CIS SDK Version:%u.%u.%u",ver.major,ver.minor,ver.micro); #endif // slpManSetPmuSleepMode(true, SLP_SLP2_STATE, false); // slpManApplyPlatVoteHandle("onenetAppTask",&onenetASlpHandler); // slpManPlatVoteDisableSleep(onenetASlpHandler, SLP_SLP2_STATE); while (1) { #ifdef USING_PRINTF printf("[%d]stateMachine:%d \r\n",__LINE__ ,stateMachine); #else ECOMM_TRACE(UNILOG_PLA_APP, onenetAppTask_sm, P_INFO, 1, "stateMachine:%u",stateMachine); #endif switch(stateMachine) { case APP_INIT_STATE: osDelay(2000/portTICK_PERIOD_MS); break; case APP_DEACTIVE_STATE: cisOnenetDeinit(); #ifdef USING_PRINTF printf("[%d] deinit onenet \r\n",__LINE__); #else ECOMM_TRACE(UNILOG_PLA_APP, onenetAppTask_1, P_INFO, 0, "deinit onenet"); #endif break; case APP_IPREADY_STATE: { appGetImsiNumSync(gImsi); #ifdef USING_PRINTF printf("[%d]IMSI = %s \r\n", __LINE__,gImsi); #else ECOMM_STRING(UNILOG_PLA_STRING, onenetAppTask_2, P_INFO, "IMSI = %s", gImsi); #endif ret = appGetSignalInfoSync(&csq, &snr, &rsrp); #ifdef USING_PRINTF printf("[%d] SNR=%d csq=%d, rsrp=%d\r\n",__LINE__, snr, csq, rsrp); #else ECOMM_TRACE(UNILOG_PLA_APP, onenetAppTask_SIG, P_INFO, 3, "SNR=%d csq=%d, rsrp=%d", snr, csq, rsrp); #endif ret = appGetLocationInfoSync(&tac, &cellID); #ifdef USING_PRINTF printf("[%d]tac=%d, cellID=%d ret=%d",__LINE__, tac, cellID, ret); #else ECOMM_TRACE(UNILOG_PLA_APP, onenetAppTask_3, P_INFO, 3, "tac=%d, cellID=%d ret=%d", tac, cellID, ret); #endif ret = appGetEDRXSettingSync(&actType, &nwEdrxValueMs, &nwPtwMs); #ifdef USING_PRINTF printf("[%d]actType=%d, nwEdrxValueMs=%d nwPtwMs=%d ret=%d",__LINE__, actType, nwEdrxValueMs, nwPtwMs, ret); #else ECOMM_TRACE(UNILOG_PLA_APP, onenetAppTask_4, P_INFO, 4, "actType=%d, nwEdrxValueMs=%d nwPtwMs=%d ret=%d", actType, nwEdrxValueMs, nwPtwMs, ret); #endif appGetPSMSettingSync(&psmMode, &tauTime, &activeTime); #ifdef USING_PRINTF printf("[%d]Get PSM info mode=%d, TAU=%d, ActiveTime=%d", __LINE__, psmMode, tauTime, activeTime); #else ECOMM_TRACE(UNILOG_PLA_APP, onenetAppTask_5, P_INFO, 3, "Get PSM info mode=%d, TAU=%d, ActiveTime=%d", psmMode, tauTime, activeTime); #endif if (psmMode == 0) appSetPSMSettingSync(1, 12*60*60, 100); // Make user obj/instance/resource prvMakeUserdata(); cisOnenetInit(); stateMachine = APP_REPORT_STATE; break; } case APP_REPORT_STATE: { #ifdef USING_PRINTF printf("[%d]check cis if ready\r\n",__LINE__); #else ECOMM_TRACE(UNILOG_PLA_APP, onenetAppTask_6, P_INFO, 0, "check cis if ready"); #endif if (cisAsyncCheckNotificationReady()) { if (cisAsynGetNotifyOnceStatus()) { stateMachine = APP_IDLE_STATE; break; } else { prvMakeUserdata(); cisDataObserveReport(); } } osDelay(10000/portTICK_PERIOD_MS); break; } case APP_IDLE_STATE: { //slpManPlatVoteEnableSleep(onenetASlpHandler, SLP_SLP2_STATE); // cancel the prohibition of sleep2 while(1) { #ifdef USING_PRINTF printf("[%d]Waiting sleep\r\n",__LINE__); #else ECOMM_TRACE(UNILOG_PLA_APP, onenetAppTask_sl0, P_INFO, 0, "Waiting sleep"); #endif osDelay(1000/portTICK_PERIOD_MS); } break; } } } } static void ProcBeforeSlp1(void *pdata, slpManLpState state) { slpManSlpState_t State = slpManPlatGetSlpState(); #ifdef USING_PRINTF printf("[%d]slp state=%d",__LINE__,State); #else ECOMM_TRACE(UNILOG_PLA_APP, ProcBeforeSlp1_0, P_SIG, 1, "slp state=%u",State); #endif /*Latch AONIO*/ slpManAONIOLatchEn(AonIOLatch_Enable); IOLatchEn res = slpManAONIOGetLatchCfg(); #ifdef USING_PRINTF printf("[%d]Get AONIO latch = %d\r\n",__LINE__,res); #else ECOMM_TRACE(UNILOG_PLA_APP, ProcBeforeSlp1_1, P_SIG, 1, "Get AONIO latch = %u",res); #endif } static void ProcAfterSlp1(void *pdata, slpManLpState state) { /*restore AONIO status*/ PowerPinConfig(AON_IO); #ifdef USING_PRINTF printf("[%d]After Sleep1, no matter sleep success or not this function will excute\r\n",__LINE__); #else ECOMM_TRACE(UNILOG_PLA_APP, ProcAfterSlp1_1, P_SIG, 0, "After Sleep1, no matter sleep success or not this function will excute"); #endif } static void ProcBeforeSlp2(void *pdata, slpManLpState state) { #ifdef USING_PRINTF printf("[%d]Before Sleep2\r\n",__LINE__); #else ECOMM_TRACE(UNILOG_PLA_APP, ProcBeforeSlp2_1, P_SIG, 0, "Before Sleep2"); #endif } static void ProcAfterSlp2(void *pdata, slpManLpState state) { #ifdef USING_PRINTF printf("[%d]Sleep2 Failed, Interrupt Pending. Only sleep failed this function will excute\r\n",__LINE__); #else ECOMM_TRACE(UNILOG_PLA_APP, ProcAfterSlp2_1, P_SIG, 0, "Sleep2 Failed, Interrupt Pending. Only sleep failed this function will excute"); #endif } static void ProcBeforeHib(void *pdata, slpManLpState state) { uint32_t *p_param = (uint32_t *)pdata; #ifdef USING_PRINTF printf("[%d]Before Hibernate = %x",__LINE__,*p_param); #else ECOMM_TRACE(UNILOG_PLA_APP, ProcBeforeHib_1, P_SIG, 1, "Before Hibernate = %x",*p_param); #endif } static void ProcAfterHib(void *pdata, slpManLpState state) { #ifdef USING_PRINTF printf("[%d]Try Hibernate Failed, Interrupt Pending. Only sleep failed this function will excute\r\n",__LINE__); #else ECOMM_TRACE(UNILOG_PLA_APP, ProcAfterHib_1, P_SIG, 0, "Try Hibernate Failed, Interrupt Pending. Only sleep failed this function will excute"); #endif } void GGACallBack(UINT8 res, UINT8 * params) { #ifdef USING_PRINTF printf("GPS:len=%d,data=%s\r\n",res,params); #else ECOMM_STRING(UNILOG_PLA_STRING, GPS_DATA, P_INFO, "gps:%s", params); #endif } void USART_callback(uint32_t event) { if(event & ARM_USART_EVENT_RX_TIMEOUT) { isRecvTimeout = true; } if(event & ARM_USART_EVENT_RECEIVE_COMPLETE) { isRecvComplete = true; } } static void processAppTask(void* arg) { uint32_t cnt; uint8_t buffer1[RECV_BUFFER_LEN]; buffer1[0]=0xff; buffer1[1]=0xfe; PROC_STATE_SWITCH(PROCESS_STATE_IDLE); while(1) { switch(gProcState) { case PROCESS_STATE_IDLE: { //slpManPlatVoteDisableSleep(processSlpHandler, SLP_SLP2_STATE); PROC_STATE_SWITCH(PROCESS_STATE_WORK); /* trigger irq config */ NVIC_EnableIRQ(PadWakeup0_IRQn); break; } case PROCESS_STATE_WORK: { /*just for debug ,PROCESS_STATE_WORK ,This state is used to handle normal business logic */ cnt = 2; UINT8 BUF[16]={0}; int i=1; while(1) { i++; NetSocDisplay(0,LED_TURN_OFF); osDelay(100); NetSocDisplay(0,LED_TURN_ON); osDelay(100); #ifdef USING_PRINTF printf("[%d]printf_test, i=%d, cnt=%d",__LINE__,i,cnt); #endif USARTdrv->Send(buffer1, 2); ECOMM_TRACE(UNILOG_PLA_APP, APPTask1, P_VALUE, 2, "printf_test, i=%u, cnt=%u",i,cnt); if (i>1000) { break; } } /* ready to sleep */ #ifdef USING_PRINTF printf("[%d]sleep switch, i=%d, cnt=%d",__LINE__,i,cnt); #endif PROC_STATE_SWITCH(PROCESS_STATE_SLEEP); break; } case PROCESS_STATE_SLEEP: { #ifdef USING_PRINTF printf("[%d]sleep entry"); #endif slpManSlpState_t State; uint8_t cnt; osDelay(3000/portTICK_PERIOD_MS); break; } } } } static void process2AppTask(void* arg) { USARTdrv->Initialize(USART_callback); USARTdrv->PowerControl(ARM_POWER_FULL); USARTdrv->Control(ARM_USART_MODE_ASYNCHRONOUS | ARM_USART_DATA_BITS_8 | ARM_USART_PARITY_NONE | ARM_USART_STOP_BITS_1 | ARM_USART_FLOW_CONTROL_NONE, 115200); uint8_t* greetStr = "UART Echo Demo\n"; USARTdrv->Send(greetStr, strlen((const char*)greetStr)); PROC_STATE_SWITCH(PROCESS_STATE_IDLE); while(1) { switch(gProcState) { case PROCESS_STATE_IDLE: { //slpManPlatVoteDisableSleep(processSlpHandler, SLP_SLP2_STATE); PROC_STATE_SWITCH(PROCESS_STATE_WORK); /* trigger irq config */ NVIC_EnableIRQ(PadWakeup0_IRQn); break; } case PROCESS_STATE_WORK: { /*just for debug ,PROCESS_STATE_WORK ,This state is used to handle normal business logic */ UINT8 BUF[16]={0}; int i=0; int cnt=0; while(1) { NetSocDisplay(1,LED_TURN_OFF); osDelay(400); NetSocDisplay(1,LED_TURN_ON); osDelay(600); USARTdrv->Receive(recBuffer, 16); USARTdrv->Send(recBuffer, 16); } PROC_STATE_SWITCH(PROCESS_STATE_SLEEP); break; } case PROCESS_STATE_SLEEP: { slpManSlpState_t State; uint8_t cnt; osDelay(3000/portTICK_PERIOD_MS); break; } } } } void processInit(void) { osThreadAttr_t task_attr; #ifndef USING_PRINTF if(BSP_GetPlatConfigItemValue(PLAT_CONFIG_ITEM_LOG_CONTROL) != 0) { HAL_UART_RecvFlowControl(false); } #endif memset(&task_attr,0,sizeof(task_attr)); memset(gProcessTaskStack, 0xA5,PROC_TASK_STACK_SIZE); task_attr.name = "ProcessAppTask"; task_attr.stack_mem = gProcessTaskStack; task_attr.stack_size = PROC_TASK_STACK_SIZE; task_attr.priority = osPriorityNormal;//osPriorityBelowNormal; task_attr.cb_mem = &gProcessTask;//task control block task_attr.cb_size = sizeof(StaticTask_t);//size of task control block osThreadNew(processAppTask, NULL, &task_attr); } void process2Init(void) { osThreadAttr_t task_attr; memset(&task_attr,0,sizeof(task_attr)); memset(gProcessTaskStack2, 0xA5,PROC_TASK_STACK_SIZE); task_attr.name = "Process2AppTask"; task_attr.stack_mem = gProcessTaskStack2; task_attr.stack_size = PROC_TASK_STACK_SIZE; task_attr.priority = osPriorityNormal;//osPriorityBelowNormal; task_attr.cb_mem = &gProcessTask2;//task control block task_attr.cb_size = sizeof(StaticTask_t);//size of task control block osThreadNew(process2AppTask, NULL, &task_attr); } void onenetInit() { osThreadAttr_t task_attr; registerPSEventCallback(NB_GROUP_ALL_MASK, onenetPSUrcCallback); memset(&task_attr,0,sizeof(task_attr)); memset(gOnenetTaskStack, 0xA5, ONENET_TASK_STACK_SIZE); task_attr.name = "OnenetAppTask"; task_attr.stack_mem = gOnenetTaskStack; task_attr.stack_size = ONENET_TASK_STACK_SIZE; task_attr.priority = osPriorityNormal; task_attr.cb_mem = &gOnenetTask;//task control block task_attr.cb_size = sizeof(StaticTask_t);//size of task control block osThreadNew(onenetAppTask, NULL, &task_attr); } void appInit(void *arg) { AdcTaskInit(); // onenetInit(); processInit(); process2Init(); } /** \fn int main_entry(void) \brief main entry function. \return */ void main_entry(void) { BSP_CommonInit(); osKernelInitialize(); registerAppEntry(appInit, NULL); if (osKernelGetState() == osKernelReady) { osKernelStart(); } while(1); }