Генериране на синусоида на STM32F3 с DMA - изкривен изход

Опитвам се да генерирам вълнова форма, използвайки const таблица, DMA и DAC.

Това е STM32F303VCT на платка Discovery F3.

Използвам libopencm3, но се надявам, че ще видите ясно какво се случва - всичко това са само функции за настройка на контролните регистри.

#define SINE_TABLE_LEN 256

static const uint16_t sine_table[] = {
    2047, 2097, 2147, 2198, 2248, 2298, 2347, 2397, 2446, 2496, 2544, 2593, 2641, 2689, 2737, 2784, 2830, 2877, 2922, 2967, 3012, 3056, 3099, 3142, 3184, 3226, 3266, 3306, 3346, 3384, 3422, 3458, 3494, 3530, 3564, 3597, 3629, 3661, 3691, 3721, 3749, 3776, 3803, 3828, 3852, 3875, 3897, 3918, 3938, 3957, 3974, 3991, 4006, 4020, 4033, 4044, 4055, 4064, 4072, 4079, 4084, 4088, 4092, 4093, 4094, 4093, 4092, 4088, 4084, 4079, 4072, 4064, 4055, 4044, 4033, 4020, 4006, 3991, 3974, 3957, 3938, 3918, 3897, 3875, 3852, 3828, 3803, 3776, 3749, 3721, 3691, 3661, 3629, 3597, 3564, 3530, 3494, 3458, 3422, 3384, 3346, 3306, 3266, 3226, 3184, 3142, 3099, 3056, 3012, 2967, 2922, 2877, 2830, 2784, 2737, 2689, 2641, 2593, 2544, 2496, 2446, 2397, 2347, 2298, 2248, 2198, 2147, 2097, 2047, 1997, 1947, 1896, 1846, 1796, 1747, 1697, 1648, 1598, 1550, 1501, 1453, 1405, 1357, 1310, 1264, 1217, 1172, 1127, 1082, 1038, 995, 952, 910, 868, 828, 788, 748, 710, 672, 636, 600, 564, 530, 497, 465, 433, 403, 373, 345, 318, 291, 266, 242, 219, 197, 176, 156, 137, 120, 103, 88, 74, 61, 50, 39, 30, 22, 15, 10, 6, 2, 1, 0, 1, 2, 6, 10, 15, 22, 30, 39, 50, 61, 74, 88, 103, 120, 137, 156, 176, 197, 219, 242, 266, 291, 318, 345, 373, 403, 433, 465, 497, 530, 564, 600, 636, 672, 710, 748, 788, 828, 868, 910, 952, 995, 1038, 1082, 1127, 1172, 1217, 1264, 1310, 1357, 1405, 1453, 1501, 1550, 1598, 1648, 1697, 1747, 1796, 1846, 1896, 1947, 1997
//  0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 272, 288, 304, 320, 336, 352, 368, 384, 400, 416, 432, 448, 464, 480, 496, 512, 528, 544, 560, 576, 592, 608, 624, 640, 656, 672, 688, 704, 720, 736, 752, 768, 784, 800, 816, 832, 848, 864, 880, 896, 912, 928, 944, 960, 976, 992, 1008, 1024, 1040, 1056, 1072, 1088, 1104, 1120, 1136, 1152, 1168, 1184, 1200, 1216, 1232, 1248, 1264, 1280, 1296, 1312, 1328, 1344, 1360, 1376, 1392, 1408, 1424, 1440, 1456, 1472, 1488, 1504, 1520, 1536, 1552, 1568, 1584, 1600, 1616, 1632, 1648, 1664, 1680, 1696, 1712, 1728, 1744, 1760, 1776, 1792, 1808, 1824, 1840, 1856, 1872, 1888, 1904, 1920, 1936, 1952, 1968, 1984, 2000, 2016, 2032, 2048, 2063, 2079, 2095, 2111, 2127, 2143, 2159, 2175, 2191, 2207, 2223, 2239, 2255, 2271, 2287, 2303, 2319, 2335, 2351, 2367, 2383, 2399, 2415, 2431, 2447, 2463, 2479, 2495, 2511, 2527, 2543, 2559, 2575, 2591, 2607, 2623, 2639, 2655, 2671, 2687, 2703, 2719, 2735, 2751, 2767, 2783, 2799, 2815, 2831, 2847, 2863, 2879, 2895, 2911, 2927, 2943, 2959, 2975, 2991, 3007, 3023, 3039, 3055, 3071, 3087, 3103, 3119, 3135, 3151, 3167, 3183, 3199, 3215, 3231, 3247, 3263, 3279, 3295, 3311, 3327, 3343, 3359, 3375, 3391, 3407, 3423, 3439, 3455, 3471, 3487, 3503, 3519, 3535, 3551, 3567, 3583, 3599, 3615, 3631, 3647, 3663, 3679, 3695, 3711, 3727, 3743, 3759, 3775, 3791, 3807, 3823, 3839, 3855, 3871, 3887, 3903, 3919, 3935, 3951, 3967, 3983, 3999, 4015, 4031, 4047, 4063, 4079
};    

