Go to Home Page

Stem Cell Project for the bf3Net TCP/IP Stack

 

By Armando Rodriguez for ATG

Introduction:

The current strategy at ATG is to provide its products with a TCP/IP connectivity instead of only USB, GPIB and/or Serial ports (RS232, RS422, RS485, etc.). For this purpose, the hardware will feature a MAC chip (SMSC LAN91C111) and a TCP/IP stack library (bf3Net from Windmill Innovations inc.) for the DSP (TMS320F2812 from Texas Instruments).

 

The library, as such, offers just a TI Algorithm Standard compliant API. This is a pretty raw thing to build an application with, a Stem Cell project is one that:

To start a new project:

 

The TMS230F2812 MAU (Minimum Addressable Unit) is a 16 bit word yet, the bf3Net stack receives, stores and transmits only 8 bit bytes, thus using half of the real storage and processing capabilities of the DSP. Hereon, Kbytes will actually mean Kilo MAU or really twice that capacity in the DSP memory space.

Preliminary Integration to the Hardware

The stack instance is created with the settings entered in the Integration Tool GUI. Theses settings must be reviewed to adapt the stack to the project.  Settings include the DHCP client ID or instance IP address, mask and default gate, in case DHCP is disabled, among others that could also be tweaked.

 

Other settings like the choice for the Engine of working in a TSK (task scheme) of in a SWI, should remain set to SWI. The reason for this choice is that this stem cell project is oriented for working as a command executer.

The queuing of a command takes very little time and must have a higher priory than command processing. A task (TSK obj) runs with the lowest priority; lower than any software interrupt (SWI), so with this choice, command processing must be confined to lower priority tasks. Any functionality triggered by a timer or software interrupt would have to be avoided for it would block the engine notification task.

 

The stem cell project has all bf3Net SWI object set to a higher priory that the command processing SWI (CMDS_swi).

 

When using DHCP, the hostname is the way of addressing the unit, since the leased IP is unknown. The hostname is DHCP extra option 12 and it is not implemented by the integration tool. The generated function BF3NETDHCP_WI_startup() in file bf3net_integrationTool.c must be replaced with the following code changing hostname to whatever this needs to be:

 

XDAS_Void BF3NETDHCP_WI_startup(

IBF3NETDHCPCLNT_Handle dhcpClient,

char *dhcpClientId,

IBF3NETDHCPCLNT_CallBackFxn cb)

{

    char hostname[] = "hostname";

    XDAS_UInt8 optionTxBuffer[32] = {

        12,   // host name option identifyer  

        0,    // host name length

        '\0',};

    // copy the client ID

    strcpy((char *)&optionTxBuffer[2], hostname);

    // set the correct size

    optionTxBuffer[1] = strlen((char *)&optionTxBuffer[2]);

    // provide client ID to the DHCP client instance

    dhcpClient->fxns->dhcpSetClntId(dhcpClient,

(XDAS_UInt8 *)dhcpClientId,

 strlen(dhcpClientId));

    // set the callback function

    dhcpClient->fxns->setCallBack(dhcpClient, cb);

    // Always set IP to 0.0.0.0 when starting DHCP

    netHandle0->fxns->setIpAddr(netHandle0,0);   

    // initiate a DHCP request (no suggested IP address,

//no extra options)

    dhcpClient->fxns->dhcpRequest(dhcpClient, 0, NULL, 0,

      &optionTxBuffer[0], optionTxBuffer[1]+2);

}

Initializes the stack and creates two listen sockets

Calling stackInit(unsigned short portNr ) initializes the stack and opens two sockets:

 

The first is the command port, for receiving commands and transmitting its replies; the second, is for unsolicited data that may be transmitted periodically o whenever some condition is met. This second port can take commands two, but any reply will be transmitted with the first socket.

 

The LED0 will start blinking with a 1 second period until a connection is detect then, the LED will lit permanently.

Implements the RX Circular Buffer and Command Parsing

A circular buffer is implemented and populated upon RX notification. Command synchronization is attained with a 4 byte terminator.  When a terminator is detected, the command is queued and the command pointer incremented to the next location after the terminator.

 

The size of the buffer is 16 Kbytes by default, but could be changed with the define BUF_SIZE in bf3NetCmds.h.

 

Upon RX notification, a reading of the remaining buffer is requested, but generally, only a smaller amount of bytes will be read. If the exact amount is actually read, the end of the buffer has been reach. When this happens the bytes from the current command pointer to the end of the buffer are copied to its beginning and the next bytes will be read into the next location. This way, all the bytes in a command are always contiguous.  So, the buffer is circular only at the command level. For proper operation (to guarantee a non overlap memcpy()), the command size can be no greater that half the buffer size.

 

