378 lines
14 KiB
C
378 lines
14 KiB
C
//=================================================================================================
|
||
//
|
||
// 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 );
|
||
}
|
||
|