# serial_hw_int_cts

serial_hw_int_cts.jal. Interrupt driven buffered serial interface with flow control.

Author | Rob Hamerling, Copyright © 2008..2020, all rights reserved.
Adapted-by | Joep Suijs, Rob Jansen
Compiler | 2.5r4

Description

    Serial communications for first or only USART:
      - receive and transmit data transfer is interrupt driven
      - receive and transmit data transfer is buffered (circular buffers)
      - provides automatic CTS flow control with spare free space for FiFo buffer
    .
    This library supports:
      - Data format: 8 bits data, 1 start-bit, 1 stop bit
      - Acceptable baud rate depends on the oscillator frequency
        (see BAUD RATES tables in the datasheet).
      - Interrupt bits used: TXIE, RCIE, PEIE and GIE.
    .
    Available procedures/functions for application programs:
    .
      - serial_hw_init()                          -- initialize communications
    .
      - serial_send_byte(byte out )         -- send byte
                                                  -- returns the transmitted byte
      - serial_hw_read(byte out ) return bit  -- receive byte
                                                  -- returns TRUE with data,
                                                  -- FALSE when no data available
      - serial_hw_write(byte in )           -- send byte (wait if queue full)
    .
      - serial_hw_data =                    -- send byte, wait if queue full
    .
      - serial_hw_tx_buffer_free()                -- get free bytes in transmit buffer
                                                  -- returns number of free bytes
    .
      -  = serial_hw_data                   -- receive byte, wait if queue empty
    .
    Directions for use of this library in application programs (in this sequence):
    .
    1. Declare the following constants:
    .
         const  serial_hw_baudrate = 115200      -- line speed must be declared (no default)
    .
         const bit serial_overflow_discard = FALSE  -- Transmit buffer overflow:
                                                 --   FALSE: wait for free space (blocking)
                                                 --   TRUE: discard data (non-blocking)
                                                 -- This flag may be dynamically changed
                                                 -- but must then be declared as 'var bit'
    .
                                                 -- Receive buffer overflow data is
                                                 -- prevented by CTS flow control, provided
                                                 -- the sender has flow control enabled.
                                                 -- Otherwise data discarded without notification!
    .
       and an alias
    .
         alias serial_ctsinv  is  pin_B4         -- Incoming data flow control signal
                                                 -- Optional, if no CTS flow control needed
                                                 -- no dummy needs to be declared.
    .
       and optionally you could define one or more of the constants below.
       You should do so if you want different values than shown (= default).
       If not defined, the following values are used:
    .
         const   SERIAL_XMTBUFSIZE  = 32         -- size of transmit buffer
         const   SERIAL_RCVBUFSIZE  = 64         -- size of receive buffer
         const   SERIAL_DELTA       = 17         -- spare space receive buffer
                                                 -- if possible keep SERIAL_DELTA = 17!
    .
       When the physical locations of pin_TX and pin_RX are configurable for a specific
       PIC, the device file will probably contain names like pin_TX_RB2 and pin_RX_RB1
       and another pair with other pin suffixes.
       Depending for which pair of pins the USART is configured aliases
       without suffixes have to be specified, like:
            alias  pin_TX            is  pin_TX_RB2
            alias  pin_RX            is  pin_RX_RB1
            alias  pin_TX_direction  is  pin_TX_RB2_direction
            alias  pin_RX_direction  is  pin_RX_RB1_direction
    .
    2. Include this library.
    .
    and somewhere before actually using serial communications:
    .
    3. Prepare pins:
          pin_B4_direction = OUTPUT              -- incoming data flow control
       Notes: - pin_TX and pin_RX are selected automatically
              - direction settings of these pins are taken care of by the library
    .
    4. Call serial_hw_init() to initialize serial communications.

