SerialSdrv.h
declares the serial driver API and the file SerialVdrv.h
declares the virtual driver API. Both types of drivers also use the SerialDrvr.h
header file. For more information on writing device drivers for the new serial manager, see section Writing a Serial or Virtual Device Driver in the chapter Serial Communication in the Palm OS Programmer's Companion.
DrvrInfoType
structure defines information about the serial hardware. It is passed to and filled in by the
DrvEntryPoint
function for a serial driver and the
DrvEntryPoint
for a virtual driver.
typedef struct {
UInt32 drvrID;
UInt32 drvrVersion;
UInt32 maxBaudRate;
UInt32 handshakeThreshold;
UInt32 portFlags;
Char * portDesc;
DrvrIRQEnum irqType;
UInt8 reserved;
} DrvrInfoType;
drvrID
| 4-character creator type, such as 'u328' |
drvrVersion
|
Version of code that works for this hardware. For this release, all serial drivers should return version kDrvrVersion here.
|
maxBaudRate
| Maximum baud rate supported by this hardware |
handshakeThreshold
| Baud rate at which hardware handshaking is necessary to be used |
portFlags
| Bit flags denoting features of this hardware. The flags are described in Port Feature Constants. |
portDesc
|
Pointer to null-terminated string describing this hardware. This string appears in the Connection panel to describe the port to the user (only if the portCncMgrVisible bit in portFlags is set). Can be NULL if the driver contains a resource (of type 'tSTR' and id kPortDescStrID ) that supplies this string.
|
irqType
|
IRQ line being used for this hardware. Specify one of the DrvrIRQEnum values. For a virtual driver, specify drvrIRQNone .
|
reserved
| Reserved for future use. |
DrvrRcvQType
structure defines the virtual driver receive buffer and function pointers to functions that access and save data to the buffer. A pointer to this structure is passed to the
VdrvOpen
function. The DrvrHWRcvQPtr
type defines a pointer to a DrvrRcvQType
structure.
typedef struct DrvrRcvQType {
void *rcvQ;
WriteByteProcPtr qWriteByte;
WriteBlockProcPtr qWriteBlock;
GetSizeProcPtr qGetSize;
GetSpaceProcPtr qGetSpace;
} DrvrRcvQType;
typedef DrvrRcvQType *DrvrHWRcvQPtr;
DdrvStatusEnum
enumerated type specifies serial status bit flags. Return these enumerated types from the
SdrvStatus
and
VdrvStatus
calls.
typedef enum DrvrStatusEnum {
drvrStatusCtsOn = 0x0001,
drvrStatusRtsOn = 0x0002,
drvrStatusDsrOn = 0x0004,
drvrStatusTxFifoFull = 0x0008,
drvrStatusTxFifoEmpty = 0x0010,
drvrStatusBreakAsserted = 0x0020,
drvrStatusDataReady = 0x0040, // For polling mode debugger only
drvrStatusLineErr = 0x0080 // For polling mode debugger only
} DrvrStatusEnum;
SdrvAPIType
structure defines the function pointers to the required serial driver functions. When passed a pointer to this structure in the
DrvEntryPoint
function, that function must fill in the pointers to the serial driver functions appropriately.
typedef struct {
SdrvOpenProcPtr drvOpen;
SdrvCloseProcPtr drvClose;
SdrvControlProcPtr drvControl;
SdrvStatusProcPtr drvStatus;
SdrvReadCharProcPtr drvReadChar;
SdrvWriteCharProcPtr drvWriteChar;
} SdrvAPIType;
SdrvCtlOpCodeEnum
enumerated type specifies a serial control operation. You should handle each of these enumerated types when passed for the controlCode
parameter to the
SdrvControl
call.
typedef enum SdrvCtlOpCodeEnum {
    sdrvOpCodeNoOp = 0,
    sdrvOpCodeSetBaudRate = 0x1000,
    sdrvOpCodeSetSettingsFlags,
    sdrvOpCodeClearErr,
    sdrvOpCodeEnableUART,
    sdrvOpCodeDisableUART,
    sdrvOpCodeEnableUARTInterrupts,
    sdrvOpCodeDisableUARTInterrupts,
    sdrvOpCodeSetSleepMode,
    sdrvOpCodeSetWakeupMode,
    sdrvOpCodeRxEnable,
    sdrvOpCodeRxDisable,
    sdrvOpCodeLineEnable,
    sdrvOpCodeFIFOCount,
    sdrvOpCodeEnableIRDA,
    sdrvOpCodeDisableIRDA,
    sdrvOpCodeStartBreak,
    sdrvOpCodeStopBreak,
    sdrvOpCodeStartLoopback,
    sdrvOpCodeStopLoopback,
    sdrvOpCodeFlushTxFIFO,
    sdrvOpCodeFlushRxFIFO,
    sdrvOpCodeGetOptTransmitSize,
    sdrvOpCodeEnableRTS,
    sdrvOpCodeDisableRTS,
    sdrvOpCodeUserDef = 0x2000
} SdrvCtlOpCodeEnum;
sdvrOpCodeSetBaudRate
| Sets the baud rate for the UART. |
sdvrOpCodeSetSettingsFlags
| Sets the data transmission options. The bit flags are described in Serial Settings Constants. |
sdvrOpCodeClearError
| Clears the hardware error state. |
sdvrOpCodeEnableUart
| Powers-up the UART and the line-drivers. |
sdvrOpCodeDisableUART
| Powers-down the UART and the line drivers. |
sdvrOpCodeEnableUARTInterrupts
| Enables the appropriate UART receive interrupts. |
sdvrOpCodeDisableUARTInterrupt s
| Disables all UART interrupts. |
sdvrOpCodeSetSleepMode
| Puts the UART in sleep mode. |
sdvrOpCodeSetWakeupMode
| Wakes up the UART from sleep mode. |
sdvrOpCodeRxEnable
| Enables the receive FIFO, enables UART interrupts, and does whatever else is necessary to allow the UART to receive data. |
sdvrOpCodeRxDisable
| Disables the receive FIFO and UART interrupts and does whatever is needed to prevent the UART from receiving data. |
sdvrOpCodeLineEnable
| Enables the main serial line driver for the UART. |
sdvrOpCodeFIFOCount
| Returns the number of bytes currently in the FIFO (or best estimate). |
sdvrOpCodeEnableIRDA
| Enable the IRDA mode and power up the IR line drivers. |
sdvrOpCodeDisableIRDA
| Disable the IRDA mode and disable the IR line drivers. |
sdvrOpCodeStartBreak
| Sends a break character or enables the sending of break characters. |
sdvrOpCodeStopBreak
| Stops sending break characters. |
sdvrOpCodeStartLoopback
| Places the UART in loopback mode. |
sdvrOpCodeStopLoopback
| Stops loopback mode. |
SdrvOpCodeFlushTxFIFO
| Flushes the contents of the transmit FIFO. |
sdrvOpCodeFlushRxFIFO
| Flushes the contents of the receive FIFO. |
sdrvOpCodeGetOptTransmitSize
| Returns the optimum buffer size for sending data or returns 0 to specify any buffer size is acceptable. |
sdrvOpCodeEnableRTS
| Asserts the RTS line. |
sdrvOpCodeDisableRTS
| Deasserts the RTS line. |
sdvrOpCodeUserDef
|
User defined function invoked via SrmControl .
|
VdrvAPIType
structure defines function pointers to the required virtual driver functions. When passed a pointer to this structure in the
DrvEntryPoint
function, that function must fill in the pointers to the virtual driver functions appropriately.
typedef struct {
VdrvOpenProcPtr drvOpen;
VdrvCloseProcPtr drvClose;
VdrvControlProcPtr drvControl;
VdrvStatusProcPtr drvStatus;
VdrvReadProcPtr drvRead;
VdrvWriteProcPtr drvWrite;
} VdrvAPIType;
VdrvCtlOpCodeEnum
enumerated type specifies a serial control operation. You should handle each of these enumerated types when passed for the controlCode
parameter to the
VdrvControl
call.
typedef enum VdrvCtlOpCodeEnum {
    vdrvOpCodeNoOp = 0,
    vdrvOpCodeSetBaudRate = 0x1000,
    vdrvOpCodeSetSettingsFlags,
    vdrvOpCodeSetCtsTimeout,
    vdrvOpCodeClearErr,
    vdrvOpCodeSetSleepMode,
    vdrvOpCodeSetWakeupMode,
    vdrvOpCodeFIFOCount,
    vdrvOpCodeStartBreak,
    vdrvOpCodeStopBreak,
    vdrvOpCodeStartLoopback,
    vdrvOpCodeStopLoopback,
    vdrvOpCodeFlushTxFIFO,
    vdrvOpCodeFlushRxFIFO,
    vdrvOpCodeSendBufferedData,
    vdrvOpCodeRcvCheckIdle,
    vdrvOpCodeEmuSetBlockingHook,
    vdrvOpCodeGetOptTransmitSize,
    vdrvOpCodeGetMaxRcvBlockSize,
    vdrvOpCodeNotifyBytesReadFromQ,
    vdrvOpCodeUserDef = 0x2000
} VdrvCtlOpCodeEnum;
vdvrOpCodeSetBaudRate
| Sets the baud rate. |
vdvrOpCodeSetSettingsFlags
| Sets the data transmission options. The bit flags are described in Serial Settings Constants. |
vdrvOpCodeSetCtsTimeout
| Hardware handshake timeout. |
vdvrOpCodeClearError
| Clears the hardware error state. |
vdvrOpCodeSetSleepMode
| Puts the port in sleep mode (not typically used for virtual drivers). |
vdvrOpCodeSetWakeupMode
| Wakes up the port from sleep mode (not typically used for virtual drivers). |
vdvrOpCodeFIFOCount
| Returns the number of bytes currently in the FIFO (or best estimate). |
vdvrOpCodeStartBreak
| Sends a break character or enables the sending of break characters. |
vdvrOpCodeStopBreak
| Stops sending break characters. |
vdvrOpCodeStartLoopback
| Starts loopback mode (not typically used for virtual drivers). |
vdvrOpCodeStopLoopback
| Stops loopback mode (not typically used for virtual drivers). |
vdrvOpCodeFlushTxFIFO
| Flushes the contents of the transmit FIFO. |
vdrvOpCodeFlushRxFIFO
| Flushes the contents of the receive FIFO. |
vdrvOpCodeSendBufferedData
| Notifies virtual device to send any buffered data it has not emptied from its internal buffers. |
vdrvOpCodeRcvCheckIdle
| Called periodically to allow virtual device time to check if there is data to be received. Because virtual devices execute in the same thread as applications, they can be prevented from handling notifications of received data. |
vdrvOpCodeEmuSetBlockingHook
| Special opCode for the Simulator. |
vdrvOpCodeGetOptTransmitSize
| Returns the optimum buffer size for sending data or returns 0 to specify any buffer size is acceptable. |
vdrvOpCodeGetMaxRcvBlockSize
| Returns the maximum receive block size that the serial manager should request from the virtual device. Can be used to implement flow control. |
vdrvOpCodeNotifyBytesReadFromQ
| Tells the virtual device that some number of bytes have been read from the receive queue by the client application. Can be used to implement flow control. |
vdvrOpCodeUserDef
|
User defined function invoked via SrmControl .
|
Err DrvEntryPoint(DrvrEntryOpCodeEnum opCode, void * uartData)
  |
-> |
Entry function code. |
  |
<-> |
Pointer to data specific to the opCode. |
opCode
parameter. The two possible codes are drvrEntryGetUartFeatures
and drvrEntryGetDrvrFuncts
.
DrvEntryPoint
is called with the drvrEntryGetUartFeatures
code when the new serial manager is installed into the system at boot time and is looking for all UART hardware currently connected to the device. When this opCode is set, the uartData
pointer points to a
DrvrInfoType
structure. This function does not allocate the structure, it just fills in the fields with information.
DrvrInfoType
struct untouched and return a -1 error.
SrmGetDeviceInfo
function. To set this string, copy it into the portDesc
field of the DrvrInfoType
structure. Alternatively, you can supply this string in a driver resource of type 'tSTR' and id kPortDescStrID
.
DrvEntryPoint
is called with the drvrEntryGetDrvrFuncts
code when a serial port is opened. The uartData
pointer points to a
SdrvAPIType
structure and DrvEntryPoint
must fill in the fields of this structure with appropriate function pointers.
Err SdrvClose(SdrvDataPtr drvrDataP)
SdrvOpen
.
SrmControl
function to the level of the hardware.
Err *SdrvControl(SdrvDataPtr drvrDataP, SdrvCtlOpCodeEnum controlCode, void * controlDataP, UInt16 * controlDataLenP)
  |
-> |
Pointer to the driver's private global area. |
  |
-> |
Control function opCode. One of the opCodes listed in the SdrvCtlOpCodeEnum type. |
  |
<-> |
Pointer to data for the specified control function. |
  |
<-> |
Pointer to length of control data being passed in or out. |
SdrvCtlOpCodeEnum
type. If this function does not support an opCode, it must return the serErrNotSupported
error code for that opCode.
controlDataP
and controlDataLenP
parameters for each of the control codes that use them. Control codes not listed do not use these parameters.
sdvrOpCodeSetBaudRate
|
-> controlDataP = Pointer to Int32 (baud rate),
-> controlDataLenP = Pointer to sizeof(Int32) .
|
sdvrOpCodeSetSettingsFlags
|
-> controlDataP = Pointer to UInt32 (bitfield; see Serial Settings Constants)
-> controlDataLenP = Pointer to sizeof(UInt32)
|
sdvrOpCodeFIFOCount
|
-> controlDataP = Pointer to Int16 , which contains the number of bytes in the FIFO.
-> controlDataLenP = Pointer to sizeof(Int16) .
|
sdrvOpCodeGetOptTransmitSize
|
<- controlDataP = Pointer to Int32 ,
<- controlDataLenP = Pointer to sizeof(Int32) .
Return the optimum buffer size for sending data, or 0 to specify any buffer size is acceptable.
|
sdvrOpCodeUserDef
|
<-> controlDataP = Pointer from SrmControl (user-defined data),
<-> controlDataLenP = Pointer to sizeof(Int32) .
|
asm Boolean SdrvISP(UInt32 param: __A0):__D0
true
if this UART has data that needs to be read; return false
if no other interrupt service is needed.
saveDataProc
function (passed into
SdrvOpen
) with the portP pointer as the parameter. The saveDataProc
function, supplied by the new serial manager, handles reading the data from the UART by calling the
SdrvReadChar
function.
SdrvISP
function must be installed in the appropriate IRQ handler by the SdrvOpen
routine.
SdrvOpen
Err SdrvOpen(SdrvDataPtr* drvrDataP, UInt32 baudRate, void * portP, SerialMgrISPProcPtr saveDataProc)
  |
