ChibiOS/RT
2.5.1
Serial Driver
Collaboration diagram for Serial Driver:

Detailed Description

Generic Serial Driver.

This module implements a generic full duplex serial driver. The driver implements a SerialDriver interface and uses I/O Queues for communication between the upper and the lower driver. Event flags are used to notify the application about incoming data, outgoing data and other I/O events.
The module also contains functions that make the implementation of the interrupt service routines much easier.

Precondition:
In order to use the SERIAL driver the HAL_USE_SERIAL option must be enabled in halconf.h.

Driver State Machine

The driver implements a state machine internally, not all the driver functionalities can be used in any moment, any transition not explicitly shown in the following diagram has to be considered an error and shall be captured by an assertion (if enabled).

dot_inline_dotgraph_3.png

Data Structures

struct  SerialDriverVMT
 SerialDriver virtual methods table. More...
struct  SerialDriver
 Full duplex serial driver class. More...
struct  SerialConfig
 Generic Serial Driver configuration structure. More...

Functions

void sdInit (void)
 Serial Driver initialization.
void sdObjectInit (SerialDriver *sdp, qnotify_t inotify, qnotify_t onotify)
 Initializes a generic full duplex driver object.
void sdStart (SerialDriver *sdp, const SerialConfig *config)
 Configures and starts the driver.
void sdStop (SerialDriver *sdp)
 Stops the driver.
void sdIncomingDataI (SerialDriver *sdp, uint8_t b)
 Handles incoming data.
msg_t sdRequestDataI (SerialDriver *sdp)
 Handles outgoing data.
 CH_IRQ_HANDLER (17)
 IRQ 17 service routine.
 CH_IRQ_HANDLER (18)
 IRQ 18 service routine.
 CH_IRQ_HANDLER (20)
 IRQ 20 service routine.
 CH_IRQ_HANDLER (21)
 IRQ 21 service routine.
void sd_lld_init (void)
 Low level serial driver initialization.
void sd_lld_start (SerialDriver *sdp, const SerialConfig *config)
 Low level serial driver configuration and (re)start.
void sd_lld_stop (SerialDriver *sdp)
 Low level serial driver stop.

Variables

SerialDriver SD1
 UART1 serial driver identifier.
SerialDriver SD2
 UART2 serial driver identifier.
SerialDriver SD3
 UART3 serial driver identifier.

Serial status flags

#define SD_PARITY_ERROR   32
 Parity error happened.
#define SD_FRAMING_ERROR   64
 Framing error happened.
#define SD_OVERRUN_ERROR   128
 Overflow happened.
#define SD_NOISE_ERROR   256
 Noise on the line.
#define SD_BREAK_DETECTED   512
 Break detected.

Serial configuration options

#define SERIAL_DEFAULT_BITRATE   38400
 Default bit rate.
#define SERIAL_BUFFERS_SIZE   16
 Serial buffers size.

Macro Functions

#define sdPutWouldBlock(sdp)   chOQIsFullI(&(sdp)->oqueue)
 Direct output check on a SerialDriver.
#define sdGetWouldBlock(sdp)   chIQIsEmptyI(&(sdp)->iqueue)
 Direct input check on a SerialDriver.
#define sdPut(sdp, b)   chOQPut(&(sdp)->oqueue, b)
 Direct write to a SerialDriver.
#define sdPutTimeout(sdp, b, t)   chOQPutTimeout(&(sdp)->oqueue, b, t)
 Direct write to a SerialDriver with timeout specification.
#define sdGet(sdp)   chIQGet(&(sdp)->iqueue)
 Direct read from a SerialDriver.
#define sdGetTimeout(sdp, t)   chIQGetTimeout(&(sdp)->iqueue, t)
 Direct read from a SerialDriver with timeout specification.
#define sdWrite(sdp, b, n)   chOQWriteTimeout(&(sdp)->oqueue, b, n, TIME_INFINITE)
 Direct blocking write to a SerialDriver.