void send_dac_sine()
{
    const uint32_t dma = DMA2;
    const uint32_t ch = DMA_CHANNEL3;

    dac_dma_disable(CHANNEL_1);
    dma_disable_channel(dma, ch);
    dma_channel_reset(dma, ch);

    // DMA config
    dma_enable_circular_mode(dma, ch);

    dma_set_peripheral_address(dma, ch, (uint32_t) &DAC_DHR12R1);
    dma_set_memory_address(dma, ch, (uint32_t) sine_table);

    dma_set_memory_size(dma, ch, DMA_CCR_MSIZE_16BIT); // uint16_t
    dma_set_peripheral_size(dma, ch, DMA_CCR_MSIZE_32BIT); // 32-bit register
    dma_set_number_of_data(dma, ch, SINE_TABLE_LEN);
    dma_enable_memory_increment_mode(dma, ch); // incr mem. addr
    dma_disable_peripheral_increment_mode(dma, ch); // keep periph addr
    dma_set_read_from_memory(dma, ch); // memory -> periph

    dma_set_priority(dma, ch, DMA_CCR_PL_VERY_HIGH);

    // launch

    dac_dma_enable(CHANNEL_1); // enable the DAC to send DMA requests
    dma_enable_channel(dma, ch);
}

DAC се задейства от TIMER6 TRGO.

Мисля, че трябва да има някакъв бъг в дефиницията на таблицата или адреса на паметта на таблицата.

DMA работи, виждам нещо изпратено до DAC.

Това обаче не е моята таблица - ето я начертана, както е уловена от ADC:

въведете описание на изображението тук

Какво може да не е наред?

пс. ако го оставя да работи по-дълго, получавам нещо това (периодично е)

въведете описание на изображението тук


person MightyPork    schedule 30.10.2015    source източник
comment
Ще съм благодарен, ако ми помогнете или дадете предложения, вместо да гласувате близо.   -  person MightyPork    schedule 30.10.2015
comment
Графиката на реалността наистина прилича на синусоида, но е твърде набита. Най-новият пример в долната част изглежда така, сякаш се опитва, но се рестартира. Проблеми с времето?   -  person Weather Vane    schedule 30.10.2015
comment
Извинете за объркването с графиките, долната действително е заснета, когато изпраща втората таблица - линейна 0..4095. Няма много смисъл tbh. Мисля, че чете различна част от паметта...   -  person MightyPork    schedule 30.10.2015
comment
но вече е (uint32_t*). Функцията приема uint32_t - абсолютен адрес. Това е 8006d42 и когато проверих разглобяването, масата е там добре...   -  person MightyPork    schedule 30.10.2015
comment
Беше uint16_t, но само смътна надежда.   -  person Weather Vane    schedule 30.10.2015
comment
да, това имах предвид. Резултатът е същият, ако го променя обаче - единствената промяна е, че получавам предупреждения от компилатора   -  person MightyPork    schedule 30.10.2015


Отговори (2)


Целият проблем беше една грешна буква в постоянен идентификатор. Дуууу

Периферният размер е посочен с DMA_CCR_PSIZE_*, а не с DMA_CCR_MSIZE_*.

Също така обърках указателите/адресите...

Пълен, работещ код:

