summaryrefslogtreecommitdiffstats
path: root/ucs2-vol/src/device_container.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ucs2-vol/src/device_container.cpp')
-rw-r--r--ucs2-vol/src/device_container.cpp171
1 files changed, 171 insertions, 0 deletions
diff --git a/ucs2-vol/src/device_container.cpp b/ucs2-vol/src/device_container.cpp
new file mode 100644
index 0000000..bda3b79
--- /dev/null
+++ b/ucs2-vol/src/device_container.cpp
@@ -0,0 +1,171 @@
+/*
+ * libmostvolume example
+ *
+ * Copyright (C) 2017 Microchip Technology Germany II GmbH & Co. KG
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * You may also obtain this software under a propriety license from Microchip.
+ * Please contact Microchip for further information.
+ *
+ */
+
+#include "device_container.h"
+#include "callbacks.h"
+#include "ucs_api.h"
+
+#define DEVCONT_TIME_RETRIGGER (uint16_t)100U
+#define DEVCONT_TIME_NOW (uint16_t)0U
+#define DEVCONT_TIME_STOP (uint16_t)0xFFFFU
+
+#define DEVCONT_UNUSED(a) (a = a)
+
+CDeviceContainer::CDeviceContainer()
+{
+ this->_idx_processing = 0U;
+ this->_ucs_inst_ptr = NULL;
+ this->_values_pptr = NULL;
+ this->_values_sz = 0U;
+ this->_tx_busy = false;
+ this->_service_requested = false;
+ this->_service_fptr = NULL;
+}
+
+CDeviceContainer::~CDeviceContainer()
+{
+ Clb_RegisterI2CResultCB(NULL, NULL); /* avoid that the result callback is fired after object is destroyed */
+}
+
+void CDeviceContainer::RegisterValues(CDeviceValue** list_pptr, uint16_t list_sz)
+{
+ this->_idx_processing = 0U;
+ this->_values_pptr = list_pptr;
+ this->_values_sz = list_sz;
+ this->_tx_busy = false;
+
+ if ((list_pptr != NULL) && (list_sz > 0U))
+ {
+ this->_idx_processing = list_sz - 1U;
+ }
+}
+
+void CDeviceContainer::ClearValues()
+{
+ this->_idx_processing = 0U;
+ this->_values_pptr = NULL;
+ this->_values_sz = 0U;
+ this->_tx_busy = false;
+}
+
+void CDeviceContainer::SetValue(uint16_t key, uint8_t value)
+{
+ uint16_t idx;
+ bool req_update = false;
+
+ for (idx = 0U; idx < this->_values_sz; idx++)
+ {
+ if (this->_values_pptr[idx]->GetKey() == key)
+ {
+ this->_values_pptr[idx]->SetValue(value);
+ if (this->_values_pptr[idx]->RequiresUpdate())
+ {
+ req_update = true;
+ }
+ }
+ }
+
+ if (req_update && (!this->_tx_busy))
+ {
+ RequestService(DEVCONT_TIME_NOW); //fire callback
+ }
+}
+
+void CDeviceContainer::IncrementProcIndex(void)
+{
+ if ((_idx_processing + 1U) >= this->_values_sz)
+ {
+ _idx_processing = 0U;
+ }
+ else
+ {
+ _idx_processing++;
+ }
+}
+
+// starts at latest position, searches next value to update, waits until response
+void CDeviceContainer::Update()
+{
+ uint16_t cnt;
+ bool error = false;
+ _service_requested = false;
+
+ if (this->_ucs_inst_ptr == NULL)
+ {
+ return;
+ }
+
+ if (this->_tx_busy)
+ {
+ return;
+ }
+
+ for (cnt = 0u; cnt < this->_values_sz; cnt++) /* just run one cycle */
+ {
+ IncrementProcIndex();
+
+ if (_values_pptr[_idx_processing]->RequiresUpdate())
+ {
+ if (_values_pptr[_idx_processing]->FireUpdateMessage())
+ {
+ Clb_RegisterI2CResultCB(&OnI2cResult, this);
+ this->_tx_busy = true;
+ break;
+ }
+ else
+ {
+ error = true;
+ }
+ }
+ }
+
+ if (error)
+ {
+ RequestService(DEVCONT_TIME_RETRIGGER);
+ }
+}
+
+void CDeviceContainer::HandleI2cResult(Ucs_I2c_Result_t result)
+{
+ DEVCONT_UNUSED(result);
+ this->_tx_busy = false;
+ this->RequestService(DEVCONT_TIME_NOW);
+}
+
+void CDeviceContainer::OnI2cResult(Ucs_I2c_Result_t result, void *obj_ptr)
+{
+ ((CDeviceContainer*)obj_ptr)->HandleI2cResult(result);
+}
+
+void CDeviceContainer::RequestService(uint16_t timeout)
+{
+ if (!_service_requested)
+ {
+ _service_requested = true;
+
+ if (_service_fptr != NULL)
+ {
+ _service_fptr(timeout);
+ }
+ }
+}