[etherlab-users] Beckhoff EL6001/EL6021 Issues
Derrill Vezina
dvezina at caron-eng.com
Fri May 23 15:01:49 CEST 2014
I have 3 state machines in my code, initialization, write, and read. The write and read state machines cannot be incremented until the initialization state machine has completed.
Everything I have done seems to match your data flow, the only difference was I was setting the 0x407x registers for the SDO configuration (the Beckhoff docs said from hardware version 03 so I wanted it to be compatible). I changed my SDO writes to the 8000:xx registers, but this did not change the data not pushing out the port. I am running the EL6021 in half duplex mode so I have tx+ tied to rx+ and tx- tied to tx-. Since I am seeing the issue with the EL6021 and the EL6001, I am just trying to get the EL6001 working first since I have the other side of the transmission line hooked up to PC.
My system is setup through a configuration file which is parsed on startup and the system adapts to what was in the contents of the file. I currently have 10 or so Beckhoff cards which are mostly I/O modules. Therefore, the SDO registers are only set on startup and do not need to have their own state machine in realtime since they can’t really change dynamically. I write all SDO registers before I configure the PDOs / domain.
Here’s how I am writing my SDO registers for the EL6001 and EL6021:
// do all of the write requests....
// the write value will change with respect to the data set in the configuration file
//
// send xon xoff tx
data[0] = ecat.device[i].EL60xx_xon_xoff_tx ? 1 : 0;
if (ecrt_master_sdo_download(ecat.master, i, 0x8000, 0x02, data, 1, &abort_code) < 0)
LOGMSG(LOG_WARNING) << "Failed to upload xon xoff tx SDO with code " << abort_code;
// check xon xoff rx
data[0] = ecat.device[i].EL60xx_xon_xoff_rx ? 1 : 0;
if (ecrt_master_sdo_download(ecat.master, i, 0x8000, 0x03, data, 1, &abort_code) < 0)
LOGMSG(LOG_WARNING) << "Failed to upload xon xoff rx SDO with code " << abort_code;
// check the baud rate
switch (ecat.device[i].EL60xx_baud_rate){
case 2400: data[0] = EL60XX_BAUD_2400; break;
case 4800: data[0] = EL60XX_BAUD_4800; break;
case 9600: data[0] = EL60XX_BAUD_9600; break;
default:
case 19200: data[0] = EL60XX_BAUD_19200; break;
case 38400: data[0] = EL60XX_BAUD_38400; break;
case 57600: data[0] = EL60XX_BAUD_57600; break;
case 115200: data[0] = EL60XX_BAUD_115200; break;
}
// upload the baud rate
if (ecrt_master_sdo_download(ecat.master, i, 0x8000, 0x11, data, 1, &abort_code) < 0)
LOGMSG(LOG_INFO) << "Failed to upload baud rate with code " << abort_code;
// check the data frame
if (ecat.device[i].EL60xx_data_bits == 7 && ecat.device[i].EL60xx_stop_bits == 1 && ecat.device[i].EL60xx_parity == 1)
data[0] = EL60XX_DATA_7E1;
else if (ecat.device[i].EL60xx_data_bits == 7 && ecat.device[i].EL60xx_stop_bits == 1 && ecat.device[i].EL60xx_parity == 2)
data[0] = EL60XX_DATA_7O1;
else if (ecat.device[i].EL60xx_data_bits == 8 && ecat.device[i].EL60xx_stop_bits == 1 && ecat.device[i].EL60xx_parity == 0)
data[0] = EL60XX_DATA_8N1;
else if (ecat.device[i].EL60xx_data_bits == 8 && ecat.device[i].EL60xx_stop_bits == 1 && ecat.device[i].EL60xx_parity == 1)
data[0] = EL60XX_DATA_8E1;
else if (ecat.device[i].EL60xx_data_bits == 8 && ecat.device[i].EL60xx_stop_bits == 1 && ecat.device[i].EL60xx_parity == 2)
data[0] = EL60XX_DATA_8O1;
else if (ecat.device[i].EL60xx_data_bits == 7 && ecat.device[i].EL60xx_stop_bits == 2 && ecat.device[i].EL60xx_parity == 2)
data[0] = EL60XX_DATA_7O2;
else if (ecat.device[i].EL60xx_data_bits == 8 && ecat.device[i].EL60xx_stop_bits == 2 && ecat.device[i].EL60xx_parity == 0)
data[0] = EL60XX_DATA_8N2;
else if (ecat.device[i].EL60xx_data_bits == 8 && ecat.device[i].EL60xx_stop_bits == 2 && ecat.device[i].EL60xx_parity == 1)
data[0] = EL60XX_DATA_8E2;
else if (ecat.device[i].EL60xx_data_bits == 8 && ecat.device[i].EL60xx_stop_bits == 2 && ecat.device[i].EL60xx_parity == 2)
data[0] = EL60XX_DATA_8O2;
else
data[0] = EL60XX_DATA_7E2;
// upload the data frame
if (ecrt_master_sdo_download(ecat.master, i, 0x8000, 0x15, data, 1, &abort_code) < 0)
LOGMSG(LOG_INFO) << "Failed to upload data frame with code " << abort_code;
// check send fifo data continuous
data[0] = ecat.device[i].EL60xx_send_fifo_continuous ? 1 : 0;
if (ecrt_master_sdo_download(ecat.master, i, 0x8000, 0x04, data, 1, &abort_code) < 0)
LOGMSG(LOG_INFO) << "Failed to upload send fifo cont. SDO with code " << abort_code;
// check send transfer rate opt.
data[0] = ecat.device[i].EL60xx_transfer_rate_opt ? 1 : 0;
if (ecrt_master_sdo_download(ecat.master, i, 0x8000, 0x05, data, 1, &abort_code) < 0)
LOGMSG(LOG_INFO) << "Failed to upload transfer rate opt. SDO with code " << abort_code;
// check the device type
if (ecat.device[i].dev_type == DEV_EL6021){
// send duplex
data[0] = ecat.device[i].EL6021_duplex ? 1 : 0;
if (ecrt_master_sdo_download(ecat.master, i, 0x8000, 0x06, data, 1, &abort_code) < 0)
LOGMSG(LOG_INFO) << "Failed to upload duplex type SDO with code " << abort_code;
// check point to point communications
data[0] = ecat.device[i].EL6021_point_to_point ? 1 : 0;
if (ecrt_master_sdo_download(ecat.master, i, 0x8000, 0x07, data, 1, &abort_code) < 0)
LOGMSG(LOG_INFO) << "Failed to upload point to point SDO with code " << abort_code;
}
else {
// check send rts cts
data[0] = ecat.device[i].EL6001_rts_cts_enable ? 1 : 0;
if (ecrt_master_sdo_download(ecat.master, i, 0x8000, 0x01, data, 1, &abort_code) < 0)
LOGMSG(LOG_INFO) << "Failed to upload rts cts enable SDO with code " << abort_code;
}
Here is my initialization sm which finishes successfully:
// check the state of the initialization
if (ecat.device[device].EL60xx_init_status == EL6021_Init_Terminal){
// read the control register first and set initialization request bit to 1
int control_byte = EC_READ_U8(ecat.domain_pd + ecat.device[device].EL60xx_control_offset);
control_byte |= EL60XX_CTRL_INIT_REQUEST;
EC_WRITE_U8(ecat.domain_pd + ecat.device[device].EL60xx_control_offset, control_byte);
// wait for verification that the initialization succeed successfully
ecat.device[device].EL60xx_init_status = EL6021_Init_Accepted;
}
else if (ecat.device[device].EL60xx_init_status == EL6021_Init_Accepted){
// read the status register to see if the device accepted the request
uint16_t status = EC_READ_U16(ecat.domain_pd + ecat.device[device].EL60xx_status_offset);
if (status & EL60XX_STAT_INIT_ACCEPTED){
// clear the init request bit...
int control_byte = EC_READ_U8(ecat.domain_pd + ecat.device[device].EL60xx_control_offset);
control_byte &= ~EL60XX_CTRL_INIT_REQUEST;
EC_WRITE_U8(ecat.domain_pd + ecat.device[device].EL60xx_control_offset, control_byte);
// wait for the transmission success
ecat.device[device].EL60xx_init_status = EL6021_Init_Verified;
}
else {
// waiting for initialization accepted...
if (ecat.device[device].EL60xx_init_print){
LOGMSG(LOG_INFO) << "Still waiting for verification of transmission on EL60xx";
ecat.device[device].EL60xx_init_print = false;
}
}
}
else if (ecat.device[device].EL60xx_init_status == EL6021_Init_Verified) {
// check the status bit and wait for terminal to set the initialization accepted bit to 0
uint16_t status = EC_READ_U16(ecat.domain_pd + ecat.device[device].EL60xx_status_offset);
if (!(status & EL60XX_STAT_INIT_ACCEPTED)){
// everything is up and running!
ecat.device[device].EL60xx_init_status = EL6021_Terminal_Ready;
// notify the user
LOGMSG(LOG_INFO) << "EL60xx device read / write terminal ready for data";
}
}
My write state sm to be working correctly as well since when I set the transmit request bit after filling the data bytes, the terminal sets the transmit request accepted bit successfully, I am just not seeing data coming out the port. This is happening with both the EL6021 and the EL6001.
This is how my write sm works right now (I just created a temporary array of 8 bytes and filled it with random data, TEST_SIZE = 8):
// get the status used for write and write sm
uint16_t status = EC_READ_U16(ecat.domain_pd + ecat.device[device].EL60xx_status_offset);
// check the write state
if (ecat.device[device].EL60xx_send_status == EL6021_Send_Idle){
// map the data to the output registers
for (int i=0;i<TEST_SIZE;i++)
EC_WRITE_U8(ecat.domain_pd + ecat.device[device].EL60xx_out_offset[i], data[i]);
// set the second byte of the control register to be the size of the output size
// mask with 255...
uint16_t control_byte = (TEST_SIZE & 255) << 8; // bit shift over by 8 and mask out the first byte
control_byte |= EL60XX_CTRL_TRANSMIT_REQUEST;
// set the transmit request bit
EC_WRITE_U8(ecat.domain_pd + ecat.device[device].EL60xx_control_offset, control_byte);
// set next step in the transaction process
ecat.device[device].EL60xx_send_status = EL6021_Send_Request;
}
else if (ecat.device[device].EL60xx_send_status == EL6021_Send_Request){
// check the status bit for successful transition...
if (status & EL60XX_STAT_TRANSMIT_ACCEPTED){
// transmit accepted and bytes sent to transmission FIFO
LOGMSG(LOG_INFO) << "Data transmission from EL6021 success with status " << status;
// set the status back to idle
ecat.device[device].EL60xx_send_status = EL6021_Send_Idle;
}
else {
// check for additional errors…
…
…
}
}
The transmit accepted status bit is set high, so my assumption is that the terminal is receiving the data (my log prints “Data transmission from EL6021 success with status ” every time through).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.etherlab.org/pipermail/etherlab-users/attachments/20140523/e29fa57c/attachment-0003.htm>
More information about the Etherlab-users
mailing list