#define SINE_TABLE_LEN 256
const uint16_t sine_table[SINE_TABLE_LEN] = { // now with actual sine
    2047, 2097, 2147, 2198, 2248, 2298, 2347, 2397, 2446, 2496, 2544, 2593, 2641, 2689, 2737, 2784, 2830, 2877, 2922, 2967, 3012, 3056, 3099, 3142, 3184, 3226, 3266, 3306, 3346, 3384, 3422, 3458, 3494, 3530, 3564, 3597, 3629, 3661, 3691, 3721, 3749, 3776, 3803, 3828, 3852, 3875, 3897, 3918, 3938, 3957, 3974, 3991, 4006, 4020, 4033, 4044, 4055, 4064, 4072, 4079, 4084, 4088, 4092, 4093, 4094, 4093, 4092, 4088, 4084, 4079, 4072, 4064, 4055, 4044, 4033, 4020, 4006, 3991, 3974, 3957, 3938, 3918, 3897, 3875, 3852, 3828, 3803, 3776, 3749, 3721, 3691, 3661, 3629, 3597, 3564, 3530, 3494, 3458, 3422, 3384, 3346, 3306, 3266, 3226, 3184, 3142, 3099, 3056, 3012, 2967, 2922, 2877, 2830, 2784, 2737, 2689, 2641, 2593, 2544, 2496, 2446, 2397, 2347, 2298, 2248, 2198, 2147, 2097, 2047, 1997, 1947, 1896, 1846, 1796, 1747, 1697, 1648, 1598, 1550, 1501, 1453, 1405, 1357, 1310, 1264, 1217, 1172, 1127, 1082, 1038, 995, 952, 910, 868, 828, 788, 748, 710, 672, 636, 600, 564, 530, 497, 465, 433, 403, 373, 345, 318, 291, 266, 242, 219, 197, 176, 156, 137, 120, 103, 88, 74, 61, 50, 39, 30, 22, 15, 10, 6, 2, 1, 0, 1, 2, 6, 10, 15, 22, 30, 39, 50, 61, 74, 88, 103, 120, 137, 156, 176, 197, 219, 242, 266, 291, 318, 345, 373, 403, 433, 465, 497, 530, 564, 600, 636, 672, 710, 748, 788, 828, 868, 910, 952, 995, 1038, 1082, 1127, 1172, 1217, 1264, 1310, 1357, 1405, 1453, 1501, 1550, 1598, 1648, 1697, 1747, 1796, 1846, 1896, 1947, 1997
};

void send_dac_sine()
{
    const uint32_t dma = DMA2;
    const uint32_t ch = DMA_CHANNEL3;

    dac_set_waveform_generation(DAC_CR_WAVE1_DIS);
    dac_dma_disable(CHANNEL_1);
    dma_disable_channel(dma, ch);
    dma_channel_reset(dma, ch);

    dma_enable_circular_mode(dma, ch);
    dma_set_peripheral_address(dma, ch, (uint32_t) &DAC_DHR12R1);
    dma_set_memory_address(dma, ch, (uint32_t) &sine_table);
    dma_set_memory_size(dma, ch, DMA_CCR_MSIZE_16BIT);
    dma_set_peripheral_size(dma, ch, DMA_CCR_PSIZE_16BIT);
    dma_set_read_from_memory(dma, ch);
    dma_set_number_of_data(dma, ch, SINE_TABLE_LEN);

    dma_set_priority(dma, ch, DMA_CCR_PL_VERY_HIGH);

    dma_enable_memory_increment_mode(dma, ch);
    dma_disable_peripheral_increment_mode(dma, ch);

    dac_dma_enable(CHANNEL_1);
    dma_enable_channel(dma, ch);
}
person MightyPork    schedule 30.10.2015
comment
Опитах се да конфигурирам таймера и GPIO, необходими за стартиране на вашия код, но не успях. Използвам платка STM32F3-DISCOVERY. Може би имате идея какво не е наред. gist.github.com/ReneHollander/7cebb2581fb7d3c13ba70f540f58acc6 Редактиране: Забравих да добавя това само мигащите светодиоди работят. Просто го поставих, за да видя дали кодът наистина работи. И очевидно използвам TIM2, но трябва да е конфигуриран правилно. - person Rene8888; 20.12.2016

пробвал ли си да го memcpy някъде? може да има нещо общо с това, че е статичен, т.е. не в нормалния стек. просто мисъл...

person David van rijn    schedule 30.10.2015
comment
Благодаря, но не е това. Опитах да го изпратя през USART и всичко е наред - person MightyPork; 30.10.2015
comment
Попаднах някъде - брои добре, но изпраща: 8x първите 16 числа, след това 8x последните 16 числа. Просто е странно. И таблицата е там в паметта, както трябва... хардуерна грешка? - person MightyPork; 30.10.2015