The default terminator is “@@\r\n”, but there’s basic command that can change this to any set of 4 bytes.

Implements Continuous TX Using 2 Buffers

Two transmission buffers are defined at instance creation; this is consistent with what was set on the bf3Net Integration tool GUI. In order to produce a continuous stream of bytes out the socket, the buffers must alternate. In other words, the DSP fills one buffer while the other is being transmitted. This mechanism is already implemented by the stem cell project and a simple function that takes a buffer of any size is exposed:

 

unsigned short BF3NET_ATG_appWrite( char *txBuf, LgUns txLength).

 

This function returns the same error code as bf3Net socketWrite(), 1 for OK and 0 for error. The transmission will process with same priority as the reception.

Command Queue

 

The host may be handling commands in an asynchronous way; commands may be transmitted from one thread, while the replies from the unit may be received in another. In other words, the host may not be waiting for a reply to send the next command.

 

Implementation of this Stem Cell project must admit this scheme, so the reception of commands should be asynchronous with its processing. Commands are received, their contents stored in the circular buffer described above and as they are parsed, a pointer to the beginning of a command is stored in a 32 level command FIFO.

 

Upon receiving a command a command interpreter SWI (SoftWare Interrupt) with a lesser priority is posted. Once a command is processed and replied, if such is requested, the SWI is re-posted over and over until the command FIFO is exhausted.

 

The size of the command FIFO is 32 by default but could be changed with the define MAX_CMD_QUEUE in bf3NetCmds.h.

Byte Stream to/from Value Conversion Macros

Since TCP/IP streams are byte streams, when sending numbers in binary format, a 16 bit word, for instance, will end up being stored in two addresses; for the DSP to use it as a 16 bit value, they must be moved into a single address in a big Endean format.  The stream transmission order is assume to be from the most significant byte to least significant order.

 

Two macros are provided here to convert 2 and 4 byte streams to 16 and 32 bit values respectively: (ToWORD and ToDWORD). For replying in a byte stream, the macros fromWORD and fromDWORD may be used.

ToWord(x)

Takes a pointer to a 2 "byte" buffer and returns a DSP 16 bit value.

ToDWORD(x)

Takes a pointer to a 2 "byte" buffer and returns a 32 bit DSP value.

FromWORD(x,y)

Takes a pointer to a 16 bit value; returns the high byte in y and low byte in y+1

FromDWORD(x,y)

Takes a pointer to a 32 bit value; returns the highest byte in y, next in y+1 and so on.

 

Basic and Test Command Implementation

Commands and replies can be entirely binary, but then, they must be delivered only from a specially designed host application. For this Stem Cell project though, we have chosen text commands/replies for this basic and testing set that be sent from HyperTerminal.

Basic commands:

Command for changing command termination string

tXXXX<old termination String>

Where XXXX are any four characters (printable or not)

 

Dump the RX buffer:

d<termination String>

 

Clear RX Buffer

c<termination String>

This command could be useful prior to sending a command with size greater than half but less than the buffer must be issued.

 

Verbatim command or reply with the enclosed string.

vxxxxxxxx…<termination String>

Will reply with xxxxxx….

 

The pause command:

p<ms><termination String>

Will delay command processing (not the command reception) for the specified amount of milliseconds. Example P1003@@\r\n will delay the next command in the queue 1 second (using the default termination string. The delay will be rounded off to the nearest ten millisecond multiple.

 

i<unsolicited content><termination string>

The default unsolicited content for transmission through the data socket is “ :)”  is the “ happy face. This command allows setting any content for testing purposes.

 

Command for disabling DHCP and setting a fixed IP

f<IP>,<Gateway IP>,<subnet mask><termination string>

The stem cell project enables the DHCP client protocol should be the factory default. This command sets a fixed 32 bit IP address in an EEPROM. At boot time, this location will be read and if different than zero, then the Stack will be initialized to that address. Issuing this command with address 0.0.0.0 will re-enable the DHCP client protocol.

 

Test Commands

These commands are only good for controlling the LED’s in the bf3Net Starting Kit test board and may be useless in the an actual project board .

 

LED control

L<0-7 led Id>, <1-4 function>, <period><termination String>

 

LED bar control

B<0-100 bar value>< termination String>

The bf3Net Starter Kit features 8 LED’s colored as a audio VU monitoring bar. 0 will lit no LED’s, while 100 o more will lit them all.

 

Animate the Bar ON

A<termination String>

Animate the Bar OFF

a<termination String>

The commands above will show/hide the animated bar that will lit the LED’s one at a time and the switch them all off, repeating this process every 450 ms. Also, the unsolicited content will be transmitted through the data socket.

 

Go to Home Page