• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Microcontrollers » MSP430™ Microcontrollers » MSP430 Ultra-Low Power 16-bit Microcontroller Forum » SPI problem with TI Launchpad + MCP2515 Can Controller
Share
MSP430™ Microcontrollers
  • Forum
  • Announcements
  • E2E Wiki
Options
  • Subscribe via RSS
MSP430 Resources
  • MSP430 Product Folder
  • MSP-EXP430G2 - MSP430 LaunchPad Value Line Development kit
  • MSP430 Getting Started Guide
  • MSP430 Microcontroller Projects
  • More Resources >
  • Forums

    SPI problem with TI Launchpad + MCP2515 Can Controller

    This question is not answered
    Seth Berggren
    Posted by Seth Berggren
    on Aug 10 2012 15:09 PM
    Intellectual410 points

    Hi, so I designed a simple circuit board that fits on top of the Launchpad. This circuit board has the MCP2515 Can Controller, SN65HVD TI Can Transceiver, and some other basic circuit components.

    All I am focusing on right now is the SPI. The issue that I am having is that the MISO (master in slave out) line is always logic high. The other lines, SCK, MOSI, STE, all work fine.

    I wrote a simple program for the Launchpad that, upon pushing the P1.3 button, sends a "Read Register" instruction to the MCP2515. This instruction is then sent a second time, and that is the end of the program.

    All communication lines are fine, except for MISO, which is stuck at logic high. After lots of playing around, I ran into a situation where the MISO line went low for a very short instant (~40 ns), and then back to high.

    Attached to this post are a picture of the schematic of my circuit board (R4 not connected), two pictures showing the waveform that I got from the Logic Analyzer, and printed below is the code that I used.

    I appreciate any help that I can get and I am happy to provide any additional information or clarifications that may be needed.

    Thank You.

    #include "msp430g2553.h"
    unsigned char step;
    void main(void){
    WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer
    P1DIR = BIT0 + BIT5 + BIT6; // LEDs and STE output
    P1SEL = BIT1 + BIT2 + BIT4;
    P1SEL2 = BIT1 + BIT2 + BIT4;
    UCA0CTL0 = UCMSB + UCMST + UCSYNC + UCCKPH + UCMODE_0;
    UCA0CTL1 |= UCSSEL_2;                   // SMCLK
    UCA0BR0 = BIT1 + BIT0;                  // /3
    UCA0BR1 = 0;                            //
    UCA0MCTL = 0;                           // No modulation
    UCA0CTL1 &= ~UCSWRST;                   // **Initialize USCI state machine**
    IE2 |= UCA0RXIE;             // Enable USCI0 RX interrupt
    DCOCTL = BIT7 + BIT6 + BIT5; //clock is ~6-8MHz
    BCSCTL1 = BIT3 + BIT2 + BIT1 + BIT0;
    //push button settings (P1.3)
    P1REN = BIT3;                       // P1.3 pullup
    P1IE |= BIT3;                       // P1.3 interrupt enabled
    P1IFG &= ~BIT3;                     // P1.3 IFG cleared
    P1IES |= BIT3;                     // P1.3 Hi/lo edge
    P1OUT |=  BIT3;                       // P1.3 set, else reset
    P1OUT &= ~BIT0; //red LED off
    P1OUT &= ~BIT6; //green LED off
    P1OUT |= BIT5; //STE high
    step = 0; //variable for testing SPI
    __bis_SR_register(LPM0_bits + GIE);     // CPU off, enable interrupts
    }
    //Push Button ISR
    #pragma vector=PORT1_VECTOR
    __interrupt void Port_1(void)
    {
    P1IFG &= ~BIT3;                 // P1.3 IFG cleared
    IFG2 |= BIT0; // cause RX interrupt
    }
    //RX ISR
    #pragma vector=USCIAB0RX_VECTOR
    __interrupt void USCIA0RX_ISR(void)
    {
    switch(step){
    case 0x0:
    P1OUT &= ~BIT5; // lower STE
    UCA0TXBUF = 0x3; // "Read" Instruction
    step++;
    case 0x1:
    UCA0TXBUF = 0xF; // "Read" address, CANCTRL reg.
    __delay_cycles(50);
    P1OUT |= BIT5; // raise STE
    step++;
    case 0x2:
    __delay_cycles(50);
    P1OUT &= ~BIT5; // lower STE
    UCA0TXBUF = 0x3; // "Read" Instruction
    step++;
    case 0x3:
    UCA0TXBUF = 0xF; // "Read" address, CANCTRL reg.
    __delay_cycles(50);
    P1OUT |= BIT5; // raise STE
    step++;
    default:
    IFG2 &= ~BIT0; // clear interrupt
    } // THE END
    }
    5852.CellAssist MSP shield schematic pic.pdf
    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    All Replies
    • Mark Green
      Posted by Mark Green
      on Aug 10 2012 17:10 PM
      Intellectual640 points

      p450 of the user guide states that you should set the UCSWRST bit before fiddling with the UCS registers. But it is set on power up so you can be let off on this one.  ;)

      Disconnect your circuit from launch pad and connect MISO to MOSI. Then re run the test with the logic analyzer connected.   

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Aug 13 2012 11:36 AM
      Guru140085 points

      Seth Berggren
      The issue that I am having is that the MISO (master in slave out) line is always logic high. The other lines, SCK, MOSI, STE, all work fine.

      So the slave doesn't send anything. Nothing that is controlled by MSP code.

      Seth Berggren
      P1OUT |= BIT5; //STE high

      Well, P1.5 isn't STE. This name is only used for USCI slave/multi master operation adn input only.
      You use this pin as normal GPIO for providing teh chip select signal for the slave, so "CS" would be more appropriate and less confusing. Note that there can be as many different CS signals as there are different slaves on the SPI bus.

      But I wonder how your code shall work.

      SPI is give-and-take. After releasing SWRST, UCA0TXIFG is set and UCA0RXIFG is clear. So your RX ISR won't be called unleyy sou actually write something into TXBUF, which in turn creates a transfer. Well, your manual setting of RXIFG in the port ISR is - surprising. But it does the job.
      However, then things get strange.
      Your RX ISR goes into case 1, where you lower teh slave chip select. Some slaves require a minimum delay after that. Then you write to TXBUF which sends the first byte. But  at this point, you should break out of the case, clear the RXIFG bit and exit the ISR. Instead you proceed right to the next case (while the SPI hasn't sent a bit yet), stuff another byte into TXBUF, do some busy-waiting cycles (a no-go inside an ISR) and never read RXBUF at all.
      This code doesn't need a switch/case structure and doesn't belong into an ISR at all.

      However, a close look on the screenshots shows that the occasional low pulse of your slave comes at the last falling edge of teh clock signal. Which isn't a valid position at all.

      So besides the coding oddity I'd say you picked the wrong polarity/phase for the clock. Usually, the clock is low-active (idle-high), which requires the CKPL bit set. And in most cases, CKPH doesn't need to be set or the slave will listen to and push data out on the wrong clock edge.

      p.s.: the Saleae analyzer is a very good device. Especially the software is excellent.

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Seth Berggren
      Posted by Seth Berggren
      on Aug 13 2012 14:48 PM
      Intellectual410 points

      Thanks for the reply Jens,

      I took most of your advice. I got rid of the delay cycles in the ISR and set the SPI mode of the MSP430 to 1,1 (the MCP2515 accepts 0,0 or 1,1 mode SPI). The only issue I ran into with changing the SPI was that, when I loaded the bytes 0x03 and 0x0F into the TX buffers, the analyzer kept reading them as 0x07 and 0x1F. I figured it is just a timing thing with the bits, so instead I sent the bytes 0x01 and 0x07, and the analyzer reads the correct bytes now.

      Still, after making those changes, the MISO line is unresponsive.

      I think my next step is to switch the MISO and MOSI lines, as suggested earlier, although I doubt that is the problem... Do you have any other suggestions that might help me out here?

      Thank You.

      Here is my new code, and below that is the new waveforms that I produced:

      #include "msp430g2553.h"
      unsigned char step;
      void main(void){
      WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer
      P1DIR = BIT0 + BIT5 + BIT6; // LEDs and CS output
      P1SEL = BIT1 + BIT2 + BIT4;
      P1SEL2 = BIT1 + BIT2 + BIT4;
      UCA0CTL0 = UCMSB + UCMST + UCSYNC + UCCKPL + UCCKPH + UCMODE_0;
      UCA0CTL1 |= UCSSEL_2;                   // SMCLK
      UCA0BR0 = BIT1 + BIT0;                  // /3
      UCA0BR1 = 0;                            //
      UCA0MCTL = 0;                           // No modulation
      UCA0CTL1 &= ~UCSWRST;                   // **Initialize USCI state machine**
      IE2 |= UCA0RXIE;             // Enable USCI0 RX interrupt
      DCOCTL = BIT7 + BIT6 + BIT5; //clock is ~6-8MHz
      BCSCTL1 = BIT3 + BIT2 + BIT1 + BIT0;
      //push button settings (P1.3)
      P1REN = BIT3;                       // P1.3 pullup
      P1IE |= BIT3;                       // P1.3 interrupt enabled
      P1IFG &= ~BIT3;                     // P1.3 IFG cleared
      P1IES |= BIT3;                     // P1.3 Hi/lo edge
      P1OUT |=  BIT3;                       // P1.3 set, else reset
      P1OUT |= BIT5; //CS high
      step = 0; //variable for switch case
      __bis_SR_register(LPM0_bits + GIE);     // CPU off, enable interrupts
      }
      //Push Button ISR
      #pragma vector=PORT1_VECTOR
      __interrupt void Port_1(void)
      {
      P1IFG &= ~BIT3;                 // P1.3 IFG cleared
      IFG2 |= BIT0; // cause RX interrupt
      }
      //RX ISR
      #pragma vector=USCIAB0RX_VECTOR
      __interrupt void USCIA0RX_ISR(void)
      {
      IFG2 &= ~BIT0; // clear RX IFG
      P1OUT &= ~BIT5; // lower CS
      switch(step){
      case 0x0:
      UCA0TXBUF = 0x1; // "Read" Instruction
      step++;
      break;
      case 0x1:
      UCA0TXBUF = 0x7; // "Read" address, CANCTRL reg.
      step++;
      break;
      case 0x2:
      P1OUT |= BIT5; // raise CS
      step = 0x0; // restart sequence by pushing button
      break;
      }
      }



      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Aug 17 2012 09:31 AM
      Guru140085 points

      Seth Berggren
      (the MCP2515 accepts 0,0 or 1,1 mode SPI)

      Well, Motorola mode 0,0 isn't TI mode 0,0. The clock polarity is reversed between the two. So I think on the MSP you'll need mode 1,0 to serve Motorola mode 0.0

      About your signals: well, I don't know the high-level protocol of your slave.

      It's possible that while you send the first byte, teh slave simply han't anythign to say (remember, it hasn't received your first byte yet adn therefore cannto send any answer, so it probably just sends an 0xff dummy).

      If the two bytes you send form a command, you'll be required to send a third dummy byte (probably 0xff) to allow the slave sending an answer. When CS goes high, this cancels the high-level protocol and the slave won't send an answer to the previous request on your next attempt.

      This would also explain the sputious blip you encountered on MISO: the slave took the last clock edge (due to wrong polarity(phase) as the beginning of a third byte and started to send its answer - which then was canceled because no more clock cycles were coming and then CS was going high again.

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    TI E2E™ Community
    • Support Forums
    • Blogs
    • Videos
    • Groups
    • Site Support & Feedback
    • Settings
    TI E2E™ Community Groups
    • TI University Program
    • Make the Switch
    • Microcontroller Projects
    • Motor Drive & Control
    Other Communities
    • Deyisupport
    • Designsomething.org
    • beagleboard.org
    • TI on Element 14
    • TI on TechXchangeSM
    Other Technical & Support Resources
    • WEBENCH® Design Center
    • Product Information Centers
    • Technical Documents
    • TI Design Network
    • TI Technical Articles
    • TI Training

    All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

    Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

    Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
    TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

    TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
    embedded processors, along with software, tools and the industry’s largest sales/support staff.

    © Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
    Trademarks | Privacy Policy | Terms of Use