Jump to content

Bit-Bang USB on MSP430G2452

Recommended Posts

Hello @@theprophet,

if the crystal is in place, it helps to stabilize the DCO to 15 MHz by having a timer running in a software frequency locked loop which counts how many DCO ticks occour within one 32768/8 Hz tick and adjusts DCO in given direction. This helps in long time connections, as temperature changes which change DCO frequency are regulated away, but for the case of detecting, you can have the same check as in the crystal-free implementation, as the DCO will be in RSEL 15 tap, too. Personally, I would opt for an P1IE line bit check instead in both cases, as the target application might want to run with 16 MHz, which is also within the BCSCTL1 RSEL tap 15.

Christian Starkjohann of V-USB has implemented a frequency locked loop on the USB protocol itself, basically every 1 ms there is a SE0 on the bus without transmitting a packet. This consumes a timer just as in the crystal variant and might be implemented by setting P1IE on the other USB line and checking for that if catching the sync pattern fails. This is called "Keep alive signaling" and occours always, not only after fresh connection as simpleavr uses this for initial clock setup. In Bootloader application, long time clock stability is not a concern, but if you are going to establish long-time connections as for your IR receiver, for example there may be a stream of warm air from ventilation with varying temperature that will cause the connection to break down over time.

"Frames: On a low speed link, to preserve bandwidth, a Keep Alive signal is sent every millisecond, instead of a Start of Frame packet. In fact Keep Alives may be sent by a hub on a low speed link whenever the hub sees a full speed token packet." http://www.usbmadesimple.co.uk/ums_3.htm See USB specification for more info.

The "USB Tinkerer" is simply a small tribute in this forum for those having advanced USB usage on MSP430 :-)


Link to post
Share on other sites
  • Replies 274
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

It works!  Unfracking believable - the mouse is moving across the screen!   Have some cleanup to do before posting the code.

Mecrimus-B 0.2 is out. English translations are included. This time, it emulates an HID mouse that moves your pointer to the right. Tested on Linux 2.6.26-2-686 with UHCI Host Controller. lsusb -v:

Good morning ! This has been directly from my bench, but I wanted to share this immediately with you before going to sleep. Of course, the next days I will provide a translation and more documentatio

Posted Images



About the long time clock stability : for my msp430 usb IR receiver project, I plan to use a crystal. Whichever choice I make (either a crystal or a potential future keep-alive-signaling sync) will need a timer. Would it be possible to directly use a 15MHz crystal so that the timerA would not be used for clock-syncing ?





Link to post
Share on other sites



I tried your code earlier today on a cygwin + win7 box. There are no more errors from the usbSetReports(), from the commandline it appeared the transfer is very smooth.


On my setup, I am missing quite a bit of packets (4 byte data) and the firmware flashed end up incorrect. (shorter as it miss some 4 byte packets).


I spend an hour or so trying to trace it. The only finding so far is that 


. when the time threshold is breached, the inbuf / idx is not 32  (8x4) bytes, but somes 7x4, 6x4, 5x4.

. I also tried to adjust the timing (uSleep() from commandline) but it did not help.

. I am getting 99% failure, in most cases from 100 packets I would miss 4+ packets, sometimes more, sometimes less, not consistent.


I am quite busy right now so is not able to continue in depth testing, will have do that next week.

I think we need more testing.


May be you can also run some regression tests, I use mspdebug "md 0xc000" to examine the flashed cells.


Also thanks for your time working on this.





This could be something w/ my setup, etc. But if you have time, du

Link to post
Share on other sites

Hello @@simpleavr,



May be you can also run some regression tests, I use mspdebug "md 0xc000" to examine the flashed cells.

That's exactly what I did for testing : I checked that the flashed app was running fine on the mcu and I checked the flashed bytes using mspdebug "md 0xc000".




. I am getting 99% failure, in most cases from 100 packets I would miss 4+ packets, sometimes more, sometimes less, not consistent.

Interesting and funny : when I was using your original version on my hw setup, nothing worked, and when you use my version on your hw setup, nothing works :smile:

In the version I posted, I reduced the timings to the minimum limit I could reach without getting errors. Perhaps we should increase them for the sake of stability.

Here are the original loose timings I was using in my first tests (giving 100% success on 3 different computers, powering the breadboard mcu from the launchpad):

- in boot430.c line 151 :

static uint16_t const USB_IDLE_DETECT_THRESHOLD = 65534;


- in commandline/main.c line 248 :



- in commandline/main.c line 252 :



My next tests are going to be about using a 3.3V LDO to power the breadboard.


Note : I am not using Cygwin. I compile bootload430 directly using MinGW. Just to be sure it had no impact, I have just performed some tests compiling the host program with Cygwin and it gives me the same results as with mingw. That's good.


