您好!
是否可以设置 UDMA 通道以发送 8位到32位 CPU 寄存器的阵列[1024]?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好!
是否可以设置 UDMA 通道以发送 8位到32位 CPU 寄存器的阵列[1024]?
非常感谢您的回答。
UDMA 通道连接到 GPIO 端口。
触发器是 GPIO 端口。
数据源是一个32位的1024数组。
目的是一个定时器匹配寄存器。
每个 GPIO 触发器应始终从数组发送一个项目到计时器的匹配寄存器。
在此配置中、一切正常。
但我只发送小于255的十进制值。
我的 SRAM 已停止运行。
如果我可以在32位的1024数组中创建一个8位的1024数组。 我可以节省大量内存。
在这里我的配置:
void init_uDMA()
{
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA));
// general uDMA setup
MAP_uDMAEnable();
MAP_uDMAControlBaseSet(uDMAControlTable);
MAP_IntEnable(INT_UDMAERR);
// led signal setup
MAP_uDMAChannelAssign(UDMA_CH5_GPIOB);
MAP_uDMAChannelAttributeDisable(UDMA_CH5_GPIOB,
UDMA_ATTR_ALTSELECT |
UDMA_ATTR_HIGH_PRIORITY |
UDMA_ATTR_REQMASK |
UDMA_ATTR_USEBURST);
MAP_uDMAChannelControlSet(UDMA_CH5_GPIOB | UDMA_PRI_SELECT,
UDMA_SIZE_32 | UDMA_SRC_INC_32 |
UDMA_DST_INC_NONE | UDMA_ARB_1);
MAP_uDMAChannelControlSet(UDMA_CH5_GPIOB | UDMA_ALT_SELECT,
UDMA_SIZE_32 | UDMA_SRC_INC_32 |
UDMA_DST_INC_NONE | UDMA_ARB_1);
}
void startStreamPri(uint16_t size)
{
MAP_uDMAChannelTransferSet(UDMA_CH5_GPIOB | UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG, &streamData_PRI,
(void *)(TIMER1_BASE + TIMER_O_TAMATCHR),
size);
DEBUG_PD6 = GPIO_PIN_6; // PRISTART
MAP_uDMAChannelEnable(UDMA_CH5_GPIOB | UDMA_PRI_SELECT);
streamStatus_PRI = ENABLED;
}
void startStreamAlt(uint16_t size)
{
MAP_uDMAChannelTransferSet(UDMA_CH5_GPIOB | UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG, &streamData_ALT,
(void *)(TIMER1_BASE + TIMER_O_TAMATCHR),
size);
DEBUG_PC4 = GPIO_PIN_4; // ALTSTART
MAP_uDMAChannelEnable(UDMA_CH5_GPIOB | UDMA_ALT_SELECT);
streamStatus_ALT = ENABLED;
}
static uint32_t streamData_PRI static uint32_t streamData_ALT
尊敬的 Kevin:
我看到、这是一个有趣的用例、我以前没有尝试过类似的操作。 我在我的末尾没有发现任何真正的问题、因为您正在更新寄存器值、所以虽然 DMA 说 "对于任何给定的传输、源数据和目标数据大小必须相同"、但我认为在这种情况下、您可以摆脱这种情况。
但是、如果不是、我在这里的理解是、您的目标是将所有内容存储为8位值:
[引用 userid="512790" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1113312/tm4c123gh6pm dma-channel-array-1024-of -8bit-send-to-32ite-cpu-register/4126403#412432]/如果可以引用81024位数组和81024位数组、则可以引用81024位数组。]因此、如果您无法成功进行8位传输、那么您可能可以找到一种方法来键入 cast 数据以进行传输? 我以前没有尝试过这样的情况、但这是我们想到的下一个解决方案。
此致、
Ralph Jacobi
我这么做了。
似乎这些值没有到达计时器匹配寄存器。
我有一个 DMA 完成中断、我可以看到 DMA 正在工作。
编辑:
我使用逻辑分析仪观察到信号、在第一次传输后、可以在匹配寄存器中看到:
0b0000'0000'0000'0000'0110'0010'0110'0010
但它必须是 DEZ 74。
出什么问题了?
EDIT2:
匹配寄存器中的值为:
0b0000'0000'0000'0000'0000'0000'0110'0010
在我启动 uDMA 通道后、会出现以下情况:
0b0000'0000'0000'0000'0100'1010'0100'1010
但它必须:
0b100'1010
DEZ 编号为74。
为什么这个数字在 BIN 中是有疑问的?
void init_SYS_CLOCK()
{
MAP_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL |
SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
MAP_SysCtlDelay(10);
}
void init_uDMA()
{
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA));
// general uDMA setup
MAP_uDMAEnable();
MAP_uDMAControlBaseSet(uDMAControlTable);
MAP_IntEnable(INT_UDMAERR);
MAP_uDMAChannelAssign(UDMA_CH5_GPIOB);
MAP_uDMAChannelAttributeDisable(UDMA_CH5_GPIOB,
UDMA_ATTR_ALTSELECT |
UDMA_ATTR_HIGH_PRIORITY |
UDMA_ATTR_REQMASK |
UDMA_ATTR_USEBURST);
MAP_uDMAChannelControlSet(UDMA_CH5_GPIOB | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 |
UDMA_DST_INC_NONE | UDMA_ARB_1);
MAP_uDMAChannelControlSet(UDMA_CH5_GPIOB | UDMA_ALT_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 |
UDMA_DST_INC_NONE | UDMA_ARB_1);
}
void init_TIMER()
{
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER1));
MAP_GPIOPinConfigure(GPIO_PB4_T1CCP0);
MAP_GPIOPinConfigure(GPIO_PB5_T1CCP1);
MAP_GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_4);
MAP_GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_5);
MAP_TimerConfigure(TIMER1_BASE, TIMER_CFG_SPLIT_PAIR |
TIMER_CFG_A_PWM | TIMER_CFG_B_PWM);
MAP_TimerLoadSet(TIMER1_BASE, TIMER_BOTH, 99);
MAP_TimerMatchSet(TIMER1_BASE, TIMER_A, 98);
MAP_TimerMatchSet(TIMER1_BASE, TIMER_B, 23);
MAP_TimerEnable(TIMER1_BASE, TIMER_BOTH);
}
void init_GPIO_B()
{
MAP_GPIODirModeSet(GPIO_PORTB_BASE, GPIO_PIN_0,
GPIO_DIR_MODE_IN);
MAP_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_0, GPIO_STRENGTH_2MA,
GPIO_PIN_TYPE_STD_WPU);
MAP_GPIODMATriggerEnable(GPIO_PORTB_BASE, GPIO_PIN_0);
MAP_GPIOIntTypeSet(GPIO_PORTB_BASE, GPIO_PIN_0, GPIO_FALLING_EDGE);
MAP_GPIOIntEnable(GPIO_PORTB_BASE, GPIO_INT_DMA);
// ------------------ //
// Priority Levels
// Priority 4 = 0xE0
// Priority 3 = 0x60
// Priority 2 = 0x20
// Priority 1 = 0x00
// ------------------ //
MAP_IntPrioritySet(INT_GPIOB, 0x20); // Priority 2
MAP_IntEnable(INT_GPIOB);
}
void startStreamPri(uint16_t size)
{
MAP_uDMAChannelTransferSet(UDMA_CH5_GPIOB | UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG, &streamData_PRI,
(void *)(TIMER1_BASE + TIMER_O_TAMATCHR),
size);
DEBUG_PD6 = GPIO_PIN_6; // PRISTART
MAP_uDMAChannelEnable(UDMA_CH5_GPIOB | UDMA_PRI_SELECT);
streamStatus_PRI = ENABLED;
}
void startStreamAlt(uint16_t size)
{
MAP_uDMAChannelTransferSet(UDMA_CH5_GPIOB | UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG, &streamData_ALT,
(void *)(TIMER1_BASE + TIMER_O_TAMATCHR),
size);
DEBUG_PC4 = GPIO_PIN_4; // ALTSTART
MAP_uDMAChannelEnable(UDMA_CH5_GPIOB | UDMA_ALT_SELECT);
streamStatus_ALT = ENABLED;
}
static uint8_t streamData_PRI[1024]; static uint8_t streamData_ALT[1024];
必须桥接端口:
需要使用电缆桥接:PB0 <--> PB5
尊敬的 Kevin:
因此、我复制了8位大小数组的问题、但我尚未找到解决该问题的方法、但我确实确定了一个折衷方案。
如果使用16位数组大小和16位传输、我看到了正确的数据传输到计时器匹配寄存器。 这会将您使用的缓冲器大小减少50%、这一点值得注意。
现在我不知道是否有办法使8位传输正常工作、因为我怀疑问题是计时器寄存器的全尺寸为16位、我不相信有办法让它正常工作 接受高8位为"0"、而不是重复数据。
此致、
Ralph Jacobi