From 620164975a968c4404c96f3e9ed1a7b9a63d6cb6 Mon Sep 17 00:00:00 2001 From: Tobias Jahnke Date: Wed, 23 Aug 2017 10:53:41 +0200 Subject: implements value retransmit and reload on failure --- HAL-afb/HAL_MOST_UNICENS/hal_most_unicens.c | 72 +++++++++++++++++++++- .../ucs2-vol/inc/device_container.h | 1 - .../HAL_MOST_UNICENS/ucs2-vol/inc/device_value.h | 13 ++-- .../ucs2-vol/src/device_container.cpp | 11 ++-- .../HAL_MOST_UNICENS/ucs2-vol/src/device_value.cpp | 66 ++++++++++++-------- HAL-afb/HAL_MOST_UNICENS/wrap_unicens.c | 4 +- 6 files changed, 128 insertions(+), 39 deletions(-) diff --git a/HAL-afb/HAL_MOST_UNICENS/hal_most_unicens.c b/HAL-afb/HAL_MOST_UNICENS/hal_most_unicens.c index 031c5b8..06fc0c1 100644 --- a/HAL-afb/HAL_MOST_UNICENS/hal_most_unicens.c +++ b/HAL-afb/HAL_MOST_UNICENS/hal_most_unicens.c @@ -28,12 +28,78 @@ #endif #define ALSA_CARD_NAME "Microchip MOST:1" +#define ALSA_DEVICE_ID "hw:1" #define PCM_MAX_CHANNELS 6 static int master_volume; static json_bool master_switch; static int pcm_volume[PCM_MAX_CHANNELS]; +static void unicens_request_card_values_cb(void *closure, int status, struct json_object *j_response) { + + json_object *j_obj; + int num_id; + int values[6]; + + AFB_INFO("unicens_request_card_values_cb: closure=%p status=%d, res=%s", closure, status, json_object_to_json_string(j_response)); + + json_object_object_get_ex(j_response, "response", &j_obj); + + if (json_object_is_type(j_obj, json_type_object)) { + + } + else if (json_object_is_type(j_obj, json_type_array)) { + AFB_ERROR("unicens_request_card_values_cb: array not handled yet"); + return; + } + else { + AFB_ERROR("unicens_request_card_values_cb: unknown response type"); + return; + } + + if (wrap_json_unpack(j_obj, "{s:i, s:[iiiiii!]}", "id", &num_id, "val", + &values[0], &values[1], &values[2], &values[3], &values[4], &values[5]) + == 0) { + AFB_NOTICE("unicens_request_card_values_cb: success, num id:%d", num_id); + } + else { + AFB_ERROR("unicens_request_card_values_cb: unpack failure"); + return; + } + +#if 0 + if (num_id == 2) { + wrap_volume_pcm(&values[0], 6); + } +#endif + +} + +__attribute__ ((unused)) static void unicens_request_card_values(const char* dev_id) { + + int err; + json_object *j_query = NULL; + + err = wrap_json_pack(&j_query, "{s:s, s:i}", "devid", dev_id, "mode", 0); + + if (err) { + AFB_ERROR("Failed to call wrap_json_pack"); + goto OnErrorExit; + } + + afb_service_call("alsacore", "getctl", j_query, + &unicens_request_card_values_cb, + NULL); + + if (err) { + AFB_ERROR("Failed to call listconfig"); + goto OnErrorExit; + } + +OnErrorExit: + return; +} + void unicens_master_vol_cb(halCtlsTagT tag, alsaHalCtlMapT *control, void* handle, json_object *j_obj) { const char *j_str = json_object_to_json_string(j_obj); @@ -142,7 +208,10 @@ STATIC int unicens_service_init() { AFB_ERROR("Failed to initialize wrapper for volume library"); goto OnErrorExit; } - + + /* request of initial card values */ + /* unicens_request_card_values(ALSA_DEVICE_ID); */ + OnErrorExit: AFB_NOTICE("Initializing HAL-MOST-UNICENS-BINDING done.."); return err; @@ -166,7 +235,6 @@ PUBLIC void unicens_event_cb(const char *evtname, json_object *j_event) { AFB_NOTICE("Node-Availability: node=0x%03X, available=%d", node, available); wrap_volume_node_avail(node, available); } - } return; diff --git a/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/inc/device_container.h b/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/inc/device_container.h index b7f373c..9fabdb5 100644 --- a/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/inc/device_container.h +++ b/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/inc/device_container.h @@ -45,7 +45,6 @@ private: void RequestService(uint16_t timeout); void IncrementProcIndex(void); void HandleI2cResult(uint8_t result); - static void OnI2cResult(uint8_t result, void *obj_ptr); uint16_t _idx_processing; diff --git a/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/inc/device_value.h b/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/inc/device_value.h index 6311346..bc8f142 100644 --- a/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/inc/device_value.h +++ b/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/inc/device_value.h @@ -73,23 +73,28 @@ public: lib_most_volume_writei2c_result_cb_t result_fptr, void *result_user_ptr);// fires message & updates actual value - void SetAvailable(bool active){this->_is_available = active;} + void SetAvailable(bool active){this->_is_available = active; _actual_value = 0x01u;} bool IsAvailable() {return this->_is_available;} uint16_t GetAddress() {return this->_address;} private: - void HandleI2cResult(uint8_t result); void ApplyMostValue(uint8_t value, DeviceValueType type, uint8_t tx_payload[]); + void HandleI2cResult(uint8_t result); + static void OnI2cResult(uint8_t result, void *obj_ptr); - bool _is_initial; // ensure first update - bool _is_available; // related node is available + bool _is_available; // related node is available + bool _is_busy; // do not update while busy DeviceValueType _type; // determines the remote i2c command uint16_t _key; // lookup key uint16_t _address; // target node/group address uint8_t _target_value; // desired value + uint8_t _transmitted_value;// value pending during transmission uint8_t _actual_value; // value set and confirmed via network uint8_t _tx_payload[20]; uint8_t _tx_payload_sz; + + lib_most_volume_writei2c_result_cb_t _result_fptr; + void *_result_user_ptr; }; #endif /* DEVICEPROPERTY_H */ diff --git a/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/src/device_container.cpp b/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/src/device_container.cpp index 4c99c89..f8b1961 100644 --- a/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/src/device_container.cpp +++ b/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/src/device_container.cpp @@ -24,7 +24,7 @@ #include #include "device_container.h" -#define DEVCONT_TIME_RETRIGGER (uint16_t)100U +#define DEVCONT_TIME_RETRIGGER (uint16_t)30U #define DEVCONT_TIME_NOW (uint16_t)0U #define DEVCONT_TIME_STOP (uint16_t)0xFFFFU @@ -123,13 +123,14 @@ void CDeviceContainer::Update() &OnI2cResult, this)) { - /*Clb_RegisterI2CResultCB(&OnI2cResult, this);*/ this->_tx_busy = true; + error = false; break; } else { error = true; + break; } } } @@ -142,9 +143,11 @@ void CDeviceContainer::Update() void CDeviceContainer::HandleI2cResult(uint8_t result) { - DEVCONT_UNUSED(result); this->_tx_busy = false; - this->RequestService(DEVCONT_TIME_NOW); + if (result == 0) + this->RequestService(DEVCONT_TIME_NOW); + else + this->RequestService(DEVCONT_TIME_RETRIGGER); } void CDeviceContainer::OnI2cResult(uint8_t result, void *obj_ptr) diff --git a/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/src/device_value.cpp b/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/src/device_value.cpp index b5f5679..7103192 100644 --- a/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/src/device_value.cpp +++ b/HAL-afb/HAL_MOST_UNICENS/ucs2-vol/src/device_value.cpp @@ -20,7 +20,7 @@ * Please contact Microchip for further information. * */ - +#include #include "device_value.h" #include "setup.h" @@ -34,11 +34,14 @@ CDeviceValue::CDeviceValue(uint16_t address, DeviceValueType type, uint16_t key) { - this->_is_initial = true; this->_is_available = false; + this->_is_busy = false; this->_address = address; this->_target_value = 0x01u; this->_actual_value = 0x01u; + + this->_result_fptr = NULL; + this->_result_user_ptr = NULL; this->_type = type; this->_key = key; @@ -86,7 +89,7 @@ void CDeviceValue::ApplyMostValue(uint8_t value, DeviceValueType type, uint8_t t // returns true if target is not actual value bool CDeviceValue::RequiresUpdate() { - if (this->_is_available && (this->_target_value != this->_actual_value)) + if (this->_is_available && !this->_is_busy && (this->_target_value != this->_actual_value)) { return true; } @@ -101,34 +104,45 @@ bool CDeviceValue::FireUpdateMessage(lib_most_volume_writei2c_cb_t writei2c_fptr int ret = -1; ApplyMostValue(this->_target_value, _type, _tx_payload); - if (this->_is_available) + if (this->_is_available && !this->_is_busy) { ret = writei2c_fptr(this->_address, &_tx_payload[0], _tx_payload_sz, - result_fptr, - result_user_ptr); + &OnI2cResult, + this); + + if (ret == 0) + { + this->_transmitted_value = this->_target_value; + this->_is_busy = true; + this->_result_fptr = result_fptr; + this->_result_user_ptr = result_user_ptr; + return true; + } } - if (ret == 0) + return false; +} + +void CDeviceValue::HandleI2cResult(uint8_t result) +{ + if (result == 0) { - // Clb_RegisterI2CResultCB(OnI2cResult, this); - // mark value as set! - this->_actual_value = this->_target_value; - return true; + /* transmission succeeded - now apply transmitted value */ + this->_actual_value = this->_transmitted_value; } - - return false; + + if (this->_result_fptr) + { + /* notify container */ + this->_result_fptr(result, this->_result_user_ptr); + } + + this->_result_fptr = NULL; + this->_result_user_ptr = NULL; + this->_is_busy = false; } -#if 0 - ret = Ucs_I2c_WritePort( CSetup::GetInstance()->RetrieveUnicensInst(), - this->_address, - 0x0F00u, /* i2c port handle */ - UCS_I2C_DEFAULT_MODE, /* 0 */ - 0u, /* block count */ - 0x2Au, /* i2c slave address */ - 0x03E8u, /* timeout 1000 milliseconds */ - _tx_payload_sz, /* data length */ - &_tx_payload[0], /* data pointer */ - &Clb_OnWriteI2CPortResult - ); -#endif +void CDeviceValue::OnI2cResult(uint8_t result, void *obj_ptr) +{ + ((CDeviceValue*)obj_ptr)->HandleI2cResult(result); +} diff --git a/HAL-afb/HAL_MOST_UNICENS/wrap_unicens.c b/HAL-afb/HAL_MOST_UNICENS/wrap_unicens.c index 0923c26..095a2fe 100644 --- a/HAL-afb/HAL_MOST_UNICENS/wrap_unicens.c +++ b/HAL-afb/HAL_MOST_UNICENS/wrap_unicens.c @@ -277,8 +277,8 @@ static void wrap_ucs_i2cwrite_cb(void *closure, int status, struct json_object * async_job_t *job_ptr = (async_job_t *)closure; if (job_ptr->result_fptr) - job_ptr->result_fptr(0U, job_ptr->result_user_ptr); - + job_ptr->result_fptr((uint8_t)abs(status), job_ptr->result_user_ptr); + free(closure); } } -- cgit 1.2.3-korg