184 void *ptr = malloc(
sizeof(
struct __co_tpdo));
193__co_tpdo_free(
void *ptr)
216 if (!obj_1800 || !obj_1a00) {
227 memset(&pdo->
comm, 0,
sizeof(pdo->
comm));
228 memset(&pdo->
map, 0,
sizeof(pdo->
map));
233 goto error_create_recv;
240 goto error_create_timer_event;
247 goto error_create_timer_swnd;
253 pdo->
inhibit = (
struct timespec){ 0, 0 };
277error_create_timer_swnd:
279error_create_timer_event:
305 trace(
"creating Transmit-PDO %d", num);
312 goto error_alloc_pdo;
315 if (!__co_tpdo_init(pdo, net, dev, num)) {
333 trace(
"destroying Transmit-PDO %d", tpdo->
num);
334 __co_tpdo_fini(tpdo);
335 __co_tpdo_free(tpdo);
347 co_unsigned16_t idx_1800 = 0x1800 + pdo->
num - 1;
351 memset(&pdo->
comm, 0,
sizeof(pdo->
comm));
352 pdo->
comm.
n = co_dev_get_val_u8(pdo->
dev, idx_1800, 0);
353 pdo->
comm.
cobid = co_dev_get_val_u32(pdo->
dev, idx_1800, 1);
354 pdo->
comm.
trans = co_dev_get_val_u8(pdo->
dev, idx_1800, 2);
356 pdo->
comm.
event = co_dev_get_val_u16(pdo->
dev, idx_1800, 5);
357 pdo->
comm.
sync = co_dev_get_val_u8(pdo->
dev, idx_1800, 6);
362 co_unsigned16_t idx_1a00 = 0x1a00 + pdo->
num - 1;
366 memset(&pdo->
map, 0,
sizeof(pdo->
map));
367 pdo->
map.
n = co_dev_get_val_u8(pdo->
dev, idx_1a00, 0);
372 pdo->
map.
map[subidx - 1] = co_sub_get_val_u32(sub);
518 if (pdo->
map.
n > 0x40)
523 case 0x00: pdo->
event = 1;
break;
584 if (pdo->
sync && cnt) {
585 if (pdo->
sync != cnt)
630 if (pdo->
map.
n > 0x40)
640 pdo->
ind(pdo, ac, NULL, 0, pdo->
data);
667 co_unsigned8_t subidx,
const co_unsigned8_t data[4])
711 msg->
data[0] =
id | 0x80;
713 msg->
data[3] = subidx;
776 msg->
data[3] = subidx;
780 pdo->
dev, idx, subidx, &pdo->
req, msg->
data + 4);
783 pdo->
ind(pdo, ac, NULL, 0, pdo->
data);
846 co_unsigned32_t swnd = co_dev_get_val_u32(pdo->
dev, 0x1007, 0x00);
848 struct timespec start = { 0, 0 };
855static co_unsigned32_t
868 co_unsigned32_t ac = 0;
876 co_unsigned32_t cobid = val.u32;
877 co_unsigned32_t cobid_old = co_sub_get_val_u32(sub);
878 if (cobid == cobid_old)
887 if (valid && valid_old && canid != canid_old)
897 if (valid && !valid_old) {
917 co_unsigned8_t trans = val.u8;
918 co_unsigned8_t trans_old = co_sub_get_val_u8(sub);
919 if (trans == trans_old)
923 if (trans > 0xf0 && trans < 0xfc)
927 if ((trans == 0xfc || trans == 0xfd)
938 co_unsigned16_t inhibit = val.u16;
939 co_unsigned16_t inhibit_old = co_sub_get_val_u16(sub);
940 if (inhibit == inhibit_old)
953 co_unsigned16_t
event = val.u16;
954 co_unsigned16_t event_old = co_sub_get_val_u16(sub);
955 if (event == event_old)
965 co_unsigned8_t sync = val.u8;
966 co_unsigned8_t sync_old = co_sub_get_val_u8(sub);
967 if (sync == sync_old)
986static co_unsigned32_t
995 co_unsigned32_t ac = 0;
1008 co_unsigned8_t n = val.u8;
1009 co_unsigned8_t n_old = co_sub_get_val_u8(sub);
1019 for (
size_t i = 1; i <= n; i++) {
1020 co_unsigned32_t map = pdo->
map.
map[i - 1];
1026 co_unsigned16_t idx = (map >> 16) & 0xffff;
1027 co_unsigned8_t subidx = (map >> 8) & 0xff;
1028 co_unsigned8_t len = map & 0xff;
1038 pdo->
dev, idx, subidx)))
1054 co_unsigned32_t map = val.u32;
1055 co_unsigned32_t map_old = co_sub_get_val_u32(sub);
1061 if (valid || pdo->
map.
n)
1066 co_unsigned16_t idx = (map >> 16) & 0xffff;
1067 co_unsigned8_t subidx = (map >> 8) & 0xff;
1155 assert(pdo->
map.
n <= 0x40);
1173 pdo->
ind(pdo, ac, NULL, 0, pdo->
data);
@ CAN_FLAG_IDE
The Identifier Extension (IDE) flag.
@ CAN_FLAG_RTR
The Remote Transmission Request (RTR) flag (unavailable in CAN FD format frames).
#define CAN_MASK_EID
The mask used to extract the 29-bit Extended Identifier from a CAN frame.
#define CAN_MAX_LEN
The maximum number of bytes in the payload of a CAN format frame.
#define CAN_MASK_BID
The mask used to extract the 11-bit Base Identifier from a CAN frame.
#define CAN_MSG_INIT
The static initializer for can_msg.
This header file is part of the CANopen library; it contains the device description declarations.
co_obj_t * co_dev_find_obj(const co_dev_t *dev, co_unsigned16_t idx)
Finds an object in the object dictionary of a CANopen device.
co_unsigned8_t co_dev_get_id(const co_dev_t *dev)
Returns the node-ID of a CANopen device.
#define CO_NUM_NODES
The maximum number of nodes in a CANopen network.
This header file is part of the utilities library; it contains the byte order (endianness) function d...
void stle_u16(uint_least8_t dst[2], uint_least16_t x)
Stores a 16-bit unsigned integer in little-endian byte order.
This header file is part of the utilities library; it contains the native and platform-independent er...
int errnum2c(errnum_t errnum)
Transforms a platform-independent error number to a native error code.
@ ERRNUM_INVAL
Invalid argument.
@ ERRNUM_AGAIN
Resource unavailable, try again.
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
This header file is part of the CANopen library; it contains the Service Data Object (SDO) declaratio...
int co_sdo_req_dn_val(struct co_sdo_req *req, co_unsigned16_t type, void *val, co_unsigned32_t *pac)
Copies the next segment of the specified CANopen SDO download request to the internal buffer and,...
void co_sdo_req_fini(struct co_sdo_req *req)
Finalizes a CANopen SDO upload/download request.
#define CO_SDO_AC_ERROR
SDO abort code: General error.
#define CO_SDO_AC_NO_SUB
SDO abort code: Sub-index does not exist.
#define CO_SDO_AC_PARAM_VAL
SDO abort code: Invalid value for parameter (download only).
#define CO_SDO_AC_PDO_LEN
SDO abort code: The number and length of the objects to be mapped would exceed the PDO length.
void co_sdo_req_init(struct co_sdo_req *req)
Initializes a CANopen SDO upload/download request.
#define CO_SDO_AC_TIMEOUT
SDO abort code: SDO protocol timed out.
#define CO_SDO_AC_NO_WRITE
SDO abort code: Attempt to write a read only object.
void can_timer_stop(can_timer_t *timer)
Stops a CAN timer and unregisters it with a network interface.
int can_net_send(can_net_t *net, const struct can_msg *msg)
Sends a CAN frame from a network interface.
void can_timer_start(can_timer_t *timer, can_net_t *net, const struct timespec *start, const struct timespec *interval)
Starts a CAN timer and registers it with a network interface.
can_timer_t * can_timer_create(void)
Creates a new CAN timer.
void can_net_get_time(const can_net_t *net, struct timespec *tp)
Retrieves the current time of a CAN network interface.
void can_timer_set_func(can_timer_t *timer, can_timer_func_t *func, void *data)
Sets the callback function invoked when a CAN timer is triggered.
void can_recv_stop(can_recv_t *recv)
Stops a CAN frame receiver from processing frames and unregisters it with the network interface.
void can_recv_set_func(can_recv_t *recv, can_recv_func_t *func, void *data)
Sets the callback function used to process CAN frames with a receiver.
void can_recv_destroy(can_recv_t *recv)
Destroys a CAN frame receiver.
void can_timer_timeout(can_timer_t *timer, can_net_t *net, int timeout)
Starts a CAN timer and registers it with a network interface.
void can_recv_start(can_recv_t *recv, can_net_t *net, uint_least32_t id, uint_least8_t flags)
Registers a CAN frame receiver with a network interface and starts processing frames.
can_recv_t * can_recv_create(void)
Creates a new CAN frame receiver.
void can_timer_destroy(can_timer_t *timer)
Destroys a CAN timer.
This header file is part of the CANopen library; it contains the object dictionary declarations.
co_sub_t * co_obj_first_sub(const co_obj_t *obj)
Finds the first sub-object (with the lowest sub-index) in a CANopen object.
co_unsigned8_t co_sub_get_subidx(const co_sub_t *sub)
Returns the sub-index of a CANopen sub-object.
co_unsigned16_t co_obj_get_idx(const co_obj_t *obj)
Returns the index of a CANopen object.
int co_sub_dn(co_sub_t *sub, void *val)
Downloads (moves) a value into a CANopen sub-object if the refuse-write-on-download flag (CO_OBJ_FLAG...
void co_obj_set_dn_ind(co_obj_t *obj, co_sub_dn_ind_t *ind, void *data)
Sets the download indication function for a CANopen object.
co_sub_t * co_sub_next(const co_sub_t *sub)
Finds the next sub-object in a CANopen object.
co_obj_t * co_sub_get_obj(const co_sub_t *sub)
Returns the a pointer to the CANopen object containing the specified sub-object.
co_unsigned16_t co_sub_get_type(const co_sub_t *sub)
Returns the data type of a CANopen sub-object.
co_unsigned32_t co_pdo_up(const struct co_pdo_map_par *par, const co_dev_t *dev, struct co_sdo_req *req, uint_least8_t *buf, size_t *pn, int chk)
Reads mapped PDO values from the object dictionary through a local SDO upload request.
co_unsigned32_t co_sam_mpdo_up(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx, struct co_sdo_req *req, uint_least8_t buf[4])
Reads the value of the specified SAM-MPDO-mapped object from the local object dictionary through a lo...
#define CO_PDO_NUM_MAPS
The maximum number of mapped application objects in a single PDO.
co_unsigned32_t co_dev_chk_tpdo(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx)
Checks if the specified object is valid and can be mapped into a Transmit-PDO.
#define CO_PDO_COBID_FRAME
The bit in the PDO COB-ID specifying whether to use an 11-bit (0) or 29-bit (1) CAN-ID.
#define CO_PDO_COBID_VALID
The bit in the PDO COB-ID specifying whether the PDO exists and is valid.
#define CO_NUM_PDOS
The maximum number of Receive/Transmit-PDOs.
#define CO_PDO_MAP_DAM_MPDO
The value of sub-index 0 of the PDO mapping parameter record indicating a a destination address mode ...
#define CO_PDO_COBID_RTR
The bit in the PDO COB-ID specifying whether RTR is allowed.
#define CO_PDO_MAP_SAM_MPDO
The value of sub-index 0 of the PDO mapping parameter record indicating a a source address mode multi...
This is the internal header file of the CANopen library.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
This header file is part of the C11 and POSIX compatibility library; it includes <string....
void * sample_data
A pointer to user-specified data for sample_ind.
struct co_sdo_req req
The CANopen SDO upload request used for reading sub-objects.
unsigned int swnd
A flag indicating the synchronous time window has expired.
struct co_pdo_map_par map
The PDO mapping parameter.
struct can_msg msg
A buffered CAN frame, used for RTR-only or event-driven TPDOs.
can_recv_t * recv
A pointer to the CAN frame receiver.
co_unsigned16_t num
The PDO number.
struct co_pdo_comm_par comm
The PDO communication parameter.
co_dev_t * dev
A pointer to a CANopen device.
co_unsigned8_t sync
The SYNC start value.
unsigned int event
A flag indicating the occurrence of an event.
co_unsigned8_t cnt
The SYNC counter value.
co_tpdo_ind_t * ind
A pointer to the indication function.
can_net_t * net
A pointer to a CAN network interface.
struct timespec inhibit
The time at which the next event-driven TPDO may be sent.
void * data
A pointer to user-specified data for ind.
int stopped
A flag specifying whether the Transmit-PDO service is stopped.
co_tpdo_sample_ind_t * sample_ind
A pointer to the sampling indication function.
can_timer_t * timer_event
A pointer to the CAN timer for events.
can_timer_t * timer_swnd
A pointer to the CAN timer for the synchronous time window.
A CAN or CAN FD format frame.
uint_least8_t data[CAN_MSG_MAX_LEN]
The frame payload (in case of a data frame).
uint_least32_t id
The identifier (11 or 29 bits, depending on the CAN_FLAG_IDE flag).
uint_least8_t flags
The flags (any combination of CAN_FLAG_IDE, CAN_FLAG_RTR, CAN_FLAG_FDF, CAN_FLAG_BRS and CAN_FLAG_ESI...
uint_least8_t len
The number of bytes in data (or the requested number of bytes in case of a remote frame).
A PDO communication parameter record.
co_unsigned8_t sync
SYNC start value.
co_unsigned16_t inhibit
Inhibit time.
co_unsigned16_t event
Event timer.
co_unsigned32_t cobid
COB-ID.
co_unsigned8_t trans
Transmission type.
co_unsigned8_t n
Highest sub-index supported.
A PDO mapping parameter record.
co_unsigned8_t n
Number of mapped objects in PDO.
co_unsigned32_t map[CO_PDO_NUM_MAPS]
An array of objects to be mapped.
A CANopen SDO upload/download request.
int co_tpdo_is_stopped(const co_tpdo_t *pdo)
Retuns 1 if the specified Transmit-PDO service is stopped, and 0 if not.
can_net_t * co_tpdo_get_net(const co_tpdo_t *pdo)
Returns a pointer to the CAN network of a Transmit-PDO.
static void co_tpdo_init_recv(co_tpdo_t *pdo)
Initializes the CAN frame receiver of a Transmit-PDO service.
void co_tpdo_set_sample_ind(co_tpdo_t *pdo, co_tpdo_sample_ind_t *ind, void *data)
Sets the indication function invoked when a Transmit-PDO starts sampling after the reception of a SYN...
void co_tpdo_destroy(co_tpdo_t *tpdo)
Destroys a CANopen Transmit-PDO service.
static co_unsigned32_t co_1800_dn_ind(co_sub_t *sub, struct co_sdo_req *req, void *data)
The download indication function for (all sub-objects of) CANopen objects 1800..19FF (TPDO communicat...
int co_tpdo_event(co_tpdo_t *pdo)
Triggers the transmission of an acyclic or event-driven PDO.
void co_tpdo_get_sample_ind(const co_tpdo_t *pdo, co_tpdo_sample_ind_t **pind, void **pdata)
Retrieves the indication function invoked when a Transmit-PDO starts sampling after the reception of ...
static void co_tpdo_init_timer_event(co_tpdo_t *pdo)
Initializes the CAN timer for events of a Transmit-PDO service.
int co_sam_mpdo_event(co_tpdo_t *pdo, co_unsigned16_t idx, co_unsigned8_t subidx)
Triggers the transmission of a DAM-MPDO.
static int co_tpdo_timer_swnd(const struct timespec *tp, void *data)
The CAN timer callback function for the synchronous time window of a Transmit-PDO service.
const struct co_pdo_map_par * co_tpdo_get_map_par(const co_tpdo_t *pdo)
Returns a pointer to the PDO mapping parameter record of a Transmit-PDO.
int co_tpdo_sample_res(co_tpdo_t *pdo, co_unsigned32_t ac)
Indicates the result of the sampling step after the reception of a SYNC event.
static int co_tpdo_timer_event(const struct timespec *tp, void *data)
The CAN timer callback function for events of a Transmit-PDO service.
const struct co_pdo_comm_par * co_tpdo_get_comm_par(const co_tpdo_t *pdo)
Returns a pointer to the PDO communication parameter record of a Transmit-PDO.
co_tpdo_t * co_tpdo_create(can_net_t *net, co_dev_t *dev, co_unsigned16_t num)
Creates a new CANopen Transmit-PDO service.
void co_tpdo_get_next(const co_tpdo_t *pdo, struct timespec *tp)
Retrieves the time at which the next event-driven TPDO may be sent.
void co_tpdo_get_ind(const co_tpdo_t *pdo, co_tpdo_ind_t **pind, void **pdata)
Retrieves the indication function invoked when a Transmit-PDO is sent or an error occurs.
static int co_tpdo_recv(const struct can_msg *msg, void *data)
The CAN receive callback function for a Transmit-PDO service.
int co_dam_mpdo_event(co_tpdo_t *pdo, co_unsigned8_t id, co_unsigned16_t idx, co_unsigned8_t subidx, const co_unsigned8_t data[4])
Triggers the transmission of a DAM-MPDO.
void co_tpdo_set_ind(co_tpdo_t *pdo, co_tpdo_ind_t *ind, void *data)
Sets the indication function invoked when a Transmit-PDO is sent or an error occurs.
int co_tpdo_start(co_tpdo_t *pdo)
Starts a Transmit-PDO service.
static co_unsigned32_t co_1a00_dn_ind(co_sub_t *sub, struct co_sdo_req *req, void *data)
The download indication function for (all sub-objects of) CANopen objects 1A00..1BFF (TPDO mapping pa...
int co_tpdo_sync(co_tpdo_t *pdo, co_unsigned8_t cnt)
Triggers the transmission of a synchronous PDO.
co_dev_t * co_tpdo_get_dev(const co_tpdo_t *pdo)
Returns a pointer to the CANopen device of a Transmit-PDO.
static int default_sample_ind(co_tpdo_t *pdo, void *data)
The default sampling indication function.
void co_tpdo_stop(co_tpdo_t *pdo)
Stops a Transmit-PDO service.
static int co_tpdo_init_frame(co_tpdo_t *pdo, struct can_msg *msg)
Initializes a CAN frame to be sent by a Transmit-PDO service.
co_unsigned16_t co_tpdo_get_num(const co_tpdo_t *pdo)
Returns the PDO number of a Transmit-PDO.
static int co_tpdo_send_frame(co_tpdo_t *pdo, const struct can_msg *msg)
Sends a CAN frame from a Transmit-PDO service and invokes the indication function.
static void co_tpdo_init_timer_swnd(co_tpdo_t *pdo)
Initializes the CAN timer for the synchronous time window of a Transmit-PDO service.
This header file is part of the CANopen library; it contains the Transmit-PDO declarations.
int co_tpdo_sample_ind_t(co_tpdo_t *pdo, void *data)
The type of a CANopen Transmit-PDO sampling indication function, invoked when the device starts sampl...
void co_tpdo_ind_t(co_tpdo_t *pdo, co_unsigned32_t ac, const void *ptr, size_t n, void *data)
The type of a CANopen Transmit-PDO indication function, invoked when a PDO is sent or an error occurs...
#define CO_DEFTYPE_UNSIGNED16
The data type (and object index) of a 16-bit unsigned integer.
int co_type_is_array(co_unsigned16_t type)
Returns 1 if the specified (static) data type is an array, and 0 if not.
#define CO_DEFTYPE_UNSIGNED8
The data type (and object index) of an 8-bit unsigned integer.
#define CO_DEFTYPE_UNSIGNED32
The data type (and object index) of a 32-bit unsigned integer.
A union of the CANopen static data types.
This header file is part of the utilities library; it contains the time function declarations.
int timespec_cmp(const void *p1, const void *p2)
Compares two times.
void timespec_add_usec(struct timespec *tp, uint_least64_t usec)
Adds usec microseconds to the time at tp.
This header file is part of the CANopen library; it contains the CANopen value declarations.