/* * Function for accessing _Communication cycle period_ (index 0x1006) from SDO server. * * For more information see file CO_SDO.h. */ static CO_SDO_abortCode_t CO_ODF_1006(CO_ODF_arg_t *ODF_arg){ CO_SYNC_t *SYNC; uint32_t value; CO_SDO_abortCode_t ret = CO_SDO_AB_NONE; SYNC = (CO_SYNC_t*) ODF_arg->object; value = CO_getUint32(ODF_arg->data); if(!ODF_arg->reading){ /* period transition from 0 to something */ if((SYNC->periodTime == 0) && (value != 0)){ SYNC->counter = 0; } SYNC->periodTime = value; SYNC->periodTimeoutTime = (value / 2U) * 3U; /* overflow? */ if(SYNC->periodTimeoutTime < value){ SYNC->periodTimeoutTime = 0xFFFFFFFFUL; } SYNC->timer = 0; } return ret; }
static CO_SDO_abortCode_t CO_ODF_1011(CO_ODF_arg_t *ODF_arg) { CO_EE_t *ee; uint32_t value; CO_SDO_abortCode_t ret = CO_SDO_AB_NONE; ee = (CO_EE_t*) ODF_arg->object; value = CO_getUint32(ODF_arg->data); if(!ODF_arg->reading) { /* don't change the old value */ CO_memcpy(ODF_arg->data, (const uint8_t*)ODF_arg->ODdataStorage, 4U); if(ODF_arg->subIndex >= 1U) { if(value == 0x64616F6CUL) { /* Clear the eeprom */ } else { ret = CO_SDO_AB_DATA_TRANSF; } } } return ret; }
static CO_SDO_abortCode_t CO_ODF_1010(CO_ODF_arg_t *ODF_arg) { CO_EE_t *ee; uint32_t value; CO_SDO_abortCode_t ret = CO_SDO_AB_NONE; ee = (CO_EE_t*) ODF_arg->object; value = CO_getUint32(ODF_arg->data); if(!ODF_arg->reading) { /* don't change the old value */ CO_memcpy(ODF_arg->data, (const uint8_t*)ODF_arg->ODdataStorage, 4U); if(ODF_arg->subIndex == 1U) { if(value == 0x65766173UL) { /* write ee->OD_ROMAddress, ee->OD_ROMSize to eeprom (blocking function) */ /* verify data */ if(0/*error*/) { ret = CO_SDO_AB_HW; } } else { ret = CO_SDO_AB_DATA_TRANSF; } } } return ret; }
CO_SDO_abortCode_t CO_ODF_1011(CO_ODF_arg_t *ODF_arg) { CO_OD_storage_t *odStor; uint32_t value; CO_SDO_abortCode_t ret = CO_SDO_AB_NONE; odStor = (CO_OD_storage_t*) ODF_arg->object; value = CO_getUint32(ODF_arg->data); if(!ODF_arg->reading) { /* don't change the old value */ CO_memcpy(ODF_arg->data, (const uint8_t*)ODF_arg->ODdataStorage, 4U); if(ODF_arg->subIndex >= 1) { /* restore default parameters */ if(value == 0x64616F6CUL) { if(CO_OD_storage_restoreSecure(odStor->filename) != 0) { ret = CO_SDO_AB_HW; } } else { ret = CO_SDO_AB_DATA_TRANSF; } } } return ret; }
static CO_SDO_abortCode_t CO_ODF_1014(CO_ODF_arg_t *ODF_arg){ uint8_t *nodeId; uint32_t value; CO_SDO_abortCode_t ret = CO_SDO_AB_NONE; nodeId = (uint8_t*) ODF_arg->object; value = CO_getUint32(ODF_arg->data); /* add nodeId to the value */ if(ODF_arg->reading){ CO_setUint32(ODF_arg->data, value + *nodeId); } return ret; }
static CO_SDO_abortCode_t CO_ODF_1200(CO_ODF_arg_t *ODF_arg){ uint8_t *nodeId; uint32_t value; CO_SDO_abortCode_t ret = CO_SDO_AB_NONE; nodeId = (uint8_t*) ODF_arg->object; value = CO_getUint32(ODF_arg->data); /* if SDO reading Object dictionary 0x1200, add nodeId to the value */ if((ODF_arg->reading) && (ODF_arg->subIndex > 0U)){ CO_setUint32(ODF_arg->data, value + *nodeId); } return ret; }
/* Restore default parameters *************************************************/ static CO_SDO_abortCode_t CO_ODF_1011(CO_ODF_arg_t *ODF_arg){ uint32_t value; CO_SDO_abortCode_t ret = CO_SDO_AB_NONE; value = CO_getUint32(ODF_arg->data); if(!ODF_arg->reading){ /* don't change the old value */ CO_memcpy(ODF_arg->data, (const uint8_t*)ODF_arg->ODdataStorage, 4U); if(ODF_arg->subIndex >= 1){ if(value == 0x64616F6CUL){ /* restore default parameters */ /* rename current file to .old, so it no longer exist */ remove(EE_ROM_FILENAME_OLD); rename(EE_ROM_FILENAME, EE_ROM_FILENAME_OLD); /* create an empty file */ FILE *fp = fopen(EE_ROM_FILENAME, "wt"); if(!fp){ rename(EE_ROM_FILENAME_OLD, EE_ROM_FILENAME); return CO_SDO_AB_HW; } /* write one byte '-' to the file */ fputc('-', fp); fclose(fp); return CO_SDO_AB_NONE; } else return CO_SDO_AB_DATA_TRANSF; } } return ret; }
/* Store parameters ***********************************************************/ static CO_SDO_abortCode_t CO_ODF_1010(CO_ODF_arg_t *ODF_arg){ CO_EE_t *ee; uint32_t value; CO_SDO_abortCode_t ret = CO_SDO_AB_NONE; ee = (CO_EE_t*) ODF_arg->object; value = CO_getUint32(ODF_arg->data); if(!ODF_arg->reading){ /* don't change the old value */ CO_memcpy(ODF_arg->data, (const uint8_t*)ODF_arg->ODdataStorage, 4U); if(ODF_arg->subIndex == 1){ if(value == 0x65766173UL){ /* store parameters */ /* rename current file to .old */ remove(EE_ROM_FILENAME_OLD); rename(EE_ROM_FILENAME, EE_ROM_FILENAME_OLD); /* open a file */ FILE *fp = fopen(EE_ROM_FILENAME, "wb"); if(!fp){ rename(EE_ROM_FILENAME_OLD, EE_ROM_FILENAME); return CO_SDO_AB_HW; } /* write data to the file */ fwrite((const void *)ee->OD_ROMAddress, 1, ee->OD_ROMSize, fp); /* write CRC to the end of the file */ uint16_t CRC = crc16_ccitt((unsigned char*)ee->OD_ROMAddress, ee->OD_ROMSize, 0); fwrite((const void *)&CRC, 1, 2, fp); fclose(fp); /* verify data */ void *buf = malloc(ee->OD_ROMSize + 4); if(buf){ fp = fopen(EE_ROM_FILENAME, "rb"); uint32_t cnt = 0; uint16_t CRC2 = 0; if(fp){ cnt = fread(buf, 1, ee->OD_ROMSize, fp); CRC2 = crc16_ccitt((unsigned char*)buf, ee->OD_ROMSize, 0); /* read also two bytes of CRC */ cnt += fread(buf, 1, 4, fp); fclose(fp); } free(buf); if(cnt == (ee->OD_ROMSize + 2) && CRC == CRC2){ /* write successful */ return CO_SDO_AB_NONE; } } /* error, set back the old file */ remove(EE_ROM_FILENAME); rename(EE_ROM_FILENAME_OLD, EE_ROM_FILENAME); return CO_SDO_AB_HW; } else return CO_SDO_AB_DATA_TRANSF; } } return ret; }
/* * Function for accessing _COB ID SYNC Message_ (index 0x1005) from SDO server. * * For more information see file CO_SDO.h. */ static CO_SDO_abortCode_t CO_ODF_1005(CO_ODF_arg_t *ODF_arg){ CO_SYNC_t *SYNC; uint32_t value; CO_SDO_abortCode_t ret = CO_SDO_AB_NONE; SYNC = (CO_SYNC_t*) ODF_arg->object; value = CO_getUint32(ODF_arg->data); if(!ODF_arg->reading){ uint8_t configureSyncProducer = 0; /* only 11-bit CAN identifier is supported */ if(value & 0x20000000UL){ ret = CO_SDO_AB_INVALID_VALUE; } else{ /* is 'generate Sync messge' bit set? */ if(value & 0x40000000UL){ /* if bit was set before, value can not be changed */ if(SYNC->isProducer){ ret = CO_SDO_AB_DATA_DEV_STATE; } else{ configureSyncProducer = 1; } } } /* configure sync producer and consumer */ if(ret == CO_SDO_AB_NONE){ SYNC->COB_ID = (uint16_t)(value & 0x7FFU); if(configureSyncProducer){ uint8_t len = 0U; if(SYNC->counterOverflowValue != 0U){ len = 1U; SYNC->counter = 0U; SYNC->timer = 0U; } SYNC->CANtxBuff = CO_CANtxBufferInit( SYNC->CANdevTx, /* CAN device */ SYNC->CANdevTxIdx, /* index of specific buffer inside CAN module */ SYNC->COB_ID, /* CAN identifier */ 0, /* rtr */ len, /* number of data bytes */ 0); /* synchronous message flag bit */ SYNC->isProducer = true; } else{ SYNC->isProducer = false; } CO_CANrxBufferInit( SYNC->CANdevRx, /* CAN device */ SYNC->CANdevRxIdx, /* rx buffer index */ SYNC->COB_ID, /* CAN identifier */ 0x7FF, /* mask */ 0, /* rtr */ (void*)SYNC, /* object passed to receive function */ CO_SYNC_receive); /* this function will process received message */ } } return ret; }