Notes

    Background information:
    .
    The PIC ports use positive logic: '1' is positive voltage, '0' is ground.
    .
    In the RS232 standard:
    - Negative voltage ('mark') means OFF for control signals, and
      indicates 1 (one) for data signals (start-, data-, stop-bits).
    - Positive voltage ('space') means ON for control signals and
      0 (zero) for start-, data- and stop-bits.
    - Signal levels: 'mark' = -3V to -15V,  'space' = +3V to +15V
    .
    Between PIC and RS232 normally an interface chip is used, such as a
    Maxim/Dallas MAX232 or MAX202. These are not only voltage level CONverters
    but also signal INverters. You should be aware of the following:
    - The inversion of PIC data-in and data-out by the MAX2x2 is required
      to convert data-, start- and stop-bits to/from the corresponding
      RS232 polarity. So nothing special has to be done in the program
      because the USART of the PIC uses 'inverted' signal levels!
    - For CTS the inversion by the MAX2x2 is NOT desired.
      Therefore the program has to use inverted signalling for CTS:
      'FALSE' is used for CTS ON and 'TRUE' for CTS OFF!
      As a reminder for this 'inverted' logic the signal is called
      serial_ctsinv (serial_ctsinv = TRUE means CTS is FALSE!).
    .
    Remember also: RxD of RS232-plug connects to TX of PIC via MAX2x2
                   TxD of RS232-plug connects to RX of PIC via MAX2x2
    .
    Additional remarks:
     - The selection of the CTS pin above is an example, any other pin
       which is configurable for output can be used.
     - Do not touch the following interrupt bits: TXIE, RCIE, PEIE and GIE

Dependencies

- usart_common

## Summary

### Global variables/contants

- `var byte _serial_xmtbuf[SERIAL_XMTBUFSIZE]`
- `var volatile byte _serial_offsetxmthead`
- `var volatile byte _serial_offsetrcvtail`
- `var volatile byte _serial_offsetrcvhead`
- `var byte _serial_rcvbuf[SERIAL_RCVBUFSIZE]`
- `var volatile byte _serial_offsetxmttail`

### Procedures

- `serial_init()`
- `serial_hw_data'put(byte in data)`
- `serial_hw_init()`
- `serial_hw_write(byte in data)`

Private

- `_serial_transmit_interrupt_handler()`
- `_serial_receive_interrupt_handler()`

### Functions

- `serial_hw_data_ready() return bit`
- `serial_receive_byte(byte out data) return bit`
- `serial_hw_tx_buffer_free() return byte`
- `serial_hw_read(byte out data) return bit`
- `serial_hw_data_available() return bit`
- `serial_hw_data'get() return byte`
- `serial_send_byte(byte in data) return byte`

## API details

### Global variables/contants

- `var byte _serial_xmtbuf[SERIAL_XMTBUFSIZE]`

      Local circular transmit buffer

- `var volatile byte _serial_offsetxmthead`

      variable keeping track of next free position in transmit buffer

- `var volatile byte _serial_offsetrcvtail`

      variable keeping track of next byte available to application program

- `var volatile byte _serial_offsetrcvhead`

      variable keeping track of next free byte in receive buffer

- `var byte _serial_rcvbuf[SERIAL_RCVBUFSIZE]`

      Local circular receive buffer

- `var volatile byte _serial_offsetxmttail`

      variable keeping track of next byte to be transmitted by interrupt handler

### Procedures

- `serial_init()`

      Deprecated

- `serial_hw_data'put(byte in data)`

      Put byte in transmit buffer as pseudo variable

- `serial_hw_init()`

      Title:     Initialize first or only serial port
      Arguments: (none)
      Returns:   (nothing)

- `serial_hw_write(byte in data)`

      Title:     Put a single byte in transmit buffer
      Arguments: Data (byte) to transmit
      Returns    (nothing)
      Notes:     - This is a variant of serial_send_byte() compatible with
      the procedure in the serial_hardware library.
       Spins when byte cannot be put in transmit buffer
      (buffer full condition).

Private

- `_serial_transmit_interrupt_handler()`

      Title:     USART serial transmit interrupt handler
      Arguments: (none)
      Returns:   (nothing)

- `_serial_receive_interrupt_handler()`

      Title:     USART serial receive interrupt handler
      Arguments: (none)
      Returns:   (nothing)
      Notes:     Sets CTS low when receive buffer has less than
       bytes free space.

### Functions

- `serial_hw_data_ready() return bit`

      generic function to check if transmit buffer is empty

- `serial_receive_byte(byte out data) return bit`

      Deprecated function -------------------

- `serial_hw_tx_buffer_free() return byte`

      Title:     Get free space in transmit buffer
      Arguments: (none)
      Returns:   Number of free bytes in transmit buffer
      Notes:     - Useful to check in advance if a string will fit in the buffer
      or if transmitting the string will block.
       Never returns zero. If "1" is returned, regard buffer as full.

- `serial_hw_read(byte out data) return bit`

      Title:     Return byte (if any) from circular receive buffer of USART
      Arguments: received byte (if any)
      Returns:   - TRUE  when byte returned
       FALSE if no byte available
      Notes:     Sets CTS high when receive buffer has more than
      bytes free space after delivering byte to caller.

- `serial_hw_data_available() return bit`

      generic function to check if a byte is received

- `serial_hw_data'get() return byte`

      Return next byte from receive buffer as pseudo variable
      Spin as long as no data available (buffer empty)

- `serial_send_byte(byte in data) return byte`

      Title:     Put a single byte in transmit buffer
      Arguments: Data (byte) to transmit
      Returns:   transmitted byte (or 0x00 when data discarded)
      Notes:     - Activates transmit interrupt handler when data buffered
       When buffer full act as indicated in 'serial_overflow_discard'
      * TRUE:  discard data (and return 0x00 as data byte)
      * FALSE: wait for free buffer space
      (returns only after data has been stored in buffer)

## Related samples

Here are the list of samples which use this library:

16f15325 | 16f15325_bluetooth_hc05_master.jal
16f15325 | 16f15325_bluetooth_hc06_slave.jal
16f1708 | 16f1708_pps_serial_hw_int_cts.jal
16f18015 | 16f18015_serial_speed_converter.jal
16f1823 | 16f1823_bluetooth_hc06_slave.jal
16f18855 | 16f18855_pps_serial_hw_int_cts.jal
16f19176 | 16f19176_dfplayer.jal
16f19176 | 16f19176_serial_hw_int_cts.jal
16f648a | 16f648a_serial_hw_int_cts.jal
16f723 | 16f723_serial_hw_int_cts.jal
16f73 | 16f73_serial_hw_int_cts.jal
16f877 | 16f877_serial_hw_int_cts.jal
16f877a | 16f877a_bluetooth_hc06_slave.jal
16f877a | 16f877a_serial_hw_int_cts.jal
16f877a | 16f877a_glcd_t6963.jal
16f88 | 16f88_serial_hw_int_cts.jal
16f88 | 16f88_serial_hw_int_cts_echo.jal
18f14k50 | 18f14k50_serial_hw_int_cts.jal
18f2450 | 18f2450_serial_hw_int_cts.jal
18f24k20 | 18f24k20_charlie_lolshield_ticker1.jal
18f2520 | 18f2520_serial_hw_int_cts.jal
18f2550 | 18f2550_serial_hw_int_cts.jal
18f2585 | 18f2585_canid4_serial_adapter.jal
18f2585 | 18f2585_can_serial_adapter.jal
18f25k22 | 18f25k22_serial_speed_converter.jal
18f2620 | 18f2620_serial_hw_int_cts.jal
18f26k42 | 18f26k42_serial_hw_int_cts.jal
18f452 | 18f452_serial_hw_int_cts.jal
18f4550 | 18f4550_serial_hw_int_cts.jal
18f4620 | 18f4620_serial_hw_int_cts.jal
18f47q43 | 18f47q43_serial_hw_int_cts.jal
18f6310 | 18f6310_serial_speed_converter.jal
18f67j50 | 18f67j50_serial_hw_int_cts.jal