This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SPI and UART of MSP430F5438

Other Parts Discussed in Thread: MSP430F5438

Hi,

I would like to verify few details in my design which includes MSP430F5438:

1. I'm going to connect SPI pins (e.g. 76,77,78,79) directly to 32 chips  with the following parameters:

LOGIC INPUTS (SDI, SCLK, , SDA, GPIO) CS

 

V

IH Input High Voltage

0.7 × V

DRIVE

V

 

V

IL Input Low Voltage

0.4

 

V

 

I

IH Input High Current

−1

 

μA

 

V

IN = VDRIVE

I

IL Input Low Current

1

 

μA

 

V

IN = GND

Hysteresis

 

150

 

mV

 

Table 4. SPI Timing Specifications

Parameter

Parameter

Limit

 

 

Unit

 

 

Description

 

 

f

 

SCLK

5

 

 

MHz max

 

 

SCLK frequency

 

 

t

 

1

5

 

 

ns min

 

 

falling edge to first SCLK falling edge CS

 

 

t

 

2

20

 

 

ns min

 

 

SCLK high pulse width

 

 

t

 

3

20

 

 

ns min

 

 

SCLK low pulse width

 

 

t

 

4

15

 

 

ns min

 

 

SDI setup time

 

 

t

 

5

15

 

 

ns min

 

 

SDI hold time

 

 

t

 

6

20

 

 

ns max

 

 

SDO access time after SCLK falling edge

 

 

t

 

7

16

 

 

ns max

 

 

rising edge to SDO high impedance CS

 

 

t

 

8

15

 

 

ns min

 

 

SCLK rising edge to high CS

 

 

Is this OK in terms of load and timing?

2. What is the maximum UART rate in transmission?

Thanks,

