Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
Arduino Core for SAMD21 CPU
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
josc941e
Arduino Core for SAMD21 CPU
Commits
5ff8ca9f
Commit
5ff8ca9f
authored
10 years ago
by
Jérôme SEMETTE
Browse files
Options
Downloads
Patches
Plain Diff
Add PWM TCC/TC support in wiring_analog.c . DAC not supported for
the moment
parent
3e2f4e77
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
cores/arduino/wiring_analog.c
+418
-0
418 additions, 0 deletions
cores/arduino/wiring_analog.c
cores/arduino/wiring_analog.c.disabled
+0
-286
0 additions, 286 deletions
cores/arduino/wiring_analog.c.disabled
with
418 additions
and
286 deletions
cores/arduino/wiring_analog.c
0 → 100644
+
418
−
0
View file @
5ff8ca9f
/*
Copyright (c) 2011 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include
"Arduino.h"
#ifdef __cplusplus
extern
"C"
{
#endif
// static int _readResolution = 10;
// static int _writeResolution = 8;
// void analogReadResolution(int res) {
// _readResolution = res;
// }
// void analogWriteResolution(int res) {
// _writeResolution = res;
// }
// static inline uint32_t mapResolution(uint32_t value, uint32_t from, uint32_t to) {
// if (from == to)
// return value;
// if (from > to)
// return value >> (from-to);
// else
// return value << (to-from);
// }
// eAnalogReference analog_reference = AR_DEFAULT;
// void analogReference(eAnalogReference ulMode)
// {
// analog_reference = ulMode;
// }
// uint32_t analogRead(uint32_t ulPin)
// {
// uint32_t ulValue = 0;
// uint32_t ulChannel;
// if (ulPin < A0)
// ulPin += A0;
// ulChannel = g_APinDescription[ulPin].ulADCChannelNumber ;
// #if defined __SAM3U4E__
// switch ( g_APinDescription[ulPin].ulAnalogChannel )
// {
// // Handling ADC 10 bits channels
// case ADC0 :
// case ADC1 :
// case ADC2 :
// case ADC3 :
// case ADC4 :
// case ADC5 :
// case ADC6 :
// case ADC7 :
// // Enable the corresponding channel
// adc_enable_channel( ADC, ulChannel );
// // Start the ADC
// adc_start( ADC );
// // Wait for end of conversion
// while ((adc_get_status(ADC) & ADC_SR_DRDY) != ADC_SR_DRDY)
// ;
// // Read the value
// ulValue = adc_get_latest_value(ADC);
// ulValue = mapResolution(ulValue, 10, _readResolution);
// // Disable the corresponding channel
// adc_disable_channel( ADC, ulChannel );
// // Stop the ADC
// // adc_stop( ADC ) ; // never do adc_stop() else we have to reconfigure the ADC each time
// break;
// // Handling ADC 12 bits channels
// case ADC8 :
// case ADC9 :
// case ADC10 :
// case ADC11 :
// case ADC12 :
// case ADC13 :
// case ADC14 :
// case ADC15 :
// // Enable the corresponding channel
// adc12b_enable_channel( ADC12B, ulChannel );
// // Start the ADC12B
// adc12b_start( ADC12B );
// // Wait for end of conversion
// while ((adc12b_get_status(ADC12B) & ADC12B_SR_DRDY) != ADC12B_SR_DRDY)
// ;
// // Read the value
// ulValue = adc12b_get_latest_value(ADC12B) >> 2;
// ulValue = mapResolution(ulValue, 12, _readResolution);
// // Stop the ADC12B
// // adc12_stop( ADC12B ) ; // never do adc12_stop() else we have to reconfigure the ADC12B each time
// // Disable the corresponding channel
// adc12b_disable_channel( ADC12B, ulChannel );
// break;
// // Compiler could yell because we don't handle DAC pins
// default :
// ulValue=0;
// break;
// }
// #endif
// #if defined __SAM3X8E__ || defined __SAM3X8H__
// static uint32_t latestSelectedChannel = -1;
// switch ( g_APinDescription[ulPin].ulAnalogChannel )
// {
// // Handling ADC 12 bits channels
// case ADC0 :
// case ADC1 :
// case ADC2 :
// case ADC3 :
// case ADC4 :
// case ADC5 :
// case ADC6 :
// case ADC7 :
// case ADC8 :
// case ADC9 :
// case ADC10 :
// case ADC11 :
// // Enable the corresponding channel
// if (ulChannel != latestSelectedChannel) {
// adc_enable_channel( ADC, ulChannel );
// if ( latestSelectedChannel != -1 )
// adc_disable_channel( ADC, latestSelectedChannel );
// latestSelectedChannel = ulChannel;
// }
// // Start the ADC
// adc_start( ADC );
// // Wait for end of conversion
// while ((adc_get_status(ADC) & ADC_ISR_DRDY) != ADC_ISR_DRDY)
// ;
// // Read the value
// ulValue = adc_get_latest_value(ADC);
// ulValue = mapResolution(ulValue, ADC_RESOLUTION, _readResolution);
// break;
// // Compiler could yell because we don't handle DAC pins
// default :
// ulValue=0;
// break;
// }
// #endif
// return ulValue;
// }
// Right now, PWM output only works on the pins with
// hardware support. These are defined in the appropriate
// pins_*.c file. For the rest of the pins, we default
// to digital output.
void
analogWrite
(
uint32_t
ulPin
,
uint32_t
ulValue
)
{
uint32_t
attr
=
g_APinDescription
[
ulPin
].
ulPinAttribute
;
uint32_t
pwm_name
=
g_APinDescription
[
ulPin
].
ulTCChannel
;
uint8_t
isTC
=
0
;
uint8_t
Channelx
;
Tc
*
TCx
;
Tcc
*
TCCx
;
// if ((attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG) {
// EAnalogChannel channel = g_APinDescription[ulPin].ulADCChannelNumber;
// if (channel == DA0 || channel == DA1) {
// uint32_t chDACC = ((channel == DA0) ? 0 : 1);
// if (dacc_get_channel_status(DACC_INTERFACE) == 0) {
// /* Enable clock for DACC_INTERFACE */
// pmc_enable_periph_clk(DACC_INTERFACE_ID);
// /* Reset DACC registers */
// dacc_reset(DACC_INTERFACE);
// /* Half word transfer mode */
// dacc_set_transfer_mode(DACC_INTERFACE, 0);
// /* Power save:
// * sleep mode - 0 (disabled)
// * fast wakeup - 0 (disabled)
// */
// dacc_set_power_save(DACC_INTERFACE, 0, 0);
// /* Timing:
// * refresh - 0x08 (1024*8 dacc clocks)
// * max speed mode - 0 (disabled)
// * startup time - 0x10 (1024 dacc clocks)
// */
// dacc_set_timing(DACC_INTERFACE, 0x08, 0, 0x10);
// /* Set up analog current */
// dacc_set_analog_control(DACC_INTERFACE, DACC_ACR_IBCTLCH0(0x02) |
// DACC_ACR_IBCTLCH1(0x02) |
// DACC_ACR_IBCTLDACCORE(0x01));
// }
// /* Disable TAG and select output channel chDACC */
// dacc_set_channel_selection(DACC_INTERFACE, chDACC);
// if ((dacc_get_channel_status(DACC_INTERFACE) & (1 << chDACC)) == 0) {
// dacc_enable_channel(DACC_INTERFACE, chDACC);
// }
// // Write user value
// ulValue = mapResolution(ulValue, _writeResolution, DACC_RESOLUTION);
// dacc_write_conversion_data(DACC_INTERFACE, ulValue);
// while ((dacc_get_interrupt_status(DACC_INTERFACE) & DACC_ISR_EOC) == 0);
// return;
// }
// }
if
((
attr
&
PIN_ATTR_PWM
)
==
PIN_ATTR_PWM
)
{
// Set selected Pin as TC/TCC Waveform out (PMUX : E )
if
(
g_APinDescription
[
ulPin
].
ulPin
<=
15
)
PORT
->
Group
[
g_APinDescription
[
ulPin
].
ulPort
].
WRCONFIG
.
reg
=
(
uint32_t
)(
PORT_WRCONFIG_WRPINCFG
|
PORT_WRCONFIG_WRPMUX
|
1
<<
(
g_APinDescription
[
ulPin
].
ulPin
)
|
(
PORT_WRCONFIG_PMUXEN
)
|
(
0x4
<<
PORT_WRCONFIG_PMUX_Pos
)
);
else
PORT
->
Group
[
g_APinDescription
[
ulPin
].
ulPort
].
WRCONFIG
.
reg
=
(
uint32_t
)(
PORT_WRCONFIG_WRPINCFG
|
PORT_WRCONFIG_WRPMUX
|
PORT_WRCONFIG_HWSEL
|
1
<<
(
g_APinDescription
[
ulPin
].
ulPin
-
16
)
|
(
PORT_WRCONFIG_PMUXEN
)
|
(
0x4
<<
PORT_WRCONFIG_PMUX_Pos
)
);
switch
(
g_APinDescription
[
ulPin
].
ulTCChannel
)
{
case
TC3_CH0
:
TCx
=
TC3
;
Channelx
=
0
;
isTC
=
1
;
break
;
case
TC3_CH1
:
TCx
=
TC3
;
Channelx
=
1
;
isTC
=
1
;
break
;
case
TCC0_CH0
:
TCCx
=
TCC0
;
Channelx
=
0
;
break
;
case
TCC0_CH1
:
TCCx
=
TCC0
;
Channelx
=
1
;
break
;
case
TCC0_CH4
:
TCCx
=
TCC0
;
//Channelx = 4;
Channelx
=
0
;
break
;
case
TCC0_CH5
:
TCCx
=
TCC0
;
//Channelx = 5;
Channelx
=
1
;
break
;
case
TCC0_CH6
:
TCCx
=
TCC0
;
//Channelx = 6;
Channelx
=
2
;
break
;
case
TCC0_CH7
:
TCCx
=
TCC0
;
//Channelx = 7;
Channelx
=
3
;
break
;
case
TCC1_CH0
:
TCCx
=
TCC1
;
Channelx
=
0
;
break
;
case
TCC1_CH1
:
TCCx
=
TCC1
;
Channelx
=
1
;
break
;
case
TCC2_CH0
:
TCCx
=
TCC2
;
Channelx
=
0
;
break
;
case
TCC2_CH1
:
TCCx
=
TCC2
;
Channelx
=
1
;
break
;
}
// --Set PORT
if
(
isTC
)
{
// -- Enable clocks according to TCCx instance to use
switch
((
uint32_t
)
TCx
)
{
case
(
uint32_t
)
TC3
:
//Enable TCx Bus clock (Timer counter control clock)
PM
->
APBCMASK
.
reg
|=
PM_APBCMASK_TC3
;
//Enable GCLK for TC3 (timer counter input clock)
GCLK
->
CLKCTRL
.
reg
=
(
uint16_t
)
((
GCLK_CLKCTRL_CLKEN
|
GCLK_CLKCTRL_GEN_GCLK0
|
(
0x1B
<<
GCLK_CLKCTRL_ID_Pos
)));
break
;
case
(
uint32_t
)
TC4
:
//Enable TCx Bus clock (Timer counter control clock)
PM
->
APBCMASK
.
reg
|=
PM_APBCMASK_TC4
;
//Enable GCLK for TC4 (timer counter input clock)
GCLK
->
CLKCTRL
.
reg
=
(
uint16_t
)
((
GCLK_CLKCTRL_CLKEN
|
GCLK_CLKCTRL_GEN_GCLK0
|
(
0x1C
<<
GCLK_CLKCTRL_ID_Pos
)));
break
;
case
(
uint32_t
)
TC5
:
//Enable TCx Bus clock (Timer counter control clock)
PM
->
APBCMASK
.
reg
|=
PM_APBCMASK_TC5
;
//Enable GCLK for TC5 (timer counter input clock)
GCLK
->
CLKCTRL
.
reg
=
(
uint16_t
)
((
GCLK_CLKCTRL_CLKEN
|
GCLK_CLKCTRL_GEN_GCLK0
|
(
0x1C
<<
GCLK_CLKCTRL_ID_Pos
)));
break
;
}
// -- Configure TC
//DISABLE TCx
TCx
->
COUNT8
.
CTRLA
.
reg
&=~
(
TC_CTRLA_ENABLE
);
//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
;
//Set PER to maximum counter value (resolution : 0xFF)
TCx
->
COUNT8
.
PER
.
reg
=
0xFF
;
// Enable TCx
TCx
->
COUNT8
.
CTRLA
.
reg
|=
TC_CTRLA_ENABLE
;
}
else
{
// -- Enable clocks according to TCCx instance to use
switch
((
uint32_t
)
TCCx
)
{
case
(
uint32_t
)
TCC0
:
//Enable TCC0 Bus clock (Timer counter control clock)
PM
->
APBCMASK
.
reg
|=
PM_APBCMASK_TCC0
;
//Enable GCLK for TCC0 (timer counter input clock)
GCLK
->
CLKCTRL
.
reg
=
(
uint16_t
)
((
GCLK_CLKCTRL_CLKEN
|
GCLK_CLKCTRL_GEN_GCLK0
|
(
0x1A
<<
GCLK_CLKCTRL_ID_Pos
)));
break
;
case
(
uint32_t
)
TCC1
:
//Enable TCC1 Bus clock (Timer counter control clock)
PM
->
APBCMASK
.
reg
|=
PM_APBCMASK_TCC1
;
//Enable GCLK for TCC1 (timer counter input clock)
GCLK
->
CLKCTRL
.
reg
=
(
uint16_t
)
((
GCLK_CLKCTRL_CLKEN
|
GCLK_CLKCTRL_GEN_GCLK0
|
(
0x1A
<<
GCLK_CLKCTRL_ID_Pos
)));
break
;
case
(
uint32_t
)
TCC2
:
//Enable TCC2 Bus clock (Timer counter control clock)
PM
->
APBCMASK
.
reg
|=
PM_APBCMASK_TCC2
;
//Enable GCLK for TCC2 (timer counter input clock)
GCLK
->
CLKCTRL
.
reg
=
(
uint16_t
)
((
GCLK_CLKCTRL_CLKEN
|
GCLK_CLKCTRL_GEN_GCLK0
|
(
0x1B
<<
GCLK_CLKCTRL_ID_Pos
)));
break
;
}
// -- Configure TCC
//DISABLE TCCx
TCCx
->
CTRLA
.
reg
&=~
(
TCC_CTRLA_ENABLE
);
//Set TCx as normal PWM
TCCx
->
WAVE
.
reg
|=
TCC_WAVE_WAVEGEN_NPWM
;
//Set TCx in waveform mode Normal PWM
TCCx
->
CC
[
Channelx
].
reg
=
(
uint32_t
)
ulValue
;
//Set PER to maximum counter value (resolution : 0xFF)
TCCx
->
PER
.
reg
=
0xFF
;
//ENABLE TCCx
TCCx
->
CTRLA
.
reg
|=
TCC_CTRLA_ENABLE
;
}
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
}
#endif
This diff is collapsed.
Click to expand it.
cores/arduino/wiring_analog.c.disabled
deleted
100644 → 0
+
0
−
286
View file @
3e2f4e77
/*
Copyright (c) 2011 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "Arduino.h"
#ifdef __cplusplus
extern "C" {
#endif
static int _readResolution = 10;
static int _writeResolution = 8;
void analogReadResolution(int res) {
_readResolution = res;
}
void analogWriteResolution(int res) {
_writeResolution = res;
}
static inline uint32_t mapResolution(uint32_t value, uint32_t from, uint32_t to) {
if (from == to)
return value;
if (from > to)
return value >> (from-to);
else
return value << (to-from);
}
eAnalogReference analog_reference = AR_DEFAULT;
void analogReference(eAnalogReference ulMode)
{
analog_reference = ulMode;
}
uint32_t analogRead(uint32_t ulPin)
{
uint32_t ulValue = 0;
uint32_t ulChannel;
if (ulPin < A0)
ulPin += A0;
ulChannel = g_APinDescription[ulPin].ulADCChannelNumber ;
#if defined __SAM3X8E__ || defined __SAM3X8H__
static uint32_t latestSelectedChannel = -1;
switch ( g_APinDescription[ulPin].ulAnalogChannel )
{
// Handling ADC 12 bits channels
case ADC0 :
case ADC1 :
case ADC2 :
case ADC3 :
case ADC4 :
case ADC5 :
case ADC6 :
case ADC7 :
case ADC8 :
case ADC9 :
case ADC10 :
case ADC11 :
// Enable the corresponding channel
if (ulChannel != latestSelectedChannel) {
adc_enable_channel( ADC, ulChannel );
if ( latestSelectedChannel != -1 )
adc_disable_channel( ADC, latestSelectedChannel );
latestSelectedChannel = ulChannel;
}
// Start the ADC
adc_start( ADC );
// Wait for end of conversion
while ((adc_get_status(ADC) & ADC_ISR_DRDY) != ADC_ISR_DRDY)
;
// Read the value
ulValue = adc_get_latest_value(ADC);
ulValue = mapResolution(ulValue, ADC_RESOLUTION, _readResolution);
break;
// Compiler could yell because we don't handle DAC pins
default :
ulValue=0;
break;
}
#endif
return ulValue;
}
static void TC_SetCMR_ChannelA(Tc *tc, uint32_t chan, uint32_t v)
{
tc->TC_CHANNEL[chan].TC_CMR = (tc->TC_CHANNEL[chan].TC_CMR & 0xFFF0FFFF) | v;
}
static void TC_SetCMR_ChannelB(Tc *tc, uint32_t chan, uint32_t v)
{
tc->TC_CHANNEL[chan].TC_CMR = (tc->TC_CHANNEL[chan].TC_CMR & 0xF0FFFFFF) | v;
}
static uint8_t PWMEnabled = 0;
static uint8_t pinEnabled[PINS_COUNT];
static uint8_t TCChanEnabled[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
void analogOutputInit(void) {
uint8_t i;
for (i=0; i<PINS_COUNT; i++)
pinEnabled[i] = 0;
}
// Right now, PWM output only works on the pins with
// hardware support. These are defined in the appropriate
// pins_*.c file. For the rest of the pins, we default
// to digital output.
void analogWrite(uint32_t ulPin, uint32_t ulValue) {
uint32_t attr = g_APinDescription[ulPin].ulPinAttribute;
if ((attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG) {
EAnalogChannel channel = g_APinDescription[ulPin].ulADCChannelNumber;
if (channel == DA0 || channel == DA1) {
uint32_t chDACC = ((channel == DA0) ? 0 : 1);
if (dacc_get_channel_status(DACC_INTERFACE) == 0) {
/* Enable clock for DACC_INTERFACE */
pmc_enable_periph_clk(DACC_INTERFACE_ID);
/* Reset DACC registers */
dacc_reset(DACC_INTERFACE);
/* Half word transfer mode */
dacc_set_transfer_mode(DACC_INTERFACE, 0);
/* Power save:
* sleep mode - 0 (disabled)
* fast wakeup - 0 (disabled)
*/
dacc_set_power_save(DACC_INTERFACE, 0, 0);
/* Timing:
* refresh - 0x08 (1024*8 dacc clocks)
* max speed mode - 0 (disabled)
* startup time - 0x10 (1024 dacc clocks)
*/
dacc_set_timing(DACC_INTERFACE, 0x08, 0, 0x10);
/* Set up analog current */
dacc_set_analog_control(DACC_INTERFACE, DACC_ACR_IBCTLCH0(0x02) |
DACC_ACR_IBCTLCH1(0x02) |
DACC_ACR_IBCTLDACCORE(0x01));
}
/* Disable TAG and select output channel chDACC */
dacc_set_channel_selection(DACC_INTERFACE, chDACC);
if ((dacc_get_channel_status(DACC_INTERFACE) & (1 << chDACC)) == 0) {
dacc_enable_channel(DACC_INTERFACE, chDACC);
}
// Write user value
ulValue = mapResolution(ulValue, _writeResolution, DACC_RESOLUTION);
dacc_write_conversion_data(DACC_INTERFACE, ulValue);
while ((dacc_get_interrupt_status(DACC_INTERFACE) & DACC_ISR_EOC) == 0);
return;
}
}
if ((attr & PIN_ATTR_PWM) == PIN_ATTR_PWM) {
ulValue = mapResolution(ulValue, _writeResolution, PWM_RESOLUTION);
if (!PWMEnabled) {
// PWM Startup code
pmc_enable_periph_clk(PWM_INTERFACE_ID);
PWMC_ConfigureClocks(PWM_FREQUENCY * PWM_MAX_DUTY_CYCLE, 0, VARIANT_MCK);
PWMEnabled = 1;
}
uint32_t chan = g_APinDescription[ulPin].ulPWMChannel;
if (!pinEnabled[ulPin]) {
// Setup PWM for this pin
PIO_Configure(g_APinDescription[ulPin].pPort,
g_APinDescription[ulPin].ulPinType,
g_APinDescription[ulPin].ulPin,
g_APinDescription[ulPin].ulPinConfiguration);
PWMC_ConfigureChannel(PWM_INTERFACE, chan, PWM_CMR_CPRE_CLKA, 0, 0);
PWMC_SetPeriod(PWM_INTERFACE, chan, PWM_MAX_DUTY_CYCLE);
PWMC_SetDutyCycle(PWM_INTERFACE, chan, ulValue);
PWMC_EnableChannel(PWM_INTERFACE, chan);
pinEnabled[ulPin] = 1;
}
PWMC_SetDutyCycle(PWM_INTERFACE, chan, ulValue);
return;
}
if ((attr & PIN_ATTR_TIMER) == PIN_ATTR_TIMER) {
// We use MCLK/2 as clock.
const uint32_t TC = VARIANT_MCK / 2 / TC_FREQUENCY;
// Map value to Timer ranges 0..255 => 0..TC
ulValue = mapResolution(ulValue, _writeResolution, TC_RESOLUTION);
ulValue = ulValue * TC;
ulValue = ulValue / TC_MAX_DUTY_CYCLE;
// Setup Timer for this pin
ETCChannel channel = g_APinDescription[ulPin].ulTCChannel;
static const uint32_t channelToChNo[] = { 0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2 };
static const uint32_t channelToAB[] = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 };
static const Tc *channelToTC[] = {
TC0, TC0, TC0, TC0, TC0, TC0,
TC1, TC1, TC1, TC1, TC1, TC1,
TC2, TC2, TC2, TC2, TC2, TC2 };
static const uint32_t channelToId[] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8 };
uint32_t chNo = channelToChNo[channel];
uint32_t chA = channelToAB[channel];
Tc *chTC = channelToTC[channel];
uint32_t interfaceID = channelToId[channel];
if (!TCChanEnabled[interfaceID]) {
pmc_enable_periph_clk(TC_INTERFACE_ID + interfaceID);
TC_Configure(chTC, chNo,
TC_CMR_TCCLKS_TIMER_CLOCK1 |
TC_CMR_WAVE | // Waveform mode
TC_CMR_WAVSEL_UP_RC | // Counter running up and reset when equals to RC
TC_CMR_EEVT_XC0 | // Set external events from XC0 (this setup TIOB as output)
TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR |
TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR);
TC_SetRC(chTC, chNo, TC);
}
if (ulValue == 0) {
if (chA)
TC_SetCMR_ChannelA(chTC, chNo, TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR);
else
TC_SetCMR_ChannelB(chTC, chNo, TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR);
} else {
if (chA) {
TC_SetRA(chTC, chNo, ulValue);
TC_SetCMR_ChannelA(chTC, chNo, TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET);
} else {
TC_SetRB(chTC, chNo, ulValue);
TC_SetCMR_ChannelB(chTC, chNo, TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_SET);
}
}
if (!pinEnabled[ulPin]) {
PIO_Configure(g_APinDescription[ulPin].pPort,
g_APinDescription[ulPin].ulPinType,
g_APinDescription[ulPin].ulPin,
g_APinDescription[ulPin].ulPinConfiguration);
pinEnabled[ulPin] = 1;
}
if (!TCChanEnabled[interfaceID]) {
TC_Start(chTC, chNo);
TCChanEnabled[interfaceID] = 1;
}
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
}
#endif
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment