📄 sdo.c
字号:
if( nbytes <= 1 )
{
if( spi_set_holdtime( msg_data[4] ) == FALSE )
sdo_error = SDO_ECODE_ATTRIBUTE;
}
else
{
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
break;
case 2:
if( nbytes <= 1 )
{
if( spi_set_rising_clk( msg_data[4] ) == FALSE )
sdo_error = SDO_ECODE_ATTRIBUTE;
}
else
{
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
break;
default:
/* The sub-index does not exist */
sdo_error = SDO_ECODE_ATTRIBUTE;
break;
}
break;
default:
/* The index can not be accessed, does not exist */
sdo_error = SDO_ECODE_NONEXISTENT;
break;
}
break;
#ifdef __2313_SLAVE_PRESENT__
case OD_PROGRAM_CODE_HI:
if( od_index_lo == OD_PROGRAM_CODE_LO )
{
if( od_subind == 1 )
{
if( nbytes == 4 || nbytes == 0 )
{
if( do_serial_instruction( &msg_data[4] ) == FALSE )
{
/* Something wrong with parameters */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The sub-index does not exist */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The index can not be accessed, does not exist */
sdo_error = SDO_ECODE_NONEXISTENT;
}
break;
#endif /* __2313_SLAVE_PRESENT__ */
case OD_SWITCH_TO_LOADER_HI:
if( od_index_lo == OD_SWITCH_TO_LOADER_LO )
{
if( od_subind == 0 )
{
if( nbytes <= 1 )
{
#ifdef __2313_SLAVE_PRESENT__
/* Disable Timer1 interrupt to stop
the Slave aliveness-check mechanism:
Slave should take control of the node,
after some time, unless.... */
timer1_stop();
#endif /* __2313_SLAVE_PRESENT__ */
/* Send a reply before making the jump... */
msg_data[0] = SDO_INITIATE_DOWNLOAD_RESP;
msg_data[4] = 0;
can_write( C91_SDOTX, C91_SDOTX_LEN, msg_data );
timer2_delay_ms( 5 );
/* ...there is a Bootloader: it will take control
(and also keep the Slave happy, if present) */
jump_to_bootloader();
}
else
{
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The sub-index does not exist */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The index can not be accessed, does not exist */
sdo_error = SDO_ECODE_NONEXISTENT;
}
break;
case OD_DEVICE_INFO_HI:
switch( od_index_lo )
{
case OD_LIFETIME_FACTOR_LO:
if( od_subind == 0 )
{
if( nbytes <= 1 )
{
/* Set new Life Time Factor */
if( guarding_set_lifetime( msg_data[4] ) == FALSE )
sdo_error = SDO_ECODE_ATTRIBUTE;
}
else
{
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The sub-index does not exist */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
break;
case OD_STORE_PARAMETERS_LO:
if( od_subind >= 1 && od_subind <= OD_STORE_MAX_SUBID )
{
if( nbytes == 4 || nbytes == 0 )
{
/* Check for correct signature */
if( msg_data[4] == 's' && msg_data[5] == 'a' &&
msg_data[6] == 'v' && msg_data[7] == 'e' )
{
if( store_save_parameters( od_subind ) == FALSE )
{
/* Something went wrong */
sdo_error = SDO_ECODE_HARDWARE;
}
}
}
else
{
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The sub-index does not exist */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
break;
case OD_DFLT_PARAMETERS_LO:
if( od_subind >= 1 && od_subind <= OD_STORE_MAX_SUBID )
{
if( nbytes == 4 || nbytes == 0 )
{
/* Check for correct signature */
if( msg_data[4] == 'l' && msg_data[5] == 'o' &&
msg_data[6] == 'a' && msg_data[7] == 'd' )
{
if( store_set_defaults( od_subind ) == FALSE )
{
/* Something went wrong */
sdo_error = SDO_ECODE_HARDWARE;
}
}
}
else
{
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The sub-index does not exist */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
break;
case OD_HEARTBEAT_TIME_LO:
if( od_subind == 0 )
{
if( nbytes == 2 || nbytes == 0 )
{
/* Set new Heartbeat Time */
if( guarding_set_heartbeattime( &msg_data[4] ) == FALSE )
sdo_error = SDO_ECODE_ATTRIBUTE;
}
else
{
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The sub-index does not exist */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
break;
default:
/* The index can not be accessed, does not exist */
sdo_error = SDO_ECODE_NONEXISTENT;
break;
}
break;
case OD_CAN_CONFIG_HI:
if( od_index_lo == OD_CAN_CONFIG_LO )
{
switch( od_subind )
{
case 1:
if( nbytes <= 1 )
{
if( can_set_rtr_disabled( msg_data[4] ) == FALSE )
sdo_error = SDO_ECODE_ATTRIBUTE;
}
else
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
break;
case 2:
if( nbytes <= 1 )
{
if( can_set_opstate_init( msg_data[4] ) == FALSE )
sdo_error = SDO_ECODE_ATTRIBUTE;
}
else
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
break;
case 3:
if( nbytes <= 1 )
{
if( can_set_busoff_maxcnt( msg_data[4] ) == FALSE )
sdo_error = SDO_ECODE_ATTRIBUTE;
}
else
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
break;
default:
/* The sub-index does not exist */
sdo_error = SDO_ECODE_ATTRIBUTE;
break;
}
}
else
{
/* The index can not be accessed, does not exist */
sdo_error = SDO_ECODE_NONEXISTENT;
break;
}
break;
case OD_ADC_CALIB_RANGE_HI:
if( od_index_lo == OD_ADC_CALIB_RANGE_LO )
{
/* There are six voltage ranges on this ADC */
if( od_subind != 0 && od_subind <= STORE_ADC_CALIB_BLOCKS )
{
if( nbytes == 4 || nbytes == 0 )
{
if( adc_calibrate_range( od_subind-1 ) == FALSE )
{
/* Reset or self-calibrate operation failed */
sdo_error = SDO_ECODE_HARDWARE;
}
}
else
{
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The sub-index does not exist */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The index can not be accessed, does not exist */
sdo_error = SDO_ECODE_NONEXISTENT;
}
break;
case OD_ADC_CALIB_PARS_HI:
if( od_index_lo < STORE_ADC_CALIB_BLOCKS )
{
/* Check for valid parameters */
if( od_subind != 0 && od_subind <= STORE_ADC_CALIB_PARS )
{
if( nbytes == 4 || nbytes == 0 )
{
if( adc_set_calib_const( od_index_lo, od_subind-1,
&msg_data[4] ) == FALSE )
{
/* Something went wrong while writing to EEPROM */
sdo_error = SDO_ECODE_HARDWARE;
}
}
else
{
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The sub-index does not exist */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The index can not be accessed, does not exist */
sdo_error = SDO_ECODE_NONEXISTENT;
}
break;
case OD_ADC_CALIB_ERASE_HI:
if( od_index_lo < STORE_ADC_CALIB_BLOCKS )
{
/* Check for valid parameters */
if( od_subind == 0 )
{
if( nbytes <= 1 )
{
if( adc_erase_calib_const( od_index_lo,
msg_data[4] ) == FALSE )
{
/* Something went wrong while writing to EEPROM */
sdo_error = SDO_ECODE_HARDWARE;
}
}
else
{
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The sub-index does not exist */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The index can not be accessed, does not exist */
sdo_error = SDO_ECODE_NONEXISTENT;
}
break;
case OD_ADC_CALIB_WR_ENA_HI:
if( od_index_lo == OD_ADC_CALIB_WR_ENA_LO )
{
if( od_subind == 0 )
{
if( nbytes <= 1 )
{
if( adc_calib_const_write_enable( msg_data[4] ) == FALSE )
{
/* Something wrong with parameters */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The sub-index does not exist */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The index can not be accessed, does not exist */
sdo_error = SDO_ECODE_NONEXISTENT;
}
break;
case OD_ELMB_SERIAL_NO_HI:
switch( od_index_lo )
{
case OD_ELMB_SERIAL_NO_LO:
if( od_subind == 0 )
{
if( nbytes == 4 || nbytes == 0 )
{
/* Set the ELMB Serial Number */
if( sn_set_serial_number( &msg_data[4] ) == FALSE )
{
/* Something went wrong */
sdo_error = SDO_ECODE_HARDWARE;
}
}
else
{
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The sub-index does not exist */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
break;
case OD_ELMB_SN_WRITE_ENA_LO:
if( od_subind == 0 )
{
if( nbytes <= 1 )
{
/* Enable a write-operation to the ELMB Serial Number */
if( sn_serial_number_write_enable( msg_data[4] ) == FALSE )
{
/* Something wrong with parameters */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* Wrong number of bytes provided */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
}
else
{
/* The sub-index does not exist */
sdo_error = SDO_ECODE_ATTRIBUTE;
}
break;
default:
/* The index can not be accessed, does not exist */
sdo_error = SDO_ECODE_NONEXISTENT;
break;
}
break;
default:
/* The index can not be accessed, does not exist */
sdo_error = SDO_ECODE_NONEXISTENT;
break;
}
/* Set appropriate SDO command specifier for reply */
msg_data[0] = SDO_INITIATE_DOWNLOAD_RESP;
/* CANopen: bytes 4 to 7 reserved, so set to zero, except when programming
the Slave: the SDO reply possibly contains a read memory byte... */
if( od_index_hi != OD_PROGRAM_CODE_HI )
{
msg_data[4] = 0;
msg_data[5] = 0;
msg_data[6] = 0;
msg_data[7] = 0;
}
return sdo_error;
}
/* ------------------------------------------------------------------------ */
static void sdo_abort( BYTE error_class,
BYTE error_code,
BYTE *msg_data )
{
msg_data[0] = SDO_ABORT_TRANSFER;
/* msg_data[1], msg_data[2], msg_data[3] should contain
index and sub-index: leave intact */
/* Error class */
msg_data[7] = error_class;
/* Error code */
msg_data[6] = error_code;
/* Additional code, not filled in for the time being */
msg_data[5] = 0;
msg_data[4] = 0;
can_write( C91_SDOTX, C91_SDOTX_LEN, msg_data );
}
/* ------------------------------------------------------------------------ */
/* Function call which results in a jump to address 0xF000
which starts the Bootloader program
(provided the Bootloader size is set (by the fuses) to 4 kWords!) */
static void jump_to_bootloader( void )
{
#ifndef __ELMB103__
BYTE flashbyte;
/* Set (byte) address in the proper registers (for ELPM access) */
asm( "ldi R30,0x00" );
asm( "ldi R31,0xE0" );
/* Set RAMPZ register to access the upper 64k page of program memory */
RAMPZ = 1;
/* Read the program memory byte and store it in 'flashbyte' */
asm( "elpm" );
asm( "mov %flashbyte, R0" );
/* Reset RAMPZ register */
RAMPZ = 0;
/* If there is no Bootloader, return to the user application ! */
if( flashbyte == 0xFF )
{
/* CANopen Error Code 0x6000: device software */
can_write_emergency( 0x00, 0x50, EMG_NO_BOOTLOADER,
0, 0, 0, ERRREG_MANUFACTURER );
return;
}
/* Disable watchdog timer (if possible) */
watchdog_disable();
/* Disable all interrupts */
CLI();
/* Z-pointer: 0xF000 (word address) */
asm( "ldi R30,0x00" );
asm( "ldi R31,0xF0" );
/* Jump to the Bootloader at (word) address 0xF000 */
asm( "ijmp" );
#endif /* __ELMB103__ */
}
/* ------------------------------------------------------------------------ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -