cancel
Showing results for 
Search instead for 
Did you mean: 

SPI handle structure did not write and shift the register

WM_IR
Senior

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

1 ACCEPTED SOLUTION

Accepted Solutions

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

View solution in original post

10 REPLIES 10
TDK
Guru

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.

If you feel a post has answered your question, please click "Accept as Solution".

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.

0693W00000Bct7HQAR.png

If you generate code using CubeMX, it will add them for you.
Otherwise, they can be found here:
https://github.com/STMicroelectronics/STM32CubeF3/tree/master/Drivers/CMSIS/Device/ST/STM32F3xx/Include
If you feel a post has answered your question, please click "Accept as Solution".

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?

I did try again, here is the screenshot of my IDE during debug Mode.

0693W00000BctA1QAJ.pngthe TXEIE is not SET

> 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.

If you feel a post has answered your question, please click "Accept as Solution".

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.

If you feel a post has answered your question, please click "Accept as Solution".

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

Some chips have a FIFO in which you can write more than one byte at a time. In that case, you need to do a byte access in order to write a single byte. In chips without a FIFO, this is unnecessary (but could still be done with no ill effect). That would be my guess as to what's going on.
If you feel a post has answered your question, please click "Accept as Solution".