#define sdWriteTimeout(sdp, b, n, t)   chOQWriteTimeout(&(sdp)->oqueue, b, n, t)
 Direct blocking write to a SerialDriver with timeout specification.
#define sdAsynchronousWrite(sdp, b, n)   chOQWriteTimeout(&(sdp)->oqueue, b, n, TIME_IMMEDIATE)
 Direct non-blocking write to a SerialDriver.
#define sdRead(sdp, b, n)   chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_INFINITE)
 Direct blocking read from a SerialDriver.
#define sdReadTimeout(sdp, b, n, t)   chIQReadTimeout(&(sdp)->iqueue, b, n, t)
 Direct blocking read from a SerialDriver with timeout specification.
#define sdAsynchronousRead(sdp, b, n)   chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_IMMEDIATE)
 Direct non-blocking read from a SerialDriver.

Defines

#define _serial_driver_methods   _base_asynchronous_channel_methods
 SerialDriver specific methods.
#define SD_MODE_PARITY   0x07
 Parity field mask.
#define SD_MODE_PARITY_NONE   0x00
 No parity.
#define SD_MODE_PARITY_EVEN   0x05
 Even parity.
#define SD_MODE_PARITY_ODD   0x07
 Odd parity.
#define SD_MODE_STOP   0x30
 Stop bits mask.
#define SD_MODE_STOP_1   0x00
 One stop bit.
#define SD_MODE_STOP_2   0x20
 Two stop bits.
#define SD_MODE_STOP_1P5   0x30
 1.5 stop bits.
#define STM8S_SERIAL_USE_UART1   TRUE
 UART1 driver enable switch.
#define STM8S_SERIAL_USE_UART2   TRUE
 UART2 driver enable switch.
#define STM8S_SERIAL_USE_UART3   TRUE
 UART3 driver enable switch.
#define _serial_driver_data
 SerialDriver specific data.
#define BRR(b)   (SYSCLK / (b))
 Macro for baud rate computation.

Typedefs

typedef struct SerialDriver SerialDriver
 Structure representing a serial driver.

Enumerations

enum  sdstate_t { SD_UNINIT = 0, SD_STOP = 1, SD_READY = 2 }
 Driver state machine possible states. More...

Function Documentation

void sdInit ( void  )

Serial Driver initialization.

Note:
This function is implicitly invoked by halInit(), there is no need to explicitly initialize the driver.
Function Class:
Initializer, this function just initializes an object and can be invoked before the kernel is initialized.

Definition at line 113 of file serial.c.

References sd_lld_init().

Referenced by halInit().

Here is the call graph for this function:

void sdObjectInit ( SerialDriver sdp,
qnotify_t  inotify,
qnotify_t  onotify 
)

Initializes a generic full duplex driver object.

The HW dependent part of the initialization has to be performed outside, usually in the hardware initialization code.

Parameters:
[out]sdppointer to a SerialDriver structure
[in]inotifypointer to a callback function that is invoked when some data is read from the Queue. The value can be NULL.
[in]onotifypointer to a callback function that is invoked when some data is written in the Queue. The value can be NULL.
Function Class:
Initializer, this function just initializes an object and can be invoked before the kernel is initialized.

Definition at line 133 of file serial.c.

References SD_STOP, SERIAL_BUFFERS_SIZE, and SerialDriver::vmt.

Referenced by sd_lld_init().

void sdStart ( SerialDriver sdp,
const SerialConfig config 
)

Configures and starts the driver.

Parameters:
[in]sdppointer to a SerialDriver object
[in]configthe architecture-dependent serial driver configuration. If this parameter is set to NULL then a default configuration is used.
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 152 of file serial.c.

References sd_lld_start(), SD_READY, and SD_STOP.

Here is the call graph for this function:

void sdStop ( SerialDriver sdp)

Stops the driver.

Any thread waiting on the driver's queues will be awakened with the message Q_RESET.

Parameters:
[in]sdppointer to a SerialDriver object
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 174 of file serial.c.

References sd_lld_stop(), SD_READY, and SD_STOP.

Here is the call graph for this function:

