MCUXpresso_MIMXRT1052xxxxB/middleware/canopen/mco/mcohw.h
2022-04-08 22:46:35 +08:00

241 lines
11 KiB
C

/**************************************************************************
MODULE: MCOHW
CONTAINS: Hardware driver specification for MicroCANopen
The specific implementations are named mcohwXXX.c, where
XXX represents the CAN hardware used.
COPYRIGHT: (c) Embedded Systems Academy (EmSA) 2002-2020
All rights reserved. www.em-sa.com/nxp
DISCLAIM: Read and understand our disclaimer before using this code!
www.esacademy.com/disclaim.htm
This software was written in accordance to the guidelines at
www.esacademy.com/software/softwarestyleguide.pdf
LICENSE: THIS IS THE NXP SDK VERSION OF MICROCANOPEN PLUS
Licensed under a modified BSD License. See LICENSE.INFO
file in the project root for full license information.
VERSION: 7.10, ESA 20-SEP-02
$LastChangedDate: 2020-09-03 22:04:52 +0200 (Thu, 03 Sep 2020) $
$LastChangedRevision: 5038 $
Implementation recommendations:
1.) CAN interrupt
The CAN interrupt should check all the possible error flags and set the
global variable gMCOConfig.HWstatus accordingly. Fatal errors must result
in a call to MCOUSER_FatalError with an error code in the range of 0x8000
to 0x87FF.
If a transmit queue is implemented, the transmit interrupt should be used
to trigger transmission of the next message in the transmit queue.
On "Basic CAN" controllers the receive interrupt copies the incoming message
into a receive FIFO. CAN controllers with "Full CAN" style capabilities
or internal receive queue might not need to maintain a software queue.
In case a hardware queue or buffers are used, the interrupt should still
check for a potential overrun and set bit RXOR in gMCOConfig.HWstatus in
case of an overrun.
2.) Timer interrupt
A 1ms timer interrupt needs to implement a local 1ms uint16_t timer tick.
The timer tick is only accessable via the functions MCOHW_GetTime and
MCOHW_IsTimeExpired to avoid data inconsistency.
In case only a multiple of 1ms is available on a system, the timer tick
would need to be incremented in each interrupt in a way that the timer
tick is still accurate (for example increment by 4 all 4ms).
***************************************************************************/
#ifndef _MCOHW_H
#define _MCOHW_H
#ifdef __cplusplus
extern "C" {
#endif
#include "mco.h"
/**************************************************************************
DOES: This function returns the global status variable.
CHANGES: The status can be changed anytime by this module, for example from
within an interrupt service routine or by any of the other
functions in this module.
BITS: 0: INIT - set to 1 after a completed initialization
left 0 if not yet inited or init failed
1: CERR - set to 1 if a CAN bit or frame error occurred
2: ERPA - set to 1 if a CAN "error passive" occurred
3: RXOR - set to 1 if a receive queue overrun occurred
4: TXOR - set to 1 if a transmit queue overrun occurred
5: Reserved
6: TXBSY - set to 1 if Transmit queue is not empty
7: BOFF - set to 1 if a CAN "bus off" error occurred
**************************************************************************/
uint8_t MCOHW_GetStatus(void);
/**************************************************************************
DOES: This function implements the initialization of the CAN interface.
RETURNS: 1 if init is completed
0 if init failed, bit INIT of MCOHW_GetStatus stays 0
**************************************************************************/
uint8_t MCOHW_Init(uint16_t BaudRate // Allowed values: 1000, 800, 500, 250, 125, 50, 25, 10
#if defined(USE_CANOPEN_FD) && (USE_CANOPEN_FD == 1)
,
uint16_t BRSBaudRate
#endif
);
/**************************************************************************
DOES: This function implements the initialization of a CAN ID hardware
filter as supported by many CAN controllers.
If hardware filters are not supported, a system can use software
filters as provided by module canfifo.c or no filters at all
(in that case ALL CAN messages are received and evaluated by
MicroCANopen)
RETURNS: 1 if filter was set
2 if this HW does not support filters
(in this case HW will receive EVERY CAN message)
0 if no more filter is available
**************************************************************************/
uint8_t MCOHW_SetCANFilter(COBID_TYPE CANID // CAN-ID to be received by filter
);
/**************************************************************************
DOES: This function implements the deletion of a previously set CAN ID
hardware filter as supported by many CAN controllers.
This function is only required if a CANopen node uses dynmaic
PDO linking extensively (frequent changes of CAN IDs used by PDOs)
RETURNS: 1 if filter was deleted
0 if filter could not be deleted
**************************************************************************/
uint8_t MCOHW_ClearCANFilter(COBID_TYPE CANID);
#if defined(USE_CANOPEN_FD) && (USE_CANOPEN_FD == 1)
/**************************************************************************
DOES: This function implements the initialization of a CAN ID hardware
filter as supported by many CAN controllers.
Allows a range of identifiers to be received
RETURNS: 1 if filter was set
2 if this HW does not support filters
(in this case HW will receive EVERY CAN message)
0 if no more filter is available
**************************************************************************/
uint8_t MCOHW_SetCANFilterRange(COBID_TYPE CANID_Start, // start of identifier range
COBID_TYPE CANID_End // end of identifier range
);
#endif // USE_CANOPEN_FD
/**************************************************************************
DOES: This function implements a CAN transmit queue. With each
function call is added to the queue.
RETURNS: 1 Message was added to the transmit queue
0 If queue is full, message was not added,
bit TXOR in MCOHW_GetStatus set
NOTES: The MicroCANopen stack will not try to add messages to the queue
"back-to-back". With each call to MCO_ProcessStack, a maximum
of one message is added to the queue. For many applications
a queue with length "1" will be sufficient. Only applications
with a high busload or very slow bus speed might need a queue
of length "3" or more.
**************************************************************************/
uint8_t MCOHW_PushMessage(CAN_MSG MEM_FAR *pTransmitBuf // Data structure with message to be send
);
/**************************************************************************
DOES: This function implements a CAN receive queue. With each
function call a message is pulled from the queue.
RETURNS: 1 Message was pulled from receive queue
0 Queue empty, no message received
NOTES: Implementation of this function greatly varies with CAN
controller used. In an SJA1000 style controller, the hardware
queue inside the controller can be used as the queue. Controllers
with just one receive buffer need a bigger software queue.
"Full CAN" style controllers might just implement multiple
message objects, one each for each ID received (using function
MCOHW_SetCANFilter).
**************************************************************************/
uint8_t MCOHW_PullMessage(CAN_MSG MEM_FAR *pTransmitBuf // Data structure with message received
);
/**************************************************************************
DOES: This function reads a 1 millisecond timer tick. The timer tick
must be a uint16_t and must be incremented once per millisecond.
RETURNS: 1 millisecond timer tick
NOTES: Data consistency must be insured by this implementation.
(On 8-bit systems, disable the timer interrupt incrementing
the timer tick while executing this function)
Systems that cannot provide a 1ms tick may consider incrementing
the timer tick only once every "x" ms, if the increment is by "x".
**************************************************************************/
uint16_t MCOHW_GetTime(void);
/**************************************************************************
DOES: This function compares a uint16_t timestamp to the internal timer tick
and returns 1 if the timestamp expired/passed.
RETURNS: 1 if timestamp expired/passed
0 if timestamp is not yet reached
NOTES: The maximum timer runtime measurable is 0x8000 (about 32 seconds).
For the usage in MicroCANopen that is sufficient.
**************************************************************************/
uint8_t MCOHW_IsTimeExpired(uint16_t timestamp // Timestamp to be checked for expiration
);
/**************************************************************************
// Recommended implementation for this function (8051 version):
{
uint16_t time_now;
EA = 0; // Disable Interrupts
time_now = gTimCnt;
EA = 1; // Enable Interrupts
timestamp++; // To ensure the minimum runtime
if (time_now > timestamp)
{
if ((time_now - timestamp) < 0x8000)
return 1;
else
return 0;
}
else
{
if ((timestamp - time_now) >= 0x8000)
return 1;
else
return 0;
}
}
**************************************************************************/
#if USE_SYNC_PRODUCER
/**************************************************************************
DOES: Activates the SYNC producer.
NOTE: Sync signal is only produced while MY_NMT_STATE is NMTSTATE_OP.
RETURNS: Notrhing.
**************************************************************************/
void MCOHW_SetSyncProducer(COBID_TYPE canid, // CAN ID used for SYNC production
uint32_t cycle, // SYNC cycle time in microseconds
uint8_t cntovr // SYNC overflow counter, zero for none used
);
#endif
#if MGR_MONITOR_ALL_NODES
/**************************************************************************
DOES: Sets all CAN receive filters for the Manager
RETURNS: TRUE or FALSE, if filter is not available
**************************************************************************/
uint8_t MCOHWMGR_SetCANFilter(void);
/**************************************************************************
DOES: Examines if a new message arrived in the receive queue
for the Manager
RETURNS: TRUE if a message was copied from the receive queue
**************************************************************************/
uint8_t MCOHWMGR_PullMessage(CAN_MSG MEM_FAR *pReceiveBuf);
#endif // MGR_MONITOR_ALL_NODES
#ifdef __cplusplus
}
#endif
#endif // _MCOHW_H
/**************************************************************************
END OF FILE
**************************************************************************/