Hello Everyone,
This is my first post here so please bear with me. Now I'm am working with
the MSP430G2553 on the Launch pad to communicate with an external 16 bit ADC
MAX1415. I need the higher resolution hence the reason I am not using the on
board ADC. Now, I am trying to use SPI communication to connect to this ADC but
I tried using the TI sample SPI code but was told it really was not a useful
example. After searching I came up with the following code but for my CheckX I
just get d255 = hFF. I think it spits this out if it doesn't find a slave.
Now I'm just not sure if for SPI I need to use interrupts or is the way I
laid out my code able to accomplish communication.
Thanks,
#include
unsigned long Check, Check1, Check2, Check3, Check4; //I put these checks to try
and see what was being received
void PinSetup(); // Not sure if I need this since with another TI Micro I used
in school I had to
void SpiSetup();
void SetMaxim();
void PinSetup()
{
P1OUT = 0x00; // P1 setup for LED & reset output
P1DIR |= BIT5 + BIT3; // P1 direction as output 1.5 = Reset
1.3=CS
P1SEL = BIT1 + BIT2 + BIT4; // [1.1 = SOMI-> PIN 13 DOUT of ADC] [1.2 =
SIMO-> PIN 14 DIN of ADC]
P1SEL2 = BIT1 + BIT2 + BIT4; // Not Sure what the difference is between Sel1
and Sel2 seems redundant
}
void SpiSetup()
{
// UCMSB = Selects Most Sig Fig 1st // UCMST = Select the SPI Module as the
Master // UCSYNC = Selecting Synchronous mode
UCA0CTL0 |= UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master Is UCCKPL
needed???
UCA0CTL1 |= UCSSEL_2; // USCI Clock source will be SMCLK
UCA0BR0 |= 0x02; // /2
UCA0BR1 = 0; //
UCA0MCTL = 0; // No modulation
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state
machine**set low
}
void SetMaxim() // Trying to set up the ADC registers for clock rate and gain
{
P1OUT &= ~BIT5; // Pin 1.5 is pulled low to reset ADC
P1OUT |= BIT5; // After ADC is reset Pin 1.5 pulled high to prevent
reset
P1OUT &= ~BIT3; // Pin 1.3 CS pulled low
UCA0TXBUF = 0x00; // Send Dummy to Start SPI
//IFG2 &= UCA0RXIFG; // Clear Flag Not sure if I need this????
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = 0x20; // h20 to to tell ADC to be prepared to write
to clock reg next
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
Check = UCA0RXBUF;
UCA0TXBUF = 0xB3; // hB3 for ADC clock run at 1Mhz
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
Check1 = UCA0RXBUF;
UCA0TXBUF = 0x10; // h10 to tell ADC to be prepared to write to
the setup reg next
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
Check2 = UCA0RXBUF;
UCA0TXBUF = 0x44; // h44 for ADC to setup
P1OUT |= BIT3; // Pull CS high
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer //NV Need
from here
PinSetup();
SpiSetup();
SetMaxim();
//IE2 |= UCA0RXIE; // Enable USCI0 RX and TX
interrupt // Do I need interrupts for this??
//__bis_SR_register(LPM0_bits + GIE); // CPU off, enable interrupts
for(;;) // Just threw in this dumy infinite loop for later use
{}
}
MSP430G2553 SPI for external ADC
Started by ●July 12, 2013
Reply by ●July 15, 20132013-07-15
Hi noefvillanueva (!?),
Often the first byte returning from a SPI slave is FF.
What do you see on the pins using a osci? Is it what you expect?
It is not easy to get SPI running with the UARTs, try bit banging (toggle
the SPI pins by software), when this is working, take a look at the spi
pins when using the uart.
Whats your name? ;-)
Matthias
"noefvillanueva" :
> Hello Everyone,
>
> This is my first post here so please bear with me. Now I'm am working
> with the MSP430G2553 on the Launch pad to communicate with an external
> 16 bit ADC MAX1415. I need the higher resolution hence the reason I am
> not using the on board ADC. Now, I am trying to use SPI communication to
> connect to this ADC but I tried using the TI sample SPI code but was
> told it really was not a useful example. After searching I came up with
> the following code but for my CheckX I just get d255 = hFF. I think it
> spits this out if it doesn't find a slave. Now I'm just not sure if for
> SPI I need to use interrupts or is the way I laid out my code able to
> accomplish communication.
>
> Thanks,
>
> #include unsigned long Check, Check1, Check2, Check3, Check4; //I put these
> checks to try and see what was being received
>
> void PinSetup(); // Not sure if I need this since with another TI Micro
> I used in school I had to void SpiSetup();
> void SetMaxim();
>
> void PinSetup()
> {
> P1OUT = 0x00; // P1 setup for LED & reset
> output P1DIR |= BIT5 + BIT3; // P1 direction
> as output 1.5 = Reset 1.3=CS P1SEL = BIT1 + BIT2 + BIT4;
> // [1.1 = SOMI-> PIN 13 DOUT of ADC] [1.2 = SIMO-> PIN
> 14 DIN of ADC] P1SEL2 = BIT1 + BIT2 + BIT4; // Not
> Sure what the difference is between Sel1 and Sel2 seems redundant
> }
>
> void SpiSetup()
> {
> // UCMSB = Selects Most Sig Fig 1st // UCMST = Select the SPI
> Module as the Master // UCSYNC = Selecting Synchronous mode
> UCA0CTL0 |= UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master Is
> UCCKPL needed??? UCA0CTL1 |= UCSSEL_2; // USCI
> Clock source will be SMCLK UCA0BR0 |= 0x02;
> // /2 UCA0BR1 = 0; //
> UCA0MCTL = 0; // No modulation
> UCA0CTL1 &= ~UCSWRST; // **Initialize USCI
> state machine**set low
> }
>
> void SetMaxim() // Trying to set up the ADC registers for clock rate and
> gain {
> P1OUT &= ~BIT5; // Pin 1.5 is pulled low to
> reset ADC P1OUT |= BIT5; // After ADC is
> reset Pin 1.5 pulled high to prevent reset
>
> P1OUT &= ~BIT3; // Pin 1.3 CS pulled low
> UCA0TXBUF = 0x00; // Send Dummy to Start SPI
>
> //IFG2 &= UCA0RXIFG; // Clear Flag Not sure if I need
> this????
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> UCA0TXBUF = 0x20; // h20 to to tell ADC to be
> prepared to write to clock reg next
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check = UCA0RXBUF;
> UCA0TXBUF = 0xB3; // hB3 for ADC clock run at 1Mhz
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check1 = UCA0RXBUF;
> UCA0TXBUF = 0x10; // h10 to tell ADC to be prepared
> to write to the setup reg next
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check2 = UCA0RXBUF;
> UCA0TXBUF = 0x44; // h44 for ADC to setup
>
> P1OUT |= BIT3; // Pull CS high
> }
>
> void main(void)
> {
> WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer //NV
> Need from here PinSetup();
> SpiSetup();
> SetMaxim();
> //IE2 |= UCA0RXIE; // Enable USCI0 RX and TX
> interrupt // Do I need interrupts for this??
> //__bis_SR_register(LPM0_bits + GIE); // CPU off, enable
> interrupts for(;;) //
> Just threw in this dumy infinite loop for later use {}
>
> }
Often the first byte returning from a SPI slave is FF.
What do you see on the pins using a osci? Is it what you expect?
It is not easy to get SPI running with the UARTs, try bit banging (toggle
the SPI pins by software), when this is working, take a look at the spi
pins when using the uart.
Whats your name? ;-)
Matthias
"noefvillanueva" :
> Hello Everyone,
>
> This is my first post here so please bear with me. Now I'm am working
> with the MSP430G2553 on the Launch pad to communicate with an external
> 16 bit ADC MAX1415. I need the higher resolution hence the reason I am
> not using the on board ADC. Now, I am trying to use SPI communication to
> connect to this ADC but I tried using the TI sample SPI code but was
> told it really was not a useful example. After searching I came up with
> the following code but for my CheckX I just get d255 = hFF. I think it
> spits this out if it doesn't find a slave. Now I'm just not sure if for
> SPI I need to use interrupts or is the way I laid out my code able to
> accomplish communication.
>
> Thanks,
>
> #include unsigned long Check, Check1, Check2, Check3, Check4; //I put these
> checks to try and see what was being received
>
> void PinSetup(); // Not sure if I need this since with another TI Micro
> I used in school I had to void SpiSetup();
> void SetMaxim();
>
> void PinSetup()
> {
> P1OUT = 0x00; // P1 setup for LED & reset
> output P1DIR |= BIT5 + BIT3; // P1 direction
> as output 1.5 = Reset 1.3=CS P1SEL = BIT1 + BIT2 + BIT4;
> // [1.1 = SOMI-> PIN 13 DOUT of ADC] [1.2 = SIMO-> PIN
> 14 DIN of ADC] P1SEL2 = BIT1 + BIT2 + BIT4; // Not
> Sure what the difference is between Sel1 and Sel2 seems redundant
> }
>
> void SpiSetup()
> {
> // UCMSB = Selects Most Sig Fig 1st // UCMST = Select the SPI
> Module as the Master // UCSYNC = Selecting Synchronous mode
> UCA0CTL0 |= UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master Is
> UCCKPL needed??? UCA0CTL1 |= UCSSEL_2; // USCI
> Clock source will be SMCLK UCA0BR0 |= 0x02;
> // /2 UCA0BR1 = 0; //
> UCA0MCTL = 0; // No modulation
> UCA0CTL1 &= ~UCSWRST; // **Initialize USCI
> state machine**set low
> }
>
> void SetMaxim() // Trying to set up the ADC registers for clock rate and
> gain {
> P1OUT &= ~BIT5; // Pin 1.5 is pulled low to
> reset ADC P1OUT |= BIT5; // After ADC is
> reset Pin 1.5 pulled high to prevent reset
>
> P1OUT &= ~BIT3; // Pin 1.3 CS pulled low
> UCA0TXBUF = 0x00; // Send Dummy to Start SPI
>
> //IFG2 &= UCA0RXIFG; // Clear Flag Not sure if I need
> this????
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> UCA0TXBUF = 0x20; // h20 to to tell ADC to be
> prepared to write to clock reg next
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check = UCA0RXBUF;
> UCA0TXBUF = 0xB3; // hB3 for ADC clock run at 1Mhz
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check1 = UCA0RXBUF;
> UCA0TXBUF = 0x10; // h10 to tell ADC to be prepared
> to write to the setup reg next
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check2 = UCA0RXBUF;
> UCA0TXBUF = 0x44; // h44 for ADC to setup
>
> P1OUT |= BIT3; // Pull CS high
> }
>
> void main(void)
> {
> WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer //NV
> Need from here PinSetup();
> SpiSetup();
> SetMaxim();
> //IE2 |= UCA0RXIE; // Enable USCI0 RX and TX
> interrupt // Do I need interrupts for this??
> //__bis_SR_register(LPM0_bits + GIE); // CPU off, enable
> interrupts for(;;) //
> Just threw in this dumy infinite loop for later use {}
>
> }
Reply by ●July 15, 20132013-07-15
PxSEL and PxSEL2 are not redundant, together they determine the function of the
port. Make sure your settings are correct to use them for SPI. Other than that,
common problems with SPI are :
- SPI clk not inside range accepted by slave
- incorrect clock phase / polarity
- for some slave you need to send a pulse (via /CS or other input) to trigger execution of the command
Also make sure the timing e.g when you reset the slave is correct.
--- In m..., "noefvillanueva" wrote:
>
> Hello Everyone,
>
> This is my first post here so please bear with me. Now I'm am working with the MSP430G2553 on the Launch pad to communicate with an external 16 bit ADC MAX1415. I need the higher resolution hence the reason I am not using the on board ADC. Now, I am trying to use SPI communication to connect to this ADC but I tried using the TI sample SPI code but was told it really was not a useful example. After searching I came up with the following code but for my CheckX I just get d255 = hFF. I think it spits this out if it doesn't find a slave. Now I'm just not sure if for SPI I need to use interrupts or is the way I laid out my code able to accomplish communication.
>
> Thanks,
>
> #include unsigned long Check, Check1, Check2, Check3, Check4; //I put these checks to try and see what was being received
>
> void PinSetup(); // Not sure if I need this since with another TI Micro I used in school I had to
> void SpiSetup();
> void SetMaxim();
>
> void PinSetup()
> {
> P1OUT = 0x00; // P1 setup for LED & reset output
> P1DIR |= BIT5 + BIT3; // P1 direction as output 1.5 = Reset 1.3=CS
> P1SEL = BIT1 + BIT2 + BIT4; // [1.1 = SOMI-> PIN 13 DOUT of ADC] [1.2 = SIMO-> PIN 14 DIN of ADC]
> P1SEL2 = BIT1 + BIT2 + BIT4; // Not Sure what the difference is between Sel1 and Sel2 seems redundant
> }
>
> void SpiSetup()
> {
> // UCMSB = Selects Most Sig Fig 1st // UCMST = Select the SPI Module as the Master // UCSYNC = Selecting Synchronous mode
> UCA0CTL0 |= UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master Is UCCKPL needed???
> UCA0CTL1 |= UCSSEL_2; // USCI Clock source will be SMCLK
> UCA0BR0 |= 0x02; // /2
> UCA0BR1 = 0; //
> UCA0MCTL = 0; // No modulation
> UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**set low
> }
>
> void SetMaxim() // Trying to set up the ADC registers for clock rate and gain
> {
> P1OUT &= ~BIT5; // Pin 1.5 is pulled low to reset ADC
> P1OUT |= BIT5; // After ADC is reset Pin 1.5 pulled high to prevent reset
>
> P1OUT &= ~BIT3; // Pin 1.3 CS pulled low
> UCA0TXBUF = 0x00; // Send Dummy to Start SPI
>
> //IFG2 &= UCA0RXIFG; // Clear Flag Not sure if I need this????
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> UCA0TXBUF = 0x20; // h20 to to tell ADC to be prepared to write to clock reg next
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check = UCA0RXBUF;
> UCA0TXBUF = 0xB3; // hB3 for ADC clock run at 1Mhz
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check1 = UCA0RXBUF;
> UCA0TXBUF = 0x10; // h10 to tell ADC to be prepared to write to the setup reg next
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check2 = UCA0RXBUF;
> UCA0TXBUF = 0x44; // h44 for ADC to setup
>
> P1OUT |= BIT3; // Pull CS high
> }
>
> void main(void)
> {
> WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer //NV Need from here
> PinSetup();
> SpiSetup();
> SetMaxim();
> //IE2 |= UCA0RXIE; // Enable USCI0 RX and TX interrupt // Do I need interrupts for this??
> //__bis_SR_register(LPM0_bits + GIE); // CPU off, enable interrupts
> for(;;) // Just threw in this dumy infinite loop for later use
> {}
>
> }
>
- SPI clk not inside range accepted by slave
- incorrect clock phase / polarity
- for some slave you need to send a pulse (via /CS or other input) to trigger execution of the command
Also make sure the timing e.g when you reset the slave is correct.
--- In m..., "noefvillanueva" wrote:
>
> Hello Everyone,
>
> This is my first post here so please bear with me. Now I'm am working with the MSP430G2553 on the Launch pad to communicate with an external 16 bit ADC MAX1415. I need the higher resolution hence the reason I am not using the on board ADC. Now, I am trying to use SPI communication to connect to this ADC but I tried using the TI sample SPI code but was told it really was not a useful example. After searching I came up with the following code but for my CheckX I just get d255 = hFF. I think it spits this out if it doesn't find a slave. Now I'm just not sure if for SPI I need to use interrupts or is the way I laid out my code able to accomplish communication.
>
> Thanks,
>
> #include unsigned long Check, Check1, Check2, Check3, Check4; //I put these checks to try and see what was being received
>
> void PinSetup(); // Not sure if I need this since with another TI Micro I used in school I had to
> void SpiSetup();
> void SetMaxim();
>
> void PinSetup()
> {
> P1OUT = 0x00; // P1 setup for LED & reset output
> P1DIR |= BIT5 + BIT3; // P1 direction as output 1.5 = Reset 1.3=CS
> P1SEL = BIT1 + BIT2 + BIT4; // [1.1 = SOMI-> PIN 13 DOUT of ADC] [1.2 = SIMO-> PIN 14 DIN of ADC]
> P1SEL2 = BIT1 + BIT2 + BIT4; // Not Sure what the difference is between Sel1 and Sel2 seems redundant
> }
>
> void SpiSetup()
> {
> // UCMSB = Selects Most Sig Fig 1st // UCMST = Select the SPI Module as the Master // UCSYNC = Selecting Synchronous mode
> UCA0CTL0 |= UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master Is UCCKPL needed???
> UCA0CTL1 |= UCSSEL_2; // USCI Clock source will be SMCLK
> UCA0BR0 |= 0x02; // /2
> UCA0BR1 = 0; //
> UCA0MCTL = 0; // No modulation
> UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**set low
> }
>
> void SetMaxim() // Trying to set up the ADC registers for clock rate and gain
> {
> P1OUT &= ~BIT5; // Pin 1.5 is pulled low to reset ADC
> P1OUT |= BIT5; // After ADC is reset Pin 1.5 pulled high to prevent reset
>
> P1OUT &= ~BIT3; // Pin 1.3 CS pulled low
> UCA0TXBUF = 0x00; // Send Dummy to Start SPI
>
> //IFG2 &= UCA0RXIFG; // Clear Flag Not sure if I need this????
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> UCA0TXBUF = 0x20; // h20 to to tell ADC to be prepared to write to clock reg next
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check = UCA0RXBUF;
> UCA0TXBUF = 0xB3; // hB3 for ADC clock run at 1Mhz
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check1 = UCA0RXBUF;
> UCA0TXBUF = 0x10; // h10 to tell ADC to be prepared to write to the setup reg next
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check2 = UCA0RXBUF;
> UCA0TXBUF = 0x44; // h44 for ADC to setup
>
> P1OUT |= BIT3; // Pull CS high
> }
>
> void main(void)
> {
> WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer //NV Need from here
> PinSetup();
> SpiSetup();
> SetMaxim();
> //IE2 |= UCA0RXIE; // Enable USCI0 RX and TX interrupt // Do I need interrupts for this??
> //__bis_SR_register(LPM0_bits + GIE); // CPU off, enable interrupts
> for(;;) // Just threw in this dumy infinite loop for later use
> {}
>
> }
>
Reply by ●July 18, 20132013-07-18
Hello Matthias,
I thought with it being Yahoo it would come up with my name Noe.
Well the first thing I fixed was P1DIR was missing BIT4 so I was never outputting a clock so I added that and in the datasheet it also says P1SEL2 should be 0 for BIT4 so I changed that.
Then I added some delays in the setup first since the ADC needs some time for the internal oscillator to start up. The delays in between the different transfers seemed to have helped but I still don't receive what I expect. In the watch window hFA instead of h20, hE9 instead of hA5, hFF instead of h10, and hFF instead of h44.
I hooked up a logic level analyzer I can see that initially both SOMI and SIMO are 255 then SIMO just goes to 192 then 0 and I don't get why.
Thanks,
Noe
#include
unsigned int Check, Check1, Check2, Check3, Check4; //I put these checks to try and see what was being received
void PinSetup()
{
P1OUT = 0x00; // P1 setup for LED & reset output
P1DIR |= BIT3 + BIT4 + BIT5 + BIT6; // P1 direction as output 1.5 = Reset 1.3=CS 1.6 = Blink LED
P1SEL |= BIT1 + BIT2 + BIT4; // [1.1 = SOMI-> PIN 13 DOUT of ADC] [1.2 = SIMO-> PIN 14 DIN of ADC]
P1SEL2 |= BIT1 + BIT2; // [1.1 = SOMI-> PIN 13 DOUT of ADC] [1.2 = SIMO-> PIN 14 DIN of ADC]
}
void SpiSetup()
{
// UCMSB = Selects Most Sig Fig 1st // UCMST = Select the SPI Module as the Master // UCSYNC = Selecting Synchronous mode
//UCA0CTL0 |= UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master
UCA0CTL1 |= UCSWRST; // **Put state machine in reset**
UCA0CTL0 |= UCCKPH + UCCKPL + UCMSB + UCMST + UCSYNC;// made ucckpl ->ucckph
UCA0CTL1 &= ~UCSSEL_2; // USCI Clock source will be SMCLK
UCA0BR0 = 0x02; // /2
UCA0BR1 = 0; // Clock divider
UCA0MCTL = 0; // No modulation
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**set low
}
void SetMaxim() // Trying to set up the ADC registers for clock rate and gain
{
//P1OUT &= ~BIT5; // Pin 1.5 is pulled low to reset ADC
//_delay_cycles(1000000);
P1OUT |= BIT5; // After ADC is reset Pin 1.5 pulled high to prevent reset
//_delay_cycles(500);
P1OUT &= ~BIT3; // Pin 1.3 CS pulled low
//_delay_cycles(500);
//IFG2 &= UCA0TXIFG; // Clear Flag Not sure if I need this????
//while ((UCA0STAT & UCBUSY)); // Transmission Done? Not sure if I need this????
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = 0x20; // send h20 to tell ADC to be ready to write to clock next
_delay_cycles(50);
Check1 = UCA0RXBUF;
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = 0xA5; // hA5 for ADC clock run at 2.5Mhz
_delay_cycles(50);
Check2 = UCA0RXBUF;
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = 0x10; // h10 to tell ADC to be ready to write to the setup reg next
_delay_cycles(50);
Check3 = UCA0RXBUF;
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = 0x44; // h44 for ADC to setup
_delay_cycles(50);
Check4 = UCA0RXBUF;
P1OUT |= BIT3; // Pull CS high
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer //NV Need from here
PinSetup();
SpiSetup();
SetMaxim();
//__bis_SR_register(LPM0_bits + GIE); // CPU off, enable interrupts
for(;;) // Just threw in this dumy infinite loop for later use
{
_delay_cycles(100000);
P1OUT ^= BIT6; // Toggle green LED (P1.6)
}
}
________________________________
From: Matthias Weingart
To: m...
Sent: Monday, July 15, 2013 1:35 AM
Subject: [msp430] Re: MSP430G2553 SPI for external ADC
Hi noefvillanueva (!?),
Often the first byte returning from a SPI slave is FF.
What do you see on the pins using a osci? Is it what you expect?
It is not easy to get SPI running with the UARTs, try bit banging (toggle
the SPI pins by software), when this is working, take a look at the spi
pins when using the uart.
Whats your name? ;-)
Matthias
"noefvillanueva" :
> Hello Everyone,
>
> This is my first post here so please bear with me. Now I'm am working
> with the MSP430G2553 on the Launch pad to communicate with an external
> 16 bit ADC MAX1415. I need the higher resolution hence the reason I am
> not using the on board ADC. Now, I am trying to use SPI communication to
> connect to this ADC but I tried using the TI sample SPI code but was
> told it really was not a useful example. After searching I came up with
> the following code but for my CheckX I just get d255 = hFF. I think it
> spits this out if it doesn't find a slave. Now I'm just not sure if for
> SPI I need to use interrupts or is the way I laid out my code able to
> accomplish communication.
>
> Thanks,
>
> #include
>
> unsigned long Check, Check1, Check2, Check3, Check4; //I put these
> checks to try and see what was being received
>
> void PinSetup(); // Not sure if I need this since with another TI Micro
> I used in school I had to void SpiSetup();
> void SetMaxim();
>
> void PinSetup()
> {
> P1OUT = 0x00; // P1 setup for LED & reset
> output P1DIR |= BIT5 + BIT3; // P1 direction
> as output 1.5 = Reset 1.3=CS P1SEL = BIT1 + BIT2 + BIT4;
> // [1.1 = SOMI-> PIN 13 DOUT of ADC] [1.2 = SIMO-> PIN
> 14 DIN of ADC] P1SEL2 = BIT1 + BIT2 + BIT4; // Not
> Sure what the difference is between Sel1 and Sel2 seems redundant
> }
>
> void SpiSetup()
> {
> // UCMSB = Selects Most Sig Fig 1st // UCMST = Select the SPI
> Module as the Master // UCSYNC = Selecting Synchronous mode
> UCA0CTL0 |= UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master Is
> UCCKPL needed??? UCA0CTL1 |= UCSSEL_2; // USCI
> Clock source will be SMCLK UCA0BR0 |= 0x02;
> // /2 UCA0BR1 = 0; //
> UCA0MCTL = 0; // No modulation
> UCA0CTL1 &= ~UCSWRST; // **Initialize USCI
> state machine**set low
> }
>
> void SetMaxim() // Trying to set up the ADC registers for clock rate and
> gain {
> P1OUT &= ~BIT5; // Pin 1.5 is pulled low to
> reset ADC P1OUT |= BIT5; // After ADC is
> reset Pin 1.5 pulled high to prevent reset
>
> P1OUT &= ~BIT3; // Pin 1.3 CS pulled low
> UCA0TXBUF = 0x00; // Send Dummy to Start SPI
>
> //IFG2 &= UCA0RXIFG; // Clear Flag Not sure if I need
> this????
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> UCA0TXBUF = 0x20; // h20 to to tell ADC to be
> prepared to write to clock reg next
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check = UCA0RXBUF;
> UCA0TXBUF = 0xB3; // hB3 for ADC clock run at 1Mhz
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check1 = UCA0RXBUF;
> UCA0TXBUF = 0x10; // h10 to tell ADC to be prepared
> to write to the setup reg next
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check2 = UCA0RXBUF;
> UCA0TXBUF = 0x44; // h44 for ADC to setup
>
> P1OUT |= BIT3; // Pull CS high
> }
>
> void main(void)
> {
> WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer //NV
> Need from here PinSetup();
> SpiSetup();
> SetMaxim();
> //IE2 |= UCA0RXIE; // Enable USCI0 RX and TX
> interrupt // Do I need interrupts for this??
> //__bis_SR_register(LPM0_bits + GIE); // CPU off, enable
> interrupts for(;;) //
> Just threw in this dumy infinite loop for later use {}
>
> }
[Non-text portions of this message have been removed]
I thought with it being Yahoo it would come up with my name Noe.
Well the first thing I fixed was P1DIR was missing BIT4 so I was never outputting a clock so I added that and in the datasheet it also says P1SEL2 should be 0 for BIT4 so I changed that.
Then I added some delays in the setup first since the ADC needs some time for the internal oscillator to start up. The delays in between the different transfers seemed to have helped but I still don't receive what I expect. In the watch window hFA instead of h20, hE9 instead of hA5, hFF instead of h10, and hFF instead of h44.
I hooked up a logic level analyzer I can see that initially both SOMI and SIMO are 255 then SIMO just goes to 192 then 0 and I don't get why.
Thanks,
Noe
#include
unsigned int Check, Check1, Check2, Check3, Check4; //I put these checks to try and see what was being received
void PinSetup()
{
P1OUT = 0x00; // P1 setup for LED & reset output
P1DIR |= BIT3 + BIT4 + BIT5 + BIT6; // P1 direction as output 1.5 = Reset 1.3=CS 1.6 = Blink LED
P1SEL |= BIT1 + BIT2 + BIT4; // [1.1 = SOMI-> PIN 13 DOUT of ADC] [1.2 = SIMO-> PIN 14 DIN of ADC]
P1SEL2 |= BIT1 + BIT2; // [1.1 = SOMI-> PIN 13 DOUT of ADC] [1.2 = SIMO-> PIN 14 DIN of ADC]
}
void SpiSetup()
{
// UCMSB = Selects Most Sig Fig 1st // UCMST = Select the SPI Module as the Master // UCSYNC = Selecting Synchronous mode
//UCA0CTL0 |= UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master
UCA0CTL1 |= UCSWRST; // **Put state machine in reset**
UCA0CTL0 |= UCCKPH + UCCKPL + UCMSB + UCMST + UCSYNC;// made ucckpl ->ucckph
UCA0CTL1 &= ~UCSSEL_2; // USCI Clock source will be SMCLK
UCA0BR0 = 0x02; // /2
UCA0BR1 = 0; // Clock divider
UCA0MCTL = 0; // No modulation
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**set low
}
void SetMaxim() // Trying to set up the ADC registers for clock rate and gain
{
//P1OUT &= ~BIT5; // Pin 1.5 is pulled low to reset ADC
//_delay_cycles(1000000);
P1OUT |= BIT5; // After ADC is reset Pin 1.5 pulled high to prevent reset
//_delay_cycles(500);
P1OUT &= ~BIT3; // Pin 1.3 CS pulled low
//_delay_cycles(500);
//IFG2 &= UCA0TXIFG; // Clear Flag Not sure if I need this????
//while ((UCA0STAT & UCBUSY)); // Transmission Done? Not sure if I need this????
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = 0x20; // send h20 to tell ADC to be ready to write to clock next
_delay_cycles(50);
Check1 = UCA0RXBUF;
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = 0xA5; // hA5 for ADC clock run at 2.5Mhz
_delay_cycles(50);
Check2 = UCA0RXBUF;
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = 0x10; // h10 to tell ADC to be ready to write to the setup reg next
_delay_cycles(50);
Check3 = UCA0RXBUF;
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = 0x44; // h44 for ADC to setup
_delay_cycles(50);
Check4 = UCA0RXBUF;
P1OUT |= BIT3; // Pull CS high
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer //NV Need from here
PinSetup();
SpiSetup();
SetMaxim();
//__bis_SR_register(LPM0_bits + GIE); // CPU off, enable interrupts
for(;;) // Just threw in this dumy infinite loop for later use
{
_delay_cycles(100000);
P1OUT ^= BIT6; // Toggle green LED (P1.6)
}
}
________________________________
From: Matthias Weingart
To: m...
Sent: Monday, July 15, 2013 1:35 AM
Subject: [msp430] Re: MSP430G2553 SPI for external ADC
Hi noefvillanueva (!?),
Often the first byte returning from a SPI slave is FF.
What do you see on the pins using a osci? Is it what you expect?
It is not easy to get SPI running with the UARTs, try bit banging (toggle
the SPI pins by software), when this is working, take a look at the spi
pins when using the uart.
Whats your name? ;-)
Matthias
"noefvillanueva" :
> Hello Everyone,
>
> This is my first post here so please bear with me. Now I'm am working
> with the MSP430G2553 on the Launch pad to communicate with an external
> 16 bit ADC MAX1415. I need the higher resolution hence the reason I am
> not using the on board ADC. Now, I am trying to use SPI communication to
> connect to this ADC but I tried using the TI sample SPI code but was
> told it really was not a useful example. After searching I came up with
> the following code but for my CheckX I just get d255 = hFF. I think it
> spits this out if it doesn't find a slave. Now I'm just not sure if for
> SPI I need to use interrupts or is the way I laid out my code able to
> accomplish communication.
>
> Thanks,
>
> #include
>
> unsigned long Check, Check1, Check2, Check3, Check4; //I put these
> checks to try and see what was being received
>
> void PinSetup(); // Not sure if I need this since with another TI Micro
> I used in school I had to void SpiSetup();
> void SetMaxim();
>
> void PinSetup()
> {
> P1OUT = 0x00; // P1 setup for LED & reset
> output P1DIR |= BIT5 + BIT3; // P1 direction
> as output 1.5 = Reset 1.3=CS P1SEL = BIT1 + BIT2 + BIT4;
> // [1.1 = SOMI-> PIN 13 DOUT of ADC] [1.2 = SIMO-> PIN
> 14 DIN of ADC] P1SEL2 = BIT1 + BIT2 + BIT4; // Not
> Sure what the difference is between Sel1 and Sel2 seems redundant
> }
>
> void SpiSetup()
> {
> // UCMSB = Selects Most Sig Fig 1st // UCMST = Select the SPI
> Module as the Master // UCSYNC = Selecting Synchronous mode
> UCA0CTL0 |= UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master Is
> UCCKPL needed??? UCA0CTL1 |= UCSSEL_2; // USCI
> Clock source will be SMCLK UCA0BR0 |= 0x02;
> // /2 UCA0BR1 = 0; //
> UCA0MCTL = 0; // No modulation
> UCA0CTL1 &= ~UCSWRST; // **Initialize USCI
> state machine**set low
> }
>
> void SetMaxim() // Trying to set up the ADC registers for clock rate and
> gain {
> P1OUT &= ~BIT5; // Pin 1.5 is pulled low to
> reset ADC P1OUT |= BIT5; // After ADC is
> reset Pin 1.5 pulled high to prevent reset
>
> P1OUT &= ~BIT3; // Pin 1.3 CS pulled low
> UCA0TXBUF = 0x00; // Send Dummy to Start SPI
>
> //IFG2 &= UCA0RXIFG; // Clear Flag Not sure if I need
> this????
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> UCA0TXBUF = 0x20; // h20 to to tell ADC to be
> prepared to write to clock reg next
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check = UCA0RXBUF;
> UCA0TXBUF = 0xB3; // hB3 for ADC clock run at 1Mhz
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check1 = UCA0RXBUF;
> UCA0TXBUF = 0x10; // h10 to tell ADC to be prepared
> to write to the setup reg next
>
> while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
> Check2 = UCA0RXBUF;
> UCA0TXBUF = 0x44; // h44 for ADC to setup
>
> P1OUT |= BIT3; // Pull CS high
> }
>
> void main(void)
> {
> WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer //NV
> Need from here PinSetup();
> SpiSetup();
> SetMaxim();
> //IE2 |= UCA0RXIE; // Enable USCI0 RX and TX
> interrupt // Do I need interrupts for this??
> //__bis_SR_register(LPM0_bits + GIE); // CPU off, enable
> interrupts for(;;) //
> Just threw in this dumy infinite loop for later use {}
>
> }
[Non-text portions of this message have been removed]
Reply by ●July 19, 20132013-07-19
Noe Villanueva :
> Then I added some delays in the setup first since the ADC needs some
> time for the internal oscillator to start up. The delays in between the
> different transfers seemed to have helped but I still don't receive what
> I expect. In the watch window hFA instead of h20, hE9 instead of hA5,
> hFF instead of h10, and hFF instead of h44.
Check the hint from distantship; i think you can do it in the UART setup...
- incorrect clock phase / polarity
M.
> Then I added some delays in the setup first since the ADC needs some
> time for the internal oscillator to start up. The delays in between the
> different transfers seemed to have helped but I still don't receive what
> I expect. In the watch window hFA instead of h20, hE9 instead of hA5,
> hFF instead of h10, and hFF instead of h44.
Check the hint from distantship; i think you can do it in the UART setup...
- incorrect clock phase / polarity
M.