<< Previous | Index | Next >> | |
|
The Rabbit 2000 and the Rabbit 3000 have hardware for a slave port, allowing a master controller to read and write certain internal registers on the Rabbit. The library,
Slaveport.lib
, implements a complete master/slave protocol for the Rabbit slave port. Sample libraries,Master_serial.lib
andSp_stream.lib
provide serial port and stream-based communication handlers using the slave port protocol.7.1 Slave Port Driver Protocol
Given the variety of embedded system implementations, the protocol for the slave port driver was designed to make the software for the master controller as simple as possible. Each interaction between the master and the slave is initiated by the master. The master has complete control over when data transfers occur and can expect single, immediate responses from the slave.
7.1.1 Overview
Master writes to the command register after setting the address register and, optionally, the data register. These registers are internal to the slave.
Slave reads the registers that were written by the master.
Slave writes to command response register after optionally setting the data register. This also causes the SLAVEATTN line on the Rabbit slave to be pulled low.
Master reads response and data registers.
Master writes to the slave port status register to clear interrupt line from the slave.
7.1.2 Registers on the Slave
From the point of view of the master, the slave is an I/O device with four register addresses.
Accessing the same address (0, 1 or 2) uses two different registers, depending on whether the access was a read or a write. In other words, when writing to address 0, the master accesses a different location than when the it reads address 0.
The status port is a bit field showing which slave port registers have been updated. For the purposes of this protocol. Only bit 3 needs to be examined. After sending a command, the master can check bit 3, which is set when the slave writes to the response register. At this point the response and returned data are valid and should be read before sending a new command. Performing a dummy write to the status register will clear this bit, so that it can be set by the next response.
Pin assignments for both the Rabbit 2000 and the Rabbit 3000 acting as a slave are as follows:
For more details and read/write signal timing see the Rabbit 2000 Microprocessor User's Manual or the Rabbit 3000 Microprocessor User's Manual.
7.1.3 Polling and Interrupts
Both the slave and the master can use interrupt or polling for the slave. The parameter passed to
SPinit()
determines which one is used. In interrupt mode, the developer can indicate whether the handler functions for the channels are interruptible or non-interruptible.7.1.4 Communication Channels
The Rabbit slave has 256 configurable channels available for communication. The developer must provide a handler function for each channel that is used. Some basic handlers are available in the library
Slave_Port.lib
. These handlers will be discussed later in this chapter.When the slave port driver is initialized, a callback table of handler functions is set up. Handler functions are added to the callback table by
SPsetHandler()
.7.2 Functions
Slave_port.lib
provides the following functions:
int SPinit ( int mode );
Description
- This function initializes the slave port driver. It sets up the callback tables for the different channels. The slave port driver can be run in either polling mode where
SPtick()
must be called periodically, or in interrupt mode where an ISR is triggered every time the master sends a command. There are two version of interrupt mode. In the first, interrupts are reenabled while the handler function is executing. In the other, the handler function will execute at the same interrupt priority as the driver ISR.Parameters
- mode
0
: For polling1
: For interrupt driven (interruptible handler functions)2
: For interrupt driven (non-interruptible handler functions)Return value
1
: Success0
: FailureLibrary
- SLAVE_PORT.LIB
int SPsetHandler ( char address, int (*handler)(), void *handler_params);
Description
- This function sets up a handler function to process incoming commands from the master for a particular slave port address.
Parameters
- address
The 8-bit slave port address of the channel that corresponds to the handler function.
- handler
Pointer to the handler function. This function must have a particular form, which is described by the function description for
MyHandler()
shown below. Setting this parameter toNULL
unloads the current handler.- handler_params
Pointer that will be saved and passed to the handler function each time it is called. This allows the handler function to be parameterized for multiple cases.
Return value
1
: Success, the handler was set.0
: Failure.Library
- SLAVE_PORT.LIB
int MyHandler ( char command, char data_in, void *params );
Description
- This function is a developer-supplied function and can have any valid Dynamic C name. Its purpose is to handle incoming commands from a master to one of the 256 channels on the slave port. A handler function must be supplied for every channel that is being used on the slave port.
Parameters
- command
This is the received command byte.
- data_in
The optional data byte
- params
The optional parameters pointer.
Return value
- This function must return an integer. The low byte must contains the response code and the high byte contains the returned data, if there is any.
Library
- This is a developer-supplied function.
void SPtick ( void );
Description
- This function must be called periodically when the slave port is used in polling mode.
Library
- SLAVE_PORT.LIB
void SPclose( void );
Description
- This function disables the slave port driver and unloads the ISR if one was used.
Library
- SLAVE_PORT.LIB
7.3 Examples
The rest of the chapter describes some useful handlers.
7.3.1 Status Handler
SPstatusHandler()
, available inSlave_port.lib
, is an example of a simple handler to report the status of the slave. To set up the function as a handler on slave port address 12, do the following:SPsetHandler (12, SPstatusHandler, &status_char);
Sending any command to this handler will cause it to respond with a
1
in the response register and the current value ofstatus_char
in the data return register.7.3.2 Serial Port Handler
Slave_port.lib
contains handlers for all four serial ports on the slave.Master_serial.lib
contains code for a master using the slave's serial port handler. This library illustrates the general case of implementing the master side of the master/slave protocol.7.3.2.1 Commands to the Slave
7.3.2.2 Slave Side of Protocol
To set up the serial port handler to connect serial port A to channel 5 , do the following:
SPsetHandler (5, SPserAhandler, NULL);
7.3.2.3 Master Side of Protocol
The following functions are in
Master_serial.lib
. They are for a master using a serial port handler on a slave.
int cof_MSgetc(char address);
Description
- Yields to other tasks until a byte is received from the serial port on the slave.
Parameters
- address
Slave channel address of the serial handler.
Return value
- Value of the received character on success.
-1
: Failure.Library
- MASTER_SERIAL.LIB
void cof_MSputc(char address, char ch);
Description
- Sends a character to the serial port. Yields until character is sent.
Parameters
- address
Slave channel address of serial handler.
- ch
Character to send.
Return value
0
: Success, character was sent.-1
: Failure, character was not sent.
Library
- MASTER_SERIAL.LIB
int cof_MSread(char address, char *buffer, int length, unsigned long timeout);
Description
- Reads bytes from the serial port on the slave into the provided buffer. Waits until at least one character has been read. Returns after buffer is full, or
timeout
has expired between reading bytes. Yields to other tasks while waiting for data.Parameters
- address
Slave channel address of serial handler.
- buffer
Buffer to store received bytes.
- length
Size of buffer.
- timeout
Time to wait between bytes before giving up on receiving anymore.
Return value
>0
: Bytes read.-1
: Failure.Library
- MASTER_SERIAL.LIB
int cof_MSwrite(char address, char *data, int length);
Description
- Transmits an array of bytes from the serial port on the slave. Yields to other tasks while waiting for write buffer to clear.
Parameters
- address
Slave channel address of serial handler.
- data
Array to be transmitted.
- length
Size of array.
Return value
- Number of bytes actually written or
-1
if error.Library
- MASTER_SERIAL.LIB
int MSclose(char address);
Description
- Closes a serial port on the slave.
Parameters
- address
Slave channel address of serial handler.
Return value
0
: Success.-1
: Failure.Library
- MASTER_SERIAL.LIB
int MSgetc(char address);
Description
- Receives a character from the serial port.
Parameters
- address
Slave channel address of serial handler.
Return value
- Value of received character.
-1
: No character available.Library
- MASTER_SERIAL.LIB
int MSgetError(char address);
Description
- Gets bitfield with any current error from the specified serial port on the slave. Error codes are:
SER_PARITY_ERROR
0x01SER_OVERRUN_ERROR
0x02Parameters
- address
Slave channel address of serial handler.
Return value
- Number of bytes free: Success.
-1
: Failure.Library
- MASTER_SERIAL.LIB
int MSinit(int io_bank);
Description
- Sets up the connection to the slave.
Parameters
- io_bank
The IO bank and chip select pin number for the slave device. This is a number from 0 to 7 inclusive.
Return value
1
: Success.Library
- MASTER_SERIAL.LIB
int MSopen(char address, unsigned long baud);
Description
- Opens a serial port on the slave, given that there is a serial handler at the specified address on the slave.
Parameters
- address
Slave channel address of serial handler.
baud
Baud rate for the serial port on the slave.
Return value
1
: Baud rate used matches the argument.0
: Different baud rate is being used.-1
: Slave port comm error occurred.
Library
- MASTER_SERIAL.LIB
int MSputc(char address, char ch);
Description
- Transmits a single character through the serial port.
Parameters
- address
Slave channel address of serial handler.
- ch
Character to send.
Return value
1
: Character sent.0
: Transmit buffer is full or locked.Library
- MASTER_SERIAL.LIB
int MSrdFree(char address);
Description
- Gets the number of bytes available in the specified serial port read buffer on the slave.
Parameters
- address
Slave channel address of serial handler.
Return value
- Number of bytes free: Success.
-1
: Failure.Library
- MASTER_SERIAL.LIB
int MSsendCommand(char address, char command, char data, char *data_returned, unsigned long timeout);
Description
- Sends a single command to the slave and gets a response. This function also serves as a general example of how to implement the master side of the slave protocol.
Parameters
- address
Slave channel address to send command to.
- command
Command to be sent to the slave (see Section 7.3.2.1).
- data
Data byte to be sent to the slave.
- data_returned
Address of variable to place data returned by the slave.
- timeout
Time to wait before giving up on slave response.
Return Value
≥
0
: Response code.-1
: Timeout occured before response.-2
: Nothing at that address (response = 0xff).Library
- MASTER_SERIAL.LIB
int MSread(char address, char *buffer, int size, unsigned long timeout);
Description
- Receives bytes from the serial port on the slave.
Parameters
- address
Slave channel address of serial handler.
- buffer
Array to put received data into.
- size
Size of array (max bytes to be read).
- timeout
Time to wait between characters before giving up on receiving any more.
Return value
- The number of bytes read into the buffer (behaves like
serXread()
).Library
- MASTER_SERIAL.LIB
int MSwrFree(char address)
Description
- Gets the number of bytes available in the specified serial port write buffer on the slave.
Parameters
- address
Slave channel address of serial handler.
Return value
- Number of bytes free: Success.
-1
: Failure.Library
- MASTER_SERIAL.LIB
int MSwrite(char address, char *data, int length);
Description
- Sends an array of bytes out the serial port on the slave (behaves like
serXwrite()
).Parameters
- address
Slave channel address of serial handler.
- data
Array of bytes to send.
- length
Size of array.
Return value
- Number of bytes actually sent.
Library
- MASTER_SERIAL.LIB
7.3.2.4 Sample Program for Master
This sample program,
/Samples/SlavePort/master_demo.c
, treats the slave like a serial port.#use "master_serial.lib"
#define SP_CHANNEL 0x42
char* const test_str = "Hello There";
main(){
char buffer[100];
int read_length;MSinit(0);
// comment this line out if talking to a stream handler
printf("open returned:0x%x\n", MSopen(SP_CHANNEL, 9600));while(1)
{
costate
{
wfd{cof_MSwrite(SP_CHANNEL, test_str, strlen(test_str));}
wfd{cof_MSwrite(SP_CHANNEL, test_str, strlen(test_str));}
}
costate
{
wfd{ read_length = cof_MSread(SP_CHANNEL, buffer, 99, 10); }
if(read_length > 0)
{
buffer[read_length] = 0; //null terminator
printf("Read:%s\n", buffer);
}
else if(read_length < 0)
{
printf("Got read error: %d\n", read_length);
}
printf("wrfree = %d\n", MSwrFree(SP_CHANNEL));
}
}
}7.3.3 Byte Stream Handler
The library,
SP_STREAM.LIB
, implements a byte stream over the slave port. If the master is a Rabbit, the functions inMASTER_SERIAL.LIB
can be used to access the stream as though it came from a serial port on the slave.7.3.3.1 Slave Side of Stream Channel
To set up the function
SPShandler()
as the byte stream handler, do the following:SPsetHandler (10, SPShandler, stream_ptr);
This sets up the stream to use channel 10 on the slave.
A sample program in Section 7.3.3.2 shows how to set up and initialize the circular buffers. An internal data structure,
SPStream
, keeps track of the buffers and a pointer to it is passed toSPsetHandler()
and some of the auxiliary functions that supports the byte stream handler. This is also shown in the sample program.7.3.3.1.1 Functions
These are the auxiliary functions that support the stream handler function,
SPShandler()
.
void cbuf_init(char *circularBuffer, int dataSize);
Description
- This function initializes a circular buffer.
Parameters
- circularBuffer
The circular buffer to initialize.
- dataSize
Size available to data. The size must be 9 bytes more than the number of bytes needed for data. This is for internal book-keeping.
Library
- RS232.LIB
int cof_SPSread(SPStream *stream, void *data, int length, unsigned long tmout);
Description
- Reads
length
bytes from the slave port input buffer or untiltmout
milliseconds transpires between bytes after the first byte is read. It will yield to other tasks while waiting for data. This function is non-reentrant.Parameters
- stream
Pointer to the stream state structure.
- data
Structure to read from slave port buffer.
- length
Number of bytes to read.
- tmout
Maximum wait in milliseconds for any byte from previous one.
Return value
- The number of bytes read from the buffer.
Library
- SP_STREAM.LIB
int cof_SPSwrite(SPStream *stream, void *data, int length);
Description
- Transmits
length
bytes to slave port output buffer.This function is non-reentrant.Parameters
- stream
Pointer to the stream state structure.
- data
Structure to write to slave port buffer.
- length
Number of bytes to write.
Return value
- The number of bytes successfully written to slave port.
Library
- SP_STREAM.LIB
void SPSinit( void );
Description
- Initializes the circular buffers used by the stream handler.
Library
- SP_STREAM.LIB
int SPSread(SPStream *stream, void *data, int length, unsigned long tmout);
Description
- Reads
length
bytes from the slave port input buffer or untiltmout
milliseconds transpires between bytes. If no data is available when this function is called, it will return immediately. This function will callSPtick()
if the slave port is in polling mode.- This function is non-reentrant.
Parameters
- stream
Pointer to the stream state structure.
- data
Buffer to read received data into.
- length
Maximum number of bytes to read.
- tmout
Time to wait between received bytes before returning.
Return value
- Number of bytes read into the data buffer
Library
- SP_STREAM.LIB
int SPSwrite(SPSream *stream, void *data, int length)
Description
- This function transmits length bytes to slave port output buffer. If the slave port is in polling mode, this function will call
SPtick()
while waiting for the output buffer to empty. This function is non-reentrant.Parameters
- stream
Pointer to the stream state structure.
- data
Bytes to write to stream.
- length
Size of write buffer.
Return value
- Number of bytes written into the data buffer.
Library
- SP_STREAM.LIB
int SPSwrFree();
Description
- Returns number of free bytes in the stream write buffer.
Return value
- Space available in the stream write buffer.
Library
- SP_STREAM.LIB
int SPSrdFree();
Description
- Returns the number of free bytes in the stream read buffer.
Return value
- Space available in the stream read buffer.
Library
- SP_STREAM.LIB
int SPSwrUsed();
Description
- Returns the number of bytes currently in the stream write buffer.
Return value
- Number of bytes currently in the stream write buffer.
Library
- SP_STREAM.LIB
int SPSrdUsed();
Description
- Returns the number of bytes currently in the stream read buffer.
Return value
- Number of bytes currently in the stream read buffer.
Library
- SP_STREAM.LIB
7.3.3.2 Byte Stream Sample Program
This program,
/Samples/SlavePort/Slave_Demo.c
, runs on a slave and implements a byte stream over the slave port.#class auto
#use "slave_port.lib"
#use "sp_stream.lib"#define STREAM_BUFFER_SIZE 31
main()
{
char buffer[10];
int bytes_read;SPStream stream;
// Circular buffers need 9 bytes for bookkeeping.
char stream_inbuf[STREAM_BUFFER_SIZE + 9];
char stream_outbuf[STREAM_BUFFER_SIZE + 9];SPStream *stream_ptr;
// setup buffers
cbuf_init(stream_inbuf, STREAM_BUFFER_SIZE);
stream.inbuf = stream_inbuf;
cbuf_init(stream_outbuf, STREAM_BUFFER_SIZE);
stream.outbuf = stream_outbuf;stream_ptr = &stream;
SPinit(1);
SPsetHandler(0x42, SPShandler, stream_ptr);
while(1)
{
bytes_read = SPSread(stream_ptr, buffer, 10, 10);
if(bytes_read)
{
SPSwrite(stream_ptr, buffer, bytes_read);
}
}
}
| |
<< Previous | Index | Next >> | |
Z-World, Inc. www.zworld.com Phone: 1.530.757.3737 Fax: 1.530.757.3792 |
Rabbit Semiconductor www.rabbitsemiconductor.com Phone: 1.530.757.8400 Fax: 1.530.757.8402 |