set initial volume from mute to default volume
[apps/agl-service-unicens.git] / ucs2-interface / ucs_lib_interf.c
index 5a6c08b..58b49d9 100644 (file)
@@ -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,23 @@ 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);
 
 /************************************************************************/
 /* Public Function Implementations                                      */
@@ -90,7 +96,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 +111,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 +121,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 +175,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 +207,30 @@ 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;
         default:
             assert(false);
             break;
@@ -279,6 +313,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 +471,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 +557,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 +735,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 +762,23 @@ 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);
+        /* Enable usage of remote GPIO ports */
+        e.cmd = UnicensCmd_GpioCreatePort;
+        e.val.GpioCreatePort.destination = node_address;
+        e.val.GpioCreatePort.debounceTime = 20;
+        EnqueueCommand(my, &e);
+        /* 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 +786,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 +813,44 @@ 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);
+}
+
+/************************************************************************/
+/* Debug Message output from UNICENS stack:                             */
+/************************************************************************/
 #if defined(UCS_TR_ERROR) || defined(UCS_TR_INFO)
 #include <stdio.h>
 #define TRACE_BUFFER_SZ 200
@@ -733,7 +858,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)
     {
@@ -750,7 +875,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)
     {