cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G070 print uint8_t shows 0

JCuna.1
Senior

I have a strange issue. I use printf function in a uart port for print some variables that I use in my code. This works perfectly in cortex m4, but now in cortex m0, the variable printed show me 0, in the next code:

uint8_t	flash_ext_init(void){
 
	uint8_t wr_word[4];
	uint8_t rd_word[4];
 
	printf("Loading flash memory BY25Q32...\n");
 
//	w25q_FirstFallingCS();
 
	memset(wr_word, 0, 4);
	memset(rd_word, 0, 4);
	wr_word[0] = W25Q_CMD_JEDEC_ID;
 
	_flash_ext_spi_write_read_data(rd_word, wr_word, 4);
 
 
	printf("Flash_stat: %02xh, %02xh, %02xh, %02xh\n", rd_word[0], rd_word[1], rd_word[2], rd_word[3]);
 
	printf("BY25Q32 flash loaded...\n");
	//	printf("Flash_stat_reg1: %02xh, flash_stat_reg2: %02xh, flash_stat_reg3: %02xh...\n", w25qxx.StatusRegister1, w25qxx.StatusRegister2, w25qxx.StatusRegister3);
 
	return 1;
}

I am using -O2 optimization, and when I make a debugging process in stm32cube ide i can see that variables has the correct value, however when the variables are printed, this print a 0 value. I have test disabling "strict aliasing" in optimization settings. And the issue is solved. However, I think is better enable this optimization flag.

12 REPLIES 12
JCuna.1
Senior

Looks like I am accesing too fast to the variable, when I add a hal_delay of 1 ms after _flash_ext_spi_writ... and before printf, the variable is printed correctly. I am following this procedure to wait for complete dma transfer:

static void _flash_ext_spi_start_wait_stop_dma_transaction(void){
	LL_SPI_Enable(FLASH_EXT_SPI_HANDLER);
 
	while(FLASH_EXT_DMA_WAIT_FOR_TX); // while(LL_DMA_IsActiveFlag_TC4(FLASH_EXT_DMA_HANDLER) == 0);
 
	while(LL_SPI_GetTxFIFOLevel(FLASH_EXT_SPI_HANDLER) != LL_SPI_TX_FIFO_EMPTY);
	while(LL_SPI_IsActiveFlag_BSY(FLASH_EXT_SPI_HANDLER) != 0);
 
	while(FLASH_EXT_DMA_WAIT_FOR_RX);  // while(LL_DMA_IsActiveFlag_TC5(FLASH_EXT_DMA_HANDLER) == 0);
 
	LL_SPI_Disable(FLASH_EXT_SPI_HANDLER);
 
	while(LL_SPI_GetRxFIFOLevel(FLASH_EXT_SPI_HANDLER) != LL_SPI_RX_FIFO_EMPTY);
}

then i disable the dma:

static void _flash_ext_spi_disable_dma(void){
	LL_DMA_DisableChannel(FLASH_EXT_DMA_HANDLER, FLASH_EXT_DMA_CHANNEL_RX);
	LL_DMA_DisableChannel(FLASH_EXT_DMA_HANDLER, FLASH_EXT_DMA_CHANNEL_TX);
 
	LL_SPI_DisableDMAReq_RX(FLASH_EXT_SPI_HANDLER);
	LL_SPI_DisableDMAReq_TX(FLASH_EXT_SPI_HANDLER);
}

JCuna.1
Senior

Optimization 1 also solve the issue, I will use -O1 as workaround. If someone has deeply knowledge in compiler flags, I will be thankful.

TDK
Guru

What's in _flash_ext_spi_write_read_data? Seems like you're using DMA. Probably rd_word needs to be marked volatile.

If you feel a post has answered your question, please click "Accept as Solution".
static void _flash_ext_spi_config_dma(uint32_t *mem_read_address, uint32_t *mem_write_address, uint32_t length){
	LL_SPI_SetRxFIFOThreshold(FLASH_EXT_SPI_HANDLER, LL_SPI_RX_FIFO_TH_QUARTER);
 
	LL_DMA_SetMode(FLASH_EXT_DMA_HANDLER, FLASH_EXT_DMA_CHANNEL_RX, LL_DMA_MODE_NORMAL);
	LL_DMA_SetDataTransferDirection(FLASH_EXT_DMA_HANDLER, FLASH_EXT_DMA_CHANNEL_RX, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
	LL_DMA_SetPeriphAddress(FLASH_EXT_DMA_HANDLER, FLASH_EXT_DMA_CHANNEL_RX, LL_SPI_DMA_GetRegAddr(FLASH_EXT_SPI_HANDLER));
	LL_DMA_SetMemoryAddress(FLASH_EXT_DMA_HANDLER, FLASH_EXT_DMA_CHANNEL_RX, (uint32_t)mem_read_address);
	LL_DMA_SetDataLength(FLASH_EXT_DMA_HANDLER, FLASH_EXT_DMA_CHANNEL_RX, length);
	LL_DMA_EnableChannel(FLASH_EXT_DMA_HANDLER, FLASH_EXT_DMA_CHANNEL_RX);
 
	LL_SPI_EnableDMAReq_RX(FLASH_EXT_SPI_HANDLER);
 
	LL_DMA_SetMode(FLASH_EXT_DMA_HANDLER, FLASH_EXT_DMA_CHANNEL_TX, LL_DMA_MODE_NORMAL);
	LL_DMA_SetDataTransferDirection(FLASH_EXT_DMA_HANDLER, FLASH_EXT_DMA_CHANNEL_TX, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
	LL_DMA_SetPeriphAddress(FLASH_EXT_DMA_HANDLER, FLASH_EXT_DMA_CHANNEL_TX, LL_SPI_DMA_GetRegAddr(FLASH_EXT_SPI_HANDLER));
	LL_DMA_SetMemoryAddress(FLASH_EXT_DMA_HANDLER, FLASH_EXT_DMA_CHANNEL_TX, (uint32_t)mem_write_address);
	LL_DMA_SetDataLength(FLASH_EXT_DMA_HANDLER, FLASH_EXT_DMA_CHANNEL_TX, length);
	LL_DMA_EnableChannel(FLASH_EXT_DMA_HANDLER, FLASH_EXT_DMA_CHANNEL_TX);
 
	LL_SPI_EnableDMAReq_TX(FLASH_EXT_SPI_HANDLER);
}

data is not handled in isr, it is filled by dma peripheral.

That isn't _flash_ext_spi_write_read_data.
If you feel a post has answered your question, please click "Accept as Solution".
Piranha
Chief II

Could be a problem of too small stack or heap size. The Newlib's printf functions require huge amounts of both...

0x400 and 0x800 of size ​

TDK
Guru

One option is that you're not waiting for the DMA transfer to complete. But that's just a guess as you still haven't shown _flash_ext_spi_write_read_data.

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