Following with that great answer
Reverse engineer LCD Protocol used in MPC2000XL
I’m trying to capture the data using stm32, it appears that I need to use DMA with Parallel Input.
I have setup Timer2 channel 1 with trigger on IOWRD(PA0), and wanted to start a dma transfer. I can capture the IOWR falling edge signal using the following code, but DMA never starts.
I’m trying to copy the GPIOD to memory, then I can process that buffer.
Here is the configuration:
void TIM2_IRQHandler(void) {
HAL_TIM_IRQHandler(&htim2);
HAL_DMA_Start_IT(htim2.hdma[TIM_DMA_ID_CC1], (uint32_t)&(GPIOD->IDR), (uint32_t)buffer, DMA_BUFFER_SIZE);
}
void HAL_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma)
{
if (hdma->Instance == DMA2_Stream2)
{
// DMA transfer complete callback code here
}
}
// DMA interrupt handler
void DMA2_Stream2_IRQHandler(void) {
HAL_DMA_IRQHandler(htim2.hdma[TIM_DMA_ID_CC1]);
}
void XferCpltCallback(DMA_HandleTypeDef *hdma)
{
if (hdma->Instance == DMA1_Stream5) {
uint8_t A1;
uint8_t CS1;
uint8_t CS2;
uint8_t data_byte = 0;
for (int i = 0; i < 8; i++) {
data_byte |= ((buffer[0] >> i) & 0x01) << i;
}
A1 = (buffer[0] >> 8) & 0x01;
CS1 = (buffer[0] >> 9) & 0x01;
CS2 = (buffer[0] >> 10) & 0x01;
if ((!CS1) && (!A1)) {
LCD1_write_cmd(data_byte);
}
if ((!CS1) && (A1)) {
LCD1_write_dat(data_byte);
}
if ((!CS2) && (!A1)) {
LCD2_write_cmd(data_byte);
}
if ((!CS2) && (A1)) {
LCD2_write_dat(data_byte);
}
}
}
static void MX_TIM2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
TIM_IC_InitTypeDef sConfigIC;
/* Peripheral clock enable */
__TIM2_CLK_ENABLE();
/* Peripheral interrupt init*/
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
/**TIM2 GPIO Configuration
PA0/WKUP ------> TIM2_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 0xFFFFFFFF;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&htim2);
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig);
HAL_TIM_IC_Init(&htim2);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);
/* Input capture stuff HERE
Change polarity as needed */
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1);
}
static void MX_DMA_Init(void)
{
__HAL_RCC_DMA1_CLK_ENABLE();
// DMA initialization code here
hdma_tim2_ch1.Instance = DMA2_Stream2;
hdma_tim2_ch1.Init.Channel = DMA_CHANNEL_6;
hdma_tim2_ch1.Init.Direction = DMA_MEMORY_TO_MEMORY;
hdma_tim2_ch1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim2_ch1.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim2_ch1.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE ; /* only reading in GPIO PB[15:8]... PB[7:0] used on FSMC */
hdma_tim2_ch1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD ;
hdma_tim2_ch1.Init.Mode = DMA_NORMAL; /* double memory buffer used */
hdma_tim2_ch1.Init.Priority = DMA_PRIORITY_HIGH;
hdma_tim2_ch1.Init.FIFOMode = DMA_FIFOMODE_DISABLE; /* using FIFO mode since memory datasize=32bit and GPIO=8bits in our case */
__HAL_LINKDMA(&htim2, hdma[TIM_DMA_ID_CC1], hdma_tim2_ch1);
if (HAL_DMA_Init(htim2.hdma[TIM_DMA_ID_CC1]) != HAL_OK)
{
Error_Handler();
}
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
}