Today, I decided to plug my oscilloscope to the usb lines to visualize the usb keep alive signal. The current setup was without crystal, with a led connected between P2.6/P2.7. I did see the keep alive signal, but I noticed something interesting else : the usb lines were being shifted a bit at the same frequency as the heartbeat led. It did not bother me specifically, but I decided to check another thing. I have one desktop PC, and two laptops (a very old one and a more recent one). On the recent laptop, when using tight timings (as the code I posted in the forum), when transferring an application, I mostly always get an error (whereas I don't get errors on the two other computers). I decided to try on that problematic laptop with the same hw setup (without crystal) and the tight timings except that I removed the heartbeat led from the breadboard. And it appears that it works fine. As soon as I plug back the heartbeat led, I randomly get "unrecognized device" from the OS, transfer errors, etc. If I use the launchpad led1 for the heartbeat, it starts working fine again.

What black magic is behind that ?

Link to post
Share on other sites

Pardon me, they are disabled:

  P2SEL = 0;
  P2DIR = BIT6|BIT7;          // indicator led
  P2OUT = 0;

It is another magic:

Led 1 is on P1.0, bit constant 1 which is generated by constant-generator-registers.
Oscillator Pins are on P2.6 and P2.7, bit constant 64/128, which require real constants to be generated and have longer opcodes.

The assembler code has cycle-accurate timing, and the toggle_syncled Macro is expected to run in 4 cycles, which is only possible with the lower 4 bits that can be accessed with the constant-generator-constants -1, 0, 1, 2, 4. With your choice for the LED pin you need 5 cycles. But no matter, there is a nop2 next to it in receiver which you can get a spare cycle from.

I am a bit puzzled if heartbeat and my original syncled are the same, but I am sure you will find the issue with this info.

Link to post
Share on other sites

Hello @@M-atthias,

Thanks for all the information. I'm going to clarify a bit here :

- the "heartbeat" led I mentioned is *not* the same as the toggle_syncled : I left the toggle_syncled on P1.2 (xor.b    #BIT2, &P1OUT), and the "heartbeat" led is something @@simpleavr introduced (a led connected between P2.6 and P2.7 without a resistor which constantly blinks as soon as the usb sie is initialized).

- when I remove the heartbeat led (connected on P2.6/P2.7 without a resistor), the usb line levels aren't shifted anymore, and the PC on which the device has most difficulties in being recognized starts to correctly recongnize and talk with the device.

- if I connect the heartbeat led between P2.7 and ground with a 330ohm resistor in between, the signal shifting does not occur anymore, and the device works fine on the problematic PC.


I think this led between P2.6/P2.7 is giving signal level/quality problems.



By the way, I if want to remove the led associated to toggle_syncled, what should the toggle_syncled macro be ? nop4 ?





Link to post
Share on other sites

@@theprophet good that you had a scope and figured out the led impact. It began as a temporary thing I put in for debug and it never occurred to me to put in a series resistor.


I would usually put in some kind of pulse off-off-off-on to limit the current if I am to direct drive leds, but I guess I missed it here. Will update my github repo and make an important note on this. Thanks.


I am not working on testing w/ my setup this weekend as it's thanks giving holiday here. Will investigate the my missing packets in a few days.

Link to post
Share on other sites



OK, so I think I had found out how I am getting lost packets (4 byte data packets). But just not sure why you are not getting them.


So eventually I pull up usbpcap again and found that for each transfer via usbSetReport(...), there is a trio of packets going to the msp430, I look at them closely and research also usb protocol details and they are doing what is expected. I.e. (1) setup packet, (2) data packet, and (3) status packet.


And bbusb uses the same interrupt to handle all of them. For boot430, we look at the length of (2) data packet, and process them accordingly when the length is 0x0a (set start / end flash address), or 0x08 (4 byte data).


We are doing this in the main program. While at the same time, the interrupt is still going on. What had happened (at least in my case), is that while process the (2) data packet, the (3) status packet comes in, and since they share the same buffer DataPacketBuffer[], at times, if the (3) status packet comes in quick enough, the length byte and the report id byte got overwritten, which in turn fails our if-then-else check to handle data bytes.


From usbpcap all the 3 packets have the same timestamp but usually I had about 10-30% of packet loss due to this problem. The solution for my case is to immediately save the "length" byte as a "cmd" byte and use the cmd byte afterwards (since the original length byte is not reliable).


So why does this happens more now on my system and why is this ad-hoc? I believe the fact is our main loop is not constantly checking for


    if(DataPacketBuffer[0]) // Check if the USB SIE has received a packet

As we are also incrementing and checking heartbeat and idle_detect counters, and checking for conditions to do erase flash, write flash, etc. So when we check and enter this condition (USB SIE), the data packet could have just arrived within a few clock cycles, or it could be 100+ cycles old, in which case upon detection, the next packet (status packet) will be present and overwrite the existing one.


I cannot have a good explanation on why you are not getting miss packets. Except I would assume your usb packets have more time separation between them, could be due to an older PC or via a hub?


But anyway, I am getting 100% reliability (even on large apps) w/ this modification. If you care to try and verify.


* This is safe for us to read the same data buffer even when the status packet had overwrite it, as the 4 byte data will not be overwritten by a status packet, status packet are zero length.

diff boot430.c.new boot430.c
<         uint8_t cmd = *DataPacketBuffer;
<       DataPacketBuffer[0] = 0;
<         //if (*DataPacketBuffer == 0x0A && *cp == 0x01)
<         if (cmd == 0x0A)
>         if (*DataPacketBuffer == 0x0A && *cp == 0x01)
<         //else if (*DataPacketBuffer == 0x08 && *cp == 0x02)
<         else if (cmd == 0x08)
>         else if (*DataPacketBuffer == 0x08 && *cp == 0x02)
<       //DataPacketBuffer[0] = 0; // Done with received packet, don't process again, allow USB SIE to receive the next packet
>       DataPacketBuffer[0] = 0; // Done with received packet, don't process again, allow US SIE to receive the next packet










Link to post
Share on other sites

Hello @@simpleavr

That seems quite a great progress again :thumbup: I'm going to test your changes shortly on my hardware breadboard setup, and on my 3 different PCs.


About why I haven't seen any lost packet on my side :

- I have one desktop PC, rather recent, but no usb 3, and two old laptops with usb 2. When I test, I check (1) by plugging it directly on a usb 2 port and (2) by plugging it through a usb hub.

- When I test, I check it works both in Windows and Linux, but I'm not compiling the windows side using cygwin : that could be of importance. Let me explain : in Linux, the usleep() works well. In Windows without cygwin, I have added an implementation of usleep() named uSleep() which works well (uses Windows "performance timing"). In cygwin, I don't know whether a cygwin's implementation of usleep() is used or my uSleep(), and supposing cygwin's usleep() is not that good, your mcu could be receiving usb packets faster than me (given that we do a usleep(2500) between each usbSetReport()). By the way, I would be interested you test my compiled bootload430.exe on your computer with your hardware setup, if you're ok.



I have been performing some more tests alongside mostly about signal quality/powering/etc. :

- I can confirm that addind a series resistor to the P2.7 heartbeat led leads to better stability, at least on my computers.

- I have rewired the standalone 3.3V LDO to try and stop using the Launchpad 3.6V power, and I often get stability problems with 3.3V, even with the crystal variant.

- However, if I increase the voltage to 3.5~3.6V (using an adjustable LDO - lm1117 in my case), I get it working fine as when powered with the Launchpad, even without the crystal. I think usb controllers have all their own sensitivity/thresholds and perhaps we should recommend using the highest possible signal levels.





Link to post
Share on other sites



I would think that my missing packet issue is not related to boot430load.exe's usleep timing. I.e. What I saw is timing issue / buffer overwrite issue between packet 2 and 3 within a SetReport() operation. I suspect it's the different usb chipset + associated kernel driver timing them differently. So I would expect even if I run your binaries, I will still have issue on my windows box. But please upload the firmware + your boot430load.exe and I will try and see.


From usbpcap output the set of the 3 packets (setup, data, status) all happened within the same 1/10,000, so it's different to pin-point the exact timing. This also indicates the msp430 has at most less than 1500 cycles running at 15Mhz (real time may be substantial less) to take care of 3 packets. That not a lot at all, before you move all data from the data packet to our own buffer, another packet can come in and mess it up.


I think the wait-for-idle changes you made takes care of the flash erase / write issue (during which the cpu is stopped), but the missing packet is caused by what I described. I did debug them using packet counters within the bootloader packet receive loop to understand this.


For the 3.3V vs 3.6V, as we are running at 15Mhz, 3.3V is close to the minimum, datasheet indicates 3.3-3.6V for 16Mhz. My experience is that the clock is less precise if running at lower voltage. Many of my projects are powered by 3V batteries and they can only run reliably at 8Mhz. So your finding is not at all surprising. Sometimes my projects employs parts that are convenient to me (3.3V LDO, single LED) but they may not be optimal. I will put notes when we check-in this version regarding the impact parts have.


If you can check the changes and feel that they didn't make things worse, let me know and I will update git as both my test and your test passes. There is no rush though if you feel to play w/ it more or may be put more enhancement to it.



Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...