📄 co_sdo1.c
字号:
case E_TRANSFER: // Data cannot be transfered or stored to the application
*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x08000020L;
break;
case E_LOCAL_CONTROL: // Data cannot be transfered or stored to the application because of local control
*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x08000021L;
break;
case E_DEV_STATE: // Data cannot be transfered or stored to the application because of the device present state
*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x08000022L;
break;
}
}
}
/*********************************************************************
* Function: void _CO_COMM_SDO1_RXEvent(void)
*
* PreCondition:
*
* Input: none
*
* Output: none
*
* Side Effects: none
*
* Overview: This is the SDO1 receive event handler.
*
* Note:
********************************************************************/
void _CO_COMM_SDO1_RXEvent(void)
{
// Process only if all 8 bytes of data are received
if (mCANGetDataLen() == 8)
{
// Init the abort code to success
_uSDO1ACode = E_SUCCESS;
// Get the first byte of the received message
_uSDO1Ctl.byte = mCANGetDataByte0();
switch(_uSDO1Ctl.byte & 0xE0)
{
case 0x00: // Download
// Continue only if initiated and in download state
if (_uSDO1State.bits.start)
if (_uSDO1State.bits.dnld)
{
// Compare the toggle bits.
if ((_uSDO1State.byte ^ _uSDO1Ctl.byte) & 0x10)
{
// Reset states
_uSDO1State.byte = 0;
// abort, toggle not alternated
_uSDO1ACode = E_TOGGLE;
COMM_SDO_1_TF = 1;
return;
}
// Copy data from the driver
*((_DATA7*)(_uSDO1RxBuf + _uSDO1Dict.reqOffst)) = *((_DATA7*)(mCANGetPtrRxData() + 1));
// Adjust the count or offset to the next segment
_uSDO1Dict.reqOffst += (~_uSDO1Ctl.rctl.n) & 0x07;
// If the count is greater than the object length then abort
if (_uSDO1Dict.reqOffst > _uSDO1Dict.len)
{
// Reset states
_uSDO1State.byte = 0;
// Abort
_uSDO1ACode = E_LEN_SERVICE;
COMM_SDO_1_TF = 1;
return;
}
// Set the next expected toggle
_uSDO1State.bits.tog = ~_uSDO1State.bits.tog;
// Set the header to respond, b'001t0000
_uSDO1TxBuf[0] = (_uSDO1Ctl.byte | 0x20) & 0xF0;
// Check for a complete flag
if (_uSDO1Ctl.rctl.c)
{
// Set the pointer to the buffer
_uSDO1Dict.pReqBuf = _uSDO1RxBuf;
// Write the object
mCO_DictObjectWrite(_uSDO1Dict);
// Reset states
_uSDO1State.byte = 0;
// Send code, whatever was returned from the object
_uSDO1ACode = mCO_DictGetRet();
COMM_SDO_1_TF = 1;
}
else
{
// Queue to send acknowledge
COMM_SDO_1_TF = 1;
}
}
break;
case 0x20: // Initiate Download
// Kill the current start if any
_uSDO1State.bits.start = 0;
// Store the multiplexor locally
_uSDO1TxBuf[1] = ((UNSIGNED16 *)(&(_uSDO1Dict.index)))->bytes.B0.byte = mCANGetDataByte1();
_uSDO1TxBuf[2] = ((UNSIGNED16 *)(&(_uSDO1Dict.index)))->bytes.B1.byte = mCANGetDataByte2();
_uSDO1TxBuf[3] = _uSDO1Dict.subindex = mCANGetDataByte3();
// Preload potential reserved locations
_uSDO1TxBuf[4] = 0;
_uSDO1TxBuf[5] = 0;
_uSDO1TxBuf[6] = 0;
_uSDO1TxBuf[7] = 0;
// Decode the object; this gets the data from the dictionary
// If the object is functionally defined, then the data is retrieved
// from the object's defined function.
mCO_DictObjectDecode(_uSDO1Dict);
// Was the object in the dictionary
if (mCO_DictGetRet() == E_SUCCESS)
{
// Check the access for this request; must have write capability
if (_uSDO1Dict.ctl & WR_BIT)
{
// Expedited download
if (_uSDO1Ctl.ictl.e)
{
// If the count is specified, set the request length from the header
if (_uSDO1Ctl.ictl.s) _uSDO1Dict.reqLen = (((~_uSDO1Ctl.ictl.n) & 0x03) + 1);
// Otherwise set the length from the object
else _uSDO1Dict.reqLen = _uSDO1Dict.len;
if (_uSDO1Dict.reqLen == _uSDO1Dict.len)
{
// Reset states
_uSDO1State.byte = 0;
// Set the pointer to the driver
_uSDO1Dict.pReqBuf = mCANGetPtrRxData() + 4;
// Call the object dictionary write function
mCO_DictObjectWrite(_uSDO1Dict);
// If the write was successful, queue to send acknowledge
_uSDO1TxBuf[0] = 0x60;
// Send abort, code returned from object
_uSDO1ACode = mCO_DictGetRet();
COMM_SDO_1_TF = 1;
}
else
{
// abort, data length does not match
_uSDO1ACode = E_LEN_SERVICE;
COMM_SDO_1_TF = 1;
}
}
// Segmented download
else
{
// If the count is specified
if (_uSDO1Ctl.ictl.s)
{
// Test the two upper most bytes, should be zero
if (mCANGetDataByte6() | mCANGetDataByte7())
{
// Send abort, length does not match, 0607 0010
_uSDO1ACode = E_LEN_SERVICE;
COMM_SDO_1_TF = 1;
return;
}
// Compare the length against the object's defined length
if (*((unsigned int *)(mCANGetPtrRxData() + 4)) != _uSDO1Dict.len)
{
// abort, data length does not match
_uSDO1ACode = E_LEN_SERVICE;
COMM_SDO_1_TF = 1;
return;
}
}
// Set the requested length
_uSDO1Dict.reqLen = _uSDO1Dict.len;
// Indicate a start download
_uSDO1State.bits.start = 1;
_uSDO1State.bits.dnld = 1;
// First toggle should be 0
_uSDO1State.bits.tog = 0;
// Reset the data count
_uSDO1Dict.reqOffst = 0;
// Start the watchdog
_uSDO1Timer = CO_SDO1_MAX_SEG_TIME;
//_uSDO1State.bits.ntime = 0;
// Queue to send acknowledge
_uSDO1TxBuf[0] = 0x60;
COMM_SDO_1_TF = 1;
}
}
else
{
// abort, access problem
_uSDO1ACode = E_CANNOT_WRITE;
COMM_SDO_1_TF = 1;
}
}
// Object not found
else
{
// Abort, return the appropriate code
_uSDO1ACode = mCO_DictGetRet();
COMM_SDO_1_TF = 1;
}
break;
case 0x40: // Initiate Upload
// Kill the current start
_uSDO1State.bits.start = 0;
// Store the multiplexor locally
_uSDO1TxBuf[1] = ((UNSIGNED16 *)(&(_uSDO1Dict.index)))->bytes.B0.byte = mCANGetDataByte1();
_uSDO1TxBuf[2] = ((UNSIGNED16 *)(&(_uSDO1Dict.index)))->bytes.B1.byte = mCANGetDataByte2();
_uSDO1TxBuf[3] = _uSDO1Dict.subindex = mCANGetDataByte3();
// Preload potential reserved locations
_uSDO1TxBuf[4] = 0;
_uSDO1TxBuf[5] = 0;
_uSDO1TxBuf[6] = 0;
_uSDO1TxBuf[7] = 0;
// Decode the object; this gets the data from the dictionary
mCO_DictObjectDecode(_uSDO1Dict);
// Check the return status from the decode
if (mCO_DictGetRet() == E_SUCCESS)
{
// Check the access for this request; must have read capability
if (_uSDO1Dict.ctl & RD_BIT)
{
// Reset offset
_uSDO1Dict.reqOffst = 0;
// Reset states
_uSDO1State.byte = 0;
// If the object len is greater than 4 then segment upload
if (_uSDO1Dict.len > 4)
{
// Set the watchdog
_uSDO1Timer = CO_SDO1_MAX_SEG_TIME;
//_uSDO1State.bits.ntime = 0;
// Indicate a start upload
_uSDO1State.bits.start = 1;
// Set pointer to internal buffer
_uSDO1Dict.pReqBuf = &(_uSDO1TxBuf[4]);
// Set the size of the object
_uSDO1TxBuf[4] = ((UNSIGNED16 *)(&(_uSDO1Dict.len)))->bytes.B0.byte;
_uSDO1TxBuf[5] = ((UNSIGNED16 *)(&(_uSDO1Dict.len)))->bytes.B1.byte;
// Set the response command, size indicated
_uSDO1TxBuf[0] = 0x41;
// Queue to send acknowledge
COMM_SDO_1_TF = 1;
}
// Expedited upload
else
{
// Set the length in the header
switch ((unsigned char)(_uSDO1Dict.len))
{
case 1: _uSDO1TxBuf[0] = 0x4F; break;
case 2: _uSDO1TxBuf[0] = 0x4B; break;
case 3: _uSDO1TxBuf[0] = 0x47; break;
case 4: _uSDO1TxBuf[0] = 0x43; break;
}
// Set the read length
_uSDO1Dict.reqLen = _uSDO1Dict.len;
// Set the pointer to the transmit buffer
_uSDO1Dict.pReqBuf = &(_uSDO1TxBuf[4]);
// Read the data from the object into the buffer
mCO_DictObjectRead(_uSDO1Dict);
// Pass any codes
_uSDO1ACode = mCO_DictGetRet();
COMM_SDO_1_TF = 1;
}
}
else
{
// abort, access problem
_uSDO1ACode = E_CANNOT_READ;
COMM_SDO_1_TF = 1;
}
}
// Object not found
else
{
// Abort, return the appropriate code
_uSDO1ACode = mCO_DictGetRet();
COMM_SDO_1_TF = 1;
}
break;
case 0x60: // Upload
if (_uSDO1State.bits.start) // Continue only if initiated
if (!_uSDO1State.bits.dnld) // and in a upload state
{
// Compare the toggle bits.
if ((_uSDO1State.byte ^ _uSDO1Ctl.byte) & 0x10)
{
// Reset states
_uSDO1State.byte = 0;
// abort, toggle not alternated
_uSDO1ACode = E_TOGGLE;
COMM_SDO_1_TF = 1;
return;
}
// Set the pointer to the transmit buffer
_uSDO1Dict.pReqBuf = &(_uSDO1TxBuf[1]);
// Set the offset
_uSDO1BytesLeft.word = _uSDO1Dict.len - _uSDO1Dict.reqOffst;
// If the data to be sent is less than 8 then set n and c
if (_uSDO1BytesLeft.word > 7)
{
_uSDO1TxBuf[0] = 0x00; _uSDO1Dict.reqLen = 7;
}
else
{
// Reset states
_uSDO1State.byte = 0;
switch (_uSDO1BytesLeft.bytes.B0.byte)
{
case 1: _uSDO1TxBuf[0] = 0x0D; _uSDO1Dict.reqLen = 1; break;
case 2: _uSDO1TxBuf[0] = 0x0B; _uSDO1Dict.reqLen = 2; break;
case 3: _uSDO1TxBuf[0] = 0x09; _uSDO1Dict.reqLen = 3; break;
case 4: _uSDO1TxBuf[0] = 0x07; _uSDO1Dict.reqLen = 4; break;
case 5: _uSDO1TxBuf[0] = 0x05; _uSDO1Dict.reqLen = 5; break;
case 6: _uSDO1TxBuf[0] = 0x03; _uSDO1Dict.reqLen = 6; break;
case 7: _uSDO1TxBuf[0] = 0x01; _uSDO1Dict.reqLen = 7; break;
}
}
// Setup the toggle
if (~_uSDO1Ctl.rctl.t){((union _SDO_CTL *)(_uSDO1TxBuf))->rctl.t = 0;}
else {((union _SDO_CTL *)(_uSDO1TxBuf))->rctl.t = 1;}
// Read the data from the object into the transmit buffer
mCO_DictObjectRead(_uSDO1Dict);
// Adjust the offset
_uSDO1Dict.reqOffst += _uSDO1Dict.reqLen;
// Set the next expected toggle
_uSDO1State.bits.tog = ~_uSDO1State.bits.tog;
// Queue to send the data
_uSDO1ACode = mCO_DictGetRet();
COMM_SDO_1_TF = 1;
}
break;
case 0x80: // Abort Request
// Reset SDO states
_uSDO1State.byte = 0;
break;
default:
// Send abort, not a valid command
_uSDO1ACode = E_CS_CMD;
COMM_SDO_1_TF = 1;
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -