diff options
author | Ronan Le Martret <ronan.lemartret@iot.bzh> | 2017-06-12 11:17:04 +0200 |
---|---|---|
committer | Ronan Le Martret <ronan.lemartret@iot.bzh> | 2017-06-29 14:40:09 +0200 |
commit | ec59d20bafb3acaaff2bbcab185a074825319e20 (patch) | |
tree | 2262fa512acadeb1dfa68bad7b2bb5a5c7de2467 /ucs2-lib/src/ucs_pmfifos.c | |
parent | a57c0b35c05c84f31ec09d3ac46b298555aa0cfb (diff) |
Update package
* use sub module for ucs2-lib (tmp fork from IoT.bzh github)
* add packaging for native build
Signed-off-by: Ronan Le Martret <ronan.lemartret@iot.bzh>
Diffstat (limited to 'ucs2-lib/src/ucs_pmfifos.c')
-rw-r--r-- | ucs2-lib/src/ucs_pmfifos.c | 448 |
1 files changed, 0 insertions, 448 deletions
diff --git a/ucs2-lib/src/ucs_pmfifos.c b/ucs2-lib/src/ucs_pmfifos.c deleted file mode 100644 index 347c1b9..0000000 --- a/ucs2-lib/src/ucs_pmfifos.c +++ /dev/null @@ -1,448 +0,0 @@ -/*------------------------------------------------------------------------------------------------*/ -/* UNICENS V2.1.0-3491 */ -/* 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. */ -/*------------------------------------------------------------------------------------------------*/ - -/*! - * \file - * \brief Implementation of class CPmFifos - * - * \cond UCS_INTERNAL_DOC - * \addtogroup G_PMFIFOS - * @{ - */ - -/*------------------------------------------------------------------------------------------------*/ -/* Includes */ -/*------------------------------------------------------------------------------------------------*/ -#include "ucs_pmfifos.h" -#include "ucs_misc.h" -#include "ucs_trace.h" - -/*------------------------------------------------------------------------------------------------*/ -/* Internal Constants */ -/*------------------------------------------------------------------------------------------------*/ -/*! \brief The initialization value of sync_count. It is incremented for each sync or un-sync attempt. */ -static const uint8_t FIFOS_SYNC_CNT_INITIAL = 0xFFU; - -/*------------------------------------------------------------------------------------------------*/ -/* Internal typedefs */ -/*------------------------------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------------------------------*/ -/* Internal prototypes */ -/*------------------------------------------------------------------------------------------------*/ -static void Fifos_Cleanup(CPmFifos *self); -static void Fifos_OnSyncTimeout(void *self); -static void Fifos_OnUnsyncTimeout(void *self); -static void Fifos_OnFifoEvent(void *self, void *fifo_id_ptr); - -static void Fifos_HandleFifoStateChange(CPmFifos *self, Pmp_FifoId_t fifo_id); -static bool Fifos_AreAllFifosInState(CPmFifos *self, Fifo_SyncState_t target_state); - -/*------------------------------------------------------------------------------------------------*/ -/* Implementation */ -/*------------------------------------------------------------------------------------------------*/ -/*! \brief Constructor of class CPmFifos - * \param self The instance - * \param base_ptr Reference to basic services - * \param channel_ptr Reference to the port message channel - * \param icm_fifo_ptr Reference to ICM FIFO, or NULL. - * \param mcm_fifo_ptr Reference to MCM FIFO, or NULL. - * \param rcm_fifo_ptr Reference to RCM FIFO, or NULL. - * \details At least one FIFO (MCM or ICM) must be provided. - */ -void Fifos_Ctor(CPmFifos *self, CBase *base_ptr, CPmChannel *channel_ptr, CPmFifo *icm_fifo_ptr, CPmFifo *mcm_fifo_ptr, CPmFifo *rcm_fifo_ptr) -{ - MISC_MEM_SET(self, 0, sizeof(*self)); - - self->base_ptr = base_ptr; - self->channel_ptr = channel_ptr; - self->state = FIFOS_S_UNSYNCED; - - self->unsync_initial = false; - Fifos_ConfigureSyncParams(self, FIFOS_SYNC_RETRIES, FIFOS_SYNC_TIMEOUT); - - self->fifos[PMP_FIFO_ID_ICM] = icm_fifo_ptr; - self->fifos[PMP_FIFO_ID_RCM] = rcm_fifo_ptr; - self->fifos[PMP_FIFO_ID_MCM] = mcm_fifo_ptr; - - T_Ctor(&self->init_timer); - Sub_Ctor(&self->event_subject, self->base_ptr->ucs_user_ptr); - Obs_Ctor(&self->obs_icm, self, &Fifos_OnFifoEvent); - Obs_Ctor(&self->obs_rcm, self, &Fifos_OnFifoEvent); - Obs_Ctor(&self->obs_mcm, self, &Fifos_OnFifoEvent); - - TR_ASSERT(self->base_ptr->ucs_user_ptr, "[FIFOS]", (!((icm_fifo_ptr == NULL) && (mcm_fifo_ptr == NULL)))); - - if (icm_fifo_ptr != NULL) - { - Fifo_AddStateObserver(icm_fifo_ptr, &self->obs_icm); - } - - if (rcm_fifo_ptr != NULL) - { - Fifo_AddStateObserver(rcm_fifo_ptr, &self->obs_rcm); - } - - if (mcm_fifo_ptr != NULL) - { - Fifo_AddStateObserver(mcm_fifo_ptr, &self->obs_mcm); - } - - TR_INFO((self->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_Ctor(): FIFOS created, state %d", 1U, self->state)); -} - -/*! \brief Adds an observer of synchronization events - * \param self The instance - * \param obs_ptr The observer. The notification result type is Fifos_Event_t. - */ -void Fifos_AddEventObserver(CPmFifos *self, CObserver *obs_ptr) -{ - TR_ASSERT(self->base_ptr->ucs_user_ptr, "[FIFOS]", (obs_ptr != 0)); - (void)Sub_AddObserver(&self->event_subject, obs_ptr); -} - -/*! \brief Removes an observer of synchronization events - * \param self The instance - * \param obs_ptr The observer. - */ -void Fifos_RemoveEventObserver(CPmFifos *self, CObserver *obs_ptr) -{ - TR_ASSERT(self->base_ptr->ucs_user_ptr, "[FIFOS]", (obs_ptr != 0)); - (void)Sub_RemoveObserver(&self->event_subject, obs_ptr); -} - -/*! \brief Forces all FIFOs to state UNSYNCED without waiting for INIC responses and - * without throwing events - * \details Stops the LLD interface and releases all pending message resources. - * This function shall be called if the UCS requires a un-normal termination - * which is not detected by port message protocol. - * \param self The instance - */ -void Fifos_ForceTermination(CPmFifos *self) -{ - TR_INFO((self->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_ForceTermination(): Termination started, state: %d", 1U, self->state)); - Fifos_Cleanup(self); - TR_INFO((self->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_ForceTermination(): Termination done, state: %d", 1U, self->state)); -} - -/*! \brief Configures retries and timeout for synchronize or un-synchronize - * operation - * \details This method shall be called before starting a synchronization or un-synchronization - * or after it has finished. The current counter of synchronization attempts is reset. - * \param self The instance - * \param retries The number of retries until event FIFOS_EV_SYNC_FAILED or - * FIFOS_EV_UNSYNC_FAILED will be notified - * \param timeout The timeout in milliseconds when the retry is performed - */ -void Fifos_ConfigureSyncParams(CPmFifos *self, uint8_t retries, uint16_t timeout) -{ - self->cmd_retries = retries; - self->cmd_timeout = timeout; - self->sync_cnt = FIFOS_SYNC_CNT_INITIAL; -} - -/*------------------------------------------------------------------------------------------------*/ -/* Synchronization */ -/*------------------------------------------------------------------------------------------------*/ -/*! \brief Initializes all port message FIFOs - * \details Possible results of the operation are the following events which are fired - * asynchronously. Refer also Fifos_AddEventObserver() and \ref Fifos_Event_t. - * - \ref FIFOS_EV_SYNC_ESTABLISHED - * - \ref FIFOS_EV_SYNC_FAILED - * \param self The instance - * \param reset_cnt If \c true resets the synchronization counter. In this case an automatic - * retries will be done after the first synchronization timeout. - * \param force_sync If \c true the method will also trigger the synchronization of already - * synced \ref CPmFifo objects. - */ -void Fifos_Synchronize(CPmFifos *self, bool reset_cnt, bool force_sync) -{ - uint8_t cnt; - self->state = FIFOS_S_SYNCING; - self->unsync_initial = false; - TR_INFO((self->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_Synchronize(): Synchronization started, state: %d", 1U, self->state)); - - if (reset_cnt) - { - self->sync_cnt = FIFOS_SYNC_CNT_INITIAL; - } - - self->sync_cnt++; - Pmch_Initialize(self->channel_ptr); /* Start LLD if not already done */ - - for (cnt = 0U; cnt < PMP_MAX_NUM_FIFOS; cnt++) - { - if (self->fifos[cnt] != NULL) - { - if (force_sync || (Fifo_GetState(self->fifos[cnt]) != FIFO_S_SYNCED)) - { - Fifo_Synchronize(self->fifos[cnt]); - } - } - } - - Tm_SetTimer(&self->base_ptr->tm, &self->init_timer, - &Fifos_OnSyncTimeout, self, - self->cmd_timeout, 0U); -} - -/*! \brief Un-initializes all port message FIFOs - * \details Possible results of the operation are the following events which are fired - * asynchronously. Refer also Fifos_AddEventObserver() and \ref Fifos_Event_t. - * - \ref FIFOS_EV_UNSYNC_COMPLETE - * - \ref FIFOS_EV_UNSYNC_FAILED - * \param self The instance - * \param reset_cnt If \c true resets the synchronization counter. In this case an automatic - * retries will be done after the first synchronization timeout. - * \param initial If the un-synchronization shall be executed prior to a initial synchronization - * it is recommended to set the argument to \c true. After notifying the event - * FIFOS_EV_UNSYNC_COMPLETE the LLD interface will not be stopped. The subsequent - * call of Fifos_Synchronize() will not start the LLD interface un-necessarily. - * To trigger a final un-synchronization \c initial shall be set to \c false. - * I.e., FIFOS_EV_UNSYNC_COMPLETE stops the LLD interface. - */ -void Fifos_Unsynchronize(CPmFifos *self, bool reset_cnt, bool initial) -{ - uint8_t cnt; - self->state = FIFOS_S_UNSYNCING; - self->unsync_initial = initial; - TR_INFO((self->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_Unsynchronize(): Un-synchronization started, state: %d", 1U, self->state)); - - if (reset_cnt) - { - self->sync_cnt = FIFOS_SYNC_CNT_INITIAL; - } - - self->sync_cnt++; - Pmch_Initialize(self->channel_ptr); /* Start LLD if not already done */ - - for (cnt = 0U; cnt < PMP_MAX_NUM_FIFOS; cnt++) - { - if (self->fifos[cnt] != NULL) - { - if (initial || (Fifo_GetState(self->fifos[cnt]) != FIFO_S_UNSYNCED_READY)) - { - Fifo_Unsynchronize(self->fifos[cnt]); - } - } - } - - Tm_SetTimer(&self->base_ptr->tm, &self->init_timer, - &Fifos_OnUnsyncTimeout, self, - self->cmd_timeout, 0U); -} - -/*! \brief Handles the synchronization timeout - * \param self The instance - */ -static void Fifos_OnSyncTimeout(void *self) -{ - CPmFifos *self_ = (CPmFifos*)self; - Fifos_Event_t the_event = FIFOS_EV_SYNC_FAILED; - - self_->state = FIFOS_S_UNSYNCED; - - TR_INFO((self_->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_OnSyncTimeout(): state: %d", 1U, self_->state)); - - if (self_->sync_cnt < self_->cmd_retries) - { - Fifos_Synchronize(self_, false, false); /* retry synchronization after first timeout */ - } - else - { - Fifos_Cleanup(self_); - Sub_Notify(&self_->event_subject, &the_event); - } -} - -/*! \brief Handles the un-synchronization timeout - * \param self The instance - */ -static void Fifos_OnUnsyncTimeout(void *self) -{ - CPmFifos *self_ = (CPmFifos*)self; - Fifos_Event_t the_event = FIFOS_EV_UNSYNC_FAILED; - - self_->state = FIFOS_S_UNSYNCED; - TR_INFO((self_->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_OnUnsyncTimeout(): state: %d", 1U, self_->state)); - - if (self_->sync_cnt < self_->cmd_retries) - { - Fifos_Unsynchronize(self_, false, self_->unsync_initial); /* retry synchronization after first timeout */ - } - else - { - self_->unsync_initial = false; /* un-sync timeout will lead to termination - stop LLD */ - Fifos_Cleanup(self_); - Sub_Notify(&self_->event_subject, &the_event); - } -} - -/*! \brief Performs a cleanup of the Port Message Channel and the dedicated FIFOs - * \details Releases all message objects which are currently in use. - * \param self The instance - */ -static void Fifos_Cleanup(CPmFifos *self) -{ - uint8_t count; - TR_INFO((self->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_Cleanup(): Channel cleanup started", 0U)); - - if (self->unsync_initial == false) - { - Pmch_Uninitialize(self->channel_ptr); - } - - for (count = 0U; count < PMP_MAX_NUM_FIFOS; count++) /* stop & cleanup all FIFOs */ - { - if (self->fifos[count] != NULL) - { /* stop and avoid recursion */ - Fifo_Stop(self->fifos[count], FIFO_S_UNSYNCED_INIT, false); - Fifo_Cleanup(self->fifos[count]); - } - } - - TR_INFO((self->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_Cleanup(): Channel cleanup completed", 0U)); - - /* notify external event after message objects were released */ - self->state = FIFOS_S_UNSYNCED; -} - -/*------------------------------------------------------------------------------------------------*/ -/* FIFO observation */ -/*------------------------------------------------------------------------------------------------*/ - -/*! \brief Notifies an event to the host class - * \param self The instance - * \param fifo_id_ptr Specific event identifier, pointer to "fifo_id" - */ -static void Fifos_OnFifoEvent(void *self, void *fifo_id_ptr) -{ - CPmFifos *self_ = (CPmFifos*)self; - Fifos_HandleFifoStateChange(self_, *((Pmp_FifoId_t*)fifo_id_ptr)); -} - -/*! \brief Executes transition to new synchronization states - * \param self The instance - * \param fifo_id The FIFO identifier - */ -static void Fifos_HandleFifoStateChange(CPmFifos *self, Pmp_FifoId_t fifo_id) -{ - Fifos_Event_t the_event; - - TR_INFO((self->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_HandleFifoStateChange(): FIFOs state: %d, FIFO: %d, FIFO State: %d", 3U, - self->state, fifo_id, Fifo_GetState(self->fifos[fifo_id]))); - - switch (self->state) - { - case FIFOS_S_SYNCING: - if (Fifos_AreAllFifosInState(self, FIFO_S_SYNCED)) - { - self->state = FIFOS_S_SYNCED; /* now the complete channel is synced */ - Tm_ClearTimer(&self->base_ptr->tm, &self->init_timer); - Fifos_ConfigureSyncParams(self, FIFOS_UNSYNC_RETRIES, FIFOS_UNSYNC_TIMEOUT); - the_event = FIFOS_EV_SYNC_ESTABLISHED; - Sub_Notify(&self->event_subject, &the_event); - TR_INFO((self->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_HandleFifoStateChange(): Synchronization of Port Message channel completed", 0U)); - } - break; - - case FIFOS_S_UNSYNCING: - if (Fifos_AreAllFifosInState(self, FIFO_S_UNSYNCED_READY)) - { - Fifos_Cleanup(self); - self->state = FIFOS_S_UNSYNCED; /* now the complete channel is un-synced */ - Tm_ClearTimer(&self->base_ptr->tm, &self->init_timer); - the_event = FIFOS_EV_UNSYNC_COMPLETE; - Sub_Notify(&self->event_subject, &the_event); - TR_INFO((self->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_HandleFifoStateChange(): Un-synchronization of Port Message channel completed", 0U)); - } - break; - - case FIFOS_S_SYNCED: - if (!Fifos_AreAllFifosInState(self, FIFO_S_SYNCED)) - { - self->state = FIFOS_S_UNSYNCING; /* set state to 'unsyncing' and wait until all FIFOs are unsynced */ - self->sync_cnt = 0U; /* pretend having triggered an un-sync which starts the timer */ - Tm_SetTimer(&self->base_ptr->tm, &self->init_timer, - &Fifos_OnUnsyncTimeout, self, - FIFOS_UNSYNC_TIMEOUT, 0U); - the_event = FIFOS_EV_SYNC_LOST; - Sub_Notify(&self->event_subject, &the_event); - TR_INFO((self->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_HandleFifoStateChange(): Lost synchronization of Port Message channel", 0U)); - } - if (Fifos_AreAllFifosInState(self, FIFO_S_UNSYNCED_READY)) - { - Fifos_Cleanup(self); - self->state = FIFOS_S_UNSYNCED; /* the complete channel suddenly goes unsynced_complete */ - Tm_ClearTimer(&self->base_ptr->tm, &self->init_timer); - the_event = FIFOS_EV_UNSYNC_COMPLETE; - Sub_Notify(&self->event_subject, &the_event); - TR_INFO((self->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_HandleFifoStateChange(): Sudden un-synchronization of Port Message channel completed", 0U)); - } - break; - - case FIFOS_S_UNSYNCED: - TR_INFO((self->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_HandleFifoStateChange(): Unexpected FIFO event in state unsynced", 0U)); - break; - - default: - TR_INFO((self->base_ptr->ucs_user_ptr, "[FIFOS]", "Fifos_HandleFifoStateChange(): Unexpected FIFOs state", 0U)); - break; - } - - MISC_UNUSED(fifo_id); -} - -/*! \brief Helper function that evaluates if all configured FIFOs are in a given state - * \param self The instance - * \param target_state The required state that is evaluated for all FIFOs - * \return \c true if all FIFOs are in the given \c target_state, otherwise \c false. - */ -static bool Fifos_AreAllFifosInState(CPmFifos *self, Fifo_SyncState_t target_state) -{ - bool ret = true; - uint8_t cnt; - - for (cnt = 0U; cnt < PMP_MAX_NUM_FIFOS; cnt++) - { - if (self->fifos[cnt] != NULL) - { - Fifo_SyncState_t state = Fifo_GetState(self->fifos[cnt]); - - if (state != target_state) - { - ret = false; - } - } - } - - return ret; -} - -/*! - * @} - * \endcond - */ - -/*------------------------------------------------------------------------------------------------*/ -/* End of file */ -/*------------------------------------------------------------------------------------------------*/ - |