2021-07-05 06:27 PM
I have declared my SPI2 base address:
#define PERIPH_BASE 0x40000000U
#define APB1PERIPH_BASE PERIPH_BASE
#define SPI2_BASEADDR (APB1PERIPH_BASE + 0x3800)
I have a SPI Handle structure:
typedef struct
{
SPI_RegDef_t *pSPIx; //This holds the base address of SPIx peripheral
SPI_Config_t SPIConfig;
uint8_t *pTxBuffer; //to store the application's Tx buffer address because this will reused by the ISR code
uint8_t *pRxBuffer; //to store the application's Rx buffer address.
uint32_t TxLen; //to store Tx Len
uint32_t RxLen; // to store Rx Len
uint8_t TxState; //to store Tx state
uint8_t RxState; //to store Rx state
}SPI_Handle_t;
Then, I have SPI register definition structure:
typedef struct
{
__vo uint32_t CR1; //can get all the SPI register dalam reference manual SPI section (SPI register map)
__vo uint32_t CR2;
__vo uint32_t SR;
__vo uint32_t DR;
__vo uint32_t CRCPR;
__vo uint32_t RXCRCR;
__vo uint32_t TXCRCR;
__vo uint32_t I2SCFGR;
__vo uint32_t I2SPR;
}SPI_RegDef_t;
Then, I do my SPI2 initialization functions:
void SPI2_Inits(void)
{
SPI_Handle_t SPI2handle; //1st, initialize spi2 handle
SPI2handle.pSPIx = SPI2; //initialize SPI base address
SPI2handle.SPIConfig.SPI_BusConfig = SPI_BUS_CONFIG_FD; //SPI configuration bus use full duplex
SPI2handle.SPIConfig.SPI_DeviceMode = SPI_DEVICE_MODE_MASTER; //jadikan device kita sebagai master kita xdk slave utk exercise ni
SPI2handle.SPIConfig.SPI_SclkSpeed = SPI_SCLK_SPEED_DIV8; //sebab kita nak 2MHz so kne divide by 8
SPI2handle.SPIConfig.SPI_DFF = SPI_DFF_8BITS; //set data format to 8 bits
SPI2handle.SPIConfig.SPI_CPOL = SPI_CPOL_LOW; //LOW to default value
SPI2handle.SPIConfig.SPI_CPHA = SPI_CPHA_LOW; //LOW to default value
SPI2handle.SPIConfig.SPI_SSM = SPI_SSM_DI; //software slave management, disable ssm for NSS pin, sebab kita guna hardware
SPI_Init(&SPI2handle); //call spi init dan send all the address of SPI2handle
}
Then, my main code wants to execute this function:
SPI_SendDataIT(&SPI2handle,&dummy,1);
The SPI_SendDataIT function is:
uint8_t SPI_SendDataIT(SPI_Handle_t *pSPIHandle, uint8_t *pTxBuffer, uint32_t Len)
{
uint8_t state = pSPIHandle->TxState;
if(state != SPI_BUSY_IN_TX)
{
pSPIHandle->pTxBuffer = pTxBuffer;
pSPIHandle->TxLen = Len;
pSPIHandle->TxState = SPI_BUSY_IN_TX;
pSPIHandle->pSPIx->CR2 |= ( 1 << SPI_CR2_TXEIE );
}
return state;
}
The problem is, in the SPI_SendData() function at the line
pSPIHandle->pSPIx->CR2 |= ( 1 << SPI_CR2_TXEIE );
where the pSPIHandle did not shift the register of CR2 inside the pSPIx address which is SPI2. In this case, I want to SET the TXEIE, but this line did not SET it.
where the SPI_CR2_TXEIE I declared in:
#define SPI_CR2_RXDMAEN 0
#define SPI_CR2_TXDMAEN 1
#define SPI_CR2_SSOE 2
#define SPI_CR2_NSSP 3
#define SPI_CR2_FRF 4
#define SPI_CR2_ERRIE 5
#define SPI_CR2_RXNEIE 6
#define SPI_CR2_TXEIE 7
#define SPI_CR2_DS 8
#define SPI_CR2_FRXTH 12
#define SPI_CR2_LDMA_RX 13
#define SPI_CR2_LDMA_TX 14
I dont find where is the fault in my code. Could someone help me? Im using stm32f302r8
Solved! Go to Solution.
2021-07-05 09:26 PM
Already found the solution, It seems the udemy course is wrong. they declare pSPIhandle locally inside the SPI_inits functions.
But then, the main program need to use the pSPIhandle. So, should declare globally. Thank you TDK for you responses and help
2021-07-05 07:44 PM
This was answered in your previous post.
https://community.st.com/s/question/0D53W00000vR2d1SAC/spi-txeie-is-not-set-even-after-configured-it
This does not set the TXEIE bit:
pSPIHandle->pSPIx->CR2 |= ( 1 << SPI_CR2_TXEIE );
This does:
pSPIHandle->pSPIx->CR2 |= SPI_CR2_TXEIE;
The CMSIS files have definitions for the registers. Seems like you're reinventing the wheel here.
Edit: Oh, you're redefining the existing definitions in the CMSIS files. Ensure these definitions don't already exist. Or better yet, just use the CMSIS header file for register definitions. Also ensure the clock is enabled.
2021-07-05 07:53 PM
Sorry I keep asking, because Im eager to find the answers, Thank you for your responds I really appreciate it.
Regarding Im redefining the existing definitions in the CMSIS files. Where do find the files? I try to find an the left Tab but, I could not see it where it is located.
2021-07-05 07:56 PM
2021-07-05 08:05 PM
Oh, you mean the MCU header file. But, in this case, I write everything from scratch. meaning I use the empty project and develop my own driver.
But what I detect is, whenever inside the function, if I write SPI_RegDef_t *pSPIx as the argument, then register can be shifted
void SPI_SendData(SPI_RegDef_t *pSPIx, uint8_t *pTxBuffer, uint32_t Len)
But, if I write SPI_Handle_t *pSPIHandle as the function argument, then the pSPIHandle will access the pSPIx (the SPI2 address). At this method it will not work.
uint8_t SPI_SendDataIT(SPI_Handle_t *pSPIHandle, uint8_t *pTxBuffer, uint32_t Len)
Is there any logic that you see?
2021-07-05 08:11 PM
I did try again, here is the screenshot of my IDE during debug Mode.
the TXEIE is not SET
2021-07-05 08:20 PM
> Is there any logic that you see?
Hard to debug through a keyhole. I can't see anything obviously wrong, although redefining CMSIS defines with different values seems like a bad idea.
Like I said above, ensure the clock is enabled. Ensure pSPIHandle->pSPIx points to SPI2 like you think it does. Ensure registers are defined as volatile.
The compiler or hardware is unlikely to be the issue here. Post a minimal working example which exhibits the problem and can be compiled.
2021-07-05 08:27 PM
If you want to create a driver from scratch, of course feel free, but it's not something I have too much interest in debugging. I had mistakenly thought you were using standard definitions based on your other post.
With your redefined value for SPI_CR2_TXEIE, (1 << SPI_CR2_TXEIE) is the correct value to use here.
2021-07-05 08:34 PM
yeah..actually I learn to develop the driver because I want to understand the details in it. But, in the real project I will use the HAL driver.
It is just for more understanding. But, I realized that different stm board have different way of code.
Example: in the udemy course, to send SPI data, they do not require type casting to write into data register. But, for my board because it needs to typecast it. So, In the SPI interrupt, I dont know what is the differences between the board that is used in the course.
So, sometimes I lost in the progress, do not know where to find the sources of the problem
2021-07-05 08:45 PM