#include #include #include #include "arch/stm32l4xxx/peripherals/dma.h" #include "arch/stm32l4xxx/peripherals/rcc.h" #include "arch/stm32l4xxx/peripherals/usart.h" #include "kern/dma/dma_manager.h" #include "test_harness.h" TEST(dma, smoke) { dma_t* dma = &DMA1; memset(dma, 0, sizeof(dma_t)); regset(dma->is_r, dma_tcif1, 1); ASSERT_EQ(dma->is_r, 2); regset(dma->is_r, dma_htif7, 1); ASSERT_EQ(dma->is_r, 67108866); return 0; } TEST(dma, cc_regset) { dma_t* dma = &DMA1; memset(dma, 0, sizeof(dma_t)); dma_channel_config_t* channel_config = &dma->channel_config[2]; regset(channel_config->cc_r, dma_cc_msize, DMA_SIZE_32_BITS); ASSERT_EQ(channel_config->cc_r, 1 << 11); return 0; } TEST(dma, correct_align) { dma_t dma; // Assert the DMA registers are aligned with what the spec says. ASSERT_EQ((long)(&dma.csel_r) - (long)(&dma), 0xA8); return 0; } TEST(dma, regset_pl) { uint32_t reg = 0; regset(reg, dma_cc_pl, DMA_PRIORITY_LEVEL_MEDIUM); ASSERT_EQ(reg, (1 << 12)); ASSERT_EQ(regget(reg, dma_cc_pl), DMA_PRIORITY_LEVEL_MEDIUM); return 0; } TEST(dma_peri, select_peripheral) { dma_opts_t opts = DEFAULT_DMA_OPTS; int ec; dma_mem2p_channel_t chan = select_dma_channel_mem2p(DMA1_PERIPH_USART2_TX, &opts, &ec); ASSERT_EQ(DMA1.channel_config[6].cpa_r, ptr2reg(&USART2.td_r)); ASSERT_EQ(regget(DMA1.channel_config[6].cc_r, dma_cc_dir), READ_FROM_MEMORY); ASSERT_EQ(regget(DMA1.channel_config[6].cc_r, dma_cc_minc), 1); ASSERT_EQ( regget(DMA1.channel_config[6].cc_r, dma_cc_pl), DMA_PRIORITY_LEVEL_MEDIUM); ASSERT_EQ(regget(DMA1.csel_r, dma_c7s), 0x2); ASSERT_EQ(regget(RCC.ahb1en_r, rcc_dma1en), 1); release_dma_channel(chan.c_); ASSERT_EQ(regget(RCC.ahb1en_r, rcc_dma1en), 0); return 0; } TEST(dma_peri, unable_to_realloc) { dma_opts_t opts = DEFAULT_DMA_OPTS; int ec = 0; dma_mem2p_channel_t chan = select_dma_channel_mem2p(DMA1_PERIPH_USART2_TX, &opts, &ec); ASSERT_EQ(ec, 0); select_dma_channel_p2mem(DMA1_PERIPH_USART2_TX, &opts, &ec); ASSERT_EQ(ec, DMA_ERROR_CHANNEL_IN_USE); release_dma_channel(chan.c_); chan = select_dma_channel_mem2p(DMA1_PERIPH_USART2_TX, &opts, &ec); ASSERT_EQ(ec, 0); release_dma_channel(chan.c_); return 0; } TEST(dma_peri, select_mem2mem) { int ec = 0; dma_opts_t opts = DEFAULT_DMA_OPTS; dma_mem2mem_channel_t chan = select_dma_channel_mem2mem(-1, &opts, &ec); ASSERT_EQ(ec, 0); ASSERT_EQ(chan.c_.dma, 1); ASSERT_EQ(chan.c_.chan, 6); dma_mem2mem_channel_t chan2 = select_dma_channel_mem2mem(-1, &opts, &ec); ASSERT_EQ(ec, 0); ASSERT_EQ(chan2.c_.dma, 1); ASSERT_EQ(chan2.c_.chan, 5); release_dma_channel(chan.c_); dma_mem2mem_channel_t chan3 = select_dma_channel_mem2mem(-1, &opts, &ec); ASSERT_EQ(chan3.c_.dma, 1); ASSERT_EQ(chan3.c_.chan, 6); release_dma_channel(chan2.c_); release_dma_channel(chan3.c_); return 0; } TEST(dma_peri, select_mem2mem_2) { dma_opts_t opts = DEFAULT_DMA_OPTS; dma_mem2mem_channel_t chans[14]; int ec; for (int i = 0; i < 14; ++i) { chans[i] = select_dma_channel_mem2mem(-1, &opts, &ec); ASSERT_EQ(ec, 0); } select_dma_channel_mem2mem(-1, &opts, &ec); ASSERT_EQ(ec, DMA_ERROR_CHANNEL_IN_USE); for (int i = 0; i < 14; ++i) { if (i < 7) { ASSERT_EQ(chans[i].c_.chan, 6 - i); ASSERT_EQ(chans[i].c_.dma, 1); } else { ASSERT_EQ(chans[i].c_.chan, 6 - (i - 7)); ASSERT_EQ(chans[i].c_.dma, 0); } release_dma_channel(chans[i].c_); } return 0; }