void sdIncomingDataI ( SerialDriver sdp,
uint8_t  b 
)

Handles incoming data.

This function must be called from the input interrupt service routine in order to enqueue incoming data and generate the related events.

Note:
The incoming data event is only generated when the input queue becomes non-empty.
In order to gain some performance it is suggested to not use this function directly but copy this code directly into the interrupt service routine.
Parameters:
[in]sdppointer to a SerialDriver structure
[in]bthe byte to be written in the driver's Input Queue
Function Class:
This is an I-Class API, this function can be invoked from within a system lock zone by both threads and interrupt handlers.

Definition at line 206 of file serial.c.

References SD_OVERRUN_ERROR.

Referenced by CH_IRQ_HANDLER().

msg_t sdRequestDataI ( SerialDriver sdp)

Handles outgoing data.

Must be called from the output interrupt service routine in order to get the next byte to be transmitted.

Note:
In order to gain some performance it is suggested to not use this function directly but copy this code directly into the interrupt service routine.
Parameters:
[in]sdppointer to a SerialDriver structure
Returns:
The byte value read from the driver's output queue.
Return values:
Q_EMPTYif the queue is empty (the lower driver usually disables the interrupt source when this happens).
Function Class:
This is an I-Class API, this function can be invoked from within a system lock zone by both threads and interrupt handlers.

Definition at line 232 of file serial.c.

Referenced by CH_IRQ_HANDLER().

CH_IRQ_HANDLER ( 17  )

IRQ 17 service routine.

Function Class:
Interrupt handler, this function should not be directly invoked.

Definition at line 229 of file serial_lld.c.

References sdRequestDataI().

Here is the call graph for this function:

CH_IRQ_HANDLER ( 18  )

IRQ 18 service routine.

Function Class:
Interrupt handler, this function should not be directly invoked.

Definition at line 250 of file serial_lld.c.

References sdIncomingDataI().

Here is the call graph for this function:

CH_IRQ_HANDLER ( 20  )

IRQ 20 service routine.

Function Class:
Interrupt handler, this function should not be directly invoked.

Definition at line 272 of file serial_lld.c.

References sdRequestDataI().

Here is the call graph for this function:

CH_IRQ_HANDLER ( 21  )

IRQ 21 service routine.

Function Class:
Interrupt handler, this function should not be directly invoked.

Definition at line 293 of file serial_lld.c.

References sdIncomingDataI().

Here is the call graph for this function:

void sd_lld_init ( void  )

Low level serial driver initialization.

Function Class:
Not an API, this function is for internal use only.

Definition at line 361 of file serial_lld.c.

References sdObjectInit().

Referenced by sdInit().

Here is the call graph for this function:

void sd_lld_start ( SerialDriver sdp,
const SerialConfig config 
)

Low level serial driver configuration and (re)start.

Parameters:
[in]sdppointer to a SerialDriver object
[in]configthe architecture-dependent serial driver configuration. If this parameter is set to NULL then a default configuration is used.
Function Class:
Not an API, this function is for internal use only.

Definition at line 392 of file serial_lld.c.

Referenced by sdStart().

void sd_lld_stop ( SerialDriver sdp)

Low level serial driver stop.

De-initializes the USART, stops the associated clock, resets the interrupt vector.

Parameters:
[in]sdppointer to a SerialDriver object
Function Class:
Not an API, this function is for internal use only.

Definition at line 426 of file serial_lld.c.

Referenced by sdStop().


Variable Documentation

UART1 serial driver identifier.

Definition at line 42 of file serial_lld.c.

UART2 serial driver identifier.

Definition at line 49 of file serial_lld.c.

UART3 serial driver identifier.

Definition at line 56 of file serial_lld.c.


Define Documentation

#define SD_PARITY_ERROR   32

Parity error happened.

Definition at line 42 of file serial.h.

#define SD_FRAMING_ERROR   64

Framing error happened.

Definition at line 43 of file serial.h.

#define SD_OVERRUN_ERROR   128

Overflow happened.

Definition at line 44 of file serial.h.

