ahmedragia21
Member
I'm trying to interface a CPU that has a parallel bus, and trying to connect it to STM32. The CPU bus is connected to PORTD, I mean by that CS1, CS2, A1, and it's data bus D0 to D7. The CPU has IOWR signal and IORD signal too, I connected them to PA1,PC6. I've tried to use Timer8, in STM32F429I, with external trigger which is PC6, and start a DMA transfer. The DMA is configured as circular buffer, and I'm trying to capture a lot of data, like 5Kbytes from PORTD that is connected to (DMA peripheral to memory). The transfer is slow, DMA hangs, The triggering from timer (IOWR) happens so fast, I don't get complete buffers, (The CPU actually sends LCD data), I'm receiving part of it sometimes, and sometimes complete picture.
I would like to know a way or an approach to solve that problem.
I'm using HAL, and that's my current code:
Timer Init:
DMA, Timer Configuration:
Processing the two buffers:
Enabling and Starting DMA Transfer:
I would like to know a way or an approach to solve that problem.
I'm using HAL, and that's my current code:
Timer Init:
Bash:
static void MX_TIM8_Init(void)
{
/* USER CODE BEGIN TIM8_Init 0 */
/* USER CODE END TIM8_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_SlaveConfigTypeDef sSlaveConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM8_Init 1 */
/* USER CODE END TIM8_Init 1 */
htim8.Instance = TIM8;
htim8.Init.Prescaler = 0;
htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
htim8.Init.Period = 65535;
htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim8.Init.RepetitionCounter = 0;
htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim8) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim8, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;
sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_FALLING;
sSlaveConfig.TriggerFilter = 0;
if (HAL_TIM_SlaveConfigSynchro(&htim8, &sSlaveConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
}
DMA, Timer Configuration:
Code:
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(htim_base->Instance==TIM8)
{
/* USER CODE BEGIN TIM8_MspInit 0 */
/* USER CODE END TIM8_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM8_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**TIM8 GPIO Configuration
PC6 ------> TIM8_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF3_TIM8;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* TIM8 DMA Init */
/* TIM8_CH4_TRIG_COM Init */
hdma_tim8_ch4_trig_com.Instance = DMA2_Stream7;
hdma_tim8_ch4_trig_com.Init.Channel = DMA_CHANNEL_7;
hdma_tim8_ch4_trig_com.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_tim8_ch4_trig_com.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim8_ch4_trig_com.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim8_ch4_trig_com.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_tim8_ch4_trig_com.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_tim8_ch4_trig_com.Init.Mode = DMA_CIRCULAR;
hdma_tim8_ch4_trig_com.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_tim8_ch4_trig_com.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_tim8_ch4_trig_com) != HAL_OK)
{
Error_Handler();
}
/* Several peripheral DMA handle pointers point to the same DMA handle.
Be aware that there is only one stream to perform all the requested DMAs. */
//__HAL_LINKDMA(htim_base,hdma[TIM_DMA_ID_CC4],hdma_tim8_ch4_trig_com);
__HAL_LINKDMA(htim_base,hdma[TIM_DMA_ID_TRIGGER],hdma_tim8_ch4_trig_com);
//__HAL_LINKDMA(htim_base,hdma[TIM_DMA_ID_COMMUTATION],hdma_tim8_ch4_trig_com);
HAL_DMA_RegisterCallback(&hdma_tim8_ch4_trig_com,HAL_DMA_XFER_CPLT_CB_ID,HAL_DMA_TransferComplete);
HAL_DMA_RegisterCallback(&hdma_tim8_ch4_trig_com,HAL_DMA_XFER_HALFCPLT_CB_ID,HAL_DMA_HalfTransferComplete);
/* TIM8 interrupt Init */
// HAL_NVIC_SetPriority(TIM8_TRG_COM_TIM14_IRQn, 2, 0);
// HAL_NVIC_EnableIRQ(TIM8_TRG_COM_TIM14_IRQn);
/* USER CODE BEGIN TIM8_MspInit 1 */
/* USER CODE END TIM8_MspInit 1 */
}
Processing the two buffers:
Code:
// Process data from the circular buffer
if(half_transfer)
{
half_transfer=0;
// Process data from the first half of the buffer
for (uint32_t i = 0; i < DMA_BUFFER_SIZE / 2; ++i) {
processData(buffer[i]);
}
}
if(full_transfer)
{
full_transfer=0;
for (uint32_t i = DMA_BUFFER_SIZE / 2; i < DMA_BUFFER_SIZE; ++i) {
processData(buffer[i]);
}
}
Enabling and Starting DMA Transfer:
Code:
__HAL_TIM_ENABLE_IT(&htim8, TIM_IT_TRIGGER);
/* Enable the TIMX OC channel */
__HAL_TIM_ENABLE_DMA(&htim8, TIM_DMA_TRIGGER);
HAL_DMA_Start_IT(&hdma_tim8_ch4_trig_com,(uint32_t)&(GPIOD->IDR),(uint32_t)buffer,sizeof(buffer));