Skip to content

Move ADC channel selection out of variant files #51

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 16, 2019
Merged
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
20 changes: 12 additions & 8 deletions cores/arduino/ard_sup/Arduino_defines.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@




// Constants
#define LOW (0x0)
#define HIGH (0x1)
#define LOW (0x0)
#define HIGH (0x1)

#define CHANGE (0x02)
#define FALLING (0x03)
#define RISING (0x04)
#define CHANGE (0x02)
#define FALLING (0x03)
#define RISING (0x04)

#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
Expand All @@ -17,6 +15,12 @@
#define RAD_TO_DEG 57.295779513082320876798154814105
#define EULER 2.718281828459045235360287471352

//Special "pads" used by the ADC to select the special internal ADC channels
#define ADC_DIFF0 100
#define ADC_DIFF1 101
#define ADC_INTERNAL_TEMP 102
#define ADC_INTERNAL_VCC_DIV3 103
#define ADC_INTERNAL_VSS 104

// Functions
// undefine stdlib's abs if encountered
Expand All @@ -43,4 +47,4 @@

#define bit(b) (1UL << (b))

#define digitalPinToInterrupt(P) (P) // all apollo3 pads are interrupt capable
#define digitalPinToInterrupt(P) (P) // all apollo3 pads are interrupt capable
86 changes: 55 additions & 31 deletions cores/arduino/ard_sup/analog/ap3_analog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,17 @@ uint16_t analogRead(uint8_t pinNumber)
am_hal_adc_sample_t Sample;
uint32_t ui32NumSamples = 1;

uint8_t padNumber = ap3_gpio_pin2pad(pinNumber);
uint8_t padNumber;

if (pinNumber >= ADC_DIFF0 && pinNumber <= ADC_INTERNAL_VSS)
{
//Special handling of internal ADC channels
padNumber = pinNumber;
}
else
{
padNumber = ap3_gpio_pin2pad(pinNumber);
}

//Look up configuration status based on pad number
uint8_t indi;
Expand Down Expand Up @@ -292,8 +302,8 @@ ap3_err_t ap3_set_pin_to_analog(uint8_t pinNumber)

uint8_t funcsel = 0;
am_hal_gpio_pincfg_t pincfg = INPUT;

retval = ap3_analog_pad_funcsel(ap3_gpio_pin2pad(pinNumber), &funcsel);

if (retval != AP3_OK)
{
return retval;
Expand Down Expand Up @@ -355,15 +365,15 @@ ap3_err_t ap3_change_channel(uint8_t padNumber)
return AP3_OK;
}


