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.

Maximum bit banging data rate

Other Parts Discussed in Thread: MSP430F2013, MSP430F2274

I need to toggle one I/O pin at a rate of 10MHz.  I'm using the MSP430F2013 and am running it at 16MHz, but the maximum frequency at which I can toggle P1.0 is 4MHz.  It seems that absolute addressing is required when changing the value of the I/O register, which inherently requires 4 cpu cycles, hence the maximum data rate of 4MHz.  Does anyone know if I can increase the speed of toggling the I/O pin?  I would really like to toggle the pin at the same rate as the clock, but I think the 4 cycle execution time cannot be overcome due to the MSP's architecture.  

  • You are correct. Using the CPU, you need at least 4 MCLKs to toggle a port pin.

    You may be able to toggle some of the port pins in 2 SMCLKs if you use the Timer to do it. And the Timer may work at higher clock rate.

  • Concerning the timer method old_cow_yellow spoke of - you can use a timer to act like a PWM to get an 8MHz frequency output on a pin.  If you'll look at the 20xx code examples, msp430x20x3_ta_17.c, it shows you the basics of turning a timer into a PWM.  You'll need to make your MCLK source the same as your SMCLK or ACLK source, and to get the maximum toggle rate, CCR0 should be (2-1) and CCR1 should be 1.

  • The data-sheet specified that the max MCLK for CPU at 3.3V < Vcc < 3.6V is 16MHz. But it seems to imply that the DCO and the Timer can handle higher frequency. Is that correct? What are the limits?

     

  • The timer cannot run at a higher frequency else you will be violating spec.

    Page 29 of the 2013 datasheet, the DCO is spec'ed up to 26 MHz, but you really cannot do anything with frequencies over Fsystem maximum (16MHz).  You have to divide the DCO down before applying it to MCLK/SMCLK/ACLK else you will also violate spec (making the results unpredictable).

  • Can anyone comment of the maximum bit bang serial baud rate for RS-232 output from a 16MHz part with the "timer" based UART?

  • I have recently been using the MSP430f2013 in a project, and I needed to use UART communications for data transmission.  I tried using the timer based UART, but I found the maximum baud rate to be restricted by the software (all in all, my TimerA0 interrupt took about 30 clock cycles). 

    I found an acceptable solution by using the USI in SPI mode with only the SDO pin enabled.  The software takes the 8 bit data byte to be transmitted, and pads it on either side with 1's and 0's to represent the Start and Stop bits, and places it in a 16 bit container for transmission.  The 16 bit container is loaded into the USI shift register for transmission, and the shift counter is loaded with the appropriate number of bits to shift out.  With this setup I am communicating with a UART format at 1 Mbps.

    As far as acheiving a higher clock rate using the DCO, it is possible to set the registers to get a higher clock rate.  The devices are rated for 16 MHz, but I have acheived close to 20 MHz when playing around with the DCO.  Also, using the MSP430f2274 in an audio application, I was able to use a 24.576 MHz crystal with the appropriate matching capacitors, and a slightly higher voltage. 

    While both of these overclocking practices acheived higher clock rates.  Using the DCO at 20 MHz, the clock was not very stable and would vary by more than 100 kHz when I put my thumb on the chip to raise its temperature.  And using the 24.576 MHz crystal, the chip would almost always crash and have to be restarted every 10 or 20 minutes.

  • Sparkchaser,

    You described a way to use USI for Async Transmit. Is there a way to use it for Async Receive?

    --OCY

  • OCR,
     
    I did not have to use the UART for receive, but looking at the users guide, I think that it might be possible.  The Users Guide states that the PxIN interrupts are still active while the ports are configured for the USI.  So, If I were to try to do this, I would write the code so that it would flow as follows:
     


    Big Disclaimer:  Nothing I am about to suggest has in any way been tested, and is the result of only a few minutes of reading the User's Guide.
     

     
    Configure the USI registers - clock, clock divider, pins, etc. as needed
    Don't clear the USISWRST yet
    Don't enable the USI counter interrupt yet
    Enable P1.7 falling edge interrupt
     
    on the P1.7 falling edge interrupt
    {
    Clear the USISWRST bit
    Load the USI counter with how many bits you want to receive
    Enable the USI counter interrupt
    Disable the P1.7 interrupt
    Clear the P1.7 interrupt flag
    }
     
    on the USI counter interrupt
    {
    Enable the P1.7 falling edge interrupt to catch the next start bit
    Read the shift register
    Clear the USI counter interrupt enable
    Set the USISWRST bit

    (optional) return to main and perform error checking
    }
      
    Some requirements:
    The input baud rate would have to be something that works with the USI clock source divided by the USIDIVx, this might mean that you would need to select a crystal that can be divided to the appropriate baud rate if you cannot control the transmitter's baud rate.
     
    The baud would have to be slow enought that the latency of the P1 interrupt routine doesn't cause you to miss the first bit of the receive byte, and the UCKPH and UCKPL would need to be configured properly.
     
    Also, the time lapse between two consecutively received bytes would have to be enough that the latency of the USI counter interrupt routine doesn't cause you to miss the falling edge of the start bit of the next byte.
     
    I think that this should allow you to receive something, and with a little playing around and clever use of an oscilloscope, you should be able to get several tens of kbps baud rate.
    Any error detection, parity checking, etc., routines for the received data byte would have to be completed before the next byte is received or else you risk having a stack buffer overrun.

    Cheers,
    Sparkchaser

  • Sparkchaser,

    Thanks for the response. I will have to try it some day.Sounds like the highest bit-rate will be similar to using Timer Capture alone

    I did manage to get 230.4kb/s with 16MHz clock.without using USI.. 16MHz is not divisible by 230.4kb/s, I was using 70 clocks for 5 of the bits and 69 clocks for 4 of the bits (the stop bit is any length >40 clocks).

**Attention** This is a public forum