//================================================================================================= // // Company: Paul Scherrer Institut // 5232 Villigen PSI // Switzerland // //------------------------------------------------------------------------------------------------- // // Project: Peltier Controller V2 // Author: Noah Piqu� (noah.pique@psi.ch) // //------------------------------------------------------------------------------------------------- // // Module: SPI-Driver // Filename: SPID_SpiDriver.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 SPI-Driver // //================================================================================================= //================================================================================================= // Section: INCLUDES // Description: List of required include files. //================================================================================================= #include "SPID_SpiDriver.h" // Application //#include "../Application/ELOG_ErrorLogger.h" // Toolbox #include "../Toolbox/UTIL_Utility.h" // Drivers #include "DIPO_DigitalPorts.h" #include "ERRH_ErrorHandler.h" // include STM32 drivers #include "stm32l4xx_hal.h" #include "cmsis_os2.h" //================================================================================================= // Section: DEFINITIONS // Description: Definition of local constants (visible by this module only). //================================================================================================= #define OS_ADC_SPI_COMPLETE_FLAG ((U32)(1<<0)) #define OS_ADC_SPI_ERROR_FLAG ((U32)(1<<1)) //================================================================================================= // 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). //================================================================================================= typedef struct { SPI_HandleTypeDef* pstSPIHandle; osMutexId_t pstMutexID; CONST osMutexAttr_t* pstMutexAttribute; U32 u32SPICompleteFlag; U32 u32SPIErrorFlag; } StSPI; //================================================================================================= // Section: LOCAL CONSTANTS // Description: Definition of local constants (visible by this module only). //================================================================================================= LOCAL CONST osMutexAttr_t m_stADCMutexAttr = { "SPID_ADC_Mutex", // human readable mutex name osMutexRecursive | osMutexPrioInherit, // attr_bits NULL, // memory for control block 0U // size for control block }; LOCAL CONST osEventFlagsAttr_t stEventAttribute = { "SPID_Event_Flags", // name of the event flags 0, // attribute bits NULL, // memory for control block 0, // size of provided memory for control block }; //================================================================================================= // Section: EXTERNAL VARIABLES // Description: Definition of external (global) variables. //================================================================================================= extern SPI_HandleTypeDef hspi1; //================================================================================================= // Section: LOCAL VARIABLES // Description: Definition of local variables (visible by this module only). //================================================================================================= LOCAL StSPI m_astSPI[SPID_eNumberOfSPIs] = { // SPID_eSPI2 { &hspi1, // SPI Handle NULL, // pstMutexID &m_stADCMutexAttr, // pstMutexAttribute OS_ADC_SPI_COMPLETE_FLAG, // u32SPICompleteFlag OS_ADC_SPI_ERROR_FLAG, // u32SPIErrorFlag }, }; LOCAL osEventFlagsId_t m_pstEventID = NULL; //================================================================================================= // Section: LOCAL FUNCTIONS (PROTOTYPES) // Description: Definition of local functions (visible by this module only). //================================================================================================= PRIVATE SPID_EnSPIs enGetSPI( SPI_HandleTypeDef* pstSPI ); //================================================================================================= // Section: EXTERNAL FUNCTIONS // Description: Definition of external (global) functions. //================================================================================================= //================================================================================================= // Section: GLOBAL FUNCTIONS // Description: Definition (implementation) of global functions. //================================================================================================= //------------------------------------------------------------------------------------------------- // Function: SPID_boInitializeModule // Description: Initializes the module // Parameters: None // Returns: BOOL, TRUE, if successful, otherwise FALSE //------------------------------------------------------------------------------------------------- BOOL SPID_boInitializeModule( VOID ) { BOOL boOK= TRUE; boOK &= ((m_pstEventID = osEventFlagsNew( &stEventAttribute )) == NULL) ? FALSE : TRUE; return( boOK ); } //------------------------------------------------------------------------------------------------- // Function: SPID_boSend // Description: Sends a number of bytes // Parameters: SPID_StHandle* pstHandle // Returns: BOOL TRUE, if successful, otherwise FALSE //------------------------------------------------------------------------------------------------- BOOL SPID_boSend( SPID_StHandle* pstHandle ) { BOOL boOK; U32 u32Flags = 0; osMutexAcquire( m_astSPI[pstHandle->enSPI].pstMutexID, osWaitForever ); // clear all flags osEventFlagsClear( m_pstEventID, m_astSPI[pstHandle->enSPI].u32SPICompleteFlag | m_astSPI[pstHandle->enSPI].u32SPIErrorFlag ); // start SPI transmission boOK = HAL_SPI_Transmit_DMA( m_astSPI[pstHandle->enSPI].pstSPIHandle, pstHandle->pu8TxBuf, pstHandle->u16TransferSize ) == HAL_OK ? TRUE : FALSE; if( boOK ) { // wait until transmisison done u32Flags = osEventFlagsWait( m_pstEventID, m_astSPI[pstHandle->enSPI].u32SPICompleteFlag | m_astSPI[pstHandle->enSPI].u32SPIErrorFlag, osFlagsWaitAny, osWaitForever ); } boOK &= ( u32Flags & m_astSPI[pstHandle->enSPI].u32SPIErrorFlag ) ? FALSE : TRUE; osMutexRelease( m_astSPI[pstHandle->enSPI].pstMutexID ); return( boOK ); } //------------------------------------------------------------------------------------------------- // Function: SPID_boSendReceive // Description: Sends a and receives a number of bytes // Parameters: SPID_StHandle* pstHandle // DIPO_EnDigitalOutput enCS // Returns: BOOL TRUE, if successful, otherwise FALSE //------------------------------------------------------------------------------------------------- BOOL SPID_boSendReceive( SPID_StHandle* pstHandle ) { BOOL boOK; U32 u32Flags = 0; osMutexAcquire( m_astSPI[pstHandle->enSPI].pstMutexID, osWaitForever ); // clear all flags osEventFlagsClear( m_pstEventID, m_astSPI[pstHandle->enSPI].u32SPICompleteFlag | m_astSPI[pstHandle->enSPI].u32SPIErrorFlag ); // start SPI boOK = HAL_SPI_TransmitReceive_DMA( m_astSPI[pstHandle->enSPI].pstSPIHandle, pstHandle->pu8TxBuf, pstHandle->pu8RxBuf, pstHandle->u16TransferSize ) == HAL_OK ? TRUE : FALSE; if( boOK ) { // wait until transmisison done u32Flags = osEventFlagsWait( m_pstEventID, m_astSPI[pstHandle->enSPI].u32SPICompleteFlag | m_astSPI[pstHandle->enSPI].u32SPIErrorFlag, osFlagsWaitAny, osWaitForever ); } boOK &= ( u32Flags & m_astSPI[pstHandle->enSPI].u32SPIErrorFlag ) ? FALSE : TRUE; osMutexRelease( m_astSPI[pstHandle->enSPI].pstMutexID ); return( boOK ); } //================================================================================================= // Section: LOCAL FUNCTIONS // Descriptionn: Definition (implementation) of local functions. //================================================================================================= ///------------------------------------------------------------------------------------------------- // Function: HAL_SPI_TxRxCpltCallback // Description: HAL spi rx/tx complete callback function // Parameters: SPI_HandleTypeDef *hspi // Returns: None //------------------------------------------------------------------------------------------------- VOID HAL_SPI_TxRxCpltCallback( SPI_HandleTypeDef *hspi ) { SPID_EnSPIs enSPI = enGetSPI( hspi ); osEventFlagsSet( m_pstEventID, m_astSPI[enSPI].u32SPICompleteFlag ); } //------------------------------------------------------------------------------------------------- // Function: HAL_SPI_TxCpltCallback // Description: HAL spi tx complete callback function // Parameters: SPI_HandleTypeDef *hspi // Returns: None //------------------------------------------------------------------------------------------------- VOID HAL_SPI_TxCpltCallback( SPI_HandleTypeDef *hspi ) { SPID_EnSPIs enSPI = enGetSPI( hspi ); osEventFlagsSet( m_pstEventID, m_astSPI[enSPI].u32SPICompleteFlag ); } //------------------------------------------------------------------------------------------------- // Function: HAL_SPI_RxCpltCallback // Description: HAL SPI rx complete callback function // Parameters: SPI_HandleTypeDef *hspi // Returns: None //------------------------------------------------------------------------------------------------- VOID HAL_SPI_RxCpltCallback( SPI_HandleTypeDef *hspi ) { SPID_EnSPIs enSPI = enGetSPI( hspi ); osEventFlagsSet( m_pstEventID, m_astSPI[enSPI].u32SPICompleteFlag ); } //------------------------------------------------------------------------------------------------- // Function: HAL_SPI_ErrorCallback // Description: HAL SPI error callback function // Parameters: SPI_HandleTypeDef *hspi // Returns: None //------------------------------------------------------------------------------------------------- VOID HAL_SPI_ErrorCallback( SPI_HandleTypeDef *hspi ) { ERRH_vSetError(SPI_ERROR_MASK | hspi->ErrorCode); SPID_EnSPIs enSPI = enGetSPI( hspi ); osEventFlagsSet( m_pstEventID, m_astSPI[enSPI].u32SPIErrorFlag ); } //------------------------------------------------------------------------------------------------- // Function: enGetSPI // Description: Gets the SPI enumeration to the corresponding SPI handle // Parameters: SPI_HandleTypeDef* pstSPI // Returns: SPID_EnSPIs //------------------------------------------------------------------------------------------------- PRIVATE SPID_EnSPIs enGetSPI( SPI_HandleTypeDef* pstSPI ) { for( U8 u8Cnt = 0; u8Cnt < SPID_eNumberOfSPIs; u8Cnt++ ) { if( m_astSPI[u8Cnt].pstSPIHandle == pstSPI ) { return( u8Cnt ); } } //ASRT_ASSERT( FALSE ); return( 0 ); }