1
0
Fork 0
CANopenNode/OD/domainDemo.c
Pedro Rodríguez Vieites 8751c52836 Added support for CiA 401 / Driver example / Test example.
User must implement the CANInterface for its own hardware
2025-03-07 17:02:55 +01:00

157 lines
5.3 KiB
C

/**
* Example access to the Object Dictionary variable of type domain.
*
* @file domainDemo.c
* @author --
* @copyright 2021 --
*
* This file is part of CANopenNode, an opensource CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "domainDemo.h"
#ifndef DOMAIN_DEMO_LENGTH_INDICATE
#define DOMAIN_DEMO_LENGTH_INDICATE 1
#endif
/* Global variables are used here for simplicity. */
/* Data simulation for domain */
static uint8_t dataSimulated = 0;
/* Index of current data byte transferred. */
static OD_size_t dataIndex = 0;
/* Size of data to be transferred. It is used when reading domainDemo
* and updated after writing domainDemo. */
static OD_size_t dataSize = 1024;
/* Extension for OD object OD_domainDemo */
static OD_extension_t domainDemo_extension;
/*
* Custom function for reading OD object _domainDemo_
*
* For more information see file CO_ODinterface.h, OD_IO_t.
*/
static ODR_t OD_read_domainDemo(OD_stream_t* stream, void* buf, OD_size_t count, OD_size_t* countRead) {
if (stream == NULL || buf == NULL || countRead == NULL || stream->subIndex != 0) {
return ODR_DEV_INCOMPAT;
}
/* Data is simple repeating sequence of values 0..255. Data can be much
* longer than count (available size of the buffer). So
* OD_read_domainDemo() may be called multiple times. */
if (stream->dataOffset == 0) {
/* Data offset is 0, so this is the first call of this function
* in current (SDO) communication. Initialize variables. */
dataSimulated = 0;
dataIndex = 0;
#if DOMAIN_DEMO_LENGTH_INDICATE > 0
/* Indicate dataLength */
size_t dataLen = dataSize;
stream->dataLength = dataLen <= 0xFFFFFFFF ? dataLen : 0;
#else
/* It is not required to indicate data length in SDO transfer */
stream->dataLength = 0;
#endif
}
/* copy application data into buf */
OD_size_t i;
for (i = 0; i < count; i++) {
uint8_t* bufU8 = (uint8_t*)buf;
if (dataIndex >= dataSize) {
break;
}
bufU8[i] = dataSimulated++;
dataIndex++;
}
*countRead = i;
/* finished? */
if (dataIndex >= dataSize) {
stream->dataOffset = 0;
return ODR_OK;
}
/* indicate partial read, this function will be called again. */
stream->dataOffset = dataIndex;
return ODR_PARTIAL;
}
/*
* Custom function for reading OD object _domainDemo_
*
* For more information see file CO_ODinterface.h, OD_IO_t.
*/
static ODR_t OD_write_domainDemo(OD_stream_t* stream, const void* buf, OD_size_t count, OD_size_t* countWritten) {
if (stream == NULL || buf == NULL || countWritten == NULL || stream->subIndex != 0) {
return ODR_DEV_INCOMPAT;
}
/* Data will be just verified for correct sequence in this example
* (repeating sequence of values 0..255). Data can be much longer than
* count (current size of data in the buffer). So OD_write_domainDemo() may
* be called multiple times. */
if (stream->dataOffset == 0) {
/* Data offset is 0, so this is the first call of this function
* in current SDO communication. Initialize variables. */
dataSimulated = 0;
dataIndex = 0;
}
/* copy received data into application */
OD_size_t i;
for (i = 0; i < count; i++) {
uint8_t* bufU8 = (uint8_t*)buf;
/* for simulation just verify, if received data is in sequence */
if (bufU8[i] != dataSimulated++) {
return ODR_INVALID_VALUE;
}
dataIndex++;
}
*countWritten = i;
stream->dataOffset = dataIndex;
/* determine, if file write finished or not (dataLength may not yet be
* indicated) */
if (stream->dataLength > 0 && stream->dataOffset >= stream->dataLength) {
stream->dataOffset = 0;
/* Simulation - set data size to data size currently written. */
dataSize = dataIndex;
return ODR_OK;
}
/* indicate partial write, this function will be called again. */
return ODR_PARTIAL;
}
/******************************************************************************/
CO_ReturnError_t domainDemo_init(OD_entry_t* OD_domainDemo, uint32_t* errInfo) {
if (OD_domainDemo == NULL || errInfo == NULL)
return CO_ERROR_ILLEGAL_ARGUMENT;
/* Initialize custom OD object "domainDemo" */
domainDemo_extension.object = NULL;
domainDemo_extension.read = OD_read_domainDemo;
domainDemo_extension.write = OD_write_domainDemo;
ODR_t odRet = OD_extension_init(OD_domainDemo, &domainDemo_extension);
if (odRet != ODR_OK) {
*errInfo = OD_getIndex(OD_domainDemo);
return CO_ERROR_OD_PARAMETERS;
}
return CO_ERROR_NO;
}