Tengo algunos problemas para que mi memoria con la configuración circular GPIO DMA sea correcta. El código de inicialización pegado a continuación tiene algunos problemas.
Estoy intentando mover los datos de una matriz uint16_t al registro GPIO- > ODR. Tengo la fuente y el destino configurados como media palabra ya que ambos son registros de 16 bits. Mi matriz tiene una longitud de 48 bytes, y quiero transferir 96 bytes (la matriz de 48 bytes 2 veces). Así que quiero que el DMA desplace los 48 bytes, luego regrese al inicio de la matriz y vuelva a hacerlo con la misma matriz.
Sin embargo, no tengo claro cómo decirle a la DMA después de cuántos bytes hay que devolver el círculo. Si configuro el tamaño de búfer en 96, simplemente sigue leyendo 48 bytes más allá de mi matriz.
void WS2812_Basic_DMA_Init2(void)
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // Enable DMA1 clock
DMA_DeInit(DMA1_Channel2); // Reset DMA1 channe1 to default values;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // M2M Disabled- Peripheral mode (requires timer trigger)
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // Circular mode
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; // High priority
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // Memory to Peripheral
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 16-bit Register
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // Always write to same register
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&GPIOC->ODR; // Output data for GPIO
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 16-bit array
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Increment through array
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&source16; // 16-bit Source data
DMA_InitStructure.DMA_BufferSize = ARRAYSIZE; // Size of source array x 2
DMA_Init(DMA1_Channel2, &DMA_InitStructure); // Initialize DMA
//Enable DMA1 channel IRQ Channel */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Enable DMA1 Channel Transfer Complete interrupt
DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);
}