cancel
Showing results for 
Search instead for 
Did you mean: 

I want to DMA Input Capture (TIM1 CCR1) frequency values towards QSPI i/f (Single SPI Mode, W25Q128JV connected), store in Flash, DMA request being triggered by TIM6 ; on a STM32L412 based board. Need your help...

BSam
Associate II

Hello All,

I am adding parts of my code. Storing to flash is working if I DMA TIM1 CCR1 to memory and then copy from memory buffer to Flash.

I assumed that writing to QSPI_DR will trigger transfer to Flash.

Is it feasible to DMA to QSPI?

/////////////////////////////////////////////////////////////////////////////////

/* Erasing sectors 1 and 2 - want to store at 0x2000*/

 W25Q_EraseSector(1);

 W25Q_EraseSector(2);

HAL_DMA_RegisterCallback(&hdma_tim6_up, HAL_DMA_XFER_CPLT_CB_ID, frequencyCollectCallback);

QSPI_CommandTypeDef com;

com.InstructionMode = QSPI_INSTRUCTION_1_LINE;

com.Instruction = W25Q_PAGE_PROGRAM;    // Command = 0x2

com.AddressSize = QSPI_ADDRESS_24_BITS;

com.AddressMode = QSPI_ADDRESS_1_LINE;

com.Address = 0x2000;

com.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;

com.AlternateBytes = QSPI_ALTERNATE_BYTES_NONE;

com.AlternateBytesSize = QSPI_ALTERNATE_BYTES_NONE;

com.DummyCycles = 0;

com.DataMode = QSPI_DATA_1_LINE;

com.NbData = 100;

com.DdrMode = QSPI_DDR_MODE_DISABLE;

com.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;

com.SIOOMode = QSPI_SIOO_INST_ONLY_FIRST_CMD;

if (HAL_QSPI_Command(&hqspi, &com, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

return W25Q_SPI_ERR;

HAL_Delay(100);

HAL_TIM_IC_Start(&htim1, TIM_CHANNEL_2); // Indirect Channel

HAL_TIM_IC_Start(&htim1, TIM_CHANNEL_1);  // main channel

HAL_Delay(10);

HAL_TIM_Base_Start(&htim6);        // Start Collecting

/* DMA from CCR1 to QSPI DR */

HAL_DMA_Start_IT(&hdma_tim6_up, (uint32_t)(&TIM1->CCR1), (uint32_t)(&QUADSPI->DR), 100);

htim6.Instance->DIER = 0x0100;

 HAL_Delay(1000);

if (buffer_full1) { //buffer_full1 is set in Interrupt routine

uint32_t flash_data_addr = 0x2000;

     uint8_t read_buf[MEM_PAGE_SIZE] = {0};

     W25Q_SingleRead(read_buf, 100, flash_data_addr);

      LOGD("\nflash_data_addr: 0x%x\n",flash_data_addr);

      for (uint32_t j=0; j< 100; j+=2)

               LOGD("0x%x\t", read_buf[j]);

while(1){}

/////////////////////////////////////////////////////////////////////////////////////////////////

 DMA init part : Have tried Mem Data Half Word alignment also

  /* TIM6 DMA Init */

   /* TIM6_UP Init */

   hdma_tim6_up.Instance = DMA1_Channel3;

   hdma_tim6_up.Init.Request = DMA_REQUEST_6;

   hdma_tim6_up.Init.Direction = DMA_PERIPH_TO_MEMORY;

   hdma_tim6_up.Init.PeriphInc = DMA_PINC_DISABLE;

   hdma_tim6_up.Init.MemInc = DMA_MINC_DISABLE;

   hdma_tim6_up.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;

   hdma_tim6_up.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;

   hdma_tim6_up.Init.Mode = DMA_NORMAL;

   hdma_tim6_up.Init.Priority = DMA_PRIORITY_VERY_HIGH;

   if (HAL_DMA_Init(&hdma_tim6_up) != HAL_OK)

2 REPLIES 2

The Hardware doesn't work this way.

You'll need to stage in RAM and be more aware of how page write works.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hello

I have these doubts, can you please clarify.

HAL_QSPI_Command(&hqspi, &com, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) -- With this I am preparing the Flash write command (QSPI CCR).

QSPI_SIOO_INST_ONLY_FIRST_CMD => implies that the command need not be repeated every write to Flash ( supported by WINBOUND W25Q128 Flash)

HAL_DMA_Start_IT : DMA transfer from TIM1_CCR1 to QSPI_DR register (Peripheral to peripheral) - This in turn should write to the QSPI_DR. The first write to QSPI_DR should provide the Write command (Command opcode 0x2) to Flash along with Data (Command+Data).

Next DMA transfers should result in QSPI_DR being written and thus write to Flash without repeating Command every write (because of QSPI_SIOO_INST_ONLY_FIRST_CMD).

I am writing <256 bytes starting from a Page Boundary. I have erased the corresponding sector at beginning.

Winbound W25Q128 Flash has 4096 byte sector, supports Sector Erase.

Page = 256 bytes.

My regards