Upload
trung-manh-huynh
View
11
Download
5
Embed Size (px)
Citation preview
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
/************************************************************************//* *//* analogShield.h -- Library for Analog Shield *//* *//************************************************************************//* Author: William J. Esposito *//* Copyright 2014, Digilent Inc. *//************************************************************************//* 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*//************************************************************************//* Module Description: *//* *//* This module contains the implementation of the object class that *//* forms a chipKIT/Aruino interface to the Analog Shield functions of *//* the Texas Instrument chipKit/arduino shield. *//* *//* *//************************************************************************//* Revision History: *//* *//* 04/22/2014(WilliamE): Created *//* 05/27/2014(MarshallW): Modified for readability and content *//* *//************************************************************************/
/* ------------------------------------------------------------ *//* Include File Definitions *//* ------------------------------------------------------------ */
#include "analogShield.h"analogShield analog;
/* ------------------------------------------------------------ *//* analogShield::analogShield**** Synopsis:** none** Parameters:** none** Errors:
-1-
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
** none**** Description:** Default constructor that sets the tristate buffers** for the ADC and DAC control pins *****/
analogShield::analogShield() {//initialize the ADC and DAC pins
//ADC pinspinMode(adccs, OUTPUT);digitalWrite(adccs, HIGH);pinMode(adcbusy, INPUT);
//DAC pinspinMode(syncPin, OUTPUT);pinMode(ldacPin, OUTPUT);digitalWrite(syncPin,HIGH);digitalWrite(ldacPin,LOW);
shieldMode = 0;
begin();}
/* ------------------------------------------------------------ *//* analogShield::begin**** Synopsis:** begin();** ** Parameters:** none**** Return Values:** none **** Errors:**** Description:** Initializes the SPI interface on the microcontroller *****/
void analogShield::begin(){#if defined(__PIC32MX__)
SPI.begin();#else //(__AVR__)// Set SS to high so a connected chip will be "deselected" by defaultdigitalWrite(SS, HIGH);
// When the SS pin is set as OUTPUT, it can be used as
-2-
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
// a general purpose output port (it doesn't influence// SPI operations).pinMode(SS, OUTPUT);
// Warning: if the SS pin ever becomes a LOW INPUT then SPI// automatically switches to Slave, so the data direction of// the SS pin MUST be kept as OUTPUT.SPCR |= _BV(MSTR);SPCR |= _BV(SPE);
// Set direction register for SCK and MOSI pin.// MISO pin automatically overrides to INPUT.// By doing this AFTER enabling SPI, we avoid accidentally// clocking in a single bit since the lines go directly// from "input" to SPI control. // http://code.google.com/p/arduino/issues/detail?id=888pinMode(SCK, OUTPUT);pinMode(MOSI, OUTPUT);
#endif}
/* ------------------------------------------------------------ *//* analogShield::end**** Synopsis:** end();** ** Parameters:** none**** Return Values:** none **** Errors:**** Description:** Closes the SPI communication interface *****/
void analogShield::end(){#if defined(__PIC32MX__)
SPI.end();#else //(__AVR__)
SPCR &= ~_BV(SPE);#endif
}
/* ------------------------------------------------------------ *//* Helper Functions *//* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
-3-
http://code.google.com/p/arduino/issues/detail?id=888
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
/* analogShield::setChannelAndModeByte**** Synopsis:** setChannelAndModeByte(channel, mode);** ** Parameters:** int channel - The channel being set from 0 to 3** bool mode - boolean to activate differential mode**** Return Values:** none **** Errors:** none** Description:** Helper function that sets the channel and mode ** control byte and sent it over SPI *****/
void analogShield::setChannelAndModeByte(byte channel, bool mode){//control byte//S - sentinel, always 1//A2 - channel select//A1 - channel select//A0 - channel select//- N/C//Single / Diff pair//PD1 - power down mode//PD0 - power down modebyte control = B10000010; //default to channel 1 '001'
//channel maskif(channel == 3){
control = control | B11100000;}
else if(channel == 2){control = control | B10100000;
}
else if(channel == 1){control = control | B11010000;
}
else if(channel == 0){control = control | B00010000;
}
//differential mode activeif(mode){
control = control & B11111011;}
-4-
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
else{control = control | B00000100;
}
#if defined(__PIC32MX__)
SPI.transfer(control);
#else //(__AVR__)SPDR = control; //Shift Out the Control Command.while (!(SPSR & _BV(SPIF)));
#endif
return;}
/* ------------------------------------------------------------ *//* ADC Functions *//* ------------------------------------------------------------ */
/* ------------------------------------------------------------ *//* analogShield::read**** Synopsis:** read(channel, mode);** ** Parameters:** int channel - The channel being set from 0 to 3** bool mode - boolean to activate differential mode**** Return Values:** unsigned int - Raw data from 0-65535 corresponding ** to the voltage presented to the ADC **** Errors:** none**** Description:** Reads a raw data value from the ADC using the ** SPI interface*****/
unsigned int analogShield::read(int channel, bool mode) {// initialize SPI:if(shieldMode != 2){
#if defined (__PIC32MX__)SPI.setDataMode(SPI_MODE3);
#else //(__AVR__)SPCR &= ~(_BV(DORD));SPCR = (SPCR & ~SPI_MODE_MASK) | SPI_MODE3;SPCR = (SPCR & ~SPI_CLOCK_MASK) | (SPI_CLOCK_DIV2 & SPI_CLOCK_MASK);
-5-
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((SPI_CLOCK_DIV2 >> 2) & SPI_2XCLOCK_MASK);#endifshieldMode = 2;
}
#if defined (__PIC32MX__)// take the SS pin low to select the chip, transfer the command, then bring the bit back high:digitalWrite(adccs,LOW);
setChannelAndModeByte(channel, mode);
digitalWrite(adccs,HIGH);
//wait for busy signal to fall. If it lasts a while, try resending.while(digitalRead(adcbusy) == 0); //wait for pin 3 to == 0
//Result ready. Read it indigitalWrite(adccs,LOW);
//collect databyte high = SPI.transfer(0x00);byte low = SPI.transfer(0x00);
//release chip selectdigitalWrite(adccs,HIGH);
//compile the result into a 32 bit integer.int result;
result = (int)high
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
//Result ready. Read it inPORTD &= B11111011; //digitalWriteFast(adccs,LOW);
//collect dataSPDR = 0;while (!(SPSR & _BV(SPIF)));byte high = SPDR;SPDR = 0;while (!(SPSR & _BV(SPIF)));byte low = SPDR;
//release chip selectPORTD |= B00000100; //digitalWriteFast(adccs,HIGH);
//compile the result into a 16 bit integer.int result;//result = (int)word(high, low);result = (int)high
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
** Reads a signed data value from the ADC using the ** SPI interface*****/
int analogShield::signedRead(int channel, bool mode) {// initialize SPI:if(shieldMode != 2){
#if defined (__PIC32MX__)SPI.setDataMode(SPI_MODE3);
#else //(__AVR__)SPCR &= ~(_BV(DORD));SPCR = (SPCR & ~SPI_MODE_MASK) | SPI_MODE3;SPCR = (SPCR & ~SPI_CLOCK_MASK) | (SPI_CLOCK_DIV2 & SPI_CLOCK_MASK);SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((SPI_CLOCK_DIV2 >> 2) & SPI_2XCLOCK_MASK);
#endifshieldMode = 2;
}
#if defined (__PIC32MX__)// take the SS pin low to select the chip, transfer the command, then bring the bit back high:digitalWrite(adccs,LOW);
setChannelAndModeByte(channel, mode);
digitalWrite(adccs,HIGH);
//wait for busy signal to fall. If it lasts a while, try resending.while(digitalRead(adcbusy) == 0); //wait for pin 3 to == 0
//Result ready. Read it indigitalWrite(adccs,LOW);
//collect databyte high = SPI.transfer(0x00);byte low = SPI.transfer(0x00);
//release chip selectdigitalWrite(adccs,HIGH);
#else //(__AVR__)// take the SS pin low to select the chip, transfer the command, then bring the bit back high:PORTD &= B11111011; //digitalWriteFast(adccs,LOW);
setChannelAndModeByte(channel, mode);
PORTD |= B00000100; //digitalWriteFast(adccs,HIGH);
//wait for busy signal to fall. If it lasts a while, try resending.while((PIND & B00001000) == 0); //wait for pin 3 to == 0
//Result ready. Read it in
-8-
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
PORTD &= B11111011; //digitalWriteFast(adccs,LOW);
//collect dataSPDR = 0;while (!(SPSR & _BV(SPIF)));byte high = SPDR;SPDR = 0;while (!(SPSR & _BV(SPIF)));byte low = SPDR;
//release chip selectPORTD |= B00000100; //digitalWriteFast(adccs,HIGH);#endif
//compile the result into a 16 bit integer.int result;//result = (int)word(high, low);result = (int)high 8;//highByte(value);
-9-
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
byte low = value & 0x00FF;//lowByte(value);
#if defined(__PIC32MX__)// take the SS pin low to select the chip:digitalWrite(syncPin,LOW);
#else// take the SS pin low to select the chip:PORTD &= B11011111; //digitalWriteFast(5,LOW);
#endif
// send in the address and value via SPI:byte call = 0x00;//00if(channel == 1)
call = 0x02;
else if(channel == 2)call = 0x04;
else if(channel == 3)call = 0x06;
//send command byte#if defined(__PIC32MX__)
SPI.transfer(call);
//send dataSPI.transfer(high);SPI.transfer(low);
// take the SS pin high to de-select the chip:digitalWrite(syncPin,HIGH);
#else //(__AVR__)SPDR = call;while (!(SPSR & _BV(SPIF)));
//send dataSPDR = high;while (!(SPSR & _BV(SPIF)));SPDR = low;while (!(SPSR & _BV(SPIF)));
// take the SS pin high to de-select the chip:PORTD |= B00100000; ////digitalWriteFast(5,HIGH);
#endif
}
/* ------------------------------------------------------------ *//* analogShield::writeAllUpdate**** Synopsis:** writeAllUpdate(channel, value);
-10-
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
** ** Parameters:** int channel - The channel being set from 0 to 3** unsigned int value - raw data value to write to ** the DAC**** Return Values:** none**** Errors:** none**** Description:** Writes a raw data value to the selected DAC data** buffer and updates DAC output*****/
void analogShield::writeAllUpdate(int channel, unsigned int value){//prep work, break up the into into two 8 bit bytesbyte high = value >> 8;//highByte(value);byte low = value & 0x00FF;//lowByte(value);
// take the SS pin low to select the chip:digitalWrite(5,LOW);
// send in the address and value via SPI:byte call = 0x20;//20if(channel == 1)
call = 0x22;
else if(channel == 2)call = 0x24;
else if(channel == 3)call = 0x26;
//send command byte#if defined(__PIC32MX__)
SPI.transfer(call);
//send dataSPI.transfer(high);SPI.transfer(low);
// take the SS pin high to de-select the chip:digitalWrite(syncPin,HIGH);
#else //(__AVR__)SPDR = call;while (!(SPSR & _BV(SPIF)));
//send dataSPDR = high;
-11-
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
while (!(SPSR & _BV(SPIF)));SPDR = low;while (!(SPSR & _BV(SPIF)));
// take the SS pin high to de-select the chip:PORTD |= B00100000; ////digitalWriteFast(5,HIGH);
#endif}
/* ------------------------------------------------------------ *//* analogShield::write**** Synopsis:** write(channel, value);** ** Parameters:** int channel - The channel being set from 0 to 3** unsigned int value - raw data value to write to ** the DAC**** Return Values:** none**** Errors:** none**** Description:** Writes a raw data value to the selected DAC data** buffer and updates DAC output*****/
void analogShield::write(int channel, unsigned int value) {
if(shieldMode != 1){
// initialize SPI:#if defined(__PIC32MX__)
SPI.setBitOrder(MSBFIRST);SPI.setDataMode(SPI_MODE1);SPI.setClockDivider(SPI_CLOCK_DIV2);
#else //(__AVR__)SPCR &= ~(_BV(DORD));SPCR = (SPCR & ~SPI_MODE_MASK) | SPI_MODE1;SPCR = (SPCR & ~SPI_CLOCK_MASK) | (SPI_CLOCK_DIV2 & SPI_CLOCK_MASK);SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((SPI_CLOCK_DIV2 >> 2) & SPI_2XCLOCK_MASK);
#endifshieldMode = 1;
}
//prep work, break up the into into two 8 bit bytesbyte high = value >> 8;//highByte(value);byte low = value & 0x00FF;//lowByte(value);
-12-
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
#if defined(__PIC32MX__)// take the SS pin low to select the chip:digitalWrite(syncPin,LOW);digitalWrite(ldacPin,LOW);
#else //(__AVR__)// take the SS pin low to select the chip:PORTD &= B11011111; //digitalWriteFast(5,LOW);
#endif
// send in the address and value via SPI:byte call = 0x10;if(channel == 1)
call = 0x12;
else if(channel == 2)call = 0x14;
else if(channel == 3)call = 0x16;
#if defined(__PIC32MX__)//send command byteSPI.transfer(call);
//send dataSPI.transfer(high);SPI.transfer(low);// take the SS pin high to de-select the chip:digitalWrite(syncPin,HIGH);//end();
#else //(__AVR__)//send command byteSPDR = call;while (!(SPSR & _BV(SPIF)));
//send dataSPDR = high;while (!(SPSR & _BV(SPIF)));SPDR = low;while (!(SPSR & _BV(SPIF)));// take the SS pin high to de-select the chip:PORTD |= B00100000; ////digitalWriteFast(5,HIGH); //end();
#endif}
/* ------------------------------------------------------------ *//* analogShield::write**** Synopsis:** write(value0, value1, simul);** ** Parameters:
-13-
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
** unsigned int value0 - Raw value from 0 to 65535 ** corresponding to -5V - 5V ** unsigned int value1 - Raw value from 0 to 65535 ** corresponding to -5V - 5V ** bool simul - used to synchronize the DAC to update ** both channels at once**** Return Values:** none**** Errors:** none**** Description:** Writes raw data values to the DAC. ** value0 => DAC channel 0** value1 => DAC channel 1 ***/
void analogShield::write(unsigned int value0, unsigned int value1, bool simul){if(shieldMode != 1){
// initialize SPI:#if defined (__PIC32MX__)
SPI.setDataMode(SPI_MODE1);
#else (__AVR__)SPCR &= ~(_BV(DORD));SPCR = (SPCR & ~SPI_MODE_MASK) | SPI_MODE1;SPCR = (SPCR & ~SPI_CLOCK_MASK) | (SPI_CLOCK_DIV2 & SPI_CLOCK_MASK);SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((SPI_CLOCK_DIV2 >> 2) & SPI_2XCLOCK_MASK);
#endifshieldMode = 1;
}
writeNoUpdate(0,value0);writeAllUpdate(1,value1);
}
/* ------------------------------------------------------------ *//* analogShield::write**** Synopsis:** write(value0, value1, value2, simul);** ** Parameters:** unsigned int value0 - Raw value from 0 to 65535 ** corresponding to -5V - 5V ** unsigned int value1 - Raw value from 0 to 65535 ** corresponding to -5V - 5V ** unsigned int value2 - Raw value from 0 to 65535 ** corresponding to -5V - 5V ** bool simul - used to synchronize the DAC to update
-14-
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
** both channels at once**** Return Values:** none**** Errors:** none**** Description:** Writes raw data values to the DAC. ** value0 => DAC channel 0** value1 => DAC channel 1 ** value2 => DAC channel 2 *****/
void analogShield::write(unsigned int value0, unsigned int value1, unsigned int value2, boolsimul){
if(shieldMode != 1){// initialize SPI:#if defined (__PIC32MX__)
SPI.setDataMode(SPI_MODE1);
#else //(__AVR__)SPCR &= ~(_BV(DORD));SPCR = (SPCR & ~SPI_MODE_MASK) | SPI_MODE1;SPCR = (SPCR & ~SPI_CLOCK_MASK) | (SPI_CLOCK_DIV2 & SPI_CLOCK_MASK);SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((SPI_CLOCK_DIV2 >> 2) & SPI_2XCLOCK_MASK);
#endifshieldMode = 1;
}
writeNoUpdate(0,value0);writeNoUpdate(1,value1);writeAllUpdate(2,value2);
}
/* ------------------------------------------------------------ *//* analogShield::write**** Synopsis:** write(value0, value1, value2, value3, simul);** ** Parameters:** unsigned int value0 - Raw value from 0 to 65535 ** corresponding to -5V - 5V ** unsigned int value1 - Raw value from 0 to 65535 ** corresponding to -5V - 5V ** unsigned int value2 - Raw value from 0 to 65535 ** corresponding to -5V - 5V ** unsigned int value3 - Raw value from 0 to 65535 ** corresponding to -5V - 5V ** bool simul - used to synchronize the DAC to update
-15-
C:\Users\mnslab\Downloads\analogshield_v2_1\AnalogShieldV2_1\analogShield.cpp Saturday, February 28, 2015 8:05 PM
** both channels at once**** Return Values:** none**** Errors:** none**** Description:** Writes raw data values to the DAC. ** value0 => DAC channel 0** value1 => DAC channel 1 ** value2 => DAC channel 2 ** value3 => DAC channel 3 *****/
void analogShield::write(unsigned int value0, unsigned int value1, unsigned int value2,unsigned int value3, bool simul){
if(shieldMode != 1){
// initialize SPI:#if defined (__PIC32MX__)
SPI.setDataMode(SPI_MODE1);
#else //(__AVR__)SPCR &= ~(_BV(DORD));SPCR = (SPCR & ~SPI_MODE_MASK) | SPI_MODE1;SPCR = (SPCR & ~SPI_CLOCK_MASK) | (SPI_CLOCK_DIV2 & SPI_CLOCK_MASK);SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((SPI_CLOCK_DIV2 >> 2) & SPI_2XCLOCK_MASK);
#endifshieldMode = 1;
}
writeNoUpdate(0,value0);writeNoUpdate(1,value1);writeNoUpdate(2,value2);writeAllUpdate(3,value3);
}
-16-