//================================================================================================= // // Company: Paul Scherrer Institut // 5232 Villigen PSI // Switzerland // //------------------------------------------------------------------------------------------------- // // Project: Peltier Controller V2 // Author: Noah Piqué (noah.pique@psi.ch) // //------------------------------------------------------------------------------------------------- // // Module: Temp // Filename: TEMP_Temperature.c // Date: Handled by Subversion (version control system) // Revision: Handled by Subversion (version control system) // History: Handled by Subversion (version control system) // //------------------------------------------------------------------------------------------------- // // Description: This source file contains all functions dealing with the temperature readout // //================================================================================================= //================================================================================================= // Section: INCLUDES // Description: List of required include files. //================================================================================================= //#include "../Application/VARH_VariableHandler.h" #include "../PDEF_ProjectDefinitions.h" #include "TEMP_Temperature.h" // Application //#include "../Application/ELOG_ErrorLogger.h" //#include "../Application/RTOS_RealTimeOs.h" // Toolbox //#include "../Toolbox/ASRT_Assert.h" #include "../Toolbox/UTIL_Utility.h" // Drivers #include "DIPO_DigitalPorts.h" #include "SPID_SpiDriver.h" #include "ADCD_ADCDriver.h" // include STM32 drivers #include "stm32l4xx_hal.h" #include #include "cmsis_os2.h" //================================================================================================= // Section: DEFINITIONS // Description: Definition of local constants (visible by this module only). //================================================================================================= #define REFRESH_MS 100 // Konstanten f�r Temperaturberechung #define RTD_A 3.9083e-3 #define RTD_B -5.775e-7 #define R_REF 3900 #define R_NOMINAL 1000 //================================================================================================= // Section: MACROS // Description: Definition of local macros (visible by this module only). //================================================================================================= //================================================================================================= // Section: ENUMERATIONS // Description: Definition of local enumerations (visible by this module only). //================================================================================================= //================================================================================================= // Section: STRUCTURES // Description: Definition of local Structures (visible by this module only). //================================================================================================= //================================================================================================= // Section: LOCAL FUNCTIONS (PROTOTYPES) // Description: Definition of local functions (visible by this module only). //================================================================================================= PRIVATE FLOAT flConvertADCData( U16 dbRTemp ); PRIVATE VOID vTempTask( PVOID arg ); //================================================================================================= // Section: LOCAL CONSTANTS // Description: Definition of local constants (visible by this module only). //================================================================================================= LOCAL CONST osMutexAttr_t m_stMutexAttr = { "TEMP_Mutex", // human readable mutex name osMutexRecursive | osMutexPrioInherit, // attr_bits NULL, // memory for control block 0U // size for control block }; LOCAL CONST osThreadAttr_t stTaskAttribute = { "TEMP_Thread", // name of the thread osThreadDetached, // attribute bits NULL, // memory for control block 0, // size of provided memory for control block NULL, // memory for stack 1024, // size of stack osPriorityNormal, // initial thread priority (default: osPriorityNormal) 0, // TrustZone module identifier 0, // reserved (must be 0) }; //================================================================================================= // Section: LOCAL VARIABLES // Description: Definition of local variables (visible by this module only). //================================================================================================= LOCAL osThreadId_t m_pstThreadID = NULL; LOCAL osMutexId_t m_pstMutexID = NULL; LOCAL FLOAT m_flTempData[ADCD_eNumberOfTemps]; //================================================================================================= // Section: EXTERNAL FUNCTIONS // Description: Definition of external (global) functions. //================================================================================================= //================================================================================================= // Section: EXTERNAL VARIABLES // Description: Definition of external (global) variables. //================================================================================================= //================================================================================================= // Section: GLOBAL FUNCTIONS // Description: Definition (implementation) of global functions. //================================================================================================= //------------------------------------------------------------------------------------------------- // Function: TEMP_boInitializeModule // Description: Initializes the module. Function must be called once immediately after power-up. // This function is thread save // Parameters: None // Returns: Boolean TRUE if successful //------------------------------------------------------------------------------------------------- BOOL TEMP_boInitializeModule( VOID ) { BOOL boOK = TRUE; boOK &= ((m_pstThreadID = osThreadNew( vTempTask, NULL, &stTaskAttribute )) == NULL ) ? FALSE : TRUE; boOK &= ((m_pstMutexID = osMutexNew( &m_stMutexAttr )) == NULL) ? FALSE : TRUE; return( boOK ); } //------------------------------------------------------------------------------------------------- // Function: TEMP_dGetValue // Description: Gets the desired temperature // Parameters: ATEMP_EnTemperature enInput // Returns: DOUBLE DValue Value from ADC //------------------------------------------------------------------------------------------------- FLOAT TEMP_dGetValue( ADCD_EnTemps enTemp ) { osMutexAcquire( m_pstMutexID, osWaitForever ); DOUBLE dValue = m_flTempData[enTemp]; osMutexRelease( m_pstMutexID ); return( dValue ); } //------------------------------------------------------------------------------------------------- // Function: TEMP_boRegisterEventNotification // Description: Register for a notification when there are new values // Parameters: TEMP_pfnEventCallback pfnCallback // PVOID pvCallbackArgument // Returns: TRUE, if successfull, otherwise FALSE //------------------------------------------------------------------------------------------------- //BOOL TEMP_boRegisterEventNotification( TEMP_pfnEventCallback pfnCallback, PVOID pvCallbackArgument ) //{ // BOOL boRet = FALSE; // osMutexAcquire( m_pstMutexID, osWaitForever ); // for( U16 u16Cnt = 0; u16Cnt < NUMBER_OF_EVENT_CALLBACKS; u16Cnt++ ) // { // if( m_apfnEventCallback[u16Cnt] == NULL ) // { // m_apfnEventCallback[u16Cnt] = pfnCallback; // m_apvCallbackArgument[u16Cnt] = pvCallbackArgument; // boRet = TRUE; // break; // } // } // osMutexRelease( m_pstMutexID ); // return( boRet ); //} //================================================================================================= // Section: LOCAL FUNCTIONS // Descriptionn: Definition (implementation) of local functions. //================================================================================================= //------------------------------------------------------------------------------------------------- // Function: vTempTask // Description: vTempTask // Parameters: None // Returns: None //------------------------------------------------------------------------------------------------- PRIVATE VOID vTempTask( PVOID arg ) { UNUSED( arg ); U32 u32Flags; BOOL boOK = TRUE; U8 error; U16 u16ADC_data[ADCD_eNumberOfTemps]; U8 u8Channel; FLOAT temp = 0; osDelay(10); while( TRUE ) { //u32Flags = osEventFlagsWait( m_pstEventID, EVENT_REFRESH, osFlagsWaitAny, osWaitForever ); //if( u32Flags & EVENT_REFRESH ) //{ boOK &= ADCD_dReadData(ADCD_eHot, &error, &u16ADC_data[ADCD_eHot]); if( boOK ) { osMutexAcquire( m_pstMutexID, osWaitForever ); m_flTempData[ADCD_eHot] = flConvertADCData( u16ADC_data[ADCD_eHot] ); //temp = flConvertADCData( u16ADC_data[ADCD_eHot] ); // for debugging //VARH_vSetVariableData( VARH_eTempHeatSink + u8Channel, (VARH_UVariable)(FLOAT)m_dbTempData[u8Channel] ); osMutexRelease( m_pstMutexID ); } else { boOK = TRUE; } boOK &= ADCD_dReadData(ADCD_eCold, &error, &u16ADC_data[ADCD_eCold]); if( boOK ) { osMutexAcquire( m_pstMutexID, osWaitForever ); m_flTempData[ADCD_eCold] = flConvertADCData( u16ADC_data[ADCD_eCold] ); //temp = flConvertADCData( u16ADC_data[ADCD_eCold] ); // for debugging //VARH_vSetVariableData( VARH_eTempHeatSink + u8Channel, (VARH_UVariable)(FLOAT)m_dbTempData[u8Channel] ); osMutexRelease( m_pstMutexID ); } else { boOK = TRUE; } //} osDelay(REFRESH_MS); // wait for ADC conversions completed // u32Flags = osEventFlagsWait( m_pstEventID, OS_EVENT_ADC_COMPLETED_FLAG, osFlagsWaitAll , ADC_TIMEOUT_MS ); // boTimeout = (u32Flags == osFlagsErrorTimeout) ? TRUE : FALSE; // boError = FALSE; // // // check if we have a timeout // if( boTimeout ) // { // //ELOG_ADD_LOG( ELOG_eADCTimeout ); // } // // // read ADC data // if( !(boSuccess = boReadADCData() ) ) // { // //ELOG_ADD_LOG( ELOG_eADCReadingDataFailed ); // } //// vIncrementChannel(); // // // reinit ADC on error, on spi failure or when timeout reached // if( boTimeout || !boSuccess ) // { // boError = TRUE; //// vADCInit(); // } // // send event to worker task, if all channels completed and no error // if( m_stADCData.u8Cannel == 0 && !boError ) // { // // send event to tasks // for( U16 u16Cnt = 0; u16Cnt < NUMBER_OF_EVENT_CALLBACKS; u16Cnt++ ) // { // if( m_apfnEventCallback[u16Cnt] != NULL ) // { // m_apfnEventCallback[u16Cnt]( m_apvCallbackArgument[u16Cnt] ); // } // } // } } } //------------------------------------------------------------------------------------------------- // Function: flConvertADCData // Description: Converts resistor value to temperature data // Parameters: U16 u16RTemp // Returns: U16, temperature in Celcius //------------------------------------------------------------------------------------------------- PRIVATE FLOAT flConvertADCData( U16 u16RTemp ) { /*u16RTemp = u16RTemp / 1000; FLOAT flT = 9.9714f * u16RTemp; flT += 235.904f; flT *= u16RTemp; flT += -245.876f;*/ FLOAT flZ1, flZ2, flZ3, flZ4, flRt, flTemp, flRpoly; flRt = u16RTemp; flRt /= 32768; flRt *= R_REF; flZ1 = -RTD_A; flZ2 = RTD_A * RTD_A - (4 * RTD_B); flZ3 = (4 * RTD_B) / R_NOMINAL; flZ4 = 2 * RTD_B; flTemp = flZ2 + (flZ3 * flRt); flTemp = (sqrt(flTemp) + flZ1) / flZ4; if (flTemp >= 0) return flTemp; // ugh. flRt /= R_NOMINAL; flRt *= 100; // normalize to 100 ohm flRpoly = flRt; flTemp = -242.02; flTemp += 2.2228 * flRpoly; flRpoly *= flRt; // square flTemp += 2.5859e-3 * flRpoly; flRpoly *= flRt; // ^3 flTemp -= 4.8260e-6 * flRpoly; flRpoly *= flRt; // ^4 flTemp -= 2.8183e-8 * flRpoly; flRpoly *= flRt; // ^5 flTemp += 1.5243e-10 * flRpoly; return( flTemp ); }