/**
* \section LICENSE
*
* This software is dual licensed under the following two licenses:
* BSD-new and GPLv2. You may use either one. See the included
* COPYING file for details.
*
* License: BSD-new
* ===============================================================================
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* License: GPLv2
* ===============================================================================
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ---------------------------------------------------------------------------
*
*
* \section DESCRIPTION
*
* Definitions for the LINlib API.
*
* \file linlib.h
* \author Kvaser AB
*/
#ifndef __LINLIB_H
#define __LINLIB_H
/**
* \defgroup LIN LIN
* @{
*/
/**
* LIN handle
*/
typedef int LinHandle;
/**
* Invalid LIN handle
*/
#define linINVALID_HANDLE ((LinHandle)(-1))
#if !WIN32
# define CompilerAssert(exp) extern char _CompilerAssert[(exp) ? 1 : -1]
#endif
/**
* \name Return codes from the LINlib functions
* \anchor linERR_xxx
* @{
*/
typedef enum {
linOK = 0, ///< OK - no error
linERR_NOMSG = -1, ///< No messages available
linERR_NOTRUNNING = -3,
linERR_RUNNING = -4,
linERR_MASTERONLY = -5,
linERR_SLAVEONLY = -6,
linERR_PARAM = -7, ///< Error in parameter
linERR_NOTFOUND = -8, ///< Specified hardware not found. This error is reported when the LIN transceiver isn't powered up
linERR_NOMEM = -9, ///< Out of memory
linERR_NOCHANNELS = -10, ///< No channels avaliable
linERR_TIMEOUT = -11, ///< Timeout occurred
linERR_NOTINITIALIZED = -12, ///< Library not initialized
linERR_NOHANDLES = -13, ///< Can't get handle
linERR_INVHANDLE = -14, ///< Handle is invalid
linERR_CANERROR = -15,
linERR_ERRRESP = -16, ///< There was an error response from the LIN interface
linERR_WRONGRESP = -17, ///< The LIN interface response wasn't the expected one
linERR_DRIVER = -18, ///< CAN driver type not supported
linERR_DRIVERFAILED = -19, ///< DeviceIOControl failed; use the Win32 GetLastError API to get the real (WIn32) error code.
linERR_NOCARD = -20, ///< The card was removed or not inserted
linERR_LICENSE = -21, ///< The license is not valid
linERR_INTERNAL = -22, ///< Internal error in the driver
linERR_NO_ACCESS = -23, ///< Access denied
linERR_VERSION = -24 ///< Function not supported in this version
} LinStatus;
/** @} */
// sizeof(LinMessageInfo) should be 68 for correct alignment
#if WIN32
#include
#endif
/**
* In certain LIN bus API calls, the following structure is used to provide more
* information about the LIN messages.
*
* \note The precision of the timing data given in us (microseconds) can be less
* than one microsecond; for low bitrates the lowest bits might always be zero.
*
* \note The min and max values listed inside [] of the message timing values
* can be calculated from the LIN specification by using the shortest (0 bytes)
* or longest (8 bytes) messages at the lowest or highest allowed bitrate.
*
* \note The LIN interface will accept messages that are a bit out-of-bounds as
* well.
*/
typedef struct {
/**
* Kvaser DRV Lin timestamp - Timestamp in milliseconds of the falling edge of
* the synch break of the message. Uses the canlib CAN timer.
*
* Kvaser LIN Leaf timestamp - Timestamp in milliseconds of the falling edge
* of the synch break of the message. Uses the canlib CAN timer.
*
* \note All Kvaser Leaf with Kvaser MagiSync&tm; are synchronized
* (also with CAN channels).
*/
unsigned long timestamp;
/**
* Length of the synch break in microseconds.
* [650 .. 13000], [400 .. 8000] for a wakeup signal.
*/
unsigned long synchBreakLength;
/**
* The total frame length in microseconds; from the synch break to the
* end of the crc. [2200 .. 173600]
*/
unsigned long frameLength;
/**
* The bitrate of the message in bits per seconds.
* Range [1000 .. 20000] (plus some margin)
*/
unsigned long bitrate;
/**
* The checksum as read from the LIN bus. Might not
* match the data in case of \ref LIN_CSUM_ERROR.
*/
unsigned char checkSum;
/**
* The id with parity of the message as read from the
* LIN bus. Might be invalid in case of \ref LIN_PARITY_ERROR.
*/
unsigned char idPar;
unsigned short z; ///< Dummy for alignment
/**
* Time in microseconds of the falling edges in the
* synch byte relative the falling edge of the start bit.
*/
unsigned long synchEdgeTime[4];
/**
* Start time in microseconds of each data byte. In case of 8-byte messages,
* the crc time isn't included (but can be deduced from frameLength).
*/
unsigned long byteTime[8];
} LinMessageInfo;
#if WIN32
#include
#endif
/**
* \name LIN message flags
* \anchor LIN_xxx
* The following flags can be returned from \ref linReadMessage() and
* \ref linReadMessageWait().
*
* @{
*/
#define LIN_TX 1 ///< The message was something we transmitted on the bus
#define LIN_RX 2 ///< The message was something we received from the bus
#define LIN_WAKEUP_FRAME 4 ///< A wake up frame was received. Id/msg/dlc are undefined
#define LIN_NODATA 8 ///< No data, only a header
#define LIN_CSUM_ERROR 16 ///< Checksum error
#define LIN_PARITY_ERROR 32 ///< ID parity error
#define LIN_SYNCH_ERROR 64 ///< A synch error
#define LIN_BIT_ERROR 128 ///< Bit error when transmitting
/** @} */
/**
* Macro for determining if a flag field contains a LIN error flag bit.
*/
#define LINERROR(f) ((f) & (LIN_NODATA | LIN_CSUM_ERROR | LIN_SYNCH_ERROR | LIN_BIT_ERROR))
// Define LINLIBAPI unless it's done already.
// (linlib.c provides its own definition of LINLIBAPI before including this file.)
//
#if WIN32
#ifndef LINLIBAPI
# if defined(__BORLANDC__)
# define LINLIBAPI __stdcall
# elif defined(_MSC_VER) || defined(__MWERKS__) || defined(__GNUC__)
# define LINLIBAPI __stdcall
# endif
#endif
#else
#define LINLIBAPI
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* This function initializes the LIN library and must be called before any other
* LIN function is called. If this function isn't called, subsequent calls to
* the other LIN functions will return \ref linERR_NOTINITIALIZED.
*
* \sa \ref linOpenChannel()
*/
void LINLIBAPI linInitializeLibrary(void);
/**
* Retrieves the transceiver information for a CAN channel. The application
* typically uses this call to find out whether a particular CAN channel has a
* LIN interface connected to it.
* For a Kvaser LIN Leaf it retrieves the transceiver type and device information.
*
* This function call will open the CAN channel, but no CAN messages are
* transmitted on it. In other words, it's risk-free to use even if no LIN
* interface is connected, or if the channel is connected to a CAN system.
*
* \note Attempts to use the channel for LIN communication will be meaningful
* only if \ref linGetTransceiverData() stores \ref canTRANSCEIVER_TYPE_LIN in \a ttype.
*
* \note A LIN interface need not be powered for this call to succeed.
*
* \note The information may not always be accurate. Especially after changing
* transceiver on a running LAPcan card, you should go on bus and off bus again
* to be sure the transceiver information is updated.
*
* \param[in] channel The number of a CAN channel for which the transceiver
* data will be retrieved.
* \param[out] eanNo A pointer to an array of 8 bytes where the EAN number of
* the LIN interface will be stored.
* \param[out] serNo A pointer to an array of 8 bytes where the serial number
* of the LIN interface will be stored.
* \param[out] ttype A pointer to an integer where the transceiver type will
* be stored.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*
* \sa \ref linGetFirmwareVersion()
*/
LinStatus LINLIBAPI linGetTransceiverData(int channel, unsigned char eanNo[8],
unsigned char serNo[8], int *ttype);
/**
* Open a channel to a LIN interface.
*
* \note For DRV Lin: The cable must be powered and connected to a LAPcan channel.
*
* \note For Kvaser LIN Leaf: The Leaf must be powered from the LIN side.
*
* \param[in] channel The number of the channel. Channel numbering is hardware
* dependent.
* This is the same channel number as used by \ref canOpenChannel().
* \param[in] flags Either one of the following values: \ref LIN_MASTER or
* \ref LIN_SLAVE.
*
* \return If the call succeeds, a handle to the opened channel is returned.
* The handle is an integer greater than or equal to zero.
*
* \return If the call fails, the return value is a negative integer indicating
* an error code. See \ref linERR_xxx for a list of possible error codes.
*
* \sa \ref linClose()
*/
LinHandle LINLIBAPI linOpenChannel(int channel, int flags);
/**
* \name Flags for linOpenChannel()
* @{
*/
#define LIN_MASTER 1 ///< The LIN interface will be a LIN master
#define LIN_SLAVE 2 ///< The LIN interface will be a LIN slave
/** @} */
/**
* Closes an open handle to a LIN channel. The handle becomes invalid and can
* not be used in subsequent calls to the LIN functions.
*
* \param[in] h A handle to an open LIN channel.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*
* \sa \ref linOpenChannel()
*/
LinStatus LINLIBAPI linClose(LinHandle h);
/**
* This function retrieves the firmware version from the LIN interface.
*
*
* \note The version numbers aren't valid until \ref linBusOn() has been called.
*
* \note The firmware in the LIN interface is divided into two parts, the boot
* code and the application. The boot code is used only when reprogramming
* (reflashing) the LIN interface. The application handles all LIN communication.
*
* \note Version numbers are, since the precambric era, divided into a major
* version number, a minor version number and a build number. These are usually
* written like, for example, 3.2.12. Here the major number is 3, the minor
* number 2 and the build number 12.
*
* \param[in] h A handle to an open LIN channel.
* \param[out] bootVerMajor A pointer to a byte where the major version number
* of the boot code is stored.
* \param[out] bootVerMinor A pointer to a byte where the minor version number
* of the boot code is stored.
* \param[out] bootVerBuild A pointer to a byte where the build number of the
* boot code is stored.
* \param[out] appVerMajor A pointer to a byte where the major version number
* of the application code is stored.
* \param[out] appVerMinor A pointer to a byte where the minor version number
* of the application code is stored.
* \param[out] appVerBuild A pointer to a byte where the build number of the application is stored.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*/
LinStatus LINLIBAPI linGetFirmwareVersion(LinHandle h,
unsigned char *bootVerMajor,
unsigned char *bootVerMinor,
unsigned char *bootVerBuild,
unsigned char *appVerMajor,
unsigned char *appVerMinor,
unsigned char *appVerBuild);
/**
* This function sets the bit rate for a master, or the initial bit rate for a
* slave. The LIN interface should not be on-bus when this function is called.
*
* \note The LIN Interface should not be on bus.
*
* \note Supported bit rates are 1000 - 20000 bits per second.
*
* \param[in] h A handle to an open LIN channel.
* \param[in] bps Bit rate in bits per second.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*/
LinStatus LINLIBAPI linSetBitrate(LinHandle h, unsigned int bps);
/**
* This function activates the LIN interface.
*
* \note It will be reset, so any setups done earlier will be lost.
*
* \param[in] h A handle to an open LIN channel.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*
* \sa \ref linBusOff()
*/
LinStatus LINLIBAPI linBusOn(LinHandle h);
/**
* This function deactivates the LIN interface. It will not participate further
* in the LIN bus traffic.
*
* \param[in] h A handle to an open LIN channel.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*
* \sa \ref linBusOn()
*/
LinStatus LINLIBAPI linBusOff(LinHandle h);
/**
* Return the current timer value (used for timestamps)
*
* \note For convenience, this call returns the timer value instead of passing
* it in a parameter. This means that if the call fails, it will still return
* a value (which then is the error code, type casted to a long unsigned
* integer - e.g. 0xFFFFFFF2 for \ref linERR_INVHANDLE. Watch out.
*
* \param[in] h A handle to an open LIN channel.
* \return If the call succeeds, the present timer value is returned.
*/
unsigned long LINLIBAPI linReadTimer(LinHandle h);
/**
* Write a LIN message.
* It is advisable to wait until the message is echoed by \ref linReadMessage()
* before transmitting a new message, or in case of a schedule table being used,
* transmit the next message when the previous one is known to be complete.
*
* \note Only available in master mode.
*
* \param[in] h A handle to an open LIN channel.
* \param[in] id The identifier of the LIN message.
* \param[in] msg A pointer to a buffer containing the data of the LIN
* message.
* \param[in] dlc The length of the LIN message.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*
* \sa \ref linWriteSync()
*/
LinStatus LINLIBAPI linWriteMessage(LinHandle h, unsigned int id, const void *msg,
unsigned int dlc);
/**
* This function writes a LIN message header to the LIN bus. A slave in the
* system is then expected to fill in the header with data.
*
* \note This call is only available in master mode.
*
* \param[in] h A handle to an open LIN channel.
* \param[in] id The identifier of the LIN message.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*/
LinStatus LINLIBAPI linRequestMessage(LinHandle h, unsigned int id);
/**
* Read a message from the LIN interface. If a message is available for
* reception, \ref linOK is returned. This is a non-blocking call. If no message
* is available in the LIN interface, an error code is returned.
*
* \note This call will also return echoes of what the LIN interface is
* transmitting with \ref linWriteMessage. In other words, the LIN interface can hear
* itself.
*
* \param[in] h A handle to an open LIN channel.
* \param[out] id A pointer to an integer where the identifier of the
* received LIN message will be stored.
* \param[out] msg A pointer to a buffer where the data of the LIN message
* will be stored.
* \param[out] dlc A pointer to an integer where the length of the received
* LIN message will be stored.
* \param[out] flags A combination of zero or more of the \ref LIN_xxx flags.
* \param[out] msgInfo A pointer to a \ref LinMessageInfo struct where data about the
* received LIN message will be stored.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*
* \sa \ref linReadMessageWait()
*/
LinStatus LINLIBAPI linReadMessage(LinHandle h, unsigned int *id, void *msg,
unsigned int *dlc, unsigned int *flags,
LinMessageInfo *msgInfo);
/**
* Read a message from the LIN interface. If a message is available for
* reception, \ref linOK is returned. This is a blocking call. It waits until a
* message is received in the LIN interface, or the specified timeout period
* elapses.
*
* \note This call will also return echoes of what the LIN interface is
* transmitting with \ref linWriteMessage(). In other words, the LIN interface can
* hear itself.
*
* \param[in] h A handle to an open LIN channel.
* \param[in] timeout The maximum number of milliseconds to wait for a message
* to be received by the LIN interface.
* \param[out] id A pointer to an integer where the identifier of the
* received LIN message will be stored.
* \param[out] msg A pointer to a buffer where the data of the LIN message
* will be stored.
* \param[out] dlc A pointer to an integer where the length of the received
* LIN message will be stored.
* \param[out] flags A combination of zero or more of the \ref LIN_xxx flags.
* \param[out] msgInfo A pointer to a \ref LinMessageInfo struct where data about the
* received LIN message will be stored.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*
* \sa \ref linReadMessage()
*/
LinStatus LINLIBAPI linReadMessageWait(LinHandle h, unsigned int *id, void *msg,
unsigned int *dlc, unsigned int *flags,
LinMessageInfo *msgInfo, unsigned long timeout);
/**
* This function updates a message buffer in a slave. The contents of the
* message buffer will be used the next time the slave is polled for the
* specified LIN message id.
*
* \note The LIN Interface must be on bus.
*
* \param[in] h A handle to an open LIN channel.
* \param[in] id The identifier of the LIN message.
* \param[in] msg A pointer to a buffer containing the data of the LIN message.
* \param[in] dlc The length of the LIN message.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*
* \sa \ref linClearMessage()
*/
LinStatus LINLIBAPI linUpdateMessage(LinHandle h, unsigned int id, const void *msg,
unsigned int dlc);
/**
* Using this function, it is possible to use the LIN interface to create
* corrupted LIN messages. You call the function once for each LIN identifier
* that should be affected.
*
* To return to normal mode, either restart the LIN interface (by going off bus
* and on the bus again) or call the function with delay and \a cFlags set to zero.
*
* \note The LIN Interface must be on bus for this command to work.
* \note It is supported in firmware version 2.4.1 and later.
*
* \param[in] h A handle to an open LIN channel.
* \param[in] id The identifier of the LIN message.
* \param[in] cFlags One or more of the \ref LIN_MSG_DISTURB_xxx flags.
* \param[in] delay The delay parameter will result in a delay of this many
* bittimes after the header and before the first data byte.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*
* \sa \ref linSetupLIN()
*/
LinStatus LINLIBAPI linSetupIllegalMessage(LinHandle h, unsigned int id,
unsigned int cFlags, unsigned int delay);
/**
* \name LIN illegal message flags
* \anchor LIN_MSG_DISTURB_xxx
* @{
*/
/**
* The checksum of transmitted messages will be inverted (and consequently illegal.)
*/
#define LIN_MSG_DISTURB_CSUM 1
/**
* The two parity bits will be inverted (and consequently illegal.)
* Used only in master mode.
*/
#define LIN_MSG_DISTURB_PARITY 2
/** @} */
/**
* \name LIN message parity
* \anchor LIN_MSG_USE_xxx
* @{
*/
/**
* Use enhanced (2.x) parity for the specified msg
*/
#define LIN_MSG_USE_STANDARD_PARITY 0x04
/**
* Use standard (1.x) parity for the specified msg
*/
#define LIN_MSG_USE_ENHANCED_PARITY 0x08
/** @} */
/**
* This function changes various settings on a LIN Interface that is on bus.
* When going on bus, the bit rate and the flag values listed below are set to
* the default value (either as hard-coded in the firmware, or as stored in the
* non-volatile memory of the LIN Interface).
*
* With this function, you can do one or more of the following things:
* - Select checksum according to LIN 2.0
* - Turn variable message length off. The message length then will depend on
* the message ID.
*
* In master mode it is also possible to change the bit rate without going off
* bus first.
*
* \note The LIN Interface must be on bus for this command to work.
* \note It is supported in firmware version 2.5.1 and later.
* \note For LIN 2.0 compliance, you must specify both \ref LIN_ENHANCED_CHECKSUM
* and \ref LIN_VARIABLE_DLC.
*
* \param[in] h A handle to an open LIN channel.
* \param[in] lFlags One or more of the following flags:
* \ref LIN_ENHANCED_CHECKSUM, \ref LIN_VARIABLE_DLC
* \param bps Specifies the bit rate in bits per second. This parameter
* can be used only in master mode. The bit rate is set
* without going off bus.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*
* \sa \ref linSetupIllegalMessage()
*/
LinStatus LINLIBAPI linSetupLIN(LinHandle h, unsigned int lFlags, unsigned int bps);
/**
* \name LIN setup
* @{
*/
/**
* When specified, the LIN interface will use the "enhanced" checksum according
* to LIN 2.0. Note that (as per the LIN 2.0 spec) the enhanced checksum is not
* used on the diagnostic frames even if the \ref LIN_ENHANCED_CHECKSUM setting
* is in effect.
*
* The default value is OFF.
*/
#define LIN_ENHANCED_CHECKSUM 1
/**
* When specified, turns variable message length on, so the the message length
* will depend on the message ID.
*
* The default value is ON.
*/
#define LIN_VARIABLE_DLC 2
/** @} */
/**
* Write a wakeup frame.
*
* If count is zero, one single wakeup frame is transmitted. If count > 1,
* several wakeup frames are transmitted spaced with 'interval' bittimes.
* The LIN interface will interrupt the sequence when a LIN message or another
* command is received. The stream of wakeups will be recived as incoming
* messages with the LIN_RX flag bit set.
*
* \param[in] h A handle to an open LIN channel.
* \param[in] count The number of wakeup frames to send.
* \param[in] interval The time, in bit times, between the wakeup frames.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*/
LinStatus LINLIBAPI linWriteWakeup(LinHandle h, unsigned int count,
unsigned int interval);
/**
* Clear a message buffer for a LIN slave. The message buffer will not answer
* next time it is polled.
*
* \param[in] h A handle to an open LIN channel.
* \param[in] id The LIN message id for which the corresponding buffer
* will be cleared.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*/
LinStatus LINLIBAPI linClearMessage(LinHandle h, unsigned int id);
/**
* Call this function to make sure all messages transmitted to the
* LIN Interface has been received by it.
*
* When messages are transmitted to the LIN Interface, they are queued by
* Windows before appearing on the CAN bus.
*
* The function returns \ref linOK if all writes are done, \ref linERR_TIMEOUT in
* case of timeout or possibly some other error code.
*
* If the LIN Interface is in master mode and a LIN message has been
* transmitted with \ref linWriteMessage(), this function will return when
* the LIN Interface has received the message. If another LIN messa ge is being
* received or transmitted, the message will not be transmitted on the
* LIN bus at once. And even if the LIN Interface is idle, the header of the new
* message will just have been started when \ref linWriteSync() retur ns.
*
* After calling \ref linUpdateMessage() and \ref linClearMessage() for a slave,
* this function is enough to know that the LIN Interface is updated.
*
* After \ref linWriteMessage(), it is advisable to wait until the message is
* echoed by \ref linReadMessage() before transmitting a new message, or in
* case of a schedule table being used, transmit the next message when
* the previous one is known to be complete.
*
* When, in master mode, a message should be transmitted after a poll
* (reception) is done, it might be necessary to call \ref linWriteMessage()
* before the result is received via \ref linReadMessage() as the LIN Interface waits
* up to the maximum frame length before knowing a received message is
* complete. A new message to transmit will force completion if the
* currently received one.
*
* \param[in] h A handle to an open LIN channel.
* \param[in] timeout The maximum number of milliseconds to wait for the queued
* messages to be transmitted by the LIN interface.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*
* \sa \ref linWriteMessage()
*/
LinStatus LINLIBAPI linWriteSync(LinHandle h, unsigned long timeout);
/**
* Return the CAN handle given an open LIN handle
*
* \param[in] h A handle to an open LIN channel.
* \param[out] canHandle A pointer to an integer where the CAN handle will be
* stored.
*
* \return \ref linOK (zero) if success
* \return \ref linERR_xxx (negative) if failure
*/
LinStatus LINLIBAPI linGetCanHandle(LinHandle h, unsigned int *canHandle);
#ifdef __cplusplus
}
#endif
/** @} */
#endif // __LINLIB_H