/*****************************************************************************
* Copyright (c) 2007 Digi International Inc., All Rights Reserved
* 
* This software contains proprietary and confidential information of Digi
* International Inc.  By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others,
* and to make no use of this software other than that for which it was
* delivered.  This is an unpublished copyrighted work of Digi International
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
* prohibited.
* 
* Restricted Rights Legend
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7031 or
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -
* Restricted Rights at 48 CFR 52.227-19, as applicable.
*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
*
*****************************************************************************/

#ifndef NACBUS_H
#define NACBUS_H

#ifdef __cplusplus
extern "C"
{
#endif

#include "Npttypes.h"
#include "nastatus.h"
#include "iop_api.h"


/*ad*
 * The NET+OS Controller Area Network (CAN) driver provides a set of APIs which applications
 * can use to communicate on a CAN bus.  CAN is defined by the 
 * @url http://www.can-cia.org/fileadmin/cia/specifications/CAN20B.pdf "CAN 2.0 Part B,"
 * @url http://www.can-cia.org/fileadmin/cia/specifications/CAN2AD.pdf "CAN 2.0 Addendum," and 
 * @url http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=33422 "ISO 11989-1:2003"
 * specifications.
 *
 * You must license the NET+OS Controller Area Network (CAN) driver from Digi before you
 * can use it.  Please register at 
 * @url http://www.digiembedded.com/requestcan to receive the required CAN bus support files.
 *
 * Once you have the necessary licenses and hardware, the first step in using the driver
 * is to configure the GPIO pins on the processor which are needed by CAN.  The CAN controller
 * uses one of the two FIM processors.  The choice of which FIM processor is determined by
 * the CAN application kit hardware.  If FIM 0 is used, then set the constants
 * @link BSP_GPIO_MUX_IOP_0_CAN_RXD and 
 * @link BSP_GPIO_MUX_IOP_0_CAN_TXD in gpio.h for CAN.  If FIM 1 is used, then set the constants
 * @link BSP_GPIO_MUX_IOP_1_CAN_RXD and 
 * @link BSP_GPIO_MUX_IOP_1_CAN_TXD for CAN.  Some of the signals, BSP_GPIO_MUX_IOP_0_CAN_TXD
 * for example, support both primary and alternate paths.  The choice of which path to use
 * is also determined by the CAN application kit hardware.  Refer to the application kit's
 * documentation for details.  Rebuild the BSP library after you have edited gpio.h.
 *
 * Call 
 * @link naCBusOpen to open the CAN driver.  This call will allocate resources needed by the 
 * driver, but will not start the CAN controller or place it on the CAN bus.  The naCBusOpen
 * function will also set a default configuration.  You must adjust the configuration as
 * required by your application before calling the 
 * @link naCBusStart function.  The most important value to set is the speed of the CAN
 * bus.  The naCBusOpen function will set a default speed of 500K bps, which is a commonly
 * used speed.  However, you must make sure that correct speed for your network is set before
 * naCBusStart is called.  You will wreak havoc on the CAN network if you attach at the
 * wrong speed.
 *
 * In addition to setting the speed, you can also adjust the bit timing parameters used
 * by the CAN controller. Use the following APIs to configure the CAN controller before
 * calling naCBusStart.
 * <list type="unordered">
 *  <item>@link naCBusBpsSet sets the speed of the CAN bus.</item>
 *  <item>@link naCBusSjwSet sets the maximum SJW for the CAN bus.</item>
 *  <item>@link naCBusSamplePointSet sets the sample point for the CAN bus.</item>
 *  <item>@link naCBusSyncPeriodSet sets the length of the synchronization period.</item>
 * </list>
 *
 * Many CAN networks have heavy traffic, and, because of this, it is usually not desirable
 * to receive all the traffic on the bus.  Usually, applications are only interested in receiving
 * specific types of messages.  You specify which messages should be received by calling
 * the 
 * @link naCBusFilterSet to set up to 8 message filters.  Each filter selects a specific
 * type of message.  The naCBusOpen function creates a set of default filters, which are used
 * if you do not override them.  The first default filter accepts all frames.  
 * The other default filters do not select any frames.
 *
 * Before starting the CAN controller, you must also register a call back function to receive
 * frames.  The CAN driver will pass received CAN frames onto your application by calling
 * this function.  Use the 
 * @link naCBusReceiverThreadInstall to set the call back.
 *
 * The receiver call back is executed by a thread.  This is convenient since threads can
 * use any NET+OS service.  The receiver thread can receive CAN request messages and send
 * replies.  However, there may be some time critical requests that your application must 
 * respond to quickly, faster than is possible by a thread.  For these cases, the
 * driver provides a way to set up automatic replies to CAN request messages.  These
 * reply messages are sent by the driver ISR whenever it receives a message which matches
 * a specific ID that you specify.  To use automatic replies, you must call the
 * @link naCBusAutoReplyAllocate to allocate a control block for each automatic reply that
 * you intend to use, and then call 
 * @link naCBusAutoReplySet to set the request ID that will trigger the reply, and the data to
 * be sent.  Note that replies can and should be sent by the receive call back thread
 * when possible.  Since the automatic replies are processed by the CAN ISR, they add
 * to the system interrupt latency and should only be used for messages that are time
 * critical.
 * 
 * Once the CAN controller has been fully configured, call 
 * @link naCBusStart to start it.  Once this function completes, the controller will be
 * operational and start sending received frames to the application.
 *
 * After naCBusStart completes, you can call 
 * @link naCBusTransmit to transmit frames.  
 * @link naCBusClose can be called any time after naCBusOpen is called to shut down 
 * the CAN controller and releases the resources used by the driver.  
 *
 * CAN has two different frame formats.  In the standard format IDs are 11-bits long, 
 * and in the extended format IDs are 29-bits long.
 * These IDs are passed to naCBusTransmit, naCBusAutoReplySet, naCBusFilterSet, and to the 
 * receiver callback in the 
 * @link NaCanId_t type, which is a 32-bit unsigned word.  The ID is always stored in 
 * bits 28-0 of the word.  If an 11-bit ID is used, then bits 28-18 hold the ID, and 
 * bits 17-0 are set to zero.  In addition, CAN frames include an RTR bit and an IDE
 * bit.  The RTR bit determines whether the message is a request or a data frame.  This
 * bit is stored in bit 31 of the NaCanId_t type, and will be set for request messages.
 * The IDE bit determines if the frame uses 11-bit or 29-bit IDs, and is stored in bit
 * 30 of the NaCanId_t type.  This bit will be set when the 29-bit ID is used.  Bit 29
 * of the NaCanId_t is reserved and must be set to zero.
 *
 * @category BSP:Device_Drivers:CAN
 * @overview CAN Driver
 * @include "nacbus.h"
 * @platform connectcore9p9215_a
 * @library bsp
 * @since 7.4
 * @external
*ad*/


/*ad*
 * Use this macro to convert 11-bit IDs into 29-bit IDs.  
 *
 * @since 7.4
 * @external 
 * @category BSP:Device_Drivers:CAN
 *
 * @param id                11-bit ID to convert
*ad*/
#define NA_CBUS_CONVERT_11BIT_ID(id)            ((id & 0x7ff) << 18)


/*ad*
 * This bit is set in a 
 * @link NaCanId_t variable to indicate a request frame.  It corresponds to the
 * RTR bit in a can frame.  An ID with this bit set is for a CAN request
 * frame.  An ID with this bit clear is for a CAN data frame.
 *
 * @since 7.4
 * @external    
 * @category BSP:Device_Drivers:CAN
*ad*/
#define NA_CBUS_CANID_IS_REQUEST                ((unsigned)(1 << 31))


/*ad*
 * This bit is set in a 
 * @link NaCanId_t variable to indicate that a frame uses a 29-bit ID.  CAN frames
 * can have 11-bit or 29-bit IDs.  This bit in the NaCanId_t type determines
 * which format is used.  NaCanId_t variables with this bit set have a 29-bit ID
 * in bits 28-0.  NaCanId_t variables with this bit clear have an 11-bit ID
 * in bits 28-18, and bits 17-0 set to zero.
 *
 * @since 7.4
 * @external    
 * @category BSP:Device_Drivers:CAN
*ad*/
#define NA_CBUS_CANID_IS_EXTENDED_FRAME         (1 << 30)

/*ad*
 * This constant indicates the maximum number of data bytes (8) in a
 * CAN message.
 *
 * @since 7.4
 * @external    
 * @category BSP:Device_Drivers:CAN
*ad*/
#define NA_CBUS_MAX_DATA_LENGTH                 (8)


/*ad*
 * This bit in the flags argument of a 
 * @link NACBusDmaReceiverFn_t receiver function represents the R0
 * bit of a CAN frame.  It should always be zero.
 *
 * @since 7.4
 * @external    
 * @category BSP:Device_Drivers:CAN
*ad*/
#define NA_CBUS_FLAGS_R0_BIT                    (1 << 4)


/*ad*
 * This bit in the flags argument of a 
 * @link NACBusDmaReceiverFn_t receiver function represents the R1
 * bit of a CAN frame.  It should always be zero.
 *
 * @since 7.4
 * @external    
 * @category BSP:Device_Drivers:CAN
*ad*/
#define NA_CBUS_FLAGS_R1_BIT                    (1 << 5)


/*ad*
 * This bit in the flags argument of a 
 * @link NACBusDmaReceiverFn_t receiver function will be set if
 * the CAN driver sent an reply to the request message.
 *
 * @since 7.4
 * @external    
 * @category BSP:Device_Drivers:CAN
*ad*/
#define NA_CBUS_SENT_AUTO_RESPONSE               (1 << 6)


/*ad*
 * This constant can be used as a mask for the flags argument of a 
 * @link NACBusDmaReceiverFn_t receiver function.  Perform a logical
 * and of this constant and the flags argument to determine value 
 * passed in the frame's length field.  In some cases, this value is not the same
 * as the actual number of bytes of data.
 *
 * @since 7.4
 * @external    
 * @category BSP:Device_Drivers:CAN
*ad*/
#define NA_CBUS_FLAGS_LENGTH_MASK               (0x1f)




/*ad*
 * This type defines a CAN Identifier.  CAN ID is stored in a 32-bit
 * word.  CAN identifers may be 11 or 29 bits long.  11-bit identifiers
 * are stored in bits 28-18, with bits 0-17 set to 0.  29-bit identifiers
 * are stored in bits 28-0.  
 *
 * Bit 31 is used to store the IDE bit.  This bit is set if the identifier
 * is 29-bits.  Bit 30 is used to store the RTR bit.  This bit is set if
 * the message is a request data message.  Bit 29 is reserved and must be
 * set to 0.
 *
 * @since 7.4
 * @external    
 * @category BSP:Device_Drivers:CAN
*ad*/
typedef WORD32 NaCanId_t;



/*ad*
 * This constant can be used as a mask for the CAN ID portion of a 
 * @link NaCanId_t variable.  The NaCanId_t type includes bits which
 * are not part of the CAN ID.  Perform a logical and of this constant
 * with a NaCanId_t variable to extract just the ID bits.
 *
 * @since 7.4
 * @external    
 * @category BSP:Device_Drivers:CAN
*ad*/
#define NA_CBUS_CANID_MASK                      (0x1fffffff)



/*ad*
 * These enumerated values define the possible values of the state field in
 * @link NACBusStatus_t structures.
 *
 * @since 7.4
 * @external    
 * @category BSP:Device_Drivers:CAN
 *
 * @param NA_CBUS_STATE_NOT_RUNNING     The CAN driver has not been started yet.
 * @param NA_CBUS_STATE_FATAL_ERROR     The CAN controller has shut down due to a fatal error.
 * @param NA_CBUS_STATE_BUS_OFF         The CAN controller has taken itself off the bus because 
 *                                      it has detected too many bus errors.
 * @param NA_CBUS_STATE_ERROR_PASSIVE   The CAN controller has detected an unusually high number 
 *                                      of bus errors.  It will still transmit and receive frames, 
 *                                      but transmits are performed at a lower priority in order
 *                                      to reduce interference with other stations.
 * @param NA_CBUS_STATE_OPERATIONAL     The CAN controller is operating with no errors.
*ad*/
typedef enum
{
    NA_CBUS_STATE_NOT_RUNNING,
    NA_CBUS_STATE_FATAL_ERROR,
    NA_CBUS_STATE_BUS_OFF,
    NA_CBUS_STATE_ERROR_PASSIVE,
    NA_CBUS_STATE_OPERATIONAL
} NACBusErrorState_t;

/*ad*
 * This structure is used by the
 * @link naCBusGetStatus function to return the current state of
 * the CAN controller and driver.
 *
 * @since 7.4
 * @external    
 * @category BSP:Device_Drivers:CAN
 *
 * @param state     This field is loaded with one of the values from 
 *                  @link NACBusErrorState_t to report the current state of the 
 *                  CAN controller and driver.
 * @param receiveErrorCount     This field holds the current receive error count for
 *                              the CAN bus.  The meaning of this value is defined by
 *                              the CAN specification.
 * @param transmitErrorCount    This field holds the current transmit error count for
 *                              the CAN bus.  The meaning of this value is defined by
 *                              the CAN specification.
*ad*/
typedef struct NACBusStatus_t
{
    NACBusErrorState_t state;
    unsigned receiveErrorCount;
    unsigned transmitErrorCount;
} NACBusStatus_t;


/*ad*
 * This type defines the call back function used to receive CAN
 * frames.  Use the 
 * @link naCBusReceiverThreadInstall function to register the call back.
 *
 * The CAN driver will call the registered call back function with each 
 * received CAN frame.
 *
 * The flags field will be loaded with the control field of the frame.  The constants
 * @link NA_CBUS_FLAGS_R0_BIT and
 * @link NA_CBUS_FLAGS_R1_BIT can be used to test the R0 and R1 bits, although they
 * should always be zero.  The 
 * @link NA_CBUS_FLAGS_LENGTH_MASK can be used to retrieve the frame's raw length field.
 * Note that the CAN specification defines the length field ambiguously, so
 * the raw length field will not necessarily be the actual number of data bytes.  
 * Use the length function argument to get the number of data bytes.  The 
 * @link NA_CBUS_SENT_AUTO_RESPONSE constant can be used to determine if the frame is 
 * a request or data frame.
 *
 * @since 7.4
 * @external    
 * @category BSP:Device_Drivers:CAN
 *
 * @param interface         indicates which CAN interface the frame was received on
 * @param id                holds the ID for the frame
 * @param flags             holds the control field for the frame
 * @param buffer            holds the data bytes for the frame.  The application must
 *                          make its own copy of the data if it needs to preserve it after
 *                          the function returns.
 * @param length            number of bytes of data in the frame
 * 
 * @see @link naCBusReceiverThreadInstall
*ad*/
typedef void (* NACBusDmaReceiverFn_t)(unsigned interface, NaCanId_t id, unsigned flags, BYTE * buffer, unsigned length);

NaStatus naCBusBpsSet(unsigned interface, unsigned bitrate);
NaStatus naCBusGetStatus(unsigned interface, NACBusStatus_t * status);
NaStatus naCBusReceiverThreadInstall(unsigned interface, NACBusDmaReceiverFn_t receiverFn, unsigned stackSize, unsigned priority, unsigned threshold);
NaStatus naCBusSamplePointSet(unsigned interface, unsigned samplePoint);
NaStatus naCBusFilterSet(unsigned interface, unsigned filterNumber, NaCanId_t id, NaCanId_t mask);
NaStatus naCBusFilterSetRejectAll(unsigned interface, unsigned filterNumber);
NaStatus naCBusSjwSet(unsigned interface, unsigned sjw);
NaStatus naCBusStart(unsigned interface);
NaStatus naCBusSyncPeriodSet(unsigned interface, unsigned syncPeriod);
NaStatus naCBusTransmit(unsigned interface, NaCanId_t id, BYTE * buffer, unsigned length);
NaStatus naCBusOpen(unsigned interface);
NaStatus naCBusClose(unsigned interface);

NaStatus naCBusAutoReplyAllocate(unsigned interface, unsigned count);
NaStatus naCBusAutoReplySet(unsigned interface, unsigned rtrIndex, unsigned id, BYTE * data, unsigned length);
NaStatus naCBusAutoReplyDisable(unsigned interface, unsigned rtrIndex);


#ifdef __cplusplus
}
#endif 


#endif
