X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=ucs2-interface%2Fucs_lib_interf.c;h=f7376c357b2b4f15e46ad4d692195fc2bbb69393;hb=refs%2Fheads%2Fkoi;hp=5a6c08b73cd3a48527ed3334594179a0eb546d2d;hpb=fe0ce6f9892d29da52a4ed5024ebe9d5964c0171;p=apps%2Fagl-service-unicens.git diff --git a/ucs2-interface/ucs_lib_interf.c b/ucs2-interface/ucs_lib_interf.c index 5a6c08b..f7376c3 100644 --- a/ucs2-interface/ucs_lib_interf.c +++ b/ucs2-interface/ucs_lib_interf.c @@ -1,5 +1,5 @@ /*------------------------------------------------------------------------------------------------*/ -/* Unicens Integration Helper Component */ +/* UNICENS Integration Helper Component */ /* Copyright 2017, Microchip Technology Inc. and its subsidiaries. */ /* */ /* Redistribution and use in source and binary forms, with or without */ @@ -56,17 +56,24 @@ static void OnLldCtrlStop( void *lld_user_ptr ); static void OnLldCtrlRxMsgAvailable( void *lld_user_ptr ); static void OnLldCtrlTxTransmitC( Ucs_Lld_TxMsg_t *msg_ptr, void *lld_user_ptr ); static void OnUnicensRoutingResult(Ucs_Rm_Route_t* route_ptr, Ucs_Rm_RouteInfos_t route_infos, void *user_ptr); -static void OnUnicensMostPortStatus(uint16_t most_port_handle, - Ucs_Most_PortAvail_t availability, Ucs_Most_PortAvailInfo_t avail_info, - uint16_t free_streaming_bw, void* user_ptr); +static void OnUnicensNetworkStatus(uint16_t change_mask, uint16_t events, Ucs_Network_Availability_t availability, + Ucs_Network_AvailInfo_t avail_info, Ucs_Network_AvailTransCause_t avail_trans_cause, uint16_t node_address, + uint8_t node_position, uint8_t max_position, uint16_t packet_bw, void *user_ptr); static void OnUnicensDebugXrmResources(Ucs_Xrm_ResourceType_t resource_type, Ucs_Xrm_ResObject_t *resource_ptr, Ucs_Xrm_ResourceInfos_t resource_infos, Ucs_Rm_EndPoint_t *endpoint_inst_ptr, void *user_ptr); static void OnUcsInitResult(Ucs_InitResult_t result, void *user_ptr); static void OnUcsStopResult(Ucs_StdResult_t result, void *user_ptr); +static void OnUcsGpioPortCreate(uint16_t node_address, uint16_t gpio_port_handle, Ucs_Gpio_Result_t result, void *user_ptr); +static void OnUcsGpioPortWrite(uint16_t node_address, uint16_t gpio_port_handle, uint16_t current_state, uint16_t sticky_state, Ucs_Gpio_Result_t result, void *user_ptr); static void OnUcsMgrReport(Ucs_MgrReport_t code, uint16_t node_address, Ucs_Rm_Node_t *node_ptr, void *user_ptr); static void OnUcsNsRun(Ucs_Rm_Node_t * node_ptr, Ucs_Ns_ResultCode_t result, void *ucs_user_ptr); static void OnUcsAmsRxMsgReceived(void *user_ptr); +static void OnUcsGpioTriggerEventStatus(uint16_t node_address, uint16_t gpio_port_handle, + uint16_t rising_edges, uint16_t falling_edges, uint16_t levels, void * user_ptr); +static void OnUcsI2CWrite(uint16_t node_address, uint16_t i2c_port_handle, + uint8_t i2c_slave_address, uint8_t data_len, Ucs_I2c_Result_t result, void *user_ptr); +static void OnUcsAmsWrite(Ucs_AmsTx_Msg_t* msg_ptr, Ucs_AmsTx_Result_t result, Ucs_AmsTx_Info_t info, void *user_ptr); /************************************************************************/ /* Public Function Implementations */ @@ -90,7 +97,7 @@ void UCSI_Init(UCSI_Data_t *my, void *pTag) result = Ucs_SetDefaultConfig(&my->uniInitData); if(UCS_RET_SUCCESS != result) { - UCSI_CB_OnUserMessage(my->tag, true, "Can not set default values to Unicens config (result=0x%X)", 1, result); + UCSI_CB_OnUserMessage(my->tag, true, "Can not set default values to UNICENS config (result=0x%X)", 1, result); assert(false); return; } @@ -105,6 +112,8 @@ void UCSI_Init(UCSI_Data_t *my, void *pTag) my->uniInitData.general.debug_error_msg_fptr = &OnUnicensDebugErrorMsg; my->uniInitData.ams.enabled = ENABLE_AMS_LIB; my->uniInitData.ams.rx.message_received_fptr = &OnUcsAmsRxMsgReceived; + my->uniInitData.network.status.notification_mask = 0xC2; + my->uniInitData.network.status.cb_fptr = &OnUnicensNetworkStatus; my->uniInitData.lld.lld_user_ptr = my; my->uniInitData.lld.start_fptr = &OnLldCtrlStart; @@ -113,9 +122,10 @@ void UCSI_Init(UCSI_Data_t *my, void *pTag) my->uniInitData.lld.tx_transmit_fptr = &OnLldCtrlTxTransmitC; my->uniInitData.rm.report_fptr = &OnUnicensRoutingResult; - my->uniInitData.rm.xrm.most_port_status_fptr = &OnUnicensMostPortStatus; my->uniInitData.rm.debug_resource_status_fptr = &OnUnicensDebugXrmResources; + my->uniInitData.gpio.trigger_event_status_fptr = &OnUcsGpioTriggerEventStatus; + RB_Init(&my->rb, CMD_QUEUE_LEN, sizeof(UnicensCmdEntry_t), my->rbBuf); } @@ -166,6 +176,7 @@ bool UCSI_ProcessRxData(UCSI_Data_t *my, void UCSI_Service(UCSI_Data_t *my) { + Ucs_Return_t ret; UnicensCmdEntry_t *e; bool popEntry = true; /*Set to false in specific case, where function will callback asynchrony.*/ assert(MAGIC == my->magic); @@ -197,6 +208,61 @@ void UCSI_Service(UCSI_Data_t *my) if (UCS_RET_SUCCESS != Ucs_Ns_Run(my->unicens, e->val.NsRun.node_ptr, OnUcsNsRun)) UCSI_CB_OnUserMessage(my->tag, true, "Ucs_Ns_Run failed", 0); break; + case UnicensCmd_GpioCreatePort: + if (UCS_RET_SUCCESS == Ucs_Gpio_CreatePort(my->unicens, e->val.GpioCreatePort.destination, 0, e->val.GpioCreatePort.debounceTime, OnUcsGpioPortCreate)) + popEntry = false; + else + UCSI_CB_OnUserMessage(my->tag, true, "Ucs_Gpio_CreatePort failed", 0); + break; + case UnicensCmd_GpioWritePort: + if (UCS_RET_SUCCESS == Ucs_Gpio_WritePort(my->unicens, e->val.GpioWritePort.destination, 0x1D00, e->val.GpioWritePort.mask, e->val.GpioWritePort.data, OnUcsGpioPortWrite)) + popEntry = false; + else + UCSI_CB_OnUserMessage(my->tag, true, "UnicensCmd_GpioWritePort failed", 0); + break; + case UnicensCmd_I2CWrite: + ret = Ucs_I2c_WritePort(my->unicens, e->val.I2CWrite.destination, 0x0F00, + (e->val.I2CWrite.isBurst ? UCS_I2C_BURST_MODE : UCS_I2C_DEFAULT_MODE), e->val.I2CWrite.blockCount, + e->val.I2CWrite.slaveAddr, e->val.I2CWrite.timeout, e->val.I2CWrite.dataLen, e->val.I2CWrite.data, OnUcsI2CWrite); + if (UCS_RET_SUCCESS == ret) + popEntry = false; + else { + UCSI_CB_OnUserMessage(my->tag, true, "Ucs_I2c_WritePort failed ret=%d", 1, ret); + assert(e->val.I2CWrite.result_fptr != NULL); + e->val.I2CWrite.result_fptr(NULL /*processing error*/, e->val.I2CWrite.request_ptr); + } + break; + case UnicensCmd_SendAmsMessage: + { + Ucs_AmsTx_Msg_t *msg; + msg = Ucs_AmsTx_AllocMsg(my->unicens, e->val.SendAms.payloadLen); + if (NULL == msg) + { + /* Try again later */ + popEntry = false; + break; + } + if (0 != e->val.SendAms.payloadLen) + { + assert(NULL != msg->data_ptr); + memcpy(msg->data_ptr, e->val.SendAms.pPayload, e->val.SendAms.payloadLen); + } + msg->custom_info_ptr = NULL; + msg->data_size = e->val.SendAms.payloadLen; + msg->destination_address = e->val.SendAms.targetAddress; + msg->llrbc = 10; + msg->msg_id = e->val.SendAms.msgId; + if (UCS_RET_SUCCESS == Ucs_AmsTx_SendMsg(my->unicens, msg, OnUcsAmsWrite)) + { + popEntry = false; + } + else + { + Ucs_AmsTx_FreeUnusedMsg(my->unicens, msg); + UCSI_CB_OnUserMessage(my->tag, true, "Ucs_AmsTx_SendMsg failed", 0); + } + break; + } default: assert(false); break; @@ -217,26 +283,20 @@ void UCSI_Timeout(UCSI_Data_t *my) bool UCSI_SendAmsMessage(UCSI_Data_t *my, uint16_t msgId, uint16_t targetAddress, uint8_t *pPayload, uint32_t payloadLen) { - Ucs_AmsTx_Msg_t *msg; - Ucs_Return_t result; + UnicensCmdEntry_t entry; assert(MAGIC == my->magic); - if (NULL == my->unicens) return false; - msg = Ucs_AmsTx_AllocMsg(my->unicens, payloadLen); - if (NULL == msg) return false; - if (0 != payloadLen) + if (NULL == my) return false; + if (payloadLen > UCS_AMS_SIZE_TX_MSG) { - assert(NULL != msg->data_ptr); - memcpy(msg->data_ptr, pPayload, payloadLen); + UCSI_CB_OnUserMessage(my->tag, true, "SendAms was called with payload length=%d, allowed is=%d", 2, payloadLen, UCS_AMS_SIZE_TX_MSG); + return false; } - msg->custom_info_ptr = NULL; - msg->data_size = payloadLen; - msg->destination_address = targetAddress; - msg->llrbc = 10; - msg->msg_id = msgId; - result = Ucs_AmsTx_SendMsg(my->unicens, msg, NULL); - if (UCS_RET_SUCCESS != result) - Ucs_AmsTx_FreeUnusedMsg(my->unicens, msg); - return UCS_RET_SUCCESS == result; + entry.cmd = UnicensCmd_SendAmsMessage; + entry.val.SendAms.msgId = msgId; + entry.val.SendAms.targetAddress = targetAddress; + entry.val.SendAms.payloadLen = payloadLen; + memcpy(entry.val.SendAms.pPayload, pPayload, payloadLen); + return EnqueueCommand(my, &entry); } bool UCSI_GetAmsMessage(UCSI_Data_t *my, uint16_t *pMsgId, uint16_t *pSourceAddress, uint8_t **pPayload, uint32_t *pPayloadLen) @@ -279,6 +339,41 @@ bool UCSI_SetRouteActive(UCSI_Data_t *my, uint16_t routeId, bool isActive) return false; } +bool UCSI_I2CWrite(UCSI_Data_t *my, uint16_t targetAddress, bool isBurst, uint8_t blockCount, + uint8_t slaveAddr, uint16_t timeout, uint8_t dataLen, uint8_t *pData, + Ucsi_ResultCb_t result_fptr, void *request_ptr) +{ + UnicensCmdEntry_t entry; + assert(MAGIC == my->magic); + if (NULL == my || NULL == pData || 0 == dataLen) return false; + if (dataLen > I2C_WRITE_MAX_LEN) return false; + entry.cmd = UnicensCmd_I2CWrite; + entry.val.I2CWrite.destination = targetAddress; + entry.val.I2CWrite.isBurst = isBurst; + entry.val.I2CWrite.blockCount = blockCount; + entry.val.I2CWrite.slaveAddr = slaveAddr; + entry.val.I2CWrite.timeout = timeout; + entry.val.I2CWrite.dataLen = dataLen; + entry.val.I2CWrite.result_fptr = result_fptr; + entry.val.I2CWrite.request_ptr = request_ptr; + memcpy(entry.val.I2CWrite.data, pData, dataLen); + return EnqueueCommand(my, &entry); +} + +bool UCSI_SetGpioState(UCSI_Data_t *my, uint16_t targetAddress, uint8_t gpioPinId, bool isHighState) +{ + uint16_t mask; + UnicensCmdEntry_t entry; + assert(MAGIC == my->magic); + if (NULL == my) return false; + mask = 1 << gpioPinId; + entry.cmd = UnicensCmd_GpioWritePort; + entry.val.GpioWritePort.destination = targetAddress; + entry.val.GpioWritePort.mask = mask; + entry.val.GpioWritePort.data = isHighState ? mask : 0; + return EnqueueCommand(my, &entry); +} + /************************************************************************/ /* Private Functions */ /************************************************************************/ @@ -402,7 +497,7 @@ static void OnUnicensError( Ucs_Error_t error_code, void *user_ptr ) UCSI_Data_t *my = (UCSI_Data_t *)user_ptr; error_code = error_code; assert(MAGIC == my->magic); - UCSI_CB_OnUserMessage(my->tag, true, "Unicens general error, code=0x%X, restarting", 1, error_code); + UCSI_CB_OnUserMessage(my->tag, true, "UNICENS general error, code=0x%X, restarting", 1, error_code); e.cmd = UnicensCmd_Init; e.val.Init.init_ptr = &my->uniInitData; EnqueueCommand(my, &e); @@ -488,22 +583,20 @@ static void OnLldCtrlTxTransmitC( Ucs_Lld_TxMsg_t *msg_ptr, void *lld_user_ptr ) static void OnUnicensRoutingResult(Ucs_Rm_Route_t* route_ptr, Ucs_Rm_RouteInfos_t route_infos, void *user_ptr) { - /*TODO: implement*/ - route_ptr = route_ptr; - route_infos = route_infos; - user_ptr = user_ptr; + uint16_t conLabel; + UCSI_Data_t *my = (UCSI_Data_t *)user_ptr; + assert(MAGIC == my->magic); + conLabel = Ucs_Rm_GetConnectionLabel(my->unicens, route_ptr); + UCSI_CB_OnRouteResult(my->tag, route_ptr->route_id, UCS_RM_ROUTE_INFOS_BUILT == route_infos, conLabel); } -static void OnUnicensMostPortStatus(uint16_t most_port_handle, - Ucs_Most_PortAvail_t availability, Ucs_Most_PortAvailInfo_t avail_info, - uint16_t free_streaming_bw, void* user_ptr) +static void OnUnicensNetworkStatus(uint16_t change_mask, uint16_t events, Ucs_Network_Availability_t availability, + Ucs_Network_AvailInfo_t avail_info, Ucs_Network_AvailTransCause_t avail_trans_cause, uint16_t node_address, + uint8_t node_position, uint8_t max_position, uint16_t packet_bw, void *user_ptr) { - /*TODO: implement*/ - most_port_handle = most_port_handle; - availability = availability; - avail_info = avail_info; - free_streaming_bw = free_streaming_bw; - user_ptr = user_ptr; + UCSI_Data_t *my = (UCSI_Data_t *)user_ptr; + assert(MAGIC == my->magic); + UCSI_CB_OnNetworkState(my->tag, UCS_NW_AVAILABLE == availability, packet_bw, max_position); } static void OnUnicensDebugXrmResources(Ucs_Xrm_ResourceType_t resource_type, @@ -668,17 +761,24 @@ static void OnUcsStopResult(Ucs_StdResult_t result, void *user_ptr) UCSI_CB_OnStop(my->tag); } +static void OnUcsGpioPortCreate(uint16_t node_address, uint16_t gpio_port_handle, Ucs_Gpio_Result_t result, void *user_ptr) +{ + UCSI_Data_t *my = (UCSI_Data_t *)user_ptr; + assert(MAGIC == my->magic); + OnCommandExecuted(my, UnicensCmd_GpioCreatePort); +} + +static void OnUcsGpioPortWrite(uint16_t node_address, uint16_t gpio_port_handle, uint16_t current_state, uint16_t sticky_state, Ucs_Gpio_Result_t result, void *user_ptr) +{ + UCSI_Data_t *my = (UCSI_Data_t *)user_ptr; + assert(MAGIC == my->magic); + OnCommandExecuted(my, UnicensCmd_GpioWritePort); +} + static void OnUcsMgrReport(Ucs_MgrReport_t code, uint16_t node_address, Ucs_Rm_Node_t *node_ptr, void *user_ptr) { UCSI_Data_t *my = (UCSI_Data_t *)user_ptr; assert(MAGIC == my->magic); - if (node_ptr && node_ptr->script_list_ptr && node_ptr->script_list_size) - { - UnicensCmdEntry_t e; - e.cmd = UnicensCmd_NsRun; - e.val.NsRun.node_ptr = node_ptr; - EnqueueCommand(my, &e); - } switch (code) { case UCS_MGR_REP_IGNORED_UNKNOWN: @@ -688,8 +788,18 @@ static void OnUcsMgrReport(Ucs_MgrReport_t code, uint16_t node_address, Ucs_Rm_N UCSI_CB_OnUserMessage(my->tag, true, "Node=%X: Ignored, because duplicated", 1, node_address); break; case UCS_MGR_REP_AVAILABLE: + { + UnicensCmdEntry_t e; UCSI_CB_OnUserMessage(my->tag, false, "Node=%X: Available", 1, node_address); + /* Execute scripts, if there are any */ + if (node_ptr && node_ptr->script_list_ptr && node_ptr->script_list_size) + { + e.cmd = UnicensCmd_NsRun; + e.val.NsRun.node_ptr = node_ptr; + EnqueueCommand(my, &e); + } break; + } case UCS_MGR_REP_NOT_AVAILABLE: UCSI_CB_OnUserMessage(my->tag, false, "Node=%X: Not available", 1, node_address); break; @@ -697,6 +807,8 @@ static void OnUcsMgrReport(Ucs_MgrReport_t code, uint16_t node_address, Ucs_Rm_N UCSI_CB_OnUserMessage(my->tag, true, "Node=%X: unknown code", 1, node_address); break; } + + UCSI_CB_OnMgrReport(my->tag, code, node_address, node_ptr); } static void OnUcsNsRun(Ucs_Rm_Node_t * node_ptr, Ucs_Ns_ResultCode_t result, void *ucs_user_ptr) @@ -722,10 +834,53 @@ static void OnUcsAmsRxMsgReceived(void *user_ptr) UCSI_CB_OnAmsMessageReceived(my->tag); } -/*---------------------------------------- - * Debug Message output from Unicens stack: - *---------------------------------------- - */ +static void OnUcsGpioTriggerEventStatus(uint16_t node_address, uint16_t gpio_port_handle, + uint16_t rising_edges, uint16_t falling_edges, uint16_t levels, void * user_ptr) +{ + uint8_t i; + UCSI_Data_t *my = (UCSI_Data_t *)user_ptr; + assert(MAGIC == my->magic); + for (i = 0; i < 16; i++) + { + if (0 != ((rising_edges >> i) & 0x1)) + UCSI_CB_OnGpioStateChange(my->tag, node_address, i, true); + if (0 != ((falling_edges >> i) & 0x1)) + UCSI_CB_OnGpioStateChange(my->tag, node_address, i, false); + } +} + +static void OnUcsI2CWrite(uint16_t node_address, uint16_t i2c_port_handle, + uint8_t i2c_slave_address, uint8_t data_len, Ucs_I2c_Result_t result, void *user_ptr) +{ + UCSI_Data_t *my = (UCSI_Data_t *)user_ptr; + assert(MAGIC == my->magic); + + if ((my->currentCmd->cmd == UnicensCmd_I2CWrite) + && (my->currentCmd->val.I2CWrite.result_fptr)) { + + my->currentCmd->val.I2CWrite.result_fptr(&result.code, my->currentCmd->val.I2CWrite.request_ptr); + } + else { + assert(false); + } + + OnCommandExecuted(my, UnicensCmd_I2CWrite); + if (UCS_I2C_RES_SUCCESS != result.code) + UCSI_CB_OnUserMessage(my->tag, true, "Remote I2C Write to node=0x%X failed", 1, node_address); +} + +static void OnUcsAmsWrite(Ucs_AmsTx_Msg_t* msg_ptr, Ucs_AmsTx_Result_t result, Ucs_AmsTx_Info_t info, void *user_ptr) +{ + UCSI_Data_t *my = (UCSI_Data_t *)user_ptr; + assert(MAGIC == my->magic); + OnCommandExecuted(my, UnicensCmd_SendAmsMessage); + if (UCS_AMSTX_RES_SUCCESS != result) + UCSI_CB_OnUserMessage(my->tag, true, "SendAms failed with result=0x%x, info=0x%X", 2, result, info); +} + +/************************************************************************/ +/* Debug Message output from UNICENS stack: */ +/************************************************************************/ #if defined(UCS_TR_ERROR) || defined(UCS_TR_INFO) #include #define TRACE_BUFFER_SZ 200 @@ -733,7 +888,7 @@ void App_TraceError(void *ucs_user_ptr, const char module_str[], const char entr { va_list argptr; char outbuf[TRACE_BUFFER_SZ]; - void *tag; + void *tag = NULL; UCSI_Data_t *my = (UCSI_Data_t *)ucs_user_ptr; if (my) { @@ -741,7 +896,7 @@ void App_TraceError(void *ucs_user_ptr, const char module_str[], const char entr tag = my->tag; } va_start(argptr, vargs_cnt); - vsprintf(outbuf, entry_str, argptr); + vsnprintf(outbuf, sizeof(outbuf), entry_str, argptr); va_end(argptr); UCSI_CB_OnUserMessage(tag, true, "Error | %s | %s", 2, module_str, outbuf); } @@ -750,7 +905,7 @@ void App_TraceInfo(void *ucs_user_ptr, const char module_str[], const char entry { va_list argptr; char outbuf[TRACE_BUFFER_SZ]; - void *tag; + void *tag = NULL; UCSI_Data_t *my = (UCSI_Data_t *)ucs_user_ptr; if (my) { @@ -758,7 +913,7 @@ void App_TraceInfo(void *ucs_user_ptr, const char module_str[], const char entry tag = my->tag; } va_start(argptr, vargs_cnt); - vsprintf(outbuf, entry_str, argptr); + vsnprintf(outbuf, sizeof(outbuf), entry_str, argptr); va_end(argptr); UCSI_CB_OnUserMessage(tag, false, "Info | %s | %s", 2, module_str, outbuf); }