<-> |
Pointer to a pointer to the driver's private global area (allocated by this function). |
  |
-> |
Initial baud rate setting. |
  |
-> |
Pointer to the open port data. |
  |
-> |
Pointer to the function where data received by interrupt is to be saved. The typedef for this function is shown in the Comments section. |
saveDataProc
function:
typedef void (*SerialMgrISPProcPtr)(void * portP:__A0)
SdrvOpen
must perform the following tasks:
GIrq
NGlobalsP
) for every IRQ line in the system. At open time, a serial driver must save its global data in this low memory global because when the interrupt is called there is no way to get the globals through the driver data parameter that the serial manager normally supplies.portP
and saveDataProc
parameters passed to SdrvOpen
in the global variable structure, because they are needed when the SdrvISP
function is called. When the interrupt routine subsequently gets called, the driver gets access to the low memory globals which contain the saveDataProc
function and the portP
pointer. This pointer is passed into the new serial manager, which then calls the driver SdrvReadChar
function in order to read all the bytes and fill its queue.GIrq3GlobalsP
). You can find the IRQ global variables defined in the header file globals.h
.drvrDataP
parameter passed into the SdrvOpen
function. This private global data pointer is passed to every serial driver function so they all have access to the global data.SdrvISP
). For example, the system trap to be patched for IRQ3 is called sysTrapHwrIRQ3Handler
(see SysTraps.h
). Be sure to save the old interrupt handler to be re-installed when DrvClose
is called. Here is an example of how to do this:oldIntHandler = SysGetTrapAddress(sysTrapHwrIRQ3Handler);
SysSetTrapAddress(sysTrapHwrIRQ3Handler, SdrvISP);
SdrvISP
asm UInt16 SdrvReadChar(SdrvDataPtr drvrDataP:__A0):__D0
Int16
value. The returned 16-bit word contains the data byte read from the hardware in the low-order byte. If there is an error, the error code is returned in the low-order byte and the error flag ($80
) is set in the high-order byte.
$80
to mark the low-order byte as an error code and not a readable byte. The error code returned in the low-order byte of D0 should be translated into one of the following four serial manager error codes: serLineErrorBreak
, serLineErrorFraming
, serLineErrorParity
, or serLineErrorHWOverrun
.
SdrvReadChar
executes during interrupt time, and cannot call any OS functions that are normally not allowed to be called during this time. All registers needed for this function should be saved onto the stack (except for D0). The A1 register must not be changed on exit.
UInt16 SdrvStatus(SdrvDataPtr drvrDataP)
DrvrStatusEnum
type.
drvrStatusCtsOn
flag should be set if the UART's CTS line is active. The drvrStatusRtsOn
flag should be set if the RTS line for the UART is currently high. The drvrStatusDsrOn
flag should be set if DSR is turned on. Again, this may not be supported on all UARTs and should be set or cleared based on the type of hardware used. The drvrStatusTxFifoFull
flag is set if the transmit FIFO for the hardware has no available space to receive more data and the flag should be cleared if the transmit FIFO does have available space. And the drvrStatusBreakAsserted
flag should be set if the UART currently has sending break characters enabled.
Err SdrvWriteChar(SdrvDataPtr drvrDataP, UInt8 aChar)
  |
