/*
* main.c
*
* MSP-EXP430G2-LaunchPad (v1.5+) User Experience Application for
* Communication to ADS1118
*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/******************************************************************************
* MSP-EXP430G2-LaunchPad User Experience Application for Communication to ADS1118
*
* 1. Program uses GRACE configuration for Device Configuration;
* - SMCLK, ACLK, DCO at 1MHz
* - USCIA0 as UART, 9600, 8 bits Data, No parity, 1 Stop (Hardware Mode)
* - USCIB0 as 3 line SPI, Master Mode, 50kHz SCLK
* - P2.0 used as CS for ADS1118 ADC device
*
* 2. Application Mode
* - Initial start configures device on power up
* - Configures connected ADS1118 device for differential measurement
* pairs of AIN0-AIN1 and AIN2-AIN3
* - Data is transmitted in continuous loop
* - Runs ADS1118 in single shot mode reading first pair, changing mux and then
* second pair storing data in a data array
* - After data is read, data is sent out UART for display as ASCII hex representation
*
* Changes:
* 1.0 Initial Release Version
*
* Texas Instruments, Inc.
******************************************************************************/
/*
* ======== Standard MSP430 includes ========
*/
#include <msp430g2553.h>
/*
* ======== Grace related includes ========
*/
#include <ti/mcu/msp430/csl/CSL.h>
/*
* ======== Function Calls ========
*/
void uart_txc(char c);
void uart_txstr(char *c);
/* "hex2asc" Converts a 32-bit integer n into an ASCII string.
digs is the maximum number of digits to display. Conversion is controlled
by mode, as follows:
- mode = 0: Leading zeroes are not printed. The string may be
less than digs digits long.
- mode = 1: Spaces are printed in place of leading zeroes. The
string will be digs digits long.
- mode = 2: Leading zeroes are printed. The string will be digs
digits long.
If the number is zero, at least one zero is printed in all modes.
This routine works by converting n to an 8-byte BCD number and calling
hex2asc. No division by 10 is performed.
*/
int hex2asc(void *n, int digs, int mode, char *s);
void ADS_Config(void);
void ADS_Read(int data[]);
void Send_Result(int *data);
void Port_Config(void);
signed int WriteSPI(unsigned int config, int mode);
void delay(void);
#define h2a(d) ((d>9)?(d+'A'-10):(d+'0'))
#define LITTLEENDIAN 1
/*
* ======== main ========
*/
int main(int argc, char *argv[])
{
CSL_init(); // Activate Grace-generated configuration
// >>>>> Fill-in user code here <<<<<
// Initialize TC data array
signed int data[6];
// Port configuration
Port_Config();
// Set ADS1118 configuration
ADS_Config();
while (1)
{
// Read the data from both input pairs
ADS_Read(data);
// Transmit the data out the UART
Send_Result(data);
}
return (0);
}
void Port_Config(void)
{
// Set P1.0, P1.3, P1.4, P2.1, P2.2, P2.4, P2.5, P2.6 and P2.7 low
P1OUT = 0x00;
P2OUT = 0x01 ;
}
/*
* Initial configuration routine. A header file could be created, but the configuration is really rather simple.
* In this case a 16-bit value representing the register contents is set to variable temp
*/
void ADS_Config(void)
{
int i;
unsigned int temp;
// Set the configuration to AIN0/AIN1, FS=+/-1.024, SS, DR=128sps, PULLUP on DOUT
temp = 0x78A;
// Set CS low and write configuration
P2OUT &= ~BIT0;
// Write the configuration
WriteSPI(temp,0);
// Set CS high to end transaction
P2OUT |= BIT0;
}
void ADS_Read(int data[])
{
unsigned int j, temp;
// Set the configuration to AIN0/AIN1, FS=+/-1.024, SS, DR=128sps, PULLUP on DOUT
temp = 0x78A;
// Set CS low and write configuration
P2OUT &= ~BIT0;
// First the data is captured by writing to each device to take start a conversion for A0-A1
WriteSPI(temp,1);
// Set CS high to end transaction
P2OUT |= BIT0;
/*
* Now we pause slightly before reading the data, or it is possible to either poll the DOUT/DRDY or enable an interrupt
* where the DOUT/DRDY transition from high to low triggers a read. In this case it is kept quite simple with a delay
*/
delay(); // May be needed depending on method
// When we read the data we restart the conversion with new mux channel A2-A3
temp = 0x378A;
// Set CS low and write configuration
P2OUT &= ~BIT0;
// Read the earlier conversion result and set to the new configuration
data[0] = WriteSPI(temp,1);
delay(); // May be needed depending on method
// Read second channel data
data[1]=WriteSPI(temp,0);
// Set CS high to end transaction
P2OUT |= BIT0;
}
signed int WriteSPI(unsigned int config, int mode)
{
signed int msb;
unsigned int temp;
char dummy;
temp = config;
if (mode==1) temp = config | 0x8000; // if mode is set to 1, this command should initiate a conversion
/*
* The process of communication chosen is to always send the configuration and read it back
* this results in a four byte transaction. The configuration is 16-bit (or 2 bytes) and is transmitted twice.
*
*/
while(!(UC0IFG&UCB0TXIFG)); // Make sure buffer is clear
/*
* First time configuration is written
*/
UCB0TXBUF = (temp >> 8 ); // Write MSB of Config
while(!(UC0IFG&UCB0RXIFG));
msb=UCB0RXBUF; // Read MSB of Result
while(!(UC0IFG&UCB0TXIFG));
UCB0TXBUF= (temp & 0xff); // Write LSB of Config
while(!(UC0IFG&UCB0RXIFG));
msb = (msb << 8) | UCB0RXBUF ; //Read LSB of Result
/*
* Second time configuration is written, although data could be sent as NOP in either transmission, just simplified in this case
*/
while(!(UC0IFG&UCB0TXIFG));
UCB0TXBUF = (temp >> 8 ); // Write MSB of Config
while(!(UC0IFG&UCB0RXIFG));
dummy=UCB0RXBUF; // Read MSB of Config
/*
* One advantage of reading the config data is that DOUT/DRDY is forced high which makes it possible to either poll the state or set an interrupt
*/
while(!(UC0IFG&UCB0TXIFG));
UCB0TXBUF= (temp & 0xff); // Write LSB of Config
while(!(UC0IFG&UCB0RXIFG));
dummy=UCB0RXBUF; //Read LSB of Config
return msb;
}
/*
* Following code relates to formatting the data for transmission on UART
*/
void Send_Result(int *data)
{
unsigned int i;
int intval = 0;
char char_array[5];
// Poke out data
uart_txstr("TEMPS:");
uart_txc('\r');
uart_txc('\n');
for (i=0; i<2; i++)
{
intval = data[i];
hex2asc(&intval, 4, 2, char_array);
uart_txstr(char_array);
uart_txc('\r');
uart_txc('\n');
}
}
int hex2asc(void *npos, int digs, int mode, char *s)
{
int i,zero;
char dig;
char *spos=s;
char *n=(char *)npos;
zero=1;
#if LITTLEENDIAN
n+=(digs-1)>>1;
#else
n+=(16-digs)>>1;
#endif
for (i=digs-1;i>=0;--i) {
if (i&1) {
dig=(*(char *)n>>4)&15;
} else {
dig=*(char *)n&15;
#if LITTLEENDIAN
--n;
#else
++n;
#endif
}
if (zero&&dig)
zero=0;
if (zero) {
switch(mode) {
case 1:
*spos++=' ';
break;
case 2:
*spos++='0';
break;
default:
break;
}
} else
*spos++=h2a(dig);
}
if (zero&&mode==1)
*(spos-1)='0';
else if (zero&&mode==0)
*spos++='0';
*spos=0;
return spos-s;
}
void uart_txc(char c)
{
while (!((UC0IFG&UCA0TXIFG)));
UCA0TXBUF=c;
}
void uart_txstr(char *c)
{
while (*c) uart_txc(*(c++));
}
void delay(void)
{
unsigned int k;
for (k = 8000; k = 0; k--) __no_operation();
}