Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
arduino-nRF5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
arduino-nRF5
Commits
112fa786
Commit
112fa786
authored
Mar 22, 2016
by
Sandeep Mistry
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Functional analogWrite
parent
cef25b74
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
74 additions
and
289 deletions
+74
-289
cores/nRF52/nRF5_SDK_11/components/drivers_nrf/hal/nrf_pwm.h
cores/nRF52/nRF5_SDK_11/components/drivers_nrf/hal/nrf_pwm.h
+14
-1
cores/nRF52/wiring_analog.c
cores/nRF52/wiring_analog.c
+60
-288
No files found.
cores/nRF52/nRF5_SDK_11/components/drivers_nrf/hal/nrf_pwm.h
View file @
112fa786
...
@@ -27,8 +27,9 @@
...
@@ -27,8 +27,9 @@
#include <stdint.h>
#include <stdint.h>
#include "nrf.h"
#include "nrf.h"
#ifndef ARDUINO
#include "nrf_assert.h"
#include "nrf_assert.h"
#endif
/**
/**
* @brief This value can be provided as a parameter for the @ref nrf_pwm_pins_set
* @brief This value can be provided as a parameter for the @ref nrf_pwm_pins_set
...
@@ -584,7 +585,9 @@ __STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_pwm,
...
@@ -584,7 +585,9 @@ __STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_pwm,
nrf_pwm_mode_t
mode
,
nrf_pwm_mode_t
mode
,
uint16_t
top_value
)
uint16_t
top_value
)
{
{
#ifndef ARDUINO
ASSERT
(
top_value
<=
PWM_COUNTERTOP_COUNTERTOP_Msk
);
ASSERT
(
top_value
<=
PWM_COUNTERTOP_COUNTERTOP_Msk
);
#endif
p_pwm
->
PRESCALER
=
base_clock
;
p_pwm
->
PRESCALER
=
base_clock
;
p_pwm
->
MODE
=
mode
;
p_pwm
->
MODE
=
mode
;
...
@@ -595,7 +598,9 @@ __STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_pwm,
...
@@ -595,7 +598,9 @@ __STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_pwm,
uint8_t
seq_id
,
uint8_t
seq_id
,
nrf_pwm_sequence_t
const
*
p_seq
)
nrf_pwm_sequence_t
const
*
p_seq
)
{
{
#ifndef ARDUINO
ASSERT
(
p_seq
!=
NULL
);
ASSERT
(
p_seq
!=
NULL
);
#endif
nrf_pwm_seq_ptr_set
(
p_pwm
,
seq_id
,
p_seq
->
values
.
p_raw
);
nrf_pwm_seq_ptr_set
(
p_pwm
,
seq_id
,
p_seq
->
values
.
p_raw
);
nrf_pwm_seq_cnt_set
(
p_pwm
,
seq_id
,
p_seq
->
length
);
nrf_pwm_seq_cnt_set
(
p_pwm
,
seq_id
,
p_seq
->
length
);
...
@@ -607,8 +612,10 @@ __STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_pwm,
...
@@ -607,8 +612,10 @@ __STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_pwm,
uint8_t
seq_id
,
uint8_t
seq_id
,
uint16_t
const
*
p_values
)
uint16_t
const
*
p_values
)
{
{
#ifndef ARDUINO
ASSERT
(
seq_id
<=
1
);
ASSERT
(
seq_id
<=
1
);
ASSERT
(
p_values
!=
NULL
);
ASSERT
(
p_values
!=
NULL
);
#endif
p_pwm
->
SEQ
[
seq_id
].
PTR
=
(
uint32_t
)
p_values
;
p_pwm
->
SEQ
[
seq_id
].
PTR
=
(
uint32_t
)
p_values
;
}
}
...
@@ -616,9 +623,11 @@ __STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_pwm,
...
@@ -616,9 +623,11 @@ __STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_pwm,
uint8_t
seq_id
,
uint8_t
seq_id
,
uint16_t
length
)
uint16_t
length
)
{
{
#ifndef ARDUINO
ASSERT
(
seq_id
<=
1
);
ASSERT
(
seq_id
<=
1
);
ASSERT
(
length
!=
0
);
ASSERT
(
length
!=
0
);
ASSERT
(
length
<=
PWM_SEQ_CNT_CNT_Msk
);
ASSERT
(
length
<=
PWM_SEQ_CNT_CNT_Msk
);
#endif
p_pwm
->
SEQ
[
seq_id
].
CNT
=
length
;
p_pwm
->
SEQ
[
seq_id
].
CNT
=
length
;
}
}
...
@@ -626,8 +635,10 @@ __STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_pwm,
...
@@ -626,8 +635,10 @@ __STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_pwm,
uint8_t
seq_id
,
uint8_t
seq_id
,
uint32_t
refresh
)
uint32_t
refresh
)
{
{
#ifndef ARDUINO
ASSERT
(
seq_id
<=
1
);
ASSERT
(
seq_id
<=
1
);
ASSERT
(
refresh
<=
PWM_SEQ_REFRESH_CNT_Msk
);
ASSERT
(
refresh
<=
PWM_SEQ_REFRESH_CNT_Msk
);
#endif
p_pwm
->
SEQ
[
seq_id
].
REFRESH
=
refresh
;
p_pwm
->
SEQ
[
seq_id
].
REFRESH
=
refresh
;
}
}
...
@@ -635,8 +646,10 @@ __STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_pwm,
...
@@ -635,8 +646,10 @@ __STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_pwm,
uint8_t
seq_id
,
uint8_t
seq_id
,
uint32_t
end_delay
)
uint32_t
end_delay
)
{
{
#ifndef ARDUINO
ASSERT
(
seq_id
<=
1
);
ASSERT
(
seq_id
<=
1
);
ASSERT
(
end_delay
<=
PWM_SEQ_ENDDELAY_CNT_Msk
);
ASSERT
(
end_delay
<=
PWM_SEQ_ENDDELAY_CNT_Msk
);
#endif
p_pwm
->
SEQ
[
seq_id
].
ENDDELAY
=
end_delay
;
p_pwm
->
SEQ
[
seq_id
].
ENDDELAY
=
end_delay
;
}
}
...
...
cores/nRF52/wiring_analog.c
View file @
112fa786
...
@@ -16,6 +16,9 @@
...
@@ -16,6 +16,9 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
*/
#include "nrf_saadc.h"
#include "nrf_pwm.h"
#include "Arduino.h"
#include "Arduino.h"
#include "wiring_private.h"
#include "wiring_private.h"
...
@@ -23,78 +26,49 @@
...
@@ -23,78 +26,49 @@
extern
"C"
{
extern
"C"
{
#endif
#endif
// static int _readResolution = 10;
#define PWM_COUNT 3
// static int _ADCResolution = 10;
// static int _writeResolution = 8;
// // Wait for synchronization of registers between the clock domains
// static __inline__ void syncADC() __attribute__((always_inline, unused));
// static void syncADC() {
// while (ADC->STATUS.bit.SYNCBUSY == 1)
// ;
// }
// // Wait for synchronization of registers between the clock domains
static
NRF_PWM_Type
*
pwms
[
PWM_COUNT
]
=
{
// static __inline__ void syncDAC() __attribute__((always_inline, unused));
NRF_PWM0
,
// static void syncDAC() {
NRF_PWM1
,
// while (DAC->STATUS.bit.SYNCBUSY == 1)
NRF_PWM2
// ;
};
// }
// // Wait for synchronization of registers between the clock domains
static
uint32_t
pwmChannelPins
[
PWM_COUNT
]
=
{
// static __inline__ void syncTC_8(Tc* TCx) __attribute__((always_inline, unused));
NRF_PWM_PIN_NOT_CONNECTED
,
// static void syncTC_8(Tc* TCx) {
NRF_PWM_PIN_NOT_CONNECTED
,
// while (TCx->COUNT8.STATUS.bit.SYNCBUSY);
NRF_PWM_PIN_NOT_CONNECTED
// }
};
// // Wait for synchronization of registers between the clock domains
static
uint16_t
pwmChannelSequence
[
PWM_COUNT
];
// static __inline__ void syncTCC(Tcc* TCCx) __attribute__((always_inline, unused));
// static void syncTCC(Tcc* TCCx) {
// while (TCCx->SYNCBUSY.reg & TCC_SYNCBUSY_MASK);
// }
// void analogReadResolution( int res )
static
int
writeResolution
=
8
;
// {
// _readResolution = res ;
// if (res > 10)
// {
// ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_12BIT_Val;
// _ADCResolution = 12;
// }
// else if (res > 8)
// {
// ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val;
// _ADCResolution = 10;
// }
// else
// {
// ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_8BIT_Val;
// _ADCResolution = 8;
// }
// syncADC();
// }
// void analogWriteResolution( int res )
void
analogReadResolution
(
int
res
)
// {
{
// _writeResolution = res ;
}
// }
// static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to )
void
analogWriteResolution
(
int
res
)
// {
{
// if ( from == to )
writeResolution
=
res
;
// {
}
// return value ;
// }
// if ( from > to )
static
inline
uint32_t
mapResolution
(
uint32_t
value
,
uint32_t
from
,
uint32_t
to
)
// {
{
// return value >> (from-to) ;
if
(
from
==
to
)
// }
{
// else
return
value
;
// {
}
// return value << (to-from) ;
// }
if
(
from
>
to
)
// }
{
return
value
>>
(
from
-
to
)
;
}
else
{
return
value
<<
(
to
-
from
)
;
}
}
/*
/*
* Internal Reference is at 1.0v
* Internal Reference is at 1.0v
...
@@ -104,242 +78,40 @@ extern "C" {
...
@@ -104,242 +78,40 @@ extern "C" {
*/
*/
void
analogReference
(
eAnalogReference
ulMode
)
void
analogReference
(
eAnalogReference
ulMode
)
{
{
// syncADC();
// switch ( ulMode )
// {
// case AR_INTERNAL:
// case AR_INTERNAL2V23:
// ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
// ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // 1/1.48 VDDANA = 1/1.48* 3V3 = 2.2297
// break;
// case AR_EXTERNAL:
// ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
// ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val;
// break;
// case AR_INTERNAL1V0:
// ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
// ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INT1V_Val; // 1.0V voltage reference
// break;
// case AR_INTERNAL1V65:
// ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
// ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
// break;
// case AR_DEFAULT:
// default:
// ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val;
// ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
// break;
// }
}
}
uint32_t
analogRead
(
uint32_t
ulPin
)
uint32_t
analogRead
(
uint32_t
ulPin
)
{
{
// uint32_t valueRead = 0;
// if ( ulPin < A0 )
// {
// ulPin += A0 ;
// }
// pinPeripheral(ulPin, PIO_ANALOG);
// if (ulPin == A0) // Disable DAC, if analogWrite(A0,dval) used previously the DAC is enabled
// {
// syncDAC();
// DAC->CTRLA.bit.ENABLE = 0x00; // Disable DAC
// //DAC->CTRLB.bit.EOEN = 0x00; // The DAC output is turned off.
// syncDAC();
// }
// syncADC();
// ADC->INPUTCTRL.bit.MUXPOS = g_APinDescription[ulPin].ulADCChannelNumber; // Selection for the positive ADC input
// // Control A
// * Bit 1 ENABLE: Enable
// * 0: The ADC is disabled.
// * 1: The ADC is enabled.
// * Due to synchronization, there is a delay from writing CTRLA.ENABLE until the peripheral is enabled/disabled. The
// * value written to CTRL.ENABLE will read back immediately and the Synchronization Busy bit in the Status register
// * (STATUS.SYNCBUSY) will be set. STATUS.SYNCBUSY will be cleared when the operation is complete.
// *
// * Before enabling the ADC, the asynchronous clock source must be selected and enabled, and the ADC reference must be
// * configured. The first conversion after the reference is changed must not be used.
// syncADC();
// ADC->CTRLA.bit.ENABLE = 0x01; // Enable ADC
// // Start conversion
// syncADC();
// ADC->SWTRIG.bit.START = 1;
// // Clear the Data Ready flag
// ADC->INTFLAG.bit.RESRDY = 1;
// // Start conversion again, since The first conversion after the reference is changed must not be used.
// syncADC();
// ADC->SWTRIG.bit.START = 1;
// // Store the value
// while ( ADC->INTFLAG.bit.RESRDY == 0 ); // Waiting for conversion to complete
// valueRead = ADC->RESULT.reg;
// syncADC();
// ADC->CTRLA.bit.ENABLE = 0x00; // Disable ADC
// syncADC();
// return mapResolution(valueRead, _ADCResolution, _readResolution);
return
0
;
return
0
;
}
}
// Right now, PWM output only works on the pins with
// Right now, PWM output only works on the pins with
// hardware support. These are defined in the appropriate
// hardware support. These are defined in the appropriate
// pins_*.c file. For the rest of the pins, we default
// pins_*.c file. For the rest of the pins, we default
// to digital output.
// to digital output.
void
analogWrite
(
uint32_t
ulPin
,
uint32_t
ulValue
)
void
analogWrite
(
uint32_t
ulPin
,
uint32_t
ulValue
)
{
{
// uint32_t attr = g_APinDescription[ulPin].ulPinAttribute ;
for
(
int
i
=
0
;
i
<
PWM_COUNT
;
i
++
)
{
if
(
pwmChannelPins
[
i
]
==
NRF_PWM_PIN_NOT_CONNECTED
||
pwmChannelPins
[
i
]
==
ulPin
)
{
// if ( (attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG )
pwmChannelPins
[
i
]
=
ulPin
;
// {
pwmChannelSequence
[
i
]
=
ulValue
;
// if ( ulPin != PIN_A0 ) // Only 1 DAC on A0 (PA02)
// {
NRF_PWM_Type
*
pwm
=
pwms
[
i
];
// return;
// }
nrf_pwm_pins_set
(
pwm
,
pwmChannelPins
);
nrf_pwm_enable
(
pwm
);
// ulValue = mapResolution(ulValue, _writeResolution, 10);
nrf_pwm_configure
(
pwm
,
NRF_PWM_CLK_16MHz
,
NRF_PWM_MODE_UP
,
(
1
<<
writeResolution
)
-
1
);
nrf_pwm_loop_set
(
pwm
,
0
);
// syncDAC();
nrf_pwm_decoder_set
(
pwm
,
NRF_PWM_LOAD_COMMON
,
NRF_PWM_STEP_AUTO
);
// DAC->DATA.reg = ulValue & 0x3FF; // DAC on 10 bits.
nrf_pwm_seq_ptr_set
(
pwm
,
0
,
&
pwmChannelSequence
[
i
]);
// syncDAC();
nrf_pwm_seq_cnt_set
(
pwm
,
0
,
1
);
// DAC->CTRLA.bit.ENABLE = 0x01; // Enable DAC
nrf_pwm_seq_refresh_set
(
pwm
,
0
,
1
);
// syncDAC();
nrf_pwm_seq_end_delay_set
(
pwm
,
0
,
0
);
// return ;
nrf_pwm_task_trigger
(
pwm
,
NRF_PWM_TASK_SEQSTART0
);
// }
break
;
// if ( (attr & PIN_ATTR_PWM) == PIN_ATTR_PWM )
}
// {
}
// if (attr & PIN_ATTR_TIMER) {
// #if !(ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10603)
// // Compatibility for cores based on SAMD core <=1.6.2
// if (g_APinDescription[ulPin].ulPinType == PIO_TIMER_ALT) {
// pinPeripheral(ulPin, PIO_TIMER_ALT);
// } else
// #endif
// {
// pinPeripheral(ulPin, PIO_TIMER);
// }
// } else {
// // We suppose that attr has PIN_ATTR_TIMER_ALT bit set...
// pinPeripheral(ulPin, PIO_TIMER_ALT);
// }
// Tc* TCx = 0 ;
// Tcc* TCCx = 0 ;
// uint8_t Channelx = GetTCChannelNumber( g_APinDescription[ulPin].ulPWMChannel ) ;
// if ( GetTCNumber( g_APinDescription[ulPin].ulPWMChannel ) >= TCC_INST_NUM )
// {
// TCx = (Tc*) GetTC( g_APinDescription[ulPin].ulPWMChannel ) ;
// }
// else
// {
// TCCx = (Tcc*) GetTC( g_APinDescription[ulPin].ulPWMChannel ) ;
// }
// // Enable clocks according to TCCx instance to use
// switch ( GetTCNumber( g_APinDescription[ulPin].ulPWMChannel ) )
// {
// case 0: // TCC0
// case 1: // TCC1
// // Enable GCLK for TCC0 and TCC1 (timer counter input clock)
// GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ;
// break ;
// case 2: // TCC2
// case 3: // TC3
// // Enable GCLK for TCC2 and TC3 (timer counter input clock)
// GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 )) ;
// break ;
// case 4: // TC4
// case 5: // TC5
// // Enable GCLK for TC4 and TC5 (timer counter input clock)
// GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC4_TC5 ));
// break ;
// case 6: // TC6 (not available on Zero)
// case 7: // TC7 (not available on Zero)
// // Enable GCLK for TC6 and TC7 (timer counter input clock)
// GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC6_TC7 ));
// break ;
// }
// while ( GCLK->STATUS.bit.SYNCBUSY == 1 ) ;
// ulValue = mapResolution(ulValue, _writeResolution, 8);
// // Set PORT
// if ( TCx )
// {
// // -- Configure TC
// // Disable TCx
// TCx->COUNT8.CTRLA.reg &= ~TC_CTRLA_ENABLE;
// syncTC_8(TCx);
// // Set Timer counter Mode to 8 bits
// TCx->COUNT8.CTRLA.reg |= TC_CTRLA_MODE_COUNT8;
// // Set TCx as normal PWM
// TCx->COUNT8.CTRLA.reg |= TC_CTRLA_WAVEGEN_NPWM;
// // Set TCx in waveform mode Normal PWM
// TCx->COUNT8.CC[Channelx].reg = (uint8_t) ulValue;
// syncTC_8(TCx);
// // Set PER to maximum counter value (resolution : 0xFF)
// TCx->COUNT8.PER.reg = 0xFF;
// syncTC_8(TCx);
// // Enable TCx
// TCx->COUNT8.CTRLA.reg |= TC_CTRLA_ENABLE;
// syncTC_8(TCx);
// }
// else
// {
// // -- Configure TCC
// // Disable TCCx
// TCCx->CTRLA.reg &= ~TCC_CTRLA_ENABLE;
// syncTCC(TCCx);
// // Set TCx as normal PWM
// TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM;
// syncTCC(TCCx);
// // Set TCx in waveform mode Normal PWM
// TCCx->CC[Channelx].reg = (uint32_t)ulValue;
// syncTCC(TCCx);
// // Set PER to maximum counter value (resolution : 0xFF)
// TCCx->PER.reg = 0xFF;
// syncTCC(TCCx);
// // Enable TCCx
// TCCx->CTRLA.reg |= TCC_CTRLA_ENABLE ;
// syncTCC(TCCx);
// }
// return ;
// }
// // -- Defaults to digital write
// pinMode( ulPin, OUTPUT ) ;
// ulValue = mapResolution(ulValue, _writeResolution, 8);
// if ( ulValue < 128 )
// {
// digitalWrite( ulPin, LOW ) ;
// }
// else
// {
// digitalWrite( ulPin, HIGH ) ;
// }
}
}
#ifdef __cplusplus
#ifdef __cplusplus
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment