Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Bugfix169 analog write #193

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ For 64-bit Linux users, ```libc6:i386```, ```libstdc++6:i386```, ```libncurses5

__NOTE__: To roll back to the original driver go to: Device Manager -> Right click on device -> Check box for "Delete the driver software for this device" and click Uninstall

###### Driver Setup for Black Magic Probe
1. Download .inf file drivers from [blacksphere github](https://github.com/blacksphere/blackmagic/tree/master/driver)
2. Plugin Black Magic Probe
3. Point the installer to the folder containing blackmagic.inf

__NOTE__: If using Windows 10 or Linux then two UART COM ports will be visible without requiring additional drivers

### Selecting a SoftDevice
SoftDevices contain the BLE stack and housekeeping, and must be downloaded once before a sketch using BLE can be loaded.
The SD consumes ~5k of Ram + some extra based on actual BLE configuration.
Expand Down
39 changes: 17 additions & 22 deletions cores/nRF5/wiring_analog_nRF51.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,16 @@
extern "C" {
#endif

#define PWM_COUNT 3
#define PIN_FREE 0xffffffff

struct PWMContext {
uint32_t pin;
uint32_t value;
uint32_t channel;
uint32_t mask;
uint32_t event;
};
static uint32_t adcReference = ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling;
static uint32_t adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling;

static struct PWMContext pwmContext[PWM_COUNT] = {
struct PWMContext pwmContext[PWM_COUNT] = {
{ PIN_FREE, 0, 1, TIMER_INTENSET_COMPARE1_Msk, 1 },
{ PIN_FREE, 0, 2, TIMER_INTENSET_COMPARE2_Msk, 2 },
{ PIN_FREE, 0, 3, TIMER_INTENSET_COMPARE3_Msk, 3 }
};

static int timerEnabled = 0;

static uint32_t adcReference = ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling;
static uint32_t adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling;
struct PWMStatus pwmStatus[PWM_TIMER_COUNT] = {0, TIMER1_IRQn};

static uint32_t readResolution = 10;
static uint32_t writeResolution = 8;
Expand Down Expand Up @@ -229,7 +218,7 @@ void analogWrite( uint32_t ulPin, uint32_t ulValue )

ulPin = g_ADigitalPinMap[ulPin];

if (!timerEnabled) {
if (pwmStatus[0].numActive == 0) {
NVIC_SetPriority(TIMER1_IRQn, 3);
NVIC_ClearPendingIRQ(TIMER1_IRQn);
NVIC_EnableIRQ(TIMER1_IRQn);
Expand All @@ -245,8 +234,6 @@ void analogWrite( uint32_t ulPin, uint32_t ulValue )
NRF_TIMER1->INTENSET = TIMER_INTENSET_COMPARE0_Msk;

NRF_TIMER1->TASKS_START = 0x1UL;

timerEnabled = true;
}

for (int i = 0; i < PWM_COUNT; i++) {
Expand All @@ -259,17 +246,25 @@ void analogWrite( uint32_t ulPin, uint32_t ulValue )
| ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
| ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);

ulValue = mapResolution(ulValue, writeResolution, 8);

pwmContext[i].value = ulValue;

NRF_TIMER1->CC[pwmContext[i].channel] = ulValue;

NRF_TIMER1->INTENSET = pwmContext[i].mask;

break;
pwmStatus[0].numActive++;
return;
}
}

// fallback to digitalWrite if no available PWM channel
if (ulValue < 128)
{
digitalWrite(ulPin, LOW);
}
else
{
digitalWrite(ulPin, LOW);
}
}

void TIMER1_IRQHandler(void)
Expand Down
37 changes: 23 additions & 14 deletions cores/nRF5/wiring_analog_nRF52.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,19 @@ extern "C" {
static uint32_t saadcReference = SAADC_CH_CONFIG_REFSEL_Internal;
static uint32_t saadcGain = SAADC_CH_CONFIG_GAIN_Gain1_5;

#define PWM_COUNT 3

static NRF_PWM_Type* pwms[PWM_COUNT] = {
NRF_PWM_Type* pwms[PWM_COUNT] = {
NRF_PWM0,
NRF_PWM1,
NRF_PWM2
};

static uint32_t pwmChannelPins[PWM_COUNT] = {
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF
struct PWMContext pwmContext[PWM_COUNT] = {
{ PIN_FREE, 0 },
{ PIN_FREE, 0 },
{ PIN_FREE, 0 }
};
static uint16_t pwmChannelSequence[PWM_COUNT];

struct PWMStatus pwmStatus[PWM_TIMER_COUNT] = {0, 0};

static int readResolution = 10;
static int writeResolution = 8;
Expand Down Expand Up @@ -220,9 +219,9 @@ void analogWrite( uint32_t ulPin, uint32_t ulValue )
ulPin = g_ADigitalPinMap[ulPin];

for (int i = 0; i < PWM_COUNT; i++) {
if (pwmChannelPins[i] == 0xFFFFFFFF || pwmChannelPins[i] == ulPin) {
pwmChannelPins[i] = ulPin;
pwmChannelSequence[i] = ulValue | bit(15);
if (pwmContext[i].pin == PIN_FREE || pwmContext[i].pin == ulPin) {
pwmContext[i].pin = ulPin;
pwmContext[i].value = ulValue;

NRF_PWM_Type* pwm = pwms[i];

Expand All @@ -236,15 +235,25 @@ void analogWrite( uint32_t ulPin, uint32_t ulValue )
pwm->COUNTERTOP = (1 << writeResolution) - 1;
pwm->LOOP = 0;
pwm->DECODER = ((uint32_t)PWM_DECODER_LOAD_Common << PWM_DECODER_LOAD_Pos) | ((uint32_t)PWM_DECODER_MODE_RefreshCount << PWM_DECODER_MODE_Pos);
pwm->SEQ[0].PTR = (uint32_t)&pwmChannelSequence[i];
pwm->SEQ[0].PTR = (uint32_t)&(pwmContext[i].value);
pwm->SEQ[0].CNT = 1;
pwm->SEQ[0].REFRESH = 1;
pwm->SEQ[0].ENDDELAY = 0;
pwm->TASKS_SEQSTART[0] = 0x1UL;

break;
pwmStatus[0].numActive++;
return;
}
}

// fallback to digitalWrite if no available PWM channel
if (ulValue < 128)
{
digitalWrite(ulPin, LOW);
}
else
{
digitalWrite(ulPin, LOW);
}
}

#ifdef __cplusplus
Expand Down
39 changes: 35 additions & 4 deletions cores/nRF5/wiring_digital.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@
#include "nrf.h"

#include "Arduino.h"
#include "wiring_private.h"

extern struct PWMContext pwmContext[PWM_COUNT];
extern struct PWMStatus pwmStatus[PWM_TIMER_COUNT];
#ifdef NRF52
extern NRF_PWM_Type* pwms[PWM_COUNT];
#endif

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -86,18 +93,42 @@ void digitalWrite( uint32_t ulPin, uint32_t ulVal )

ulPin = g_ADigitalPinMap[ulPin];

for (uint8_t i = 0; i < PWM_COUNT; i++)
{
if (pwmContext[i].pin == ulPin)
{
pwmContext[i].pin = PIN_FREE;
#ifdef NRF52
// Disable the PWM
NRF_PWM_Type* pwm = pwms[i];
pwm->ENABLE = (PWM_ENABLE_ENABLE_Disabled << PWM_ENABLE_ENABLE_Pos);
#endif
pwmStatus[0].numActive--;
}
}

#ifdef NRF51
// Turn off the Timer if no pwm signals are allocated
for (uint8_t i = 0; i < PWM_TIMER_COUNT; i++)
{
if (pwmStatus[i].numActive == 0)
{
NVIC_ClearPendingIRQ(pwmStatus[i].irqNumber);
NVIC_DisableIRQ(pwmStatus[i].irqNumber);
}
}
#endif

switch ( ulVal )
{
case LOW:
NRF_GPIO->OUTCLR = (1UL << ulPin);
break ;
break;

default:
NRF_GPIO->OUTSET = (1UL << ulPin);
break ;
break;
}

return ;
}

int digitalRead( uint32_t ulPin )
Expand Down
19 changes: 18 additions & 1 deletion cores/nRF5/wiring_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,26 @@
extern "C" {
#endif


#include "wiring_constants.h"

#define PWM_COUNT 3
#define PWM_TIMER_COUNT 1 // 3 channels of TIMER1 are used. TIMER2 also could be used for PWM
#define PIN_FREE 0xffffffff

struct PWMContext {
uint32_t pin;
uint32_t value;
#ifdef NRF51
uint32_t channel;
uint32_t mask;
uint32_t event;
#endif
};

struct PWMStatus {
int8_t numActive;
int8_t irqNumber;
};

#ifdef __cplusplus
} // extern "C"
Expand Down
24 changes: 24 additions & 0 deletions platform.txt
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,27 @@ tools.openocd.erase.pattern=
tools.openocd.bootloader.params.verbose=-d2
tools.openocd.bootloader.params.quiet=-d0
tools.openocd.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -f interface/{program.protocol}.cfg -c "{program.setup_command}" -f target/{upload.target}.cfg -c "init; halt; nrf51 mass_erase; program {{{runtime.platform.path}/cores/nRF5/SDK/components/softdevice/{softdevice}/hex/{softdevice}_{upload.target}_{softdeviceversion}_softdevice.hex}} verify reset; shutdown;"

#
# blackmagic probe upload
#
tools.blackmagicprobe.path={runtime.tools.gcc-arm-none-eabi-5_2-2015q4.path}/bin/
tools.blackmagicprobe.cmd=arm-none-eabi-gdb

tools.blackmagicprobe.upload.speed=230400

tools.blackmagicprobe.erase.params.verbose=
tools.blackmagicprobe.erase.params.quiet=-q --batch-silent
tools.blackmagicprobe.erase.pattern="{path}{cmd}" -quiet -cd "{build.path}" -ex "target extended-remote \\.\{serial.port}" -ex "monitor swdp_scan" -ex "attach 1" -ex "monitor erase mass" -ex "echo \nErase finished!\n" -ex "detach" -ex "quit"

tools.blackmagicprobe.upload.params.verbose=
tools.blackmagicprobe.upload.params.quiet=-q --batch-silent
tools.blackmagicprobe.upload.pattern="{path}{cmd}" -quiet -cd "{build.path}" -b {upload.speed} -l 10 -ex "set debug remote 0" -ex "set target-async off" -ex "set remotetimeout 10" -ex "set mem inaccessible-by-default off" -ex "set confirm off" -ex "set height 0" -ex "target extended-remote \\.\{serial.port}" -ex "monitor swdp_scan" -ex "attach 1" -ex "file {build.project_name}.elf" -ex "load" -ex "tbreak main" -ex "run" -ex "echo \nUpload complete!\n" -ex "quit"

tools.blackmagicprobe.program.params.verbose=
tools.blackmagicprobe.program.params.quiet=-q --batch-silent
tools.blackmagicprobe.program.pattern="{path}{cmd}" -quiet -cd "{build.path}" -b {upload.speed} -l 10 -ex "set debug remote 0" -ex "set target-async off" -ex "set remotetimeout 10" -ex "set mem inaccessible-by-default off" -ex "set confirm off" -ex "set height 0" -ex "target extended-remote \\.\{serial.port}" -ex "monitor swdp_scan" -ex "attach 1" -ex "file {build.project_name}.elf" -ex "load" -ex "tbreak main" -ex "run" -ex "echo \nProgram complete!\n" -ex "quit"

tools.blackmagicprobe.bootloader.params.verbose=
tools.blackmagicprobe.bootloader.params.quiet=-q --batch-silent
tools.blackmagicprobe.bootloader.pattern="{path}{cmd}" -quiet -cd "{runtime.platform.path}/cores/nRF5/SDK/components/softdevice/{softdevice}/hex/" -ex "target extended-remote \\.\{serial.port}" -ex "monitor swdp_scan" -ex "attach 1" -ex "monitor erase mass" -ex "load {softdevice}_{upload.target}_{softdeviceversion}_softdevice.hex" -ex "echo \nSoftdevice upload complete!\n" -ex "detach" -ex "quit"
10 changes: 10 additions & 0 deletions programmers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,13 @@ cmsisdap.protocol=cmsis-dap
cmsisdap.program.protocol=cmsis-dap
cmsisdap.program.tool=openocd
cmsisdap.program.setup_command=;

bmp.name=Black Magic Probe (GDB)
bmp.communication=USB
bmp.protocol=
bmp.program.protocol=
bmp.erase.tool=blackmagicprobe
bmp.upload.tool=blackmagicprobe
bmp.program.tool=blackmagicprobe
bmp.bootloader.tool=blackmagicprobe
bmp.program.extra_params=;