Skip to content

Commit d9b1d87

Browse files
Marcus Chang0xc0170
authored andcommitted
NRF52 series PWM reimplementation for SDK 14.2
Driver uses new API in SDK 14.2
1 parent d1ba108 commit d9b1d87

File tree

7 files changed

+414
-330
lines changed

7 files changed

+414
-330
lines changed

targets/TARGET_NORDIC/TARGET_NRF5x/PeripheralPinsDefault.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,10 @@ MBED_WEAK const PinMapI2C PinMap_I2C[1] = {
3030
MBED_WEAK const PinMapSPI PinMap_SPI[1] = {
3131
{NC, NC, NC, NC}
3232
};
33+
34+
/* Default mapping between PWM pins and PWM instance.
35+
* Can be overwritten by user.
36+
*/
37+
MBED_WEAK const PinMapPWM PinMap_PWM[1] = {
38+
{NC, NC}
39+
};

targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52832/config/sdk_config.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,14 +2266,14 @@
22662266

22672267

22682268
#ifndef PWM1_ENABLED
2269-
#define PWM1_ENABLED 0
2269+
#define PWM1_ENABLED 1
22702270
#endif
22712271

22722272
// <q> PWM2_ENABLED - Enable PWM2 instance
22732273

22742274

22752275
#ifndef PWM2_ENABLED
2276-
#define PWM2_ENABLED 0
2276+
#define PWM2_ENABLED 1
22772277
#endif
22782278

22792279
// <q> PWM3_ENABLED - Enable PWM3 instance

targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/config/sdk_config.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,21 +2266,21 @@
22662266

22672267

22682268
#ifndef PWM1_ENABLED
2269-
#define PWM1_ENABLED 0
2269+
#define PWM1_ENABLED 1
22702270
#endif
22712271

22722272
// <q> PWM2_ENABLED - Enable PWM2 instance
22732273

22742274

22752275
#ifndef PWM2_ENABLED
2276-
#define PWM2_ENABLED 0
2276+
#define PWM2_ENABLED 1
22772277
#endif
22782278

22792279
// <q> PWM3_ENABLED - Enable PWM3 instance
22802280

22812281

22822282
#ifndef PWM3_ENABLED
2283-
#define PWM3_ENABLED 0
2283+
#define PWM3_ENABLED 1
22842284
#endif
22852285

22862286
// </e>

targets/TARGET_NORDIC/TARGET_NRF5x/objects.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
#include "PeripheralNames.h"
4545
#include "PinNames.h"
4646

47+
#include "nrf_pwm.h"
48+
4749
#ifdef __cplusplus
4850
extern "C" {
4951
#endif
@@ -62,10 +64,12 @@ struct port_s {
6264
};
6365

6466
struct pwmout_s {
65-
PWMName pwm_name;
67+
int instance;
6668
PinName pin;
67-
uint8_t pwm_channel;
68-
void * pwm_struct;
69+
nrf_pwm_values_common_t pulse;
70+
uint16_t period;
71+
float percent;
72+
nrf_pwm_sequence_t sequence;
6973
};
7074

7175
struct i2c_s {

targets/TARGET_NORDIC/TARGET_NRF5x/pinmap_ex.c

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,28 @@
3131
/* Define number of instances */
3232
#define NORDIC_TWI_COUNT TWI_COUNT
3333
#define NORDIC_SPI_COUNT SPI_COUNT
34+
#define NORDIC_PWM_COUNT PWM_COUNT
3435

3536
/* Define which instance to return when there are no free instances left.
3637
* The Mbed HAL API doesn't provide a way for signaling initialization errors
3738
* so we return the default value. Any instance conflicts must be handled
3839
* by the driver implementation.
3940
*/
4041
#define DEFAULT_I2C_INSTANCE 0 // SPI counts down, choose instance furthest away
41-
#define DEFAULT_SPI_INSTANCE (SPI_COUNT - 1) // I2C counts up, choose instance furthers away
42+
#define DEFAULT_SPI_INSTANCE (NORDIC_SPI_COUNT - 1) // I2C counts up, choose instance furthers away
43+
#define DEFAULT_PWM_INSTANCE (NORDIC_PWM_COUNT - 1)
44+
45+
46+
/***
47+
* _____ _____ _____ ___ _____
48+
* / ____| __ \_ _|__ \ / ____|
49+
* | (___ | |__) || | ) | |
50+
* \___ \| ___/ | | / /| |
51+
* ____) | | _| |_ / /_| |____
52+
* |_____/|_| |_____|____|\_____|
53+
*
54+
*
55+
*/
4256

4357
/* Internal data structure shared between SPI and I2C to keep track of allocated
4458
* instances. The data structure is shared to reflect the hardware sharing.
@@ -246,3 +260,108 @@ int pin_instance_spi(PinName mosi, PinName miso, PinName clk)
246260

247261
return instance;
248262
}
263+
264+
265+
/***
266+
* _______ ____ __
267+
* | __ \ \ / / \/ |
268+
* | |__) \ \ /\ / /| \ / |
269+
* | ___/ \ \/ \/ / | |\/| |
270+
* | | \ /\ / | | | |
271+
* |_| \/ \/ |_| |_|
272+
*
273+
*
274+
*/
275+
276+
/* Internal data structure to keep track of allocated instances.
277+
*/
278+
static PinName nordic_internal_pwm[NORDIC_PWM_COUNT] = {
279+
NC,
280+
NC,
281+
NC,
282+
#if (NORDIC_PWM_COUNT == 4)
283+
NC,
284+
#endif
285+
};
286+
287+
/**
288+
* Brief Find hardware instance for the provided PWM pin.
289+
*
290+
* The function will search the PeripheralPin map for a pre-allocated
291+
* assignment. If none is found the allocation map will be searched
292+
* to see if the same pins have been assigned an instance before.
293+
*
294+
* If no assignement is found and there is an empty slot left in the
295+
* map, the pins are stored in the map and the hardware instance is
296+
* returned.
297+
*
298+
* If no free instances are available, the default instance is returned.
299+
*
300+
* Parameter pwm pwm pin.
301+
*
302+
* Return Hardware instance associated with provided pins.
303+
*/
304+
int pin_instance_pwm(PinName pwm)
305+
{
306+
int instance = NC;
307+
308+
/* Search pin map for pre-allocated instance */
309+
for (size_t index = 0; (PinMap_PWM[index].pwm != NC); index++) {
310+
311+
/* Compare pins to entry. */
312+
if (PinMap_PWM[index].pwm == pwm) {
313+
314+
DEBUG_PRINTF("found: %d %d\r\n", pwm, PinMap_PWM[index].instance);
315+
316+
/* Instance found, save result. */
317+
instance = PinMap_PWM[index].instance;
318+
319+
/* Lock out entry in map. */
320+
nordic_internal_pwm[instance] = pwm;
321+
break;
322+
}
323+
}
324+
325+
/* No instance was found in static map. */
326+
if (instance == NC) {
327+
328+
/* Search dynamic map for entry. */
329+
for (size_t index = 0; index < NORDIC_PWM_COUNT; index++) {
330+
331+
/* Pins match previous dynamic allocation, return instance. */
332+
if (nordic_internal_pwm[index] == pwm) {
333+
334+
instance = index;
335+
break;
336+
}
337+
}
338+
}
339+
340+
/* No instance was found in dynamic map. */
341+
if (instance == NC) {
342+
343+
/* Search dynamic map for empty slot. */
344+
for (size_t index = 0; index < NORDIC_PWM_COUNT; index++) {
345+
346+
/* Empty slot found, reserve slot by storing pins. */
347+
if (nordic_internal_pwm[index] == NC) {
348+
349+
nordic_internal_pwm[index] = pwm;
350+
351+
instance = index;
352+
break;
353+
}
354+
}
355+
}
356+
357+
#if defined(DEFAULT_PWM_INSTANCE)
358+
/* Exhausted all options. Return default value. */
359+
if (instance == NC) {
360+
instance = DEFAULT_PWM_INSTANCE;
361+
}
362+
#endif
363+
364+
DEBUG_PRINTF("PWM: %d %d\r\n", pwm, instance);
365+
366+
return instance;
367+
}

targets/TARGET_NORDIC/TARGET_NRF5x/pinmap_ex.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ typedef struct {
4242

4343
extern const PinMapSPI PinMap_SPI[];
4444

45+
/* Data structure for pre-allocated PWM instances. */
46+
typedef struct {
47+
PinName pwm;
48+
int instance;
49+
} PinMapPWM;
50+
51+
extern const PinMapPWM PinMap_PWM[];
52+
4553
/**
4654
* @brief Find hardware instance for the provided I2C pins.
4755
*
@@ -83,6 +91,25 @@ int pin_instance_i2c(PinName sda, PinName scl);
8391
*/
8492
int pin_instance_spi(PinName mosi, PinName miso, PinName clk);
8593

94+
/**
95+
* @brief Find hardware instance for the provided PWM pins.
96+
*
97+
* The function will search the PeripheralPin map for a pre-allocated
98+
* assignment. If none is found the allocation map will be searched
99+
* to see if the same pins have been assigned an instance before.
100+
*
101+
* If no assignement is found and there is an empty slot left in the
102+
* map, the pins are stored in the map and the hardware instance is
103+
* returned.
104+
*
105+
* If no free instances are available, the default instance is returned.
106+
*
107+
* @param[in] pwm pwm pin.
108+
*
109+
* @return Hardware instance associated with provided pins.
110+
*/
111+
int pin_instance_pwm(PinName pwm);
112+
86113
#ifdef __cplusplus
87114
}
88115
#endif

0 commit comments

Comments
 (0)