Referenced by sdIncomingDataI().

#define SD_NOISE_ERROR   256

Noise on the line.

Definition at line 45 of file serial.h.

#define SD_BREAK_DETECTED   512

Break detected.

Definition at line 46 of file serial.h.

#define SERIAL_DEFAULT_BITRATE   38400

Default bit rate.

Configuration parameter, this is the baud rate selected for the default configuration.

Definition at line 63 of file serial.h.

#define SERIAL_BUFFERS_SIZE   16

Serial buffers size.

Configuration parameter, you can change the depth of the queue buffers depending on the requirements of your application.

Note:
The default is 16 bytes for both the transmission and receive buffers.

Definition at line 74 of file serial.h.

Referenced by sdObjectInit().

#define _serial_driver_methods   _base_asynchronous_channel_methods

SerialDriver specific methods.

Definition at line 109 of file serial.h.

#define sdPutWouldBlock (   sdp)    chOQIsFullI(&(sdp)->oqueue)

Direct output check on a SerialDriver.

Note:
This function bypasses the indirect access to the channel and checks directly the output queue. This is faster but cannot be used to check different channels implementations.
See also:
chIOPutWouldBlock()
Deprecated:
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 153 of file serial.h.

#define sdGetWouldBlock (   sdp)    chIQIsEmptyI(&(sdp)->iqueue)

Direct input check on a SerialDriver.

Note:
This function bypasses the indirect access to the channel and checks directly the input queue. This is faster but cannot be used to check different channels implementations.
See also:
chIOGetWouldBlock()
Deprecated:
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 166 of file serial.h.

#define sdPut (   sdp,
 
)    chOQPut(&(sdp)->oqueue, b)

Direct write to a SerialDriver.

Note:
This function bypasses the indirect access to the channel and writes directly on the output queue. This is faster but cannot be used to write to different channels implementations.
See also:
chIOPut()
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 178 of file serial.h.

#define sdPutTimeout (   sdp,
  b,
 
)    chOQPutTimeout(&(sdp)->oqueue, b, t)

Direct write to a SerialDriver with timeout specification.

Note:
This function bypasses the indirect access to the channel and writes directly on the output queue. This is faster but cannot be used to write to different channels implementations.
See also:
chIOPutTimeout()
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 190 of file serial.h.

#define sdGet (   sdp)    chIQGet(&(sdp)->iqueue)

Direct read from a SerialDriver.

Note:
This function bypasses the indirect access to the channel and reads directly from the input queue. This is faster but cannot be used to read from different channels implementations.
See also:
chIOGet()
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 202 of file serial.h.

#define sdGetTimeout (   sdp,
 
)    chIQGetTimeout(&(sdp)->iqueue, t)

Direct read from a SerialDriver with timeout specification.

Note:
This function bypasses the indirect access to the channel and reads directly from the input queue. This is faster but cannot be used to read from different channels implementations.
See also:
chIOGetTimeout()
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 214 of file serial.h.

#define sdWrite (   sdp,
  b,
 
)    chOQWriteTimeout(&(sdp)->oqueue, b, n, TIME_INFINITE)

Direct blocking write to a SerialDriver.

Note:
This function bypasses the indirect access to the channel and writes directly to the output queue. This is faster but cannot be used to write from different channels implementations.
See also:
chIOWriteTimeout()
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 226 of file serial.h.

#define sdWriteTimeout (   sdp,
  b,
  n,
 
)    chOQWriteTimeout(&(sdp)->oqueue, b, n, t)

Direct blocking write to a SerialDriver with timeout specification.

Note:
This function bypasses the indirect access to the channel and writes directly to the output queue. This is faster but cannot be used to write to different channels implementations.
See also:
chIOWriteTimeout()
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 240 of file serial.h.

#define sdAsynchronousWrite (   sdp,
  b,
 
)    chOQWriteTimeout(&(sdp)->oqueue, b, n, TIME_IMMEDIATE)

Direct non-blocking write to a SerialDriver.