Rafi

  • rafi zachut said:
    In the schematics of the board I saw that the  USB to UART chip (TUSB3410VF) has the DTR and RTS pins available.

    It may be possible to use them for the toggling. In fact, the default serial port connection does it this way.

    The only question is the timing. Having an USB protocol between the PC and the serial port is by magnitudes slower and has way more jitter than a direct manipulation of a COM port chip. IIRC, there are some timing restrictions for the BSL entry. In case of the 54xxA devices, they are so tight that it is almost impossible to meet them with a real serial port (at least under Windows with all the driver overhead, if not coded directly into the driver). For the other devices, it might work.

    I'd say it's worth a try. But I don't know the RIUSB well enough to say anything final.

    rafi zachut said:
    Can we modify the BSL-scripter to send some dummy characters at the beginning just to trigger the BSL using the HW I described?

    Modifying it is surely not the problem :) Whether it's worth all the effort is another thing.

    Basically it's what I implemented for the 5438: application will get new firmware through its normal communicaiton channel (which is a packet-based RF connection) adn stores it, part by part, in excess flash (above 64k).
    One all is sent, the fiirmware enters update mode, which copies the complete, CRC-checked new fiormware from above 64k to below 64k (not overwriting the 1k updater code, whcih will never be erased and ensures that the device will retry if it is interrupted during the update). After done, it will start the new firmware as if the device was just reset.

    it doe snot need BSL-scripter or the BSL, as the old firmware will do the transfer. Using the TUSB, this could be a standard serial connection without any tricks.

  • thanks for the reply.

    I run the BSL-scripter and saw the pins RTS and DTR of the USB to UART (on the experiment board) supply the desired sequence at some point only the pulse are ~50ms width. Is it OK if I use the 5438?

    Where can I find the timing of the sequence for the msp430f5438?

    Does this sequence must be on start-up or it can be any time? 

    thanks,

    Rafi

  • rafi zachut said:
    only the pulse are ~50ms width. Is it OK if I use the 5438?

    AFAIK there is not timing restriction on the 5438. Only teh 54xxA has a (very tight) timing listed in teh errata sheet. Too tight for many systems.

    rafi zachut said:
    Where can I find the timing of the sequence for the msp430f5438

    IIRC, it is in the appnote about the BSL (slau265). Also, there is a brief description in the device datasheet (mainly the listing of the used pins and a reference to slau265)

    rafi zachut said:
    Does this sequence must be on start-up or it can be any time? 

    I can be any time, but since it includes pulling RST low, it will turn any time into startup time :)
    (except if RST has been assigned to NMI, but then it is no more RST and therefore the sequence cannot be completed at all - but I'm not 100$ sure of this, I never tested)

  • Thanks for the reply.

    My next question is regarding writing to the flash of the msp430f5438 from the running code.

    for example: writing a function that when called -  a vector will be saved in the flash, and the vector values will ba available after the next power-up.

    Do you have a code example for that?

    Thanks,

    Rafi

  • rafi zachut said:
    My next question is regarding writing to the flash of the msp430f5438 from the running code.

    Can you start a new thread for this? It really has nothing to do with SPI and UART anymore :)

    BTW, there are several threads abotu runtime programming the flash in the forum. With code examples and all necessary explanations and considerations.

  • Hello,

    I am using the MSP430F5438 microcontroller and i want to develop a SPI communication between the microcontroller and a L9942 device (driver for stepper motor that  should receive a 16 bits data to command the motor and send a 16 bits diagnostic response ). I have two questions:

     

    1) I am using  _EINT() (which enable all interrpts)  to enable the hardware interrupt  to receive data from the L9942 . It is possible to use an other instruction to active only the SPI interrupt.

     

    2)  I tried the 3 wire SPI communication and it works. The problem is when I send a 16 bits data to the device, the L9942 send continuously his response (16bits)  but I need only  one response for each SPI command sent (only SPI hardware interrupt occurs).

    i tried to use the 4 wire SPI communication and i put the chip select a 0 to start transmission and after loading the second byte to send on the TXBUFF i put chip select to 1 to stop communication. But, i have no result with this method.


       DATA=SPI_TXdata_uint16;
       DATA>>=8;                                  
       poids_fort=(u8)DATA;                         

      DATA=SPI_TXdata_uint16;
       poids_faible=(u8)DATA; 
      
       SPI_TX_uint16 = false;
      
       P4OUT &=~SM_CSN_PIN;                     // CSN =0 to start transmission
       
       while (!(UCB3IFG& UCTXIFG));                  // USCI_B3 TX buffer ready?
       UCB3TXBUF = poids_faible;                    //first byte transmission
       
       while (!(UCB3IFG& UCTXIFG));
       UCB3TXBUF = poids_fort;                     //second byte transmission
       if(UCB3TXBUF==poids_fort)
        {
         SPI_VISUALISATION_SEL&=~LED1;
         SPI_VISUALISATION_DIR |= LED1;
         SPI_VISUALISATION_OUT|= LED1;         // P1.0 = 1 ==> Led D1 ON ==>end of transmission
        }
      
       P4OUT |= SM_CSN_PIN;                     // CSN =1 to stop transmission

     

     

     

  • son am said:
    I am using  _EINT() (which enable all interrpts)  to enable the hardware interrupt  to receive data from the L9942 . It is possible to use an other instruction to active only the SPI interrupt.

    Well, this is a two-step process.

    _EINT() and its counterpart _DINT() (there are alternatives __enable_interrupts() and others, but all set/clear the same GIE bit in the status register) are for a global control of all interrupts. This is to just say 'do not disturb me now' for any interrupt source that might be active.

    Yet all possible interrupt sources are inactive as default. To activate an interupt source, you need to set the associated IE bit (e.g. UCTXIE). Only those events with the associated IE bit set will trigger an interrupt. And only if GIE (global interrupt enable) is set.

    There is no shortcut to say 'disable all interrupts except of this one'. If you only want the SPI RX or TX interrupt, you have to manually disable all other interrupt sources by clearing their IE bit. But you only have to do so for those you manually activated before, else their IE bit is already clear.

    However, if you jsut want to see whther an interrupt would occur if it were enable, you can just check the IFG (= Interrupt FlaG) bit, as you do it in the posted code. No need for enabling interrupts at all.

    son am said:
    The problem is when I send a 16 bits data to the device, the L9942 send continuously his response (16bits)  but I need only  one response for each SPI command sent (only SPI hardware interrupt occurs).

    Ye, that' sSPI. You give and you take. One byte for each byte. That's how SPi works. You cannot send without receiving, and you cannot receive without sending. If you don't need the answer, ignore it. If you don't need to send anything, send a dummy byte (usually 0xff) and wait for the answer.
    Remember, that when you receive the first answer, the client has just received your (first) command byte. So the answer you just got cannot be the answer to your command.
    Once you're finished sending all data, you will need to send additional dummy bytes to get the response to your data.

    son am said:
    i tried to use the 4 wire SPI communication and i put the chip select a 0 to start transmission and after loading the second byte to send on the TXBUFF i put chip select to 1 to stop communication. But, i have no result with this method.

    Once you loaded the second byte to TXBUF, it just sits there. At this moment probably not even the first byte has been sent. The previous content of TXBUF has been moved to the output shift register, but may or may not have been shifted out yet (depending on the clocks). That TXIFG is set only means that TXBUF is ready to receive the next byte, not that the previous byte has been sent.
    You need to check the BUSY bit to see wehther the transfer has ended. If you remove the chip select before the complete transfer has ended, you'll interrupt the transmission at its current point.

    son am said:
    UCB3TXBUF = poids_fort;                     //second byte transmission
       if(UCB3TXBUF==poids_fort)
        {

    This condition is always true. TXBUF will not change its content even if TXIFG has been set or the transfer has finished. It only changes its content if you write something new there.

    son am said:
    DATA=SPI_TXdata_uint16;
       DATA>>=8;                                  
       poids_fort=(u8)DATA;                         

      DATA=SPI_TXdata_uint16;
       poids_faible=(u8)DATA; 
     

    Maybe I'm missing something here, but why not just doing
    poids_fort=SPI_TXdata_uint16 >>8;
    poids_faible=SPI_TXdata_uint16;

    Or simply do a

    UCB3TXBUF = SPI_TXdata_uint16;
    [...]
    UCB3TXBUF = SPI_TXdata_uint16>>8;

     

  • thanks for your responses.

    I tried to use the BUSY bit to check if the first byte was be sent successfully to be able to transmit the second byte but my code still blocked in the instruction

    (while (!(UCB3STAT&UCBUSY));  so I can't send any other byte.

    Could you please help me.

  • This loop loops as long as UCBUSY is clear (whcih is a permanent state then, since you're not doing anything to make it busy again). You want to loop as long as UCBUSY is set. So remove the '!'.

    note that UCBUSY is set as long as a transfer is underways and clears when complete. Opposite to the IFG flags which go high to indicate that the job is done (actually, they too are high during an unhandled condition like send buffer empty or receive buffer full, but normally that's what you are waiting for, not for 'receive buffer no longer full', so the logic seems reversed)
    In other words: UCBUSY marks when the device is busy, not when it is idle

  • thanks for your help.

    I have a question about generating a PWM signal which specified frequency. I used the MSP430F5438 microcontroller and the timer B  to generate a 32 KHz PWM signal so I used the ACLK = 32KHz as clock source and I configured the different registers of the timer. I found a sample code that shows that the TB0CCR0 fixed the period of the PWM signal ( PWM frequency = clock source frequency devided by the CCR0 value). So to generate the 32KHz PWM signal,

       TB0CCR0 =1;                                                // PWM signal frequency= 32KHz /1=32KHz 
      
      TB0CCR1= (unsigned short)(32767);        // PWM duty cycle =50%
      TB0CCTL1= OUTMOD_7;                    //  TA1CCR1 reset/set
      TB0CTL=TBSSEL_1|MC_2;                 // ACLK, continuous mode

    But when I visualise the PWM pin I found a PWM signal which a very low frequency ( 6 or 7 Hz).

    Could you please help me.

  • son am said:
    I have a question about generating a PWM signal which specified frequency.

    And this is a thread with the title "SPI and UART of MSP430F5438".

    However, I'll answer you.

    Clocking the tiemr with 32kHz doe snot mean 32kHz PWM frequency. It means 32kHz timer tick frequency. With the CCR0 you can limit the timer cycle time to n ticks when the timer runs in up mode. Else the timer cycle time is 65536 ticks (continuous mode).

    To set a duty cycle, youo have to configure the other CCR registers to the desired fraction of the tiem rcycle time. So if the timer is in continuous mode,  CCRx (including CCR0) set to 32768 results in 50% duty cycle. if th etiemr is in up mode, a duty cycle of 50% is achieved by setting CCRx to 50% of CCR0.

    Actually, you write 1 less to CCR0 for the 'up mode' cycle, since '0' is a valid tick too.

    Example: if you set teh tiemr in up mode and CCR0 to 99 (100-1), one PWM cycle will take 100 timer ticks (= 100/32768s = 327,68Hz).

    Setting CCR1 to 50 will reset TB1 when the timer rolls to 0 and sets it when the timer counts to 50, which is 50% duty cycle.

    Since usually, the DC is meant as '1' time, it is better(clearer) to use set/reset mode, so the output is set at start of a cycle and reset after the given period. Else you have to invert all the calculations.

    It is not possible to get 0% duty cycle, since setting CCR1 to 0 will set and reset the output at the same time (it is undefined, which one has precedence). Setting CCR1 to 100 (or above) will result in the output being set(or reset, depending on mode) at TAR=0 and then never being touched again, as the timer will never count to 100.

    With your posted code, you will clock the timer with 32768Hz, resulting in 0.5Hz PWM frequency. And 50% duty cycle: 1s on, 1s off.
    If you see a higher frequency, then there's something wrong with the not posted part of your code (maybe WDT resets or wrong initialization of the clock module)

  •  thanks for help and sorry to have posted in the wrong thread

  • If I understand well, to have a 32768Hz PWM signal I should use the up mode whith a clock source ACLK = 32768Hz  and CCR0=9999 (10000-1) .

    I am right?

    thanks for help

  • hello Jens,

    thanks for your help and I tried to follow your recommendation about SPI communication and it works. But i need help concerning the SPI communication in my application. In fact, the MSP430F5438 have to communicate with the L9942 using the SPI communication. As we know all, when we send a byte we receive a byte. But the datasheet of the L9942 shows that the device send a 16 bits data if only it receive 16 bit data also. SO, I would like to know how could I receive the 16 bits data whith an SPI workinf whith registers of 8bits.we found here the L9942 datasheet to understand well how it works.

    Thanks

    0451.L9942.pdf

  • son am said:
    o have a 32768Hz PWM signal I should use the up mode whith a clock source ACLK = 32768Hz  and CCR0=9999 (10000-1) 

    No, this would result in a 3.2768Hz PWM signal.
    You clock the timer with a certain frequency, and CCR0+1 is the number of ticks that make one cycle. So the PWM frequency is ftimer/(CCR0+1).
    To get a 32768Hz PWM signal, you had to clock the timer with 3.2768MHz and set CCR0 to 99. (nice side effect: the CD in percent would be equal to the value you write to CCRx then, except for 0%)

     

    About the SPI question: it does not matter whether you are transmitting/receiving 2*8 bit or 1*16 bit. SPI is a bitstream (the chip select signal is used to synchronize to a byte/word border or dat apacked border)
    All you have to do is to withe rsplice th e16 bit you want to send into 2*8 bit or concat the received 2 bytes to a 16 bit word. That's all.
    I never met an SPI device which used a transfer length that was not a multiple of 8 bit. Even those 21 bit ADCs are padding their data with 3 '0' bits. And others just take the last x bits sent (before ending the transfer by de-asserting CS) when you transfer more than they want.

  • thanks for your reply,

    I have a question concerning the role of "OUTMOD" bits of the TB0CCTL1. In my code I set OUTMOD bits to 111 ( I choose the reset/set mode: OUTMOD 7) but I read in the datasheet : "Modes 2, 3, 6, and 7 are not useful for TBxCL0 because EQUn = EQU0"  but i didn't understand it well so I didn't know how mode should I choose for my application ( to obtain 32KHz PWM signal).

    I fixed the timer clock at SMCLK=1MHz and CCR0=30 ( 1MHz/31= 32KHz) but I still worried about the output mode (OUTMOD).

    TB0CCR0 =(unsigned short)(30);           
    TB0CCR1= (unsigned short)(32767);        // PWM duty cycle =50%
    TB0CCTL1= OUTMOD_7;                            //  TB0CCR1 reset/set
    TB0CTL=TBSSEL_2|MC_1;                       // SMCLK=1MHz, up mode

     

  • I tried the code with SMCLK=1MHz and CCR0=30 in up mode and OUTMOD_7 but I obtain on the oscilloscope a signal which is always high. I change the mode from up mode to continuous mode so I obtain a PWM signal but the PWM frequency is 16Hz and not 32KHz.

    Could you please help me.

  • son am said:
    I change the mode from up mode to continuous mode so I obtain a PWM signal but the PWM frequency is 16Hz and not 32KHz.

    In continuous mode, the timer counts from 0 to 65535 and 0 again. When it coutns to 0, the CCR0 output is set, and when it counts to 30, it is reset. The resulting frequency is 15.26Hz and the duty cycle is 0.047%. That's right. (31/65536).

    When you use up mode, the timer counts from 0 to CCR0, where the CCR0 ouput is reset, then begins with 0 again, where the CCR0 output is set again.

    son am said:
    I obtain on the oscilloscope a signal which is always high

    Your output isn't high, it is a 1000000/31 = 32768Hz PWM with a duty cycle of 1/31 = 3.2%. However, these 3.2% are a small peak of 1µs (1/fTimer) and most likely slipped your attention.

    If you change the outmode to 4 (toggle), you'll see a 50% DC output of 16129Hz.

    You cannot have a PWM output from CCR0 when CCR0 is controlling the PWM frequency. All you can get is a 50%DC output on half frequency or a single-tick pulse output on full frequency.

    And when you get a PWM output from CCR0, then you cannot control teh PWM cycle time (= PWM frequency) with it. You cannot eat the cake and keep it.

    You need to set up CCR1 to get a real PWM output with the CCR0 controlled requency.

     

  • son am said:
    I read in the datasheet : "Modes 2, 3, 6, and 7 are not useful for TBxCL0 because EQUn = EQU0"

    This refers to the double-action modes, Those happen when TAR reaches teh value of the CCR register (first action) and when TAR counts to 0 (the second action).

    If CCR0 is controlling the timer in up mode, the tiemr rolls over from TAR=CCR0 to TAR=0, so the two actions immediately follow each other.

    But since the two conditions are always 1 timer tick apart, these mdoes are not completely useless. In a different thread where we discussed and tested this, we came to the conclusion that the writer of the guide either didn't notice that there will be a 1-tick-sized spike in these modes, or didn't want to write a complicated explanation of this special case and simply said these mdoes are useless for CCR0 when the timer is in up mode.

    And you seemed to fall in the same trap and didn't notice the spike too :)

  • thanks for your reply,

    I understand now how the timer runs to generate PWM signal and I followed your instructions and  I obtain finally the result I want.

    thanks again

  • Hello,

    I know that this tread treats the SPI and UART problems but I have a problem with my bluetooth module PAN1315 used with the MSP430 Experimented board and I hope that you help me to reslove this problem.

    In fact, I establish a Bluetooth connexion between my PC and the PAN1315 Bluetooth moduleI using  the "Advanced Serial Port terminal"  software. I try to send a bluetooth frame and  visualise the frame received by the PAN1315 using the Terminal Input/output of the IAR.

    when the number of bytes in the sent frame become higher than 121 bytes, the PAN1315 will receive this frame in paquets of 121 bytes.

    For example, when I send a frame of 506 bytes, I obtain:

     SPP_RECVD_DATA_IND  

     data length= 121 

     received data = the 121 first bytes of the data sent

    SPP_RECVD_DATA_IND  

     data length= 121 

     received data = the 121 second bytes of the data sent  

     SPP_RECVD_DATA_IND  

     data length= 121 

     received data = the 121 third bytes of the data sent

    SPP_RECVD_DATA_IND  

     data length= 121 

     received data = the 121 fourth bytes of the data sent

    SPP_RECVD_DATA_IND  

     data length= 22

     received data = the 22 last bytes of the data sent

     

  • son am said:
    I know that this tread treats the SPI and UART problems but I have a problem with my bluetooth module

    Now that's completely off-topic. Why don't you simply start a new thread? It will be read by people who are interested in this new topic and not just ignored by those who don't care for SPI.

    son am said:
    I hope that you help me to reslove this problem

    No, I don't have any experience with BT.

  • son am said:
    I know that this tread treats the SPI and UART problems but I have a problem with my bluetooth module

    Now that's completely off-topic. Why don't you simply start a new thread? It will be read by people who are interested in this new topic and not just ignored by those who don't care for SPI.

    son am said:
    I hope that you help me to reslove this problem

    No, I don't have any experience with BT.

  • thanks for your reply,

    I will post in a new thread

  • Hi

            I have going to interface the MSP430f5438 with digital potentiometer MCP41010 by SPI communication.For that i have write the code as below.My spi  had some problem because of that i am not able to write the value in the data registers.If anyone had any solution for me then please send me.

     

     

    void spi_init(void)
    {
       
      //unsigned char spi_cmd,spi_data;
      WDTCTL = WDTPW+WDTHOLD;                   // Stop watchdog timer

      P10OUT |= 0x01;                            //Chip select
      P10DIR |= 0x0B;                            // Set P10-1 to output direction
      P10SEL |= 0xA;                            // P10.1,3 option select for the si and clk

      UCB3CTL1 |= UCSWRST;                      // **Put state machine in reset**
      UCB3CTL0 |= UCMST+UCSYNC+UCMSB;    // 3-pin, 8-bit SPI master
                                                // Clock polarity high, MSB
      UCB3CTL1 |= UCSSEL_2;                     // SMCLK
      UCB3BR0 = 0x02;                           // /2
      UCB3BR1 = 0;                              //
      //UCA3MCTL = 0;                             // No modulation
      UCB3CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
     // UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt

      P10OUT &= ~0x01;                           // Now with SPI signals initialized,
      P10OUT |= 0x01;                            // reset slave


    }

    void spi_write(unsigned char data)
    {
       while (!(UCB3IFG&UCTXIFG));               // USCI_A0 TX buffer ready?
      UCB3TXBUF = data;    

    }

    void main (void)

    {

    spi_init();

    P10OUT&=~0x01;

    spi_write(17);      //command set for the digital pot IC

    spi_write(120);   //values given to the data register

    P10OUT |=0x01;

    }

     

  • *sigh* why are you postign this problem in several threads?
    Also, you got an answer from me in the private conversation you started.

    (short solution: the slave is deselected before the second byte is transmitted completely)

**Attention** This is a public forum