bool ap3_pwm_is_running(uint32_t ui32TimerNumber, uint32_t ui32TimerSegment){
bool ap3_pwm_is_running(uint32_t ui32TimerNumber, uint32_t ui32TimerSegment)
{
volatile uint32_t *pui32ConfigReg;
bool is_enabled = false;

//
// Find the correct control register.
//
pui32ConfigReg = (uint32_t*)CTIMERADDRn(CTIMER, ui32TimerNumber, CTRL0);
pui32ConfigReg = (uint32_t *)CTIMERADDRn(CTIMER, ui32TimerNumber, CTRL0);

//
// Begin critical section while config registers are read and modified.
Expand All @@ -378,7 +388,8 @@ bool ap3_pwm_is_running(uint32_t ui32TimerNumber, uint32_t ui32TimerSegment){
//
// Check the "enable bit"
//
if( ui32ConfigVal & (CTIMER_CTRL0_TMRA0EN_Msk | CTIMER_CTRL0_TMRB0EN_Msk) ){
if (ui32ConfigVal & (CTIMER_CTRL0_TMRA0EN_Msk | CTIMER_CTRL0_TMRB0EN_Msk))
{
is_enabled = true;
}

Expand All @@ -390,39 +401,51 @@ bool ap3_pwm_is_running(uint32_t ui32TimerNumber, uint32_t ui32TimerSegment){
return is_enabled;
}


void ap3_pwm_wait_for_pulse(uint32_t timer, uint32_t segment, uint32_t output, uint32_t margin){
void ap3_pwm_wait_for_pulse(uint32_t timer, uint32_t segment, uint32_t output, uint32_t margin)
{

volatile uint32_t *pui32CompareReg;
volatile uint32_t ctimer_val;
uint32_t cmpr0;

// Only wait if the ctimer is running to avoid a deadlock
if( ap3_pwm_is_running( timer, segment) ){
if (ap3_pwm_is_running(timer, segment))
{

// Get the comapre register address
if( segment == AM_HAL_CTIMER_TIMERA ){
if( output == AM_HAL_CTIMER_OUTPUT_NORMAL ){
pui32CompareReg = (uint32_t*)CTIMERADDRn(CTIMER, timer, CMPRA0);
}else{
pui32CompareReg = (uint32_t*)CTIMERADDRn(CTIMER, timer, CMPRAUXA0);
if (segment == AM_HAL_CTIMER_TIMERA)
{
if (output == AM_HAL_CTIMER_OUTPUT_NORMAL)
{
pui32CompareReg = (uint32_t *)CTIMERADDRn(CTIMER, timer, CMPRA0);
}
}else{
if( output == AM_HAL_CTIMER_OUTPUT_NORMAL ){
pui32CompareReg = (uint32_t*)CTIMERADDRn(CTIMER, timer, CMPRB0);
}else{
pui32CompareReg = (uint32_t*)CTIMERADDRn(CTIMER, timer, CMPRAUXB0);
else
{
pui32CompareReg = (uint32_t *)CTIMERADDRn(CTIMER, timer, CMPRAUXA0);
}
}
else
{
if (output == AM_HAL_CTIMER_OUTPUT_NORMAL)
{
pui32CompareReg = (uint32_t *)CTIMERADDRn(CTIMER, timer, CMPRB0);
}
else
{
pui32CompareReg = (uint32_t *)CTIMERADDRn(CTIMER, timer, CMPRAUXB0);
}
}

// Get the compare value
cmpr0 = ((uint32_t)(*(pui32CompareReg)) & 0x0000FFFF);

if( cmpr0 ){ // Only wait when cmpr0 is greater than 0 to avoid an infinite while loop
if (cmpr0)
{ // Only wait when cmpr0 is greater than 0 to avoid an infinite while loop
// Wait for the timer value to be less than the compare value so that it is safe to change
ctimer_val = am_hal_ctimer_read( timer, segment);
while( (ctimer_val + 0) >= cmpr0 ){
ctimer_val = am_hal_ctimer_read( timer, segment);
ctimer_val = am_hal_ctimer_read(timer, segment);
while ((ctimer_val + 0) >= cmpr0)
{
ctimer_val = am_hal_ctimer_read(timer, segment);
}
}
}
Expand Down Expand Up @@ -534,16 +557,16 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk)
if ((th == 0) || (fw == 0))
{
output = AM_HAL_CTIMER_OUTPUT_FORCE0;
set_periods = false; // disable setting periods when going into a forced mode
set_periods = false; // disable setting periods when going into a forced mode
}
else if (th == fw)
{
output = AM_HAL_CTIMER_OUTPUT_FORCE1;
set_periods = false; // disable setting periods when going into a forced mode
set_periods = false; // disable setting periods when going into a forced mode
}

// Wait until after high pulse to change the state (avoids inversion)
ap3_pwm_wait_for_pulse( timer, segment, output, 10);
ap3_pwm_wait_for_pulse(timer, segment, output, 10);

// Configure the pin
am_hal_ctimer_output_config(timer,
Expand All @@ -558,7 +581,8 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk)
// (AM_HAL_CTIMER_FN_PWM_REPEAT | AP3_ANALOG_CLK | AM_HAL_CTIMER_INT_ENABLE) );
(AM_HAL_CTIMER_FN_PWM_REPEAT | clk));

if(set_periods){
if (set_periods)
{
// If this pad uses secondary output:
if (output == AM_HAL_CTIMER_OUTPUT_SECONDARY)
{
Expand Down Expand Up @@ -603,17 +627,17 @@ ap3_err_t analogWriteResolution(uint8_t res)
ap3_err_t analogWrite(uint8_t pin, uint32_t val)
{
// Determine the high time based on input value and the current resolution setting
uint32_t clk = AM_HAL_CTIMER_HFRC_12MHZ; // Use an Ambiq HAL provided value to select which clock
uint32_t fw = 0xFFFF; // Choose the frame width in clock periods (32767 -> ~ 180 Hz)
uint32_t clk = AM_HAL_CTIMER_HFRC_12MHZ; // Use an Ambiq HAL provided value to select which clock
uint32_t fw = 0xFFFF; // Choose the frame width in clock periods (32767 -> ~ 180 Hz)
if (val >= ((0x01 << _analogWriteBits) - 1))
{
val = fw; // Enable FORCE1
}
else
{
val <<= (16 - _analogWriteBits); // Shift over the value to fill available resolution
val <<= (16 - _analogWriteBits); // Shift over the value to fill available resolution
}

return ap3_pwm_output(pin, val, fw, clk);
}

Expand Down
2 changes: 1 addition & 1 deletion cores/arduino/ard_sup/ap3_analog_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ SOFTWARE.

enum EXTRA_ADC_PADS
{
AP3_ADC_DIFF0_PAD = 51, //More than physical pads on Apollo3
AP3_ADC_DIFF0_PAD = 100, //More than physical pads on Apollo3
AP3_ADC_DIFF1_PAD,
AP3_ADC_TEMP_PAD,
AP3_ADC_DIV3_PAD,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

Feel like supporting open source hardware?
Buy a board from SparkFun!
SparkFun Edge: https://www.sparkfun.com/products/15170
SparkFun Edge: https://www.sparkfun.com/artemis

Hardware Connections:
Upload code
Expand All @@ -30,37 +30,37 @@ void setup()

pinMode(LED, OUTPUT);

//analogReadResolution(14); //Set resolution to 14 bit
analogReadResolution(14); //Set resolution to 14 bit
//analogReadResolution(16); //Set resolution to 16 bit - will pad ADC output with two zeros
}

void loop()
{
digitalWrite(LED, LOW);

int myValue1 = analogRead(A1); //Automatically sets pin to analog input
Serial.print("A1: ");
int myValue1 = analogRead(A3); //Automatically sets pin to analog input
Serial.print("A3: ");
Serial.print(myValue1);

int internalTemp = analogRead(ADC_TEMP); //Read internal temp sensor. 3.8mV/C, +/-3C
Serial.print("\tinternalTemp: ");
Serial.print(internalTemp);

int vss = analogRead(ADC_VSS); //Read internal VSS
Serial.print("\tvss: ");
Serial.print(vss);

//TODO enable battload
int div3 = analogRead(ADC_DIV3); //Read VCC across a 1/3 resistor divider
int div3 = analogRead(ADC_INTERNAL_VCC_DIV3); //Read VCC across a 1/3 resistor divider
Serial.print("\tVCC/3: ");
Serial.print(div3);

float vcc = (float)div3 * 6 / 1024.0; //Convert 1/3 VCC to VCC
float vcc = (float)div3 * 6 / 16384.0; //Convert 1/3 VCC to VCC
Serial.print(" VCC: ");
Serial.print(vcc, 2);
Serial.print("V");

//pinMode(A4, OUTPUT); //Reset analog function to false.
int internalTempVoltage = analogRead(ADC_INTERNAL_TEMP); //Read internal temp sensor. 3.8mV/C, +/-3C
double internalTemp = internalTempVoltage * vcc / 16384.0; //Convert internal temp reading to voltage
internalTemp /= 0.0038; //Convert voltage to degrees C
Serial.print("\tinternalTemp: ");
Serial.print(internalTemp, 2);

int vss = analogRead(ADC_INTERNAL_VSS); //Read internal VSS (should be 0)
Serial.print("\tvss: ");
Serial.print(vss);

Serial.println();

Expand Down
69 changes: 32 additions & 37 deletions variants/SparkFun_BlackBoard_Artemis/config/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,43 +25,38 @@ SOFTWARE.
const ap3_gpio_pad_t ap3_variant_pinmap[AP3_VARIANT_NUM_PINS] = {
//~ = PWM, A = ADC
//Apollo Pad, //Silkscreen indicator - Pin functions
25, //0 - ~RX1/SDA2/MISO2
24, //1 - ~TX1/32kHz/SWO
35, //2/A6 - ~A/TX1/I2SDAT/PDMCLK
4, //3 - ~RX1/SLINT
22, //4 - ~PDMCLK/SWO
23, //5 - ~I2SWCLK/CMPOUT
27, //6 - ~SCL2/SCK2
28, //7 - ~MOSI2/I2SWCLK
32, //8/A8 - ~A/SCCIO
12, //9/A9 - ~A/PDMCLK/TX1
13, //10/A10 - ~A/I2SBCLK/RX1
7, //11 - ~MOSI0/CLKOUT
6, //12 - ~MISO0/SDA0/I2SDAT
5, //13 - ~LED/SCK0/SCL0
40, //14 - SDA4/MISO4/RX1
39, //15 - ~SCL4/SCK4/TX1
29, //16/A0 - ~A/PDMDATA
11, //17/A1 - ~A/PDMDATA
34, //18/A2 - A/CMPRF2/PDMDATA
33, //19/A3 - ~A/SWO/32kHz
16, //20/A4 - A/TRIG0/SCCRST
31, //21/A5 - ~A/SCCCLK
48, //22 - ~TX0/SCL5/SCK5
49, //23 - ~RX0/SDA5/MISO5
8, //24 - Solder pad, SCL1/SCK1/TX1/SCCLK
9, //25 - Solder pad, SDA1/MISO1/RX1/SCCIO
10, //26 - Solder pad, MOSI1/TX1/PDMCLK
38, //27 - Solder pad, MOSI3/TX1
42, //28 - Solder pad, ~SCL3/SCK3/TX1
43, //29 - Solder pad, ~SDA3/MISO3/RX1
36, //30 - Not exposed, PDMDATA of Mic
37, //31 - Not exposed, PDMCLK of Mic
AP3_ADC_DIFF0_PAD, //32 - Not a real pad, ADC_DIFF0
AP3_ADC_DIFF1_PAD, //33 - Not a real pad, ADC_DIFF1
AP3_ADC_TEMP_PAD, //34 - Not a real pad, ADC_TEMP
AP3_ADC_DIV3_PAD, //35 - Not a real pad, ADC_DIV3
AP3_ADC_VSS_PAD, //36 - Not a real pad, ADC_VSS
25, //0 - ~RX1/SDA2/MISO2
24, //1 - ~TX1/32kHz/SWO
35, //2/A6 - ~A/TX1/I2SDAT/PDMCLK
4, //3 - ~RX1/SLINT
22, //4 - ~PDMCLK/SWO
23, //5 - ~I2SWCLK/CMPOUT
27, //6 - ~SCL2/SCK2
28, //7 - ~MOSI2/I2SWCLK
32, //8/A8 - ~A/SCCIO
12, //9/A9 - ~A/PDMCLK/TX1
13, //10/A10 - ~A/I2SBCLK/RX1
7, //11 - ~MOSI0/CLKOUT
6, //12 - ~MISO0/SDA0/I2SDAT
5, //13 - ~LED/SCK0/SCL0
40, //14 - SDA4/MISO4/RX1
39, //15 - ~SCL4/SCK4/TX1
29, //16/A0 - ~A/PDMDATA
11, //17/A1 - ~A/PDMDATA
34, //18/A2 - A/CMPRF2/PDMDATA
33, //19/A3 - ~A/SWO/32kHz
16, //20/A4 - A/TRIG0/SCCRST
31, //21/A5 - ~A/SCCCLK
48, //22 - ~TX0/SCL5/SCK5
49, //23 - ~RX0/SDA5/MISO5
8, //24 - Solder pad, SCL1/SCK1/TX1/SCCLK
9, //25 - Solder pad, SDA1/MISO1/RX1/SCCIO
10, //26 - Solder pad, MOSI1/TX1/PDMCLK
38, //27 - Solder pad, MOSI3/TX1
42, //28 - Solder pad, ~SCL3/SCK3/TX1
43, //29 - Solder pad, ~SDA3/MISO3/RX1
36, //30 - Not exposed, PDMDATA of Mic
37, //31 - Not exposed, PDMCLK of Mic
};

// Uart Definitions
Expand Down
7 changes: 1 addition & 6 deletions variants/SparkFun_BlackBoard_Artemis/config/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ SOFTWARE.

#include "Arduino.h"

#define AP3_VARIANT_NUM_PINS (37)
#define AP3_VARIANT_NUM_PINS (32)

// Pin map declaration
extern const ap3_gpio_pad_t ap3_variant_pinmap[AP3_VARIANT_NUM_PINS];
Expand Down Expand Up @@ -58,11 +58,6 @@ extern Uart Serial1;
#define A8 8
#define A9 9
#define A10 10
#define ADC_DIFF0 32 //Not legal pins. Used for pad lookup
#define ADC_DIFF1 33
#define ADC_TEMP 34
#define ADC_DIV3 35
#define ADC_VSS 36

#define LED_BUILTIN 13

Expand Down
Loading