-> |
Pointer to the driver's private global area. |
  |
-> |
Byte of data to be written to the UART. |
Err DrvEntryPoint(DrvrEntryOpCodeEnum opCode, void * uartData)
  |
-> |
Entry function code. |
  |
<-> |
Pointer to data specific to the opCode. |
opCode
parameter. The two possible codes are drvrEntryGetUartFeatures
and drvrEntryGetDrvrFuncts
.
DrvEntryPoint
is called with the drvrEntryGetUartFeatures
code when the new serial manager is installed into the system at boot time and is looking for all installed drivers. When this opCode is set, the uartData
pointer points to a
DrvrInfoType
structure. This function does not allocate the structure, it just fills in the fields with information.
DrvrInfoType
struct untouched and return a -1 error.
SrmGetDeviceInfo
function. To set this string, copy it into the portDesc
field of the DrvrInfoType
structure. Alternatively, you can supply this string in a driver resource of type 'tSTR' and id kPortDescStrID
.
DrvEntryPoint
is called with the drvrEntryGetDrvrFuncts
code when a virtual port is opened. The uartData
pointer points to a
VdrvAPIType
structure and DrvEntryPoint
must fill in the fields of this structure with appropriate function pointers.
Err VdrvClose(VdrvDataPtr drvrDataP)
SrmControl
function to the level of the virtual device.
Err *VdrvControl(VdrvDataPtr drvrDataP, VdrvCtlOpCodeEnum controlCode, void * controlDataP, UInt16 * controlDataLenP)
  |
-> |
Pointer to the driver's private global area. |
  |
