stm32f3 DMA no envía la matriz de datos correctamente

Tengo un problema peculiar con STM32F303 DMA.

Estoy usando libopencm3, pero espero que vea claramente lo que está sucediendo: son solo funciones para configurar los registros de control.

Estoy enviando datos de una matriz constante a un DAC, pero está enviando los datos de forma incorrecta.

(nota: he reemplazado el contenido de la tabla de senos con una escala de 0-4095 para la depuración)

const uint16_t sine_table[SINE_TABLE_LEN] = {
    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_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_MSIZE_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);
}

Primero traté de medir la salida con un ADC, pero luego me di cuenta de que podía leer el registro de entrada del DAC y enviar ESO a través de UART.

Está enviando 8x los primeros 16 números, que 8x los últimos 16 números.

Logré capturar más o menos lo que está sucediendo (descargando algunos registros y salida DAC (primera columna) sobre USART:

Starting sine DMA
DMA started...
20,   DAC = 0     CNTDR 255
30,   DAC = 16     CNTDR 254
20,   DAC = 32     CNTDR 253
56,   DAC = 48     CNTDR 252
33,   DAC = 64     CNTDR 251
35,   DAC = 80     CNTDR 250
35,   DAC = 96     CNTDR 249
58,   DAC = 112     CNTDR 248
45,   DAC = 128     CNTDR 247
63,   DAC = 144     CNTDR 246
83,   DAC = 160     CNTDR 245
133,   DAC = 176     CNTDR 244
123,   DAC = 192     CNTDR 243
129,   DAC = 208     CNTDR 242
146,   DAC = 224     CNTDR 241
160,   DAC = 240     CNTDR 240
183,   DAC = 0     CNTDR 239
16,   DAC = 16     CNTDR 238
30,   DAC = 32     CNTDR 237
51,   DAC = 48     CNTDR 236
49,   DAC = 64     CNTDR 235
26,   DAC = 80     CNTDR 234
29,   DAC = 96     CNTDR 233
40,   DAC = 112     CNTDR 232
61,   DAC = 128     CNTDR 231
100,   DAC = 144     CNTDR 230
99,   DAC = 160     CNTDR 229
96,   DAC = 176     CNTDR 228
139,   DAC = 192     CNTDR 227
131,   DAC = 208     CNTDR 226
150,   DAC = 224     CNTDR 225
203,   DAC = 240     CNTDR 224
177,   DAC = 0     CNTDR 223
20,   DAC = 16     CNTDR 222
23,   DAC = 32     CNTDR 221
20,   DAC = 48     CNTDR 220
33,   DAC = 64     CNTDR 219
28,   DAC = 80     CNTDR 218
67,   DAC = 96     CNTDR 217
40,   DAC = 112     CNTDR 216
46,   DAC = 128     CNTDR 215
77,   DAC = 144     CNTDR 214
91,   DAC = 160     CNTDR 213
96,   DAC = 176     CNTDR 212
113,   DAC = 192     CNTDR 211
134,   DAC = 208     CNTDR 210
158,   DAC = 224     CNTDR 209
164,   DAC = 240     CNTDR 208
176,   DAC = 0     CNTDR 207
20,   DAC = 16     CNTDR 206
21,   DAC = 32     CNTDR 205
56,   DAC = 48     CNTDR 204
29,   DAC = 64     CNTDR 203
66,   DAC = 80     CNTDR 202
63,   DAC = 96     CNTDR 201
49,   DAC = 112     CNTDR 200
55,   DAC = 128     CNTDR 199
68,   DAC = 144     CNTDR 198
79,   DAC = 160     CNTDR 197
99,   DAC = 176     CNTDR 196
115,   DAC = 192     CNTDR 195
168,   DAC = 208     CNTDR 194
164,   DAC = 224     CNTDR 193
166,   DAC = 240     CNTDR 192
206,   DAC = 0     CNTDR 191
24,   DAC = 16     CNTDR 190
66,   DAC = 32     CNTDR 189
59,   DAC = 48     CNTDR 188
47,   DAC = 64     CNTDR 187
39,   DAC = 80     CNTDR 186
29,   DAC = 96     CNTDR 185
37,   DAC = 112     CNTDR 184
61,   DAC = 128     CNTDR 183
66,   DAC = 144     CNTDR 182
84,   DAC = 160     CNTDR 181
101,   DAC = 176     CNTDR 180
152,   DAC = 192     CNTDR 179
133,   DAC = 208     CNTDR 178
182,   DAC = 224     CNTDR 177
165,   DAC = 240     CNTDR 176
185,   DAC = 0     CNTDR 175
33,   DAC = 16     CNTDR 174
27,   DAC = 32     CNTDR 173
25,   DAC = 48     CNTDR 172
24,   DAC = 64     CNTDR 171
41,   DAC = 80     CNTDR 170
64,   DAC = 96     CNTDR 169
55,   DAC = 112     CNTDR 168
47,   DAC = 128     CNTDR 167
66,   DAC = 144     CNTDR 166
83,   DAC = 160     CNTDR 165
121,   DAC = 176     CNTDR 164
115,   DAC = 192     CNTDR 163
154,   DAC = 208     CNTDR 162
185,   DAC = 224     CNTDR 161
187,   DAC = 240     CNTDR 160
187,   DAC = 0     CNTDR 159
55,   DAC = 16     CNTDR 158
58,   DAC = 32     CNTDR 157
24,   DAC = 48     CNTDR 156
25,   DAC = 64     CNTDR 155
35,   DAC = 80     CNTDR 154
33,   DAC = 96     CNTDR 153
49,   DAC = 112     CNTDR 152
53,   DAC = 128     CNTDR 151
87,   DAC = 144     CNTDR 150
79,   DAC = 160     CNTDR 149
103,   DAC = 176     CNTDR 148
121,   DAC = 192     CNTDR 147
133,   DAC = 208     CNTDR 146
163,   DAC = 224     CNTDR 145
168,   DAC = 240     CNTDR 144
194,   DAC = 0     CNTDR 143
34,   DAC = 16     CNTDR 142
34,   DAC = 32     CNTDR 141
18,   DAC = 48     CNTDR 140
27,   DAC = 64     CNTDR 139
48,   DAC = 80     CNTDR 138
68,   DAC = 96     CNTDR 137
80,   DAC = 112     CNTDR 136
46,   DAC = 128     CNTDR 135
63,   DAC = 144     CNTDR 134
82,   DAC = 160     CNTDR 133
101,   DAC = 176     CNTDR 132
144,   DAC = 192     CNTDR 131
166,   DAC = 208     CNTDR 130
149,   DAC = 224     CNTDR 129
189,   DAC = 240     CNTDR 128
207,   DAC = 0     CNTDR 127
23,   DAC = 3855     CNTDR 126
3527,   DAC = 3871     CNTDR 125
3531,   DAC = 3887     CNTDR 124
3523,   DAC = 3903     CNTDR 123
3550,   DAC = 3919     CNTDR 122
3524,   DAC = 3935     CNTDR 121
3522,   DAC = 3951     CNTDR 120
3537,   DAC = 3967     CNTDR 119
3525,   DAC = 3983     CNTDR 118
3521,   DAC = 3999     CNTDR 117
3526,   DAC = 4015     CNTDR 116
3528,   DAC = 4031     CNTDR 115
3523,   DAC = 4047     CNTDR 114
3522,   DAC = 4063     CNTDR 113
3525,   DAC = 4079     CNTDR 112
3526,   DAC = 4095     CNTDR 111
32,   DAC = 3855     CNTDR 110
3517,   DAC = 3871     CNTDR 109
3525,   DAC = 3887     CNTDR 108
3527,   DAC = 3903     CNTDR 107
3523,   DAC = 3919     CNTDR 106
3553,   DAC = 3935     CNTDR 105
3523,   DAC = 3951     CNTDR 104
3522,   DAC = 3967     CNTDR 103
3524,   DAC = 3983     CNTDR 102
3524,   DAC = 3999     CNTDR 101
3541,   DAC = 4015     CNTDR 100
3520,   DAC = 4031     CNTDR 99
3519,   DAC = 4047     CNTDR 98
3521,   DAC = 4063     CNTDR 97
3539,   DAC = 4079     CNTDR 96
3517,   DAC = 4095     CNTDR 95
43,   DAC = 3855     CNTDR 94
3547,   DAC = 3871     CNTDR 93
3519,   DAC = 3887     CNTDR 92
3518,   DAC = 3903     CNTDR 91
3519,   DAC = 3919     CNTDR 90
3521,   DAC = 3935     CNTDR 89
3530,   DAC = 3951     CNTDR 88
3541,   DAC = 3967     CNTDR 87
3519,   DAC = 3983     CNTDR 86
3538,   DAC = 3999     CNTDR 85
3538,   DAC = 4015     CNTDR 84
3520,   DAC = 4031     CNTDR 83
3535,   DAC = 4047     CNTDR 82
3521,   DAC = 4063     CNTDR 81
3523,   DAC = 4079     CNTDR 80
3517,   DAC = 4095     CNTDR 79
21,   DAC = 3855     CNTDR 78
3542,   DAC = 3871     CNTDR 77
3523,   DAC = 3887     CNTDR 76
3524,   DAC = 3903     CNTDR 75
3517,   DAC = 3919     CNTDR 74
3517,   DAC = 3935     CNTDR 73
3527,   DAC = 3951     CNTDR 72
3526,   DAC = 3967     CNTDR 71
3523,   DAC = 3983     CNTDR 70
3523,   DAC = 3999     CNTDR 69
3529,   DAC = 4015     CNTDR 68
3551,   DAC = 4031     CNTDR 67
3525,   DAC = 4047     CNTDR 66
3542,   DAC = 4063     CNTDR 65
3545,   DAC = 4079     CNTDR 64
3522,   DAC = 4095     CNTDR 63
39,   DAC = 3855     CNTDR 62
3519,   DAC = 3871     CNTDR 61
3524,   DAC = 3887     CNTDR 60
3536,   DAC = 3903     CNTDR 59
3529,   DAC = 3919     CNTDR 58
3521,   DAC = 3935     CNTDR 57
3520,   DAC = 3951     CNTDR 56
3515,   DAC = 3967     CNTDR 55
3522,   DAC = 3983     CNTDR 54
3522,   DAC = 3999     CNTDR 53
3522,   DAC = 4015     CNTDR 52
3524,   DAC = 4031     CNTDR 51
3519,   DAC = 4047     CNTDR 50
3523,   DAC = 4063     CNTDR 49
3531,   DAC = 4079     CNTDR 48
3513,   DAC = 4095     CNTDR 47
29,   DAC = 3855     CNTDR 46
3518,   DAC = 3871     CNTDR 45
3548,   DAC = 3887     CNTDR 44
3526,   DAC = 3903     CNTDR 43
3523,   DAC = 3919     CNTDR 42
3547,   DAC = 3935     CNTDR 41
3542,   DAC = 3951     CNTDR 40
3538,   DAC = 3967     CNTDR 39
3515,   DAC = 3983     CNTDR 38
3528,   DAC = 3999     CNTDR 37
3522,   DAC = 4015     CNTDR 36
3518,   DAC = 4031     CNTDR 35
3519,   DAC = 4047     CNTDR 34
3519,   DAC = 4063     CNTDR 33
3521,   DAC = 4079     CNTDR 32
3519,   DAC = 4095     CNTDR 31
41,   DAC = 3855     CNTDR 30
3528,   DAC = 3871     CNTDR 29
3535,   DAC = 3887     CNTDR 28
3533,   DAC = 3903     CNTDR 27
3525,   DAC = 3919     CNTDR 26
3546,   DAC = 3935     CNTDR 25
3523,   DAC = 3951     CNTDR 24
3522,   DAC = 3967     CNTDR 23
3548,   DAC = 3983     CNTDR 22
3522,   DAC = 3999     CNTDR 21
3549,   DAC = 4015     CNTDR 20
3522,   DAC = 4031     CNTDR 19
3519,   DAC = 4047     CNTDR 18
3523,   DAC = 4063     CNTDR 17
3554,   DAC = 4079     CNTDR 16
3539,   DAC = 4095     CNTDR 15
14,   DAC = 3855     CNTDR 14
3519,   DAC = 3871     CNTDR 13
3523,   DAC = 3887     CNTDR 12
3523,   DAC = 3903     CNTDR 11
3527,   DAC = 3919     CNTDR 10
3532,   DAC = 3935     CNTDR 9
3518,   DAC = 3951     CNTDR 8
3545,   DAC = 3967     CNTDR 7
3540,   DAC = 3983     CNTDR 6
3525,   DAC = 3999     CNTDR 5
3523,   DAC = 4015     CNTDR 4
3518,   DAC = 4031     CNTDR 3
3541,   DAC = 4047     CNTDR 2
3551,   DAC = 4063     CNTDR 1
3537,   DAC = 4079     CNTDR 256
3521,   DAC = 0     CNTDR 255 // Continues periodically...

¿Puede ser por alguna mala configuración? ¿O es tal vez una falla de hardware? (Lo dudo, aunque...)

Respuestas (1)

El problema era

dma_set_memory_size(dma, ch, DMA_CCR_MSIZE_16BIT);
dma_set_peripheral_size(dma, ch, DMA_CCR_MSIZE_16BIT);

debería haber sido

dma_set_memory_size(dma, ch, DMA_CCR_MSIZE_16BIT);
dma_set_peripheral_size(dma, ch, DMA_CCR_PSIZE_16BIT); // note the P