Reply by Rick Collins January 4, 20022002-01-04
Keith,

Thanks for the info. I will see if I can get this to work. But I am not
clear about generating a file to feed into this program. I can't find a
FILE2HEX utility with the CC tools. I have a HEX30 utility. Will that do
the job? Can you explain how to use the HEX30 utility to generate the
appropriate format file?

I understand why the serial boot loader "skips" the first two words in the
file. These are used to initialize the memory access when reading from a
boot PROM. The serial port has no need for this. I suspect that you are
really saying that the DSP boot loader does NOT skip these two words if
sent and so the PC must not send them, right?

I don't understand the "dummy" section in your sample hex file. Is this a
result of the FILE2HEX tool? As far as I can tell, there is no reason for
using the dummy section, right? I also noticed that you skip a line when
you read in the file and then skip two lines when you output the serial
stream. Is there a one line text header in the file as well as the two
header words that need to be skipped?

Rick Collins At 10:36 AM 1/4/02, Keith E. Larson wrote:
>Hi Rick
>
>I put togther this example last year showing how to bit bang out the correct
>serial port patterns using the PC printer port data lines as the drivers. I
>did not work out the receive side as I had no intention of porting the DSK
>drivers and debugger, but I suppose it could also be done with a little
>effort.
>
> Serial Booting the VC33 and C31
> from the PC printer port
>
>The following is taken from a message and has not been fully massaged into
>an application note. It took me about 5 hours to slap together the circuit
>and the code, so it may be a little rough on the edges. Never the less it
>works. Note that both the host side and DSP side code are given and that I
>used the DSK tools to generate the HEX file (much much easier to use!). Here
>are some other questions and answers that may come up.
>
> The receiving serial port (bootside) should be inactive when reset
>occurs. This simply means the FSR is inactive as the clock and data are dont
>care unless a frame start is detected.
>
> The serial port boot mode skips over the first two words of a normal boot
>from EPROM file. Dont ask why, its just that way and has been for a very
>long time. Incidentaly, note how stupid it was to even include the bus
>control in the header. This is a memory mapped register and can therefor be
>loaded as a data block. So the bootloader code could have been even simpler!
>
> The send side transmitter should be in the same state as the receiver
>except for the clock edge. Send and receive should use opposite edges
>unless you need to run at very fast rates in a bad environment in which case
>you will need to have some control over the skew. The configuration is
>given in the bootloader source code.
>
> Minimum pulse widths are 2*H when your external sources are synchronous
>to the receiving CPU's master clock. This is a kind of Nyquist limit that
>is imposed by the fact that each pin input is first passed through a set of
>synchronizing latches. If you are not synchronous, you need to be below
>the Nyquist rate. The data sheet shows 2.6*H, but the hard cold truth is
>that this is actualy 2.00001*H ... if the H clock rate is very slow. At
>speed the setup and hold times become significant enough to warrant the 2.6.
>
> PS: The TMX (PG version 1.0 and 1.1) VC33's have a slight problem with
>delays in the serial port that does limit the speed when used at min
>volatage, max speed and high temperature. This wont be a problem for a
>printer port link and is fixed in the production version (PG 1.2) currently
>shipping.
>
> There is no maximum width when configured in this mode since the clock
>is external. All you need to ensure is that the data bit is clean and
>stable at the time the sample is taken. In my code I ran the delay all the
>way to 50ms. This was teadiously slow even for this very short program.
>Please note however that the 'delay()' function has given me some problems
>in WIN98. I dont know exactly whats going on, but I suspect that Windows is
>trying to mis-manage the timers. So... I simply created my own delay the
>old fashioned brute force kind of way.
>
>Serial port receive configuration
>(from bootloader code comments)
> Recieve control: 0x111 (all pins are serial port pins)
> Global control : 0xA300000
>
> RRESET = 1 Reset receive port
> RINT = 1 Enable RINT (will be polled in boot s/w)
> RTINT = 0 Recieve timer off
> RLEN = 3 32 bit
> FSRP = 0 active high
> DRP = 0 active high
> CLKRP = 0 active high
> RFSM = 0 Standard mode (non continuous, use FSX).
> RVAREN = 0 Fixed data rate signaling (Falling edge starts xmit)
> RCLKSRC = 0 External
> RSRFULL = 0 Polling bit
> RRDY = 0 Polling bit >Expected waveform
> ______ _______________
>FSR \_______________________________/////// \___________
> _______ _______ _______ _______ _________ __
>DR XXXXXX__MSB__X_______X_______X__LSB__XXXXXXXXXXXXXXXXX___MSB___X__
> _ ___ ___ ___ ___ ___ ___ ___ ___
>CLKR \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ >Making the connection
>
>The circuit construction I used is quite simple. I simply took a male DB25
>connector and soldered in a 13x2 array of extra long wire wrap posts. I had
>to bend them out a little bit and clip off the 26th contact. I then clipped
>out the posts for D0-D5 leaving a little stub to solder to and replaced them
>with 330 ohm resistors (100 should be even better but I did not have that
>value in my desk drawer). I then used jumper wires with female wire-wrap
>post connectors on each end to make the connections to my test board.
>
>Note: The TMS320VC33 uses Schmidt Hysterisis inputs for all inputs except
>for the data bus. This helps considerably in quality signal reception.
>
>Host Side Code
>
>/*--------------------------------
> Booting a C31/C33 from a printer port
> Keith Larson
> (c) Texas Instruments Inc, 2001
>
> VC33 connections to printer port are as follows. Add a series
> resistor 100-470 ohms in series to prevent accidental buffer
> contention since each of the serial port lines can be configured
> as an output.
>
> D0 - CLKR
> D1 - DR
> D2 - FSR
> D3 - RESET
> D4 - INT3
>
>Note: If you want to create a logic waveform you can modify the
> outport() function to also print in binary to a file or
> screen dump.
>----------------------------------*/
>#include <conio.h>
>#include <stdio.h>
>#include <stdlib.h>
>#include "dsk.h"
>
>#define CLKR (clkr^ 1) // 1 CLKRP
>#define DR (dr ^ 0) // 2 DRP
>#define FSR (fsr ^ 0) // 4 FSRP
>
>ulong boot_data[256];
>uint port = 0x378; // LPT1 data address, 0x278 for LPT2
>int RESET = 1;
>int INT3 = 1;
>int dr, clkr, fsr;
>int dat;
>char buf[82];
>//
>// If this program is to run in a Windows DOS box
>// use this delay instead of the normal delay function
>// There is some kind of bug in WIN98. Apparently in
>// how the timers are interrupted.
>#define DELAY 0 // Try 50+ for very slow!
>void mydelay(int ms);
>void ReadHexFile(ulong *d, char *Name);
>//
>void serial_out(ulong val)
>{
> int s;
> ulong v;
> printf("Sending: %08lx ",val);
> clkr = 0<<0;
> dr = 0<<1;
> fsr = 1<<2; // FSR is active for more than 1 CLKR cycle
> for(s=0;s<2;s++)
> {
> dat = FSR|DR|CLKR; outport(port,0x18|dat); clkr^=1; // Clock twice with
>FSX=1
> }
> mydelay(DELAY);
> for(s1;s>-1;s--)
> {
> fsr = 0<<2; // FSR goes back to inactive on 1st bit
> v=(val>>s)&1;
> dr = (int)v;
> printf("%d",dr);
> dr = dr<<1;
> dat = FSR|DR|CLKR;outport(port,0x18|dat); clkr^=1;
> dat = FSR|DR|CLKR;outport(port,0x18|dat); clkr^=1;
> mydelay(DELAY);
> }
> printf("\n");
>}
>
>void main(void)
>{
> long L,A;
> ulong *sd;
> clrscr();
> ReadHexFile(boot_data, "xf_togl.hex");
> clkr = 0<<0; // clkr is inactive
> dr = 0<<1;
> fsr = 0<<2; // fsr is inactive
> dat = FSR|DR|CLKR; dat|=0x00; outport(port,dat); printf("I=0 R=0
>%04x\n",dat);
> dat = FSR|DR|CLKR; dat|=0x08; outport(port,dat); printf("I=0 R=1
>%04x\n",dat);
> dat = FSR|DR|CLKR; dat|=0x18; outport(port,dat); printf("I=1 R=1
>%04x\n",dat);
> printf("Boot start\n");
> mydelay(DELAY);
> //
> // Now running bootloader in serial mode
> //
> sd = boot_data+2; // skip memwidth and bus_control
> for(;;)
> {
> L = *sd++; // send block length
> serial_out(L); // zero terminates boot
> if(L==0) break; // if zero, done
> A = *sd++; // send block address
> serial_out(A);
> for(;L>0;L--) // send block
> {
> serial_out(*sd++);
> }
> }
> printf("Boot complete\n\n");
>}
>//===================================================
>// If this program is to run in a Windows DOS box
>// use this delay instead of the normal delay function
>// There is some kind of bug in WIN98
>void mydelay(int ms)
>{
> int t;
> for(;ms>0;ms--)
> {
> for(t=0;t<500;t++)
> inport(port+1);
> }
>}
>void ReadHexFile(ulong *d, char *Name)
>{
> int cnt;
> char *c,*eptr;
> FILE *file;
> printf("preparing to read: %s\n",Name);
> file = fopen(Name,"rb");
> if(file==NULL) { printf("cant open %s",Name); exit(1);}
> c = fgets(buf,80,file);
> if(c==NULL) { printf("invalid hex file\n"); exit(1);}
> cnt = 0;
> for(;;)
> {
> c = fgets(buf,80,file);
> if(c==NULL) break;
> *d++ = strtol(buf,&eptr,0);
> cnt++;
> }
> printf("%d lines read\n\n",cnt);
>}
>
>Assembly Code I used for Testing the Bootloader
>
>;***************************************************************
>; XF_TOGL.ASM
>; Keith Larson
>; (c) Texas Instruments Inc, 2001
>;
>; Toggles the XF0 and XF1 pins (and the IACK pin) at the loop
>; rate. Add nops or some other kind of delay to change the
>; pulse rates and widths.
>;
>; NOTE: Avoid 0x809800 and 0x809801 as these locations
>; are used by the bootloader as stack space
>;***************************************************************
> .start "CODE",0x809802
> .sect "CODE"
> .entry MAIN
>MAIN LOPOWER
> ldp @0x808064
> ldi 0x1018,R0
> sti R0,@0x808064
>LOOP1 ldi 1000,RC
> RPTB LOOP2
> ldi 0x22,IOF
> ldi 0x66,IOF
>LOOP2 iack @0x80A000
> b LOOP1
>
>*********** Resulting DSK generated Hex file *********
>FILE2HEX
>0x00000008 Bus Width <- Skip this in SP boot
>0x000010f8 Bus Control ws=7 <- Skip this in SP boot
>0x00000001 Dummy Section size
>0x00809802 Dummy Start Address
>0x00000000 Dummy Data
>0x0000000a Section Size
>0x00809802 Start Address 'CODE'
>0x10800001
>0x50700080
>0x08601018
>0x15208064
>0x087b03e8
>0x6480980a
>0x08780022
>0x08780066
>0x1b20a000
>0x6a00fffa
>0x00000000 Terminate Load >Anyone had experience with booting a C31 DSP via the DSP serial port?
>Specifically I am looking for PC code to control parallel port IO lines
>under Windows 95 to let me boot a DSP in order to program the flash on the
>board.
>
>We had been doing this via the emulator, but the pod just quit. Rather than
>continue doing it this way, I would rather put the effort into getting the
>boards up via the DSP serial port. The emulator GEL scripts never worked
>very well. They would sometimes run correctly and sometimes not.
>
>I have code to run on the DSP to let me program the flash if I can get the
>program into the ram on board.
>
>Rick Collins
Rick Collins
Arius - A Signal Processing Solutions Company
Specializing in DSP and FPGA design http://www.arius.com
4 King Ave 301-682-7772 Voice
Frederick, MD 21701-3110 301-682-7666 FAX