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.

MSP430F5x SBW (Spy-Bi-Wire) programming

Other Parts Discussed in Thread: MSP430F5435, MSP430F5328, MSP430F2012, MSP430F2013

Has anyone successfully executed the example from SLAU320 for SBW programming the MSP 5 series (V2)?

I have been working on a MSP430F5x SBW programmer for our factory and following the code from the Replicator project (SLAU320).  A lot of this is working but some critical things are not, such as turning off the WDT at the beginning of the programming session.

I am using the MSPFET (Under control of the FET-Pro430 software) as my reference platform to program the device that I'm working on and looking at what it does vs what I am doing.  After much pain manually decoding the SBW logic captures I finally broke down and wrote an automated decoder:  See decoder output here.

The first thing that jumps out at me is the three undocumented instructions, 0x30. 0x42 and 0xB0. 

  •     0x30 and 0x42 are related to the 16 bit data shift (DR16)
  •     0xB0 is related to a 32 bit data shift (DR32) never used in the SLAU320 code.

There are large chunks that line up with SLAU320 but a lot that is over and above what is in the documentation and code resource.

  • TI source code can be used as good starting point, but if you want more, you must do it (and resolve all bugs) by yourself . I am working on my own SBW+ multi-programmer (http://forum.43oh.com/topic/2972-sbw-msp430f550x-based-programmer/) and I used SLAU320 as starting point. It is able to program 4 devices at once, and it is much faster than TI/Elprotronic replicator or gang solution.

    Unfortunately, can't help you with 30/43/B0. Thank you for your logs, because there are very useful for anybody who is working on SBW related stuff.

    Here is example of flashing 2 MSP430F5435 devices with my programmer:

    D:\msp430>flash -f sbw_test_192.txt -e -w -v

    File "sbw_test_192.txt"
    196608 bytes

    Get Device
    Device: 1  JTID: 91  Fuse: OK  1A04: 54 35  1A06: 10 10
    Device: 2  JTID: 91  Fuse: OK  1A04: 54 35  1A06: 10 10

    Erase

    Write
    Address: 05C00 Words: 2014
    Address: 06BBC Words: 2014
    ...

    Address: 33F84 Words: 2014
    Address: 34F40 Words: 1632
    Size: 196608 bytes  Time: 1328 ms  Speed: 144,58 KB/s

    Verify
    Address: 05C00 Words: 98304
    Size: 196608 bytes  Time: 969 ms  Speed: 198,14 KB/s

    Release Device

    Total Time: 2594 ms

  • Out of frustration I was hand decoding the known good operations that eventually evolved into the automated decoder from which these transaction dumps were derived.  At least now I can compare the published SLAU320 data with the actual working system to find the holes and get to a more stable result.

    http://ppl.ug/SWjuR4XCNpA/                 UI

    http://ppl.ug/rLcYOLbyXr4/                      Instuctions

    http://ppl.ug/89yrR7BYdgE/                    Transaction dumps

  •  There is not much about reported slau320 bugs. I found only this http://e2e.ti.com/support/microcontrollers/msp430/f/166/t/233271.aspx

  •      I've updated the SBW capture data dumps and the SBW decoder UI.  The data dump includes annotated copies of the write and erase captures, you can really see the high level code flow.  There are also files for each of the function call sequences.

    • Decoder:           http://ppl.ug/nncakc6GXnI/
    • Data dumps:     http://ppl.ug/TYOUVc-F0kY/

         The next step is to build an even higher level pattern recognizer to do what I am doing manually, i,e, to convert sequences of SBW transactions (IR8, DR16 etc) into function calls.  90% of the dump, translates to documented sequences such as WRITE_MEM() with  the other 10% belonging to the un-documented stuff that I'm trying to figure out.  This particular write operation turns off the WDT.  Note the PREP_MEM() function call that uses the undocumented 0x42 instruction and precedes the documented WRITE_MEM() function call.  Simply writing to the WDT control register with WRITE_MEM() does not work without PREP_MEM() being called first.

     

            00.033086250  IR8(CTRL_CAPTURE) = 0x91        PREP_MEM(0x0015C)
            00.033216000  DR16(0x0000)      = 0xC301
            00.033419750  IR8(CTRL_CAPTURE) = 0x91
            00.033549250  DR16(0x0000)      = 0xC301
            00.033743750  CLR_TCLK(1)
            00.033757250  IR8(ADDR_16BIT)   = 0x91
            00.033880250  DR20(0x0015C)     = 0x00000
            00.034106500  SET_TCLK(0)
            00.034115000  CLR_TCLK(1)
            00.034128500  IR8(0x42)         = 0x91
            00.034251250  DR16(0x0000)      = 0x6904
            00.034442750  IR8(CTRL_CAPTURE) = 0x91
            00.034565500  DR16(0x0000)      = 0xC301
            00.034755000  SET_TCLK(0)
            00.034763500  CLR_TCLK(1)
            00.034773000  SET_TCLK(0)

            00.034795500  IR8(CTRL_CAPTURE) = 0x91        WRITE_MEM(0x0015C,0x5A84)

            00.034925000  DR16(0x0000)      = 0xC301
            00.035120000  CLR_TCLK(1)
            00.035133250  IR8(CTRL_16BIT)   = 0x91
            00.035256750  DR16(0x0500)      = 0xC301
            00.035446500  IR8(ADDR_16BIT)   = 0x91
            00.035569500  DR20(0x0015C)     = 0x015C0
            00.035796250  SET_TCLK(0)
            00.035808250  IR8(DATA_TO_ADDR) = 0x91
            00.035932250  DR16(0x5A84)      = 0x0000
            00.036115750  CLR_TCLK(1)
            00.036129000  IR8(CTRL_16BIT)   = 0x91
            00.036252250  DR16(0x0501)      = 0xC301
            00.036439250  SET_TCLK(0)
            00.036447750  CLR_TCLK(1)
            00.036457250  SET_TCLK(0)

  • Heres the current state of the decode effort:  http://ppl.ug/VUFzTMuSt5U/

    About 99% of it is split into obvious functional blocks that can be programmed fairly easily, even if 10% of them are based on undocumented instructions or accesses to undocumented memory areas.  The files that start with 124_ are the raw output of the SBW decoder, files that start with A124_ are annotated with function names at the start of each block and other notes.  There are also RTF files with more notes.

    jt

  • I can see why the MSPFET under FET-PrRO430 takes so long to write to flash:

    In the BSL write test:

    1.  Read out RAM at 0x1C00 to 0x1CF4

    2.  Upload flash write code to that space.

    3.  Execute code, upload 0xF0 words and write flash

    4.  Restore the RAM from step 1.

    Repeat 1-4 four more times until the entire 2K is written.

    Unlike the erase functions that save the RAM restore to the end and simply change the 3 address and block size control words for each block, the write does 100% of the effort for every 0xF0 block of words.

    jt

  • Hi John,

    Are you still having problems with these instructions? Can you send me the context where you see them?  I can check with the tools team to see if they have any comments.

    Regards,

    Luis R

  • Luis,

    From my correspondence with John, here is the latest data he has sent:

     -------------------------------------------------------------------------------------------------------------------------------

    Reverse engineering the logic analyzer captures is where the questions came from (The discussion thread I set up has all of the capture/decodes).  Below is a (very) small chunk from the beginning of the write-bsl capture.  All three of the undocumented commands are used in just this small section (in RED).

     

            ////////////////////////////////////////////////////////////////////////

            // 124_MSP430F5328_Write BSL.bin

            ////////////////////////////////////////////////////////////////////////

            // Break Limit-mS       1

            // ----------------------

            // Bits Read       349055

            // Bits Used       349054

            // ----------------------

            // IR8()             7888  [No translation: 0xB0,0x30,0x42]

            // DR16()            9261

            // DR20()            1329

            // DR32()              34

            // CLR_TCLK()        4801

            // SET_TCLK()        4822

            // BIT()                1

            // RESET_TAP()          2

            // TMS_TOGGLE()         2

            // ----------------------

            // Total            28206

            ////////////////////////////////////////////////////////////////////////

            00.023458750  ENTER_TEST_MODE()

           

            ------------  DELAY_MS(023)

           

            00.000000000  SBW_ENTRY_PULSE()

           

            ------------  DELAY_MS(010)

           

            00.010115000  RESET_TAP()

            00.010191750  TMS_TOGGLE()

            00.010874000  TMS_TOGGLE()

            00.011556000  BIT(110)

            00.011563750  RESET_TAP()

            00.011645500  IR8(DATA_BYPASS)  = 0x91

            00.011787500  IR8(CORE_IPID)    = 0x91

            00.011909750  DR16(0x0000)      = 0x0103

            00.012101000  IR8(DEVICE_ID)    = 0x91

            00.012223500  DR20(0x00000)     = 0x01A00

            00.012473000  IR8(0xB0)         = 0x91

            00.012601750  DR32(0x00000087)  = 0x00000000

            00.012943750  DR32(0x00000000)  = 0x00000504

            00.013330000  IR8(0xB0)         = 0x91

            00.013458750  DR32(0x00000088)  = 0x05040000

            00.013801750  DR32(0x00006D8E)  = 0x00002480

            00.014151000  IR8(0x30)         = 0x91

            00.014280500  DR16(0x0005)      = 0x000C

            00.014473250  IR8(CTRL_16BIT)   = 0x91

            00.014596500  DR16(0x1501)      = 0x0011

            00.014789000  IR8(CTRL_CAPTURE) = 0x91

            00.014913500  DR16(0x0000)      = 0xD201

            00.015108250  CLR_TCLK(1)

            00.015118000  SET_TCLK(0)

            00.015131750  IR8(CTRL_16BIT)   = 0x91

            00.015255000  DR16(0x0C01)      = 0x9251

           

            ------------  DELAY_MS(017)

           

            00.032142250  DR16(0x0401)      = 0xCB01

            00.032329750  CLR_TCLK(1)

            00.032339500  SET_TCLK(0)

            00.032348000  CLR_TCLK(1)

            00.032357500  SET_TCLK(0)

            00.032366250  CLR_TCLK(1)

            00.032376000  SET_TCLK(0)

            00.032384500  CLR_TCLK(1)

            00.032394250  SET_TCLK(0)

            00.032403000  CLR_TCLK(1)

            00.032412500  SET_TCLK(0)

            00.032426250  IR8(CTRL_16BIT)   = 0x91

            00.032549750  DR16(0x0501)      = 0x4201

            00.032735250  CLR_TCLK(1)

            00.032744750  SET_TCLK(0)

            00.032765000  IR8(0x30)         = 0x91

            00.032894500  DR16(0x000E)      = 0x0005

            00.033086250  IR8(CTRL_CAPTURE) = 0x91

            00.033216000  DR16(0x0000)      = 0xC301

            00.033419750  IR8(CTRL_CAPTURE) = 0x91

            00.033549250  DR16(0x0000)      = 0xC301

            00.033743750  CLR_TCLK(1)

            00.033757250  IR8(ADDR_16BIT)   = 0x91

            00.033880250  DR20(0x0015C)     = 0x00000

            00.034106500  SET_TCLK(0)

            00.034115000  CLR_TCLK(1)

            00.034128500  IR8(0x42)         = 0x91

            00.034251250  DR16(0x0000)      = 0x6904

            00.034442750  IR8(CTRL_CAPTURE) = 0x91

            00.034565500  DR16(0x0000)      = 0xC301

            00.034755000  SET_TCLK(0)

            00.034763500  CLR_TCLK(1)

            00.034773000  SET_TCLK(0)

            00.034795250  IR8(CTRL_CAPTURE) = 0x91

            00.034925000  DR16(0x0000)      = 0xC301

            00.035120000  CLR_TCLK(1)

            00.035133250  IR8(CTRL_16BIT)   = 0x91

            ...

    -------------------------------------------------------------------------------------------------------------------------------

    Thanks for your help,

    Josh

  •      The 0x42 instruction makes sense now.  I noticed that the READ_MEM() function from SLAU320 did not always return the right value for RAM in the lower 64K address space where READ_MEM_QUICK() generally would.  The problem was first noticed in particular with the WDT control register at 0x015C which made operation very unstable:  If you can't turn off the WDT the CPU constantly resets. 

         In looking at the decode data, I could see a pairing of blocks, one using the 0x42 instruction (Which I had called PREP_MEM() as a place holder) followed by a traditional WRITE_MEM() block.  Below is a block that is always used at the end of the  the GET_DEVICE() function:

            00.033419750  IR8(CTRL_CAPTURE) = 0x91        READ_MEM(0x015C)
            00.033549250  DR16(0x0000)      = 0xC301
            00.033743750  CLR_TCLK(1)
            00.033757250  IR8(ADDR_16BIT)   = 0x91
            00.033880250  DR20(0x0015C)     = 0x00000
            00.034106500  SET_TCLK(0)
            00.034115000  CLR_TCLK(1)
            00.034128500  IR8(0x42)         = 0x91
            00.034251250  DR16(0x0000)      = 0x6904     //Current WDT register
            00.034442750  IR8(CTRL_CAPTURE) = 0x91
            00.034565500  DR16(0x0000)      = 0xC301
            00.034755000  SET_TCLK(0)
            00.034763500  CLR_TCLK(1)
            00.034773000  SET_TCLK(0)


            00.034795250  IR8(CTRL_CAPTURE) = 0x91        WRITE_MEM(0x015C,0x5A84)
            00.034925000  DR16(0x0000)      = 0xC301
            00.035120000  CLR_TCLK(1)
            00.035133250  IR8(CTRL_16BIT)   = 0x91
            00.035256750  DR16(0x0500)      = 0xC301
            00.035446500  IR8(ADDR_16BIT)   = 0x91
            00.035569500  DR20(0x0015C)     = 0x015C0
            00.035796250  SET_TCLK(0)
            00.035808250  IR8(DATA_TO_ADDR) = 0x91
            00.035932250  DR16(0x5A84)      = 0x0000     //write is back after setting the disable bit
            00.036115750  CLR_TCLK(1)
            00.036129000  IR8(CTRL_16BIT)   = 0x91
            00.036252250  DR16(0x0501)      = 0xC301
            00.036439000  SET_TCLK(0)
            00.036447750  CLR_TCLK(1)
            00.036457250  SET_TCLK(0)

         I finally figured out that the function should really be called READ_MEM() as shown above .  Since JTAG does not have the ability to set or clear bits, but just write whole bytes, the 0x42 instruction is used to read memory so that it can be manipulated and then written back.  You can also see the use of the read functionality during initialization where the memory from 0xFF0 to 0xFFF is read out (The old school descriptor block).

         That just leaves the 0x30 and 0xB0 instructions to figure out as well as those writes to 0x0110 and 0x011E (Among others).

  • Here's the current annotated decode data, including function level blocks and notes:  http://ppl.ug/pMmiVZXc5fw/

         Here's the current source code (Yes, a single file for the entire MSP430 controller) compiled on CCS PICC running on a PIC18F26K20 running at 64MHz (16MIPS) at 3.3V:  http://ppl.ug/FJMK4_j63x8/

         Electrically, there are no direction changes as the data out pin is connected to the data in pin with a 1K resistor with the timing adjusted to allow a 1.5nF cap on the DIO line.

         I can now Read, Write, Erase any area of Flash on an MSP430F5328 with 100% reliability.   I still don't know what some of the code does, such as the 0xB0 and 0x30 instructions, but the decode provided enough visibility to distill what was there into workable function groups.  I was able to remove about 70% of the processing required to access the device vs the MSPFET under the Elptronic FET-Pro430 UI by not doing things over and over:  For instance, I have a global upload_state variable so that when I call the write or erase functions, they know whether their is already in RAM and if not they uploads the code.  Multiple calls to the same functions only need to upload the parameters that have changed on subsequent calls.

    jt

  •      SBW is now in the factory programming MSPs.  Still has the un-documented blocks but it works great!  Added much more granularity in the timing specifications to take advantage for the 62.4nS instruction cycle of my PIC so the bit timing is the same as the MSPFET/Elptronic combo.  Did loop testing of the init function with blank and programmed/running MSPs as well as 0, 1500 and 3300pF on the TDIO (Reset) line:  >2500 cycles in all 6 combinations  for 15K inits with zero failures.

    • C Source:                     http://ppl.ug/IzJykU63V_w/
    • Decoder UI 1.00.02:   http://ppl.ug/xF6W5CoxEOo/
    • Capture/Decode:        http://ppl.ug/7uw5LHOAoBw/

         After I recover, I'll start working on enhancements.

    jt

  •   I have a project that has a MSP 54xx and a MSP430AFE2xx.   I was told by TI there was a software example and tech note slau320 that I could use to program the 2xx with the 54xx.   Unfortunately this is not a "software" example and that it requires a replicator board with some bidirectional hardware ICs (sn74xx45).   currently I have two Texas instrument development boards, one for each processor and no extra hardware.   I have traced through the replicator hardware and determined how the port 5 pins  are brought out to the JTAG header  but when I interconnect the two boards I am unable to successfully program the 2xx chip.  I've tried all 3 modes [jtag, sbwjtag, and sbw] without any success. 

    I believe these bidirectional chips are only needed because of the various programming modes a programmer can go support [4wire or 2wire]. I hope to remove all of the external hardware that the replicator project has and uses.

    I see John was able to use a pic part to program his target without the bidirectional chips.  Has anyone been able to do this with a MSP?  I'm hoping to use the 2 wire spy by wire interface but I'm ready for anything at this point.

    thank you for your time. 

    M.

  • My SBW+ multi-programer is based on MSP430F550x and connected to PC over USB. It is able to flash up to 8 devices, MSP430F5xx or MSP430x2xx, present at bus, at once. I used slau320 as starting point. Don't have any glue logic on board, only few parts needed for chip itself to work.

    http://forum.43oh.com/topic/2972-sbw-msp430f550x-based-programmer

  • zrno soli said:

    My SBW+ multi-programer is based on MSP430F550x and connected to PC over USB. It is able to flash up to 8 devices, MSP430F5xx or MSP430x2xx, present at bus, at once. I used slau320 as starting point. Don't have any glue logic on board, only few parts needed for chip itself to work.

    http://forum.43oh.com/topic/2972-sbw-msp430f550x-based-programmer

    Hi zmo,
    I think I found the source at the top of the 2nd page of that forume but I can not download it.  tried to become a member but I can not get pass the Security Check. tried several time without success.  is there another place I can download your code? 
    thanks
  • MARTY S36411 said:

    Hi zmo,

    I think I found the source at the top of the 2nd page of that forume but I can not download it.  tried to become a member but I can not get pass the Security Check. tried several time without success.  is there another place I can download your code? 
    thanks

    No, it is not open source, and you can't find it anywhere. File on top of the 2nd page is test target firmware used for flashing.

    I just noted that I used slau320 as starting point (software, not hardware). I completely optimized slau320 code, and put it together with fast USB stack (mine, not from TI). It is done completely in assembler and it is fastest flashing tool for MSP430x2xx / MSP430F5xx on planet.

    Don't know about your project target, but if you want to build your own JTAG/SBW tool slau320 is good starting point. Don't make full copy, take just what you need and adapt it as you wish. If you don't want to do this you can use BSL.

  • If you look back into the earlier posts, I linked to my C source code for the PIC.

    jt

  • zrno soli said:

    No, it is not open source, and you can't find it anywhere. File on top of the 2nd page is test target firmware used for flashing.

    I just noted that I used slau320 as starting point (software, not hardware). I completely optimized slau320 code, and put it together with fast USB stack (mine, not from TI). It is done completely in assembler and it is fastest flashing tool for MSP430x2xx / MSP430F5xx on planet.

    sorry zrno, my misunderstanding.    still, thank you for your input.

    zrno soli said:

    Don't know about your project target, but if you want to build your own JTAG/SBW tool slau320 is good starting point. Don't make full copy, take just what you need and adapt it as you wish. If you don't want to do this you can use BSL.

    The BSL was my first choice (done it before) but the MSP430afe2xx MSPs do not support it. How long did it take you to complete you software (just the SBW stuff) from the slau320 base code?  I ask because I've been given 4 days and just need to give management some feedback if this is off
    In my case, I can simplifiy a lot, the MSPF54xx will only be reporgraming one afe2xx that is on the same board.  no protection HW needed. so simpler is better.
     
    I'll have a quick look at John.s PIC code.  it may traslate into my target faster than the current Replicator430's (program anything) code is now.
    Thank you
  • MARTY S36411 said:

    The BSL was my first choice (done it before) but the MSP430afe2xx MSPs do not support it. How long did it take you to complete you software (just the SBW stuff) from the slau320 base code?  I ask because I've been given 4 days and just need to give management some feedback if this is off. 

    In my case, I can simplifiy a lot, the MSPF54xx will only be reporgraming one afe2xx that is on the same board.  no protection HW needed. so simpler is better.

    I done first basic SBW based on slau320, 5 years ago. It was able only to flash MSP430F2xx devices on slow speed, an I use it for MSP430F2012 / MSP430F2013 that don't have BSL. Even I lost some time for translating slau320 code back to assembler (and you don't need to do this), I am afraid that one week is not enough (especially if you are not familiar with MSP430 flashing).

  •      My project was all about the V2 MSP430F5x SBW programming, for which SLAU320 was nearly useless.  The app note and the replicator source code was originally done for the MSP430F2x and 4x V1 devices and worked well enough but when they cut and pasted for V2 they really hosed it.

         The first pass of my V2 programmer used the PIC I/O ports directly with a test device close to the PIC.  The production factory programmers used high current (25mA) gates to drive the cable and fixture parasitics as well as double the recommended maximum reset line capacitance of 1500pF.

         All of the source code as well as the logic analyzer capture/decode data from the MSPFET are linked in previous posts.

**Attention** This is a public forum