Skip to content

Commit

Permalink
Merge pull request #112 from embedded-office/develop
Browse files Browse the repository at this point in the history
release v4.3.0
  • Loading branch information
michael-hillmann authored Jul 13, 2022
2 parents aeaba5b + 0689b81 commit 3ed1ae9
Show file tree
Hide file tree
Showing 53 changed files with 2,078 additions and 643 deletions.
25 changes: 23 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,27 @@ and starting with version 4.1.0 this project adheres to [Semantic Versioning](ht

## [unreleased]

none
- nothing

## [4.3.0] - 2022-07-13

### Added

- Add a note in documentation to usage and api about the need of sorted object dictionary
- Add support for SDO client segmented transfers [@tonbo777](https://github.com/tonbo777)
- Add support of mapping values with 3 bytes in PDOs
- Introducte callbacks for read/write PDO mapped values larger than 4 bytes

### Changed

- Adjust SDO client API documentation to reflect conditions for expedited and segmented transfers

### Fixed

- Avoid variable declaration if SDO client is disabled [@jernejsk](https://github.com/jernejsk)
- Allow direct data in object dictionaries running on 16bit microcontrollers

> **Note**: The datatype in the object dictionary was `uintptr_t` in previous versions. For 16bit microcontrollers `uintptr_t` may contain only 24bit instead of the required 32bits for direct data storage. For this reason, in version 4.3.0 and later the object dictionary should use `CO_DATA` as data type.
## [4.2.0] - 2022-04-01

Expand Down Expand Up @@ -174,7 +194,8 @@ none
- First Open Source Release.


[unreleased]: https://github.com/embedded-office/canopen-stack/compare/v4.2.0...HEAD
[unreleased]: https://github.com/embedded-office/canopen-stack/compare/v4.3.0...HEAD
[4.3.0]: https://github.com/embedded-office/canopen-stack/compare/v4.2.0...v4.3.0
[4.2.0]: https://github.com/embedded-office/canopen-stack/compare/v4.1.8...v4.2.0
[4.1.8]: https://github.com/embedded-office/canopen-stack/compare/v4.1.7...v4.1.8
[4.1.7]: https://github.com/embedded-office/canopen-stack/compare/v4.1.6...v4.1.7
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required (VERSION 3.15)
project (CanopenStack VERSION 4.2.0)
project (CanopenStack VERSION 4.3.0)

# Make CANopen library
add_subdirectory(canopen)
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The source code is compliant to the C99 standard and you must cross-compile the
- Block transfers
- Unlimited number of SDO clients which supports:
- Expedited transfers
- Segmented transfers
- Unlimited number of TPDO and RPDOs which supports:
- Synchronized operation
- Asynchronous operation
Expand Down Expand Up @@ -115,7 +116,7 @@ The CANopen dictionary is an array of object entries, which we can allocate stat
```c
const CO_OBJ MyDict[MY_DICT_LEN] = {
/* setup application specific dictionary, example entry: */
{ CO_KEY(0x1000, 0, CO_UNSIGNED32|CO_OBJ_D__R_), 0, (uintptr_t)(0u) },
{ CO_KEY(0x1000, 0, CO_UNSIGNED32|CO_OBJ_D__R_), 0, (CO_DATA)(0u) },
/* : */
};
```
Expand Down
128 changes: 126 additions & 2 deletions canopen/include/co_csdo.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ typedef enum {
CO_CSDO_TRANSFER_NONE = 0, /*!< No transfer is currently ongoing */
CO_CSDO_TRANSFER_UPLOAD = 1, /*!< SDO upload is being executed */
CO_CSDO_TRANSFER_DOWNLOAD = 2, /*!< SDO download is being executed */
CO_CSDO_TRANSFER_UPLOAD_SEGMENT = 3, /*!< SDO segment upload is being executed */
CO_CSDO_TRANSFER_DOWNLOAD_SEGMENT = 4, /*!< SDO segment download is being executed */

} CO_CSDO_TRANSFER_TYPE;

Expand Down Expand Up @@ -84,6 +86,21 @@ typedef void (*CO_CSDO_CALLBACK_T)(struct CO_CSDO_T *csdo,
uint8_t sub,
uint32_t code);


/*! \brief SDO SEGMENTED TRANSFER
*
* This structure holds the data, which are needed for the segmented
* SDO transfer.
*/
typedef struct CO_CSDO_SEG_T {
uint32_t Size; /*!< Size of object entry */
uint32_t Num; /*!< Number of transfered bytes */
uint8_t TBit; /*!< Segment toggle bit */

} CO_CSDO_SEG;



/*! \brief SDO CLIENT TRANSFER
*
* This structure contains information required for handling ongoing SDO
Expand All @@ -101,7 +118,8 @@ typedef struct CO_CSDO_TRANSFER_T {
uint32_t Size; /*!< Transfered data size */
int16_t Tmr; /*!< Identifier of timeout timer */
CO_CSDO_CALLBACK_T Call; /*!< Notification callback */

uint32_t Buf_Idx; /*!< Buffer Index */
uint8_t TBit; /*!< Segment toggle bit */
} CO_CSDO_TRANSFER;

/*! \brief SDO CLIENT
Expand All @@ -117,7 +135,6 @@ typedef struct CO_CSDO_T {
uint8_t NodeId; /*!< Node-Id of addressed SDO server */
CO_CSDO_STATE State; /*!< Current CSDO state */
CO_CSDO_TRANSFER Tfer; /*!< Current CSDO transfer info */

} CO_CSDO;

/******************************************************************************
Expand Down Expand Up @@ -356,6 +373,113 @@ void COCSdoAbort(CO_CSDO *csdo, uint32_t err);
*/
void COCSdoTransferFinalize(CO_CSDO *csdo);

/*! \brief INIT CSDO SEGMENTED UPLOAD
*
* This function generates the request for 'First Upload SDO Segment Protocol'.
*
* Entry condition for this function is the SDO response command byte
* with the following condition:
* \code
* +---+---+---+---+---+---+---+---+
* | 2 | 0 | 0 | 0 | 1 |
* +---+---+---+---+---+---+---+---+
* 7 6 5 4 3 2 1 0
*
* => condition := "command must be 0x41"*
* \endcode
*
* \param csdo
* Pointer to SDO client object
*
* \param width
* Object size in byte
*
* \retval ==CO_ERR_NONE on success
* \retval !=CO_ERR_NONE on CSDO abort
*/
CO_ERR COCSdoInitUploadSegmented(CO_CSDO *csdo);

/*! \brief SEGMENTED UPLOAD
*
* This function generates the request for 'Upload SDO Segment Protocol'.
*
* Entry condition for this function is the SDO response command byte
* with the following condition:
* \code
* +---+---+---+---+---+---+---+---+
* | 0 | t | n | c |
* +---+---+---+---+---+---+---+---+
* 7 6 5 4 3 2 1 0
*
* => condition = "command & 0xE0 must be 0x00"
* \endcode
*
* \param csdo
* Pointer to SDO client object
*
* \retval ==CO_ERR_NONE on success
* \retval !=CO_ERR_NONE on CSDO abort
*/
CO_ERR COCSdoUploadSegmented(CO_CSDO *csdo);

/*! \brief INIT CSDO SEGMENTED DOWNLOAD
*
* This function generates the request for 'First Download SDO Segment
* Protocol'.
*
* Entry condition for this function is the SDO response command byte
* with the following condition:
* \code
* +---+---+---+---+---+---+---+---+
* | 3 | 0 0 0 0 0 |
* +---+---+---+---+---+---+---+---+
* 7 6 5 4 3 2 1 0
*
* => condition = "command must be 0x60"
* \endcode
*
* \param csdo
* Pointer to SDO client object
*
* \retval ==CO_ERR_NONE on success
* \retval !=CO_ERR_NONE on CSDO abort
*/
CO_ERR COCSdoInitDownloadSegmented(CO_CSDO *csdo);

/*! \brief SEGMENTED DOWNLOAD
*
* This function generates the request for 'Download SDO Segment
* Protocol'.
*
* Entry condition for this function is the SDO request command byte
* with the following condition:
* \code
* +---+---+---+---+---+---+---+---+
* | 0 | t | n | c |
* +---+---+---+---+---+---+---+---+
* 7 6 5 4 3 2 1 0
*
* => condition = "command & 0xE0 must be 0x00"
* \endcode
*
* \param csdo
* Pointer to SDO client object
*
* \retval ==CO_ERR_NONE on success
* \retval !=CO_ERR_NONE on CSDO abort
*/
CO_ERR COCSdoDownloadSegmented(CO_CSDO *csdo);

/*! \brief
*
* This function finish SDO segmented download sequence.
*
* \param csdo
* Reference to SDO client
*
*/
CO_ERR COCSdoFinishDownloadSegmented(CO_CSDO *csdo);

#if defined __cplusplus
}
#endif
Expand Down
61 changes: 38 additions & 23 deletions canopen/include/co_obj.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ extern "C" {
* This define may be used in object dictionary definitions. It marks the
* first unused object entry.
*/
#define CO_OBJ_DIR_ENDMARK { (uint32_t)0, (CO_OBJ_TYPE *)0, (uintptr_t)0 }
#define CO_OBJ_DIR_ENDMARK { (uint32_t)0, (CO_OBJ_TYPE *)0, (CO_DATA)0 }

#define CO_TSTRING ((CO_OBJ_TYPE *)&COTString) /*!< Object Type String */
#define CO_TDOMAIN ((CO_OBJ_TYPE *)&COTDomain) /*!< Object Type Domain */
Expand Down Expand Up @@ -262,13 +262,13 @@ extern "C" {
* the CAN-ID (standard or extended format)
* \{
*/
#define CO_COBID_SYNC_STD(generate, id) \
(((uint32_t)(id) & 0x7ffuL) | \
#define CO_COBID_SYNC_STD(generate, id) \
(CO_DATA)(((uint32_t)(id) & 0x7ffuL) | \
((uint32_t)(generate) & 0x1uL) << 30u)

#define CO_COBID_SYNC_EXT(generate, id) \
(((uint32_t)(id) & 0x1fffffffuL) | \
((uint32_t)0x1uL << 29u) | \
#define CO_COBID_SYNC_EXT(generate, id) \
(CO_DATA)(((uint32_t)(id) & 0x1fffffffuL) | \
((uint32_t)0x1uL << 29u) | \
((uint32_t)(generate) & 0x1uL) << 30u)
/*! \} */

Expand All @@ -293,15 +293,15 @@ extern "C" {
* \{
*/
#define CO_COBID_TIME_STD(consume, produce, id) \
(((uint32_t)(id) & 0x7ffuL) | \
((uint32_t)(consume) & 0x1uL) << 31u) | \
((uint32_t)(produce) & 0x1uL) << 30u))
(CO_DATA)(((uint32_t)(id) & 0x7ffuL) | \
(((uint32_t)(consume) & 0x1uL) << 31u) | \
(((uint32_t)(produce) & 0x1uL) << 30u))

#define CO_COBID_TIME_EXT(consume, produce, id) \
(((uint32_t)(id) & 0x1fffffffuL) | \
(CO_DATA)(((uint32_t)(id) & 0x1fffffffuL) | \
((uint32_t)0x1uL << 29u) | \
((uint32_t)(consume) & 0x1uL) << 31u) | \
((uint32_t)(produce) & 0x1uL) << 30u))
(((uint32_t)(consume) & 0x1uL) << 31u) | \
(((uint32_t)(produce) & 0x1uL) << 30u))
/*! \} */

/*! \brief COB-ID EMCY
Expand All @@ -324,13 +324,13 @@ extern "C" {
* \{
*/
#define CO_COBID_EMCY_STD(valid, id) \
(((uint32_t)(id) & 0x7ffuL) | \
((uint32_t)(1u - ((valid) & 0x1u)) << 31u)
(CO_DATA)(((uint32_t)(id) & 0x7ffuL) | \
((uint32_t)(1u - ((valid) & 0x1u)) << 31u))

#define CO_COBID_EMCY_EXT(valid, id) \
(((uint32_t)(id) & 0x1fffffffuL) | \
(CO_DATA)(((uint32_t)(id) & 0x1fffffffuL) | \
((uint32_t)0x1uL << 29u) | \
((uint32_t)(1u - ((valid) & 0x1u)) << 31u)
((uint32_t)(1u - ((valid) & 0x1u)) << 31u))
/*! \} */

/*! \brief SDO server/client COB-ID parameter
Expand All @@ -357,12 +357,12 @@ extern "C" {
* \{
*/
#define CO_COBID_SDO_STD(valid, dynamic, id) \
(((uint32_t)(id) & 0x7ffuL) | \
(CO_DATA)(((uint32_t)(id) & 0x7ffuL) | \
(((uint32_t)(dynamic) & 0x1u) << 30u) | \
((uint32_t)(1uL - ((valid) & 0x1u)) << 31u))

#define CO_COBID_SDO_EXT(valid, dynamic, id) \
(((uint32_t)(id) & 0x1fffffffuL) | \
(CO_DATA)(((uint32_t)(id) & 0x1fffffffuL) | \
((uint32_t)0x1u << 29u) | \
(((uint32_t)(dynamic) & 0x1u) << 30u) | \
((uint32_t)(1uL - ((valid) & 0x1u)) << 31u))
Expand Down Expand Up @@ -396,11 +396,11 @@ extern "C" {
* \{
*/
#define CO_COBID_RPDO_STD(valid, id) \
(((uint32_t)(id) & 0x7ffuL) | \
(CO_DATA)(((uint32_t)(id) & 0x7ffuL) | \
((uint32_t)(1uL - ((valid) & 0x1u)) << 31u))

#define CO_COBID_RPDO_EXT(valid, id) \
(((uint32_t)(id) & 0x1fffffffuL) | \
(CO_DATA)(((uint32_t)(id) & 0x1fffffffuL) | \
((uint32_t)0x1u << 29u) | \
((uint32_t)(1uL - ((valid) & 0x1u)) << 31u))
/*! \} */
Expand Down Expand Up @@ -440,12 +440,12 @@ extern "C" {
* \{
*/
#define CO_COBID_TPDO_STD(valid, id) \
(((uint32_t)(id) & 0x7ffuL) | \
(CO_DATA)(((uint32_t)(id) & 0x7ffuL) | \
((uint32_t)0x1u << 30u) | \
((uint32_t)(1uL - ((valid) & 0x1u)) << 31u))

#define CO_COBID_TPDO_EXT(valid, id) \
(((uint32_t)(id) & 0x1fffffffuL) | \
(CO_DATA)(((uint32_t)(id) & 0x1fffffffuL) | \
((uint32_t)0x1u << 29u) | \
((uint32_t)0x1u << 30u) | \
((uint32_t)(1uL - ((valid) & 0x1u)) << 31u))
Expand Down Expand Up @@ -473,6 +473,21 @@ struct CO_NODE_T; /* Declaration of canopen node structure */
struct CO_OBJ_TYPE_T; /* Declaration of object type structure */
struct CO_DICT_T; /* Declaration of object dictionary structure */

/*! \brief OBJECT DATA TYPE
*
* This type holds a pointer to the object entrys data. To allow storage of
* constant values directly within the object dictionary, this type must be
* able to hold a complete 32bit value.
*
* \note This is required for 8bit and 16bit controllers, where pointers may
* represent 24bit only.
*/
#if UINTPTR_MAX < UINT32_MAX
typedef uint32_t CO_DATA;
#else
typedef uintptr_t CO_DATA;
#endif

/*! \brief OBJECT ENTRY
*
* This structure holds all data, needed for managing a single object
Expand All @@ -490,7 +505,7 @@ typedef struct CO_OBJ_T {
/* - 7: 1=direct (ptr is value if Type=0) */
const struct CO_OBJ_TYPE_T *Type; /*!< ==0: value access via Data-Ptr, */
/* !=0: access via type structure */
uintptr_t Data; /*!< Address of value or data structure */
CO_DATA Data; /*!< Address of value or data structure */
/* or data value for direct access */
} CO_OBJ;

Expand Down
Loading

0 comments on commit 3ed1ae9

Please sign in to comment.