Clarification on how to generate a 10kHz sine wave with PWM and DMA

I'm struggling when using PWM and DMA to generate a sine wave. I'm sure I'm not interpreting the documentation right, and I hope someone can point me in the right direction

I tried the following code

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <string.h>
#include "nrf_drv_pwm.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "boards.h"
#include "bsp.h"
#include "app_timer.h"
#include "nrf_drv_clock.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
static nrf_drv_pwm_t m_pwm = NRF_DRV_PWM_INSTANCE(0);
static void init_bsp()
{
APP_ERROR_CHECK(nrf_drv_clock_init());
nrf_drv_clock_lfclk_request(NULL);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

If I understand correctly how PWM works, with a 16MHz clock and a 1000 counter top, should give me a "pwm step" of 16kHz. Since I have 40 elements in the sine lookup table, the resulting sine frequency should be 400Hz. And I get something very close (minus the analog filtering part, that I'm still trying to figure out how to do properly)

In order to get to 10kHz, I need to reduce counter top to 40, and use 40 steps for the sine lookup table (or any similar combination, 40 and 40 just happens to work nicely with a 16Mz clock). Which seems rather low to get a good sine wave. I tried using the following, and sure enough I get a 10kHz wave

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static nrf_pwm_values_wave_form_t /*const*/ m_demo_seq_values[] =
{
20,0,0,40,
23,0,0,40,
26,0,0,40,
29,0,0,40,
32,0,0,40,
34,0,0,40,
36,0,0,40,
38,0,0,40,
39,0,0,40,
40,0,0,40,
40,0,0,40,
40,0,0,40,
39,0,0,40,
38,0,0,40,
36,0,0,40,
34,0,0,40,
32,0,0,40,
29,0,0,40,
26,0,0,40,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Do I understand correctly the relationship between counter top and the values in the sequence array? Is there a way to do better than what I'm doing in generating a 10kHz sine wave? An old trick for memory limited processors was to store only the first 90 degrees of the sine table, and "mirror" it 4 times, as appropriate, but I could not think of a way to make it work here

Since I need only one channel, do I need to have the nrf_pwm_values_wave_form_t array to have all those 0 values, or is there a way to save memory? 

Lastly, any idea why I get a "warning: initialization of 'const nrf_pwm_values_wave_form_t *' from incompatible pointer type 'nrf_pwm_values_wave_form_t (*)[20]' [-Wincompatible-pointer-types]" in line 88? I thought I used the pointers as defined by nrf_pwm.h