318 lines
8.8 KiB
C
318 lines
8.8 KiB
C
/**
|
|
* @file ivec_mcal_spi.c
|
|
* @author Akshat Dabas (akshat@vecmocon.com)
|
|
* @brief This source file contains API and Private members for SPI Functionality
|
|
* @version 0.1.0
|
|
* @date 2024-Mar-12
|
|
*
|
|
* @copyright Copyright (c) 2024
|
|
*
|
|
*/
|
|
|
|
#include "../Core/Include/ivec_mcal_spi.h"
|
|
|
|
/*REQUIRED SPI CONFIGS*/
|
|
|
|
/*=======================================================================================PRIVATE_MEMBERS======================================================================================*/
|
|
|
|
static volatile uint8_t b_SPI0_INIT_FLAG=0;
|
|
|
|
static volatile uint8_t b_SPI1_INIT_FLAG=0;
|
|
|
|
static volatile int i32bufferIdx0=0;
|
|
|
|
static volatile int i32bufferIdx1=0;
|
|
|
|
static volatile uint8_t u8rxbuffer0[SPI_PKT_SIZE], u8rxbuffer1[SPI_PKT_SIZE];
|
|
|
|
static const DL_SPI_Config gSPI_0_config = {
|
|
.mode = DL_SPI_MODE_CONTROLLER,
|
|
.frameFormat = DL_SPI_FRAME_FORMAT_MOTO3_POL1_PHA1,
|
|
.parity = DL_SPI_PARITY_NONE,
|
|
.dataSize = DL_SPI_DATA_SIZE_8,
|
|
.bitOrder = DL_SPI_BIT_ORDER_MSB_FIRST,
|
|
};
|
|
|
|
static const DL_SPI_ClockConfig gSPI_0_clockConfig = {
|
|
.clockSel = DL_SPI_CLOCK_BUSCLK,
|
|
.divideRatio = DL_SPI_CLOCK_DIVIDE_RATIO_1
|
|
};
|
|
|
|
/*____________________________________________________________________________________________________________________________________________________________________________________________*/
|
|
|
|
|
|
/*=============================================================================================================================================================================================
|
|
PRIVATE_DECLARATIONS
|
|
==============================================================================================================================================================================================*/
|
|
|
|
/**
|
|
* @brief Receive in static buffer Function for UART
|
|
*
|
|
* @param uart_inst
|
|
* @return uint8_t
|
|
*/
|
|
uint8_t _prv_u8MCAL_spi_receive(SPI_Regs *SPI_inst)
|
|
{
|
|
uint8_t temp;
|
|
temp=DL_SPI_receiveData8(SPI_inst);
|
|
return temp;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to read byte by byte in IRQ Handler
|
|
*
|
|
*/
|
|
void _prv_vspicallback()
|
|
{
|
|
switch (DL_SPI_getPendingInterrupt(SPI0))
|
|
{
|
|
case DL_SPI_IIDX_RX:
|
|
|
|
if(i32bufferIdx0>SPI_PKT_SIZE-1)
|
|
{
|
|
i32bufferIdx0=0;
|
|
}
|
|
|
|
u8rxbuffer0[i32bufferIdx0]=_prv_u8MCAL_spi_receive(SPI0);
|
|
i32bufferIdx0++;
|
|
|
|
break;
|
|
case DL_SPI_IIDX_RX_TIMEOUT:
|
|
__asm("nop");
|
|
break;
|
|
case DL_SPI_IIDX_RX_FULL:
|
|
__asm("nop");
|
|
break;
|
|
case DL_SPI_IIDX_TX_UNDERFLOW:
|
|
__asm("nop");
|
|
break;
|
|
case DL_SPI_IIDX_PARITY_ERROR:
|
|
__asm("nop");
|
|
break;
|
|
case DL_SPI_IIDX_RX_OVERFLOW:
|
|
__asm("nop");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch (DL_SPI_getPendingInterrupt(SPI1))
|
|
{
|
|
case DL_SPI_IIDX_RX:
|
|
|
|
if(i32bufferIdx1>SPI_PKT_SIZE-1)
|
|
{
|
|
i32bufferIdx1=0;
|
|
}
|
|
|
|
u8rxbuffer1[i32bufferIdx1]=_prv_u8MCAL_spi_receive(SPI1);
|
|
i32bufferIdx1++;
|
|
|
|
break;
|
|
case DL_SPI_IIDX_RX_TIMEOUT:
|
|
__asm("nop");
|
|
break;
|
|
case DL_SPI_IIDX_RX_FULL:
|
|
__asm("nop");
|
|
break;
|
|
case DL_SPI_IIDX_TX_UNDERFLOW:
|
|
__asm("nop");
|
|
break;
|
|
case DL_SPI_IIDX_PARITY_ERROR:
|
|
__asm("nop");
|
|
break;
|
|
case DL_SPI_IIDX_RX_OVERFLOW:
|
|
__asm("nop");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Default Interrupt Callback for SPI_0
|
|
*
|
|
*/
|
|
void SPI0_IRQHandler(void)
|
|
{
|
|
_prv_vspicallback();
|
|
|
|
}
|
|
|
|
void SPI1_IRQHandler(void)
|
|
{
|
|
_prv_vspicallback();
|
|
|
|
}
|
|
|
|
|
|
/*=============================================================================================================================================================================================
|
|
API
|
|
==============================================================================================================================================================================================*/
|
|
|
|
/**
|
|
* @brief Initialize SPI in Controller/Master Mode
|
|
*
|
|
* @param SPI_inst Pointer to SPI config registers
|
|
* @param BR enum to set SPI Bit Rate
|
|
* @return xCoreStatus_t
|
|
*/
|
|
IVEC_CoreStatus_e xMCAL_SPI_init(SPI_Regs *SPI_inst, IVEC_SpiCs_e xCS )
|
|
{
|
|
assert(SPI_inst == SPI0 || SPI_inst == SPI1);
|
|
|
|
assert(!(b_SPI0_INIT_FLAG == 1 && b_SPI1_INIT_FLAG == 1));
|
|
|
|
if(xCS!=0)
|
|
{
|
|
return IVEC_CORE_STATUS_INIT_FAIL;
|
|
}
|
|
DL_SPI_setClockConfig(SPI_inst, (DL_SPI_ClockConfig *) &gSPI_0_clockConfig);
|
|
DL_SPI_init(SPI_inst, (DL_SPI_Config *) &gSPI_0_config);
|
|
|
|
/* Configure Controller mode */
|
|
if(xCS==0)
|
|
{
|
|
/*
|
|
* Set the bit rate clock divider to generate the serial output clock
|
|
* outputBitRate = (spiInputClock) / ((1 + SCR) * 2)
|
|
* 1000000 = (40000000)/((1 + 19) * 2)
|
|
*/
|
|
DL_SPI_setBitRateSerialClockDivider(SPI_inst, 19);
|
|
}
|
|
//DL_SPI_enableLoopbackMode(SPI_inst);
|
|
/* Set RX and TX FIFO threshold levels */
|
|
//DL_SPI_setFIFOThreshold(SPI_inst, DL_SPI_RX_FIFO_LEVEL_1_2_FULL, DL_SPI_TX_FIFO_LEVEL_1_2_EMPTY);
|
|
DL_SPI_setFIFOThreshold(SPI_inst, DL_SPI_RX_FIFO_LEVEL_ONE_FRAME, DL_SPI_TX_FIFO_LEVEL_EMPTY);
|
|
/*Enable Interrupt*/
|
|
DL_SPI_enableInterrupt(SPI_inst, (DL_SPI_INTERRUPT_PARITY_ERROR |
|
|
DL_SPI_INTERRUPT_RX |
|
|
DL_SPI_INTERRUPT_RX_FULL |
|
|
DL_SPI_INTERRUPT_RX_OVERFLOW |
|
|
DL_SPI_INTERRUPT_RX_TIMEOUT |
|
|
DL_SPI_INTERRUPT_TX_UNDERFLOW));
|
|
/* Enable module */
|
|
DL_SPI_enable(SPI_inst);
|
|
|
|
if(SPI_inst==SPI0)
|
|
{
|
|
NVIC_EnableIRQ(SPI0_INT_IRQn);
|
|
b_SPI0_INIT_FLAG=1;
|
|
}
|
|
else if(SPI_inst==SPI1)
|
|
{
|
|
NVIC_EnableIRQ(SPI1_INT_IRQn);
|
|
b_SPI1_INIT_FLAG=1;
|
|
}
|
|
return IVEC_CORE_STATUS_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to Receive SPI Message
|
|
*
|
|
* @param SPI_inst Pointer to SPI config registers
|
|
* @param u8SPI_RxData variable where received data will be stored
|
|
* @param size Number of bytes to read
|
|
* @return xCoreStatus_t
|
|
*/
|
|
IVEC_CoreStatus_e _prv_xSPI_getData(SPI_Regs *SPI_inst, uint8_t *u8SPI_RxData, uint8_t size )
|
|
{
|
|
assert(SPI_inst == SPI0 || SPI_inst == SPI1);
|
|
assert(b_SPI0_INIT_FLAG != 0 || b_SPI1_INIT_FLAG != 0);
|
|
|
|
if(SPI_inst==SPI0)
|
|
{
|
|
for(uint8_t i=0;i<size;i++)
|
|
{
|
|
for(uint8_t j=0;j<=i32bufferIdx0;j++)
|
|
{
|
|
u8SPI_RxData[j]=u8rxbuffer0[j];
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if(SPI_inst==SPI1)
|
|
{
|
|
for(uint8_t i=0;i<size;i++)
|
|
{
|
|
for(uint8_t j=0;j<=i32bufferIdx1;j++)
|
|
{
|
|
u8SPI_RxData[j]=u8rxbuffer1[j];
|
|
}
|
|
}
|
|
|
|
}
|
|
i32bufferIdx0=0;
|
|
i32bufferIdx1=0;
|
|
return IVEC_CORE_STATUS_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to Transmit SPI Message
|
|
*
|
|
* @param SPI_inst Pointer to CAN config registers
|
|
* @param u8SPI_TxData data to be transmitted
|
|
* @param size Number of bytes to transmit
|
|
* @return xCoreStatus_t
|
|
*/
|
|
IVEC_CoreStatus_e xMCAL_SPI_TxData(SPI_Regs *SPI_inst, uint8_t *u8SPI_TxData, uint8_t * u8SPI_RxData,uint8_t size)
|
|
{
|
|
|
|
assert(SPI_inst == SPI0 || SPI_inst == SPI1);
|
|
assert(b_SPI0_INIT_FLAG != 0 || b_SPI1_INIT_FLAG != 0);
|
|
|
|
if (!DL_SPI_isTXFIFOFull(SPI_inst))
|
|
{
|
|
DL_GPIO_clearPins(GPIOB,DL_GPIO_PIN_20);
|
|
for(uint8_t i=0;i<size;i++)
|
|
{
|
|
DL_SPI_transmitData8(SPI_inst,u8SPI_TxData[i]);
|
|
while(DL_SPI_isBusy(SPI_inst));
|
|
}
|
|
|
|
} else
|
|
{
|
|
return IVEC_CORE_STATUS_ERROR;
|
|
}
|
|
|
|
|
|
DL_GPIO_setPins(GPIOB,DL_GPIO_PIN_20);
|
|
|
|
_prv_xSPI_getData(SPI_inst,u8SPI_RxData, size );
|
|
|
|
return IVEC_CORE_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief
|
|
*
|
|
* @param SPI_inst Pointer to SPI config registers
|
|
* @return xCoreStatus_t
|
|
*/
|
|
IVEC_CoreStatus_e xMCAL_SPI_deinit(SPI_Regs *SPI_inst)
|
|
{
|
|
assert(SPI_inst == SPI0 || SPI_inst == SPI1);
|
|
assert(b_SPI0_INIT_FLAG != 0 || b_SPI1_INIT_FLAG != 0);
|
|
|
|
if(SPI_inst==SPI0)
|
|
{
|
|
NVIC_DisableIRQ(SPI0_INT_IRQn);
|
|
DL_SPI_disablePower(SPI_inst);
|
|
b_SPI0_INIT_FLAG=0;
|
|
}
|
|
else if(SPI_inst==SPI1)
|
|
{
|
|
NVIC_DisableIRQ(SPI1_INT_IRQn);
|
|
DL_SPI_disablePower(SPI_inst);
|
|
b_SPI1_INIT_FLAG=0;
|
|
}
|
|
return IVEC_CORE_STATUS_SUCCESS;
|
|
}
|
|
|
|
/*____________________________________________________________________________________________________________________________________________________________________________________________*/
|
|
|
|
|