TECware/Core/Drivers/SPID_SpiDriver.c
2022-07-07 18:00:11 +02:00

378 lines
14 KiB
C
Raw Blame History

//=================================================================================================
//
// Company: Paul Scherrer Institut
// 5232 Villigen PSI
// Switzerland
//
//-------------------------------------------------------------------------------------------------
//
// Project: Peltier Controller V2
// Author: Noah Piqu<71> (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 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;
#if defined(PDEF_FUNCTION_PARAMETER_CHECK_ENABLED) && PDEF_FUNCTION_PARAMETER_CHECK_ENABLED == TRUE
if( pstHandle == NULL || pstHandle->enSPI >= SPID_eNumberOfSPIs )
{
ELOG_ADD_LOG( ELOG_eInvalidFunctionParameter );
return( FALSE );
}
#endif
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;
#if defined(PDEF_FUNCTION_PARAMETER_CHECK_ENABLED) && PDEF_FUNCTION_PARAMETER_CHECK_ENABLED == TRUE
if( pstHandle == NULL || pstHandle->enSPI >= SPID_eNumberOfSPIs )
{
ELOG_ADD_LOG( ELOG_eInvalidFunctionParameter );
return( FALSE );
}
#endif
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 )
{
#if defined(PDEF_FUNCTION_PARAMETER_CHECK_ENABLED) && PDEF_FUNCTION_PARAMETER_CHECK_ENABLED == TRUE
if( hspi == NULL )
{
ELOG_ADD_LOG( ELOG_eInvalidFunctionParameter );
return;
}
#endif
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 )
{
#if defined(PDEF_FUNCTION_PARAMETER_CHECK_ENABLED) && PDEF_FUNCTION_PARAMETER_CHECK_ENABLED == TRUE
if( hspi == NULL )
{
ELOG_ADD_LOG( ELOG_eInvalidFunctionParameter );
return;
}
#endif
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 )
{
#if defined(PDEF_FUNCTION_PARAMETER_CHECK_ENABLED) && PDEF_FUNCTION_PARAMETER_CHECK_ENABLED == TRUE
if( hspi == NULL )
{
ELOG_ADD_LOG( ELOG_eInvalidFunctionParameter );
return;
}
#endif
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 )
{
#if defined(PDEF_FUNCTION_PARAMETER_CHECK_ENABLED) && PDEF_FUNCTION_PARAMETER_CHECK_ENABLED == TRUE
if( hspi == NULL )
{
ELOG_ADD_LOG( ELOG_eInvalidFunctionParameter );
return;
}
#endif
// check rx overrun error
if( hspi->ErrorCode & HAL_SPI_ERROR_OVR )
{
//ELOG_ADD_LOG( ELOG_eSPIOverrunError );
}
// check rx dma transfer error
if( hspi->hdmarx->ErrorCode & HAL_DMA_ERROR_TE )
{
//ELOG_ADD_LOG( ELOG_eDMAHTransferError );
}
// check tx dma transfer error
if( hspi->hdmatx->ErrorCode & HAL_DMA_ERROR_TE )
{
//ELOG_ADD_LOG( ELOG_eDMAHTransferError );
}
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 )
{
#if defined(PDEF_FUNCTION_PARAMETER_CHECK_ENABLED) && PDEF_FUNCTION_PARAMETER_CHECK_ENABLED == TRUE
if( pstSPI == NULL )
{
ELOG_ADD_LOG( ELOG_eInvalidFunctionParameter );
ASRT_ASSERT( FALSE );
}
#endif
for( U8 u8Cnt = 0; u8Cnt < SPID_eNumberOfSPIs; u8Cnt++ )
{
if( m_astSPI[u8Cnt].pstSPIHandle == pstSPI )
{
return( u8Cnt );
}
}
//ASRT_ASSERT( FALSE );
return( 0 );
}