-> |
Control function opCode. One of the opCodes listed in the VdrvCtlOpCodeEnum type. |
  |
<-> |
Pointer to data for the specified control function. |
  |
<-> |
Pointer to length of control data being passed in or out. |
VdrvCtlOpCodeEnum
type. If this function does not support an opCode, it must return the serErrNotSupported
error code for that opCode.
controlDataP
and controlDataLenP
parameters for each of the control codes that use them. Control codes not listed do not use these parameters.
vdvrOpCodeSetBaudRate
|
-> controlDataP = Pointer to Int32 (baud rate),
-> controlDataLenP = Pointer to sizeof(Int32) .
|
vdvrOpCodeSetSettingsFlags
|
-> controlDataP = Pointer to UInt32 (bitfield; see Serial Settings Constants)
-> controlDataLenP = Pointer to sizeof(UInt32)
|
vdvrOpCodeFIFOCount
|
-> controlDataP = Pointer to Int16 , which contains the number of bytes in the FIFO.
-> controlDataLenP = Pointer to sizeof(Int16) .
|
vdrvOpCodeGetOptTransmitSize
|
<- controlDataP = Pointer to Int32 (buffer size),
<- controlDataLenP = Pointer to sizeof(Int32) .
Return the optimum buffer size for sending data, or 0 to specify any buffer size is acceptable.
|
vdrvOpCodeGetMaxRcvBlockSize
|
<- controlDataP = Pointer to Int32 (block size),
<- controlDataLenP = Pointer to sizeof(Int32) .
Return the maximum block size that the serial manager should request from the virtual device.
|
vdrvOpCodeNotifyBytesReadFromQ
|
-> controlDataP = Pointer to Int32 (number of bytes read),
-> controlDataLenP = Pointer to sizeof(Int32) .
|
vdvrOpCodeUserDef
|
<-> controlDataP = Pointer from SrmControl (user-defined data),
<-> controlDataLenP = Pointer to sizeof(Int32) .
|
Err VdrvOpen(VdrvDataPtr* drvrDataP, UInt32 baudRate, DrvrHWRcvQPtr rcvQP)
  |
<-> |
Pointer to a pointer to the driver's private global area (allocated by this function). A pointer to this private global area is passed to the other virtual driver functions. |
  |
-> |
Initial baud rate setting. |
  |
-> |
Pointer to the driver's receive queue buffer structure. For details on the fields, see DrvrRcvQType . |
drvrDataP
), do any set-up necessary for communicating with other software, and save the rcvQP
pointer since it will need the functions and pointers to structures enclosed within to be able to save received data into the new serial manager's receive queue.
UInt16 VdrvStatus(VdrvDataPtr drvrDataP)
DrvrStatusEnum
type.
UInt32 VdrvWrite(VdrvDataPtr drvrDataP, void * bufP, UInt32 size, Err* errP)
  |
-> |
Pointer to the driver's private global area. |
  |
-> |
Pointer to buffer containing the data to be written to the virtual device. |
  |
-> |
Number of bytes in the buffer bufP . |
  |
<- |
Pointer to an error code resulting from the operation. Zero is returned if there is no error. |
VdrvOpen
function.
typedef UInt32 (*GetSizeProcPtr)(void * theQ)
typedef UInt32 (*GetSpaceProcPtr)(void * theQ)
typedef Err (*WriteBlockProcPtr)(void * theQ, UInt8 * bufP, UInt16 size, UInt16 lineErrs)
  |
-> |
Pointer to the receive queue. |
  |
-> |
Pointer to the buffer holding bytes for the WriteBlock function. |
  |
-> |
Size of bufP . |
  |
-> |
Any serial line errors received should be reported here. |
typedef Err (*WriteByteProcPtr)(void * theQ, UInt8 theByte, UInt16 lineErrs)
  |
-> |
Pointer to the receive queue. |
  |
-> |
The byte to be written to the queue. |
  |
-> |
Any serial line errors received should be reported here. |
  |   |