Skip to content
Snippets Groups Projects
Select Git revision
  • 6618adb455f9122345499ac5c816a02400fcff4d
  • main default protected
2 results

misc.c

Blame
  • user avatar
    Timothe Jost authored
    6618adb4
    History
    misc.c 6.14 KiB
    /*-----------------------------------------------------------------------------
     *  File: misc.c
     *
     *  This file is part of Sensapex smcp1_proxy codebase.
     *
     *  Created by Veli-Matti Kananen
     *  Copyright (c) 2024 Sensapex Oy. All rights reserved.
     *---------------------------------------------------------------------------*/
    #include <stdio.h>
    #include <assert.h>
    #include <signal.h>
    #include "misc.h"
    #include "constants.h"
    #include "integration.h"
    #include "port.h"
    #include "functions.h"
    
    // Defines
    #define ACTUATOR_STATUS_BUSY 0x00000001
    
    // program closing signal
    volatile sig_atomic_t SHOULD_EXIT = 0;
    
    volatile sig_atomic_t PROXY_INIT_COMPLETE = 0;
    
    // Static function prototypes
    static mcu_error initActuator(mcu_actuator act);
    
    // Static variables
    static hwInfo mcu_hw_info = {0, 0, 0};
    static systemInfo mcu_system_info = {0, 0, 7, 0x10, 55555, MCU_COMMON_FEATURES_MASK};
    static pthread_mutex_t actMutexBusyIndHandle = PTHREAD_MUTEX_INITIALIZER;
    static uint32_t actStatus = 0;
    volatile uint32_t gUmxStatus = 0;
    
    const hwInfo *mcu_commonGetHwInfo(bool refreshCache)
    {
        if (refreshCache)
        {
            // TODO. Update the cache from ... somewhere.
            mcu_hw_info.hwid = 50;
        }
        return &mcu_hw_info;
    }
    
    systemInfo *mcu_commonGetSystemConf(bool refreshCache)
    {
        systemInfo *retval = NULL;
        mcu_error status = MCU_ERROR_NONE;
    
        if (refreshCache)
        {
            // TODO
        }
        if (status == MCU_ERROR_NONE)
        {
            retval = &mcu_system_info;
        }
        return retval;
    }
    
    mcu_error mcu_commonSetSystemConf(systemInfo *info, bool writeThrough)
    {
        mcu_error retval = MCU_ERROR_NONE;
        mcu_system_info = *info;
        if (writeThrough)
        {
            // TODO
        }
        return retval;
    }
    bool mcu_pwmIsBusy(const mcu_actuator actuator, int *state)
    {
        UNUSED(actuator);
        UNUSED(state);
        return false;
    }
    
    bool mcu_commonIsExpired(uint32_t current_ms, uint32_t start_ms,
                             uint32_t period_ms)
    {
        return ((current_ms - start_ms) >= period_ms || start_ms > current_ms);
    }
    
    mcu_error initSystem()
    {
        mcu_error retval = MCU_ERROR_NONE;
    
        // Init a crash log mutex
        systemInfo *info = mcu_commonGetSystemConf(true);
    
        // Read mcu system configuration
        if (info->udp_port == MCU_16_BIT_DATA_UNDEFINED)
        {
            // Uninitialized. Set default values and save the configuration.
            info->features = 0;
            info->rd_features = 0;
            info->axis = 0;
            info->smcp_version = 0x10;
            info->udp_port = SMCP1_DEF_UDP_PORT;
            info->features_mask = MCU_COMMON_FEATURES_MASK;
            // Resolve the used head configuration.
            // Store the configuration in EEPROM.
            retval = mcu_commonSetSystemConf(info, true);
        }
    
        // Initialize connected actuators
        if (retval == MCU_ERROR_NONE)
        {
            int axisMask = 0;
            for (mcu_actuator act = ACTUATOR_FIRST; act <= ACTUATOR_LAST; act++)
            {
                mcu_error initStatus = initActuator(actuators[act]);
                if (initStatus == MCU_ERROR_NONE)
                {
                    axisMask |= (1 << act);
                }
                else
                {
                    break;
                }
            }
            info->axis = axisMask;
        }
    
        // Initialize the supported SMCP version
        if (retval == MCU_ERROR_NONE)
        {
            retval = mcu_smcp10_init();
            assert(retval == MCU_ERROR_NONE);
    
            /*
            if (retval == MCU_ERROR_NONE) {
                // Set the default hello sender callback
                switch (info->smcp_version)
                {
                    case 0x10:
                        heartbeat_fptr = &mcu_smcp10_heartbeat;
                        pos_notify_fptr = &mcu_smcp10_handlePosNotify;
                        break;
                    default:
                        heartbeat_fptr = NULL;
                        pos_notify_fptr = NULL;
                        break;
                }
            }
            */
        }
    
        // Read HW info from EEPROM to cache
        if (retval == MCU_ERROR_NONE)
        {
            const hwInfo *hw_info = mcu_commonGetHwInfo(true);
            info->features_mask = MCU_COMMON_FEATURES_MASK;
        }
    
        return retval;
    }
    
    mcu_error initActuator(mcu_actuator act)
    {
        return integrationInitActuator(act);
    }
    
    bool mcu_commonIsActuatorEnabled(const mcu_actuator act, const systemInfo *info)
    {
        const systemInfo *sysInfoPtr = info ? info : mcu_commonGetSystemConf(false);
        return sysInfoPtr->axis & (1 << act);
    }
    
    mcu_error mcu_actuatorGetPosition(const mcu_actuator actuatorId, int *position, bool rawData)
    {
        int posValue;
        mcu_error retval = integrationGetPosition(actuatorId, &posValue, rawData);
        if (retval == MCU_ERROR_NONE)
        {
            *position = posValue;
        }
        return retval;
    }
    
    static uint32_t mcu_waveformGetStatus()
    {
        return gUmxStatus;
    }
    
    mcu_error mcu_waveformSetStatus(uint32_t statusBits, bool enable)
    {
        mcu_error retval = MCU_ERROR_NONE;
    
        volatile uint32_t prevStatus = mcu_waveformGetStatus();
        volatile uint32_t newStatus = prevStatus;
    
        if (enable)
        {
            newStatus |= statusBits;
        }
        else
        {
            newStatus &= ~(statusBits);
        }
    
        gUmxStatus = newStatus;
    
        if (prevStatus != newStatus)
        {
            retval = mcu_smcp10BroadcastStatusChangedNotification(newStatus);
        }
    
        return retval;
    }
    
    mcu_error mcu_actuatorSetBusyStatus(const mcu_actuator actuator, const uint32_t status)
    {
        mcu_error retval = MCU_ERROR_NONE;
    
        osStatus mutexState = osMutexWait(&actMutexBusyIndHandle, 10); // max wait time 10 ms
        retval = mutexState == osOK ? retval : MCU_ERROR_GENERAL;
        assert(mutexState == osOK);
        if (retval == MCU_ERROR_NONE)
        {
            if (status == 0)
            {
                actStatus &= ~(1 << actuator);
            }
            else
            {
                actStatus |= (1 << actuator);
            }
    
            bool busy = actStatus == 0 ? false : true;
    
            retval = mcu_waveformSetStatus(ACTUATOR_STATUS_BUSY, busy);
    
            mutexState = osMutexRelease(&actMutexBusyIndHandle);
            assert(mutexState == osOK);
            if (retval == MCU_ERROR_NONE)
            {
                retval = mutexState == osOK ? retval : MCU_ERROR_GENERAL;
            }
        }
        return retval;
    }
    
    uint32_t mcu_actuatorGetBusyStatus(const mcu_actuator actuator)
    {
        return actStatus & (1 << actuator);
    }