Note:
This function bypasses the indirect access to the channel and writes directly to the output queue. This is faster but cannot be used to write to different channels implementations.
See also:
chIOWriteTimeout()
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 253 of file serial.h.

#define sdRead (   sdp,
  b,
 
)    chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_INFINITE)

Direct blocking read from a SerialDriver.

Note:
This function bypasses the indirect access to the channel and reads directly from the input queue. This is faster but cannot be used to read from different channels implementations.
See also:
chIOReadTimeout()
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 266 of file serial.h.

#define sdReadTimeout (   sdp,
  b,
  n,
 
)    chIQReadTimeout(&(sdp)->iqueue, b, n, t)

Direct blocking read from a SerialDriver with timeout specification.

Note:
This function bypasses the indirect access to the channel and reads directly from the input queue. This is faster but cannot be used to read from different channels implementations.
See also:
chIOReadTimeout()
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 280 of file serial.h.

#define sdAsynchronousRead (   sdp,
  b,
 
)    chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_IMMEDIATE)

Direct non-blocking read from a SerialDriver.

Note:
This function bypasses the indirect access to the channel and reads directly from the input queue. This is faster but cannot be used to read from different channels implementations.
See also:
chIOReadTimeout()
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 293 of file serial.h.

#define SD_MODE_PARITY   0x07

Parity field mask.

Definition at line 38 of file serial_lld.h.

#define SD_MODE_PARITY_NONE   0x00

No parity.

Definition at line 39 of file serial_lld.h.

#define SD_MODE_PARITY_EVEN   0x05

Even parity.

Definition at line 40 of file serial_lld.h.

#define SD_MODE_PARITY_ODD   0x07

Odd parity.

Definition at line 41 of file serial_lld.h.

#define SD_MODE_STOP   0x30

Stop bits mask.

Definition at line 43 of file serial_lld.h.

#define SD_MODE_STOP_1   0x00

One stop bit.

Definition at line 44 of file serial_lld.h.

#define SD_MODE_STOP_2   0x20

Two stop bits.

Definition at line 45 of file serial_lld.h.

#define SD_MODE_STOP_1P5   0x30

1.5 stop bits.

Definition at line 46 of file serial_lld.h.

#define STM8S_SERIAL_USE_UART1   TRUE

UART1 driver enable switch.

If set to TRUE the support for UART1 is included.

Note:
The default is TRUE.

Definition at line 58 of file serial_lld.h.

#define STM8S_SERIAL_USE_UART2   TRUE

UART2 driver enable switch.

If set to TRUE the support for UART3 is included.

Note:
The default is TRUE.

Definition at line 67 of file serial_lld.h.

#define STM8S_SERIAL_USE_UART3   TRUE

UART3 driver enable switch.

If set to TRUE the support for UART3 is included.

Note:
The default is TRUE.

Definition at line 76 of file serial_lld.h.

#define _serial_driver_data
Value:
_base_asynchronous_channel_data                                           \
  /* Driver state.*/                                                        \
  sdstate_t                 state;                                          \
  /* Input queue.*/                                                         \
  InputQueue                iqueue;                                         \
  /* Output queue.*/                                                        \
  OutputQueue               oqueue;                                         \
  /* Input circular buffer.*/                                               \
  uint8_t                   ib[SERIAL_BUFFERS_SIZE];                        \
  /* Output circular buffer.*/                                              \
  uint8_t                   ob[SERIAL_BUFFERS_SIZE];                        \

SerialDriver specific data.

Definition at line 113 of file serial_lld.h.

#define BRR (   b)    (SYSCLK / (b))

Macro for baud rate computation.

Note:
Make sure the final baud rate is within tolerance.

Definition at line 135 of file serial_lld.h.


Typedef Documentation

typedef struct SerialDriver SerialDriver

Structure representing a serial driver.

Definition at line 102 of file serial.h.


Enumeration Type Documentation

enum sdstate_t

Driver state machine possible states.

Enumerator:
SD_UNINIT 

Not initialized.

SD_STOP 

Stopped.

SD_READY 

Ready.

Definition at line 93 of file serial.h.