diff options
Diffstat (limited to 'tests/test_dma.c')
-rw-r--r-- | tests/test_dma.c | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/tests/test_dma.c b/tests/test_dma.c new file mode 100644 index 0000000..50cdb5b --- /dev/null +++ b/tests/test_dma.c @@ -0,0 +1,189 @@ +#include "test_harness.h" +#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 <stdio.h> +#include <stdlib.h> +#include <memory.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; +} |