mirror of
https://gitlab.com/etherlab.org/ethercat.git
synced 2026-02-06 11:51:45 +08:00
Basic reading realtime Sdo access working.
This commit is contained in:
@@ -41,10 +41,13 @@
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
// module parameters
|
||||
// Module parameters
|
||||
#define FREQUENCY 100
|
||||
|
||||
// Optional features
|
||||
#define CONFIGURE_MAPPING
|
||||
#define EXTERNAL_MEMORY
|
||||
#define SDO_ACCESS
|
||||
|
||||
#define PFX "ec_mini: "
|
||||
|
||||
@@ -112,6 +115,13 @@ static ec_pdo_info_t el2004_mapping[] = {
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifdef SDO_ACCESS
|
||||
static ec_sdo_request_t *sdo;
|
||||
static int not_first_time = 0;
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void check_domain1_state(void)
|
||||
{
|
||||
ec_domain_state_t ds;
|
||||
@@ -155,6 +165,32 @@ void check_master_state(void)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifdef SDO_ACCESS
|
||||
void read_sdo(void)
|
||||
{
|
||||
switch (ecrt_sdo_request_state(sdo)) {
|
||||
case EC_REQUEST_COMPLETE:
|
||||
if (not_first_time) {
|
||||
printk(KERN_INFO PFX "Sdo value: 0x%04X\n",
|
||||
EC_READ_U16(ecrt_sdo_request_data(sdo)));
|
||||
} else {
|
||||
not_first_time = 1;
|
||||
}
|
||||
ecrt_sdo_request_read(sdo);
|
||||
break;
|
||||
case EC_REQUEST_FAILURE:
|
||||
printk(KERN_INFO PFX "Failed to read Sdo!\n");
|
||||
ecrt_sdo_request_read(sdo);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_INFO PFX "Still busy...\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void cyclic_task(unsigned long data)
|
||||
{
|
||||
// receive process data
|
||||
@@ -168,7 +204,7 @@ void cyclic_task(unsigned long data)
|
||||
|
||||
if (counter) {
|
||||
counter--;
|
||||
} else { // do this at FREQUENCY
|
||||
} else { // do this at 1 Hz
|
||||
counter = FREQUENCY;
|
||||
|
||||
// calculate new process data
|
||||
@@ -176,6 +212,11 @@ void cyclic_task(unsigned long data)
|
||||
|
||||
// check for master state (optional)
|
||||
check_master_state();
|
||||
|
||||
#ifdef SDO_ACCESS
|
||||
// read process data Sdo
|
||||
read_sdo();
|
||||
#endif
|
||||
}
|
||||
|
||||
// write process data
|
||||
@@ -256,6 +297,19 @@ int __init init_mini_module(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SDO_ACCESS
|
||||
printk(KERN_INFO PFX "Creating Sdo requests...\n");
|
||||
if (!(sc = ecrt_master_slave_config(master, 0, 1, Beckhoff_EL3162))) {
|
||||
printk(KERN_ERR PFX "Failed to get slave configuration.\n");
|
||||
goto out_release_master;
|
||||
}
|
||||
|
||||
if (!(sdo = ecrt_slave_config_create_sdo_request(sc, 0x3102, 2, 2))) {
|
||||
printk(KERN_ERR PFX "Failed to create Sdo request.\n");
|
||||
goto out_release_master;
|
||||
}
|
||||
#endif
|
||||
|
||||
printk(KERN_INFO PFX "Registering Pdo entries...\n");
|
||||
if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
|
||||
printk(KERN_ERR PFX "Pdo entry registration failed!\n");
|
||||
|
||||
@@ -131,6 +131,9 @@ typedef struct ec_slave_config ec_slave_config_t; /**< \see ec_slave_config */
|
||||
struct ec_domain;
|
||||
typedef struct ec_domain ec_domain_t; /**< \see ec_domain */
|
||||
|
||||
struct ec_sdo_request;
|
||||
typedef struct ec_sdo_request ec_sdo_request_t; /**< \see ec_sdo_request. */
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Bus state.
|
||||
@@ -248,6 +251,28 @@ typedef struct {
|
||||
offset in the process data. */
|
||||
} ec_pdo_entry_reg_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Generic request state.
|
||||
*/
|
||||
typedef enum {
|
||||
EC_REQUEST_QUEUED,
|
||||
EC_REQUEST_IN_PROGRESS,
|
||||
EC_REQUEST_COMPLETE,
|
||||
EC_REQUEST_FAILURE
|
||||
} ec_request_state_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Sdo request error.
|
||||
*
|
||||
* This is used as return type of ecrt_sdo_request_error().
|
||||
*/
|
||||
typedef enum {
|
||||
EC_SDO_REQUEST_SUCCESS, /**< There is no error. */
|
||||
EC_SDO_REQUEST_TIMEOUT, /**< The request timed out. */
|
||||
} ec_sdo_request_error_t;
|
||||
|
||||
/******************************************************************************
|
||||
* Global functions
|
||||
*****************************************************************************/
|
||||
@@ -513,6 +538,18 @@ int ecrt_slave_config_sdo32(
|
||||
uint32_t value /**< Value to set. */
|
||||
);
|
||||
|
||||
/** Create an Sdo request to exchange Sdos during realtime operation.
|
||||
*
|
||||
* The created Sdo request object is freed automatically when the master is
|
||||
* released.
|
||||
*/
|
||||
ec_sdo_request_t *ecrt_slave_config_create_sdo_request(
|
||||
ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
uint16_t index, /**< Sdo index. */
|
||||
uint8_t subindex, /**< Sdo subindex. */
|
||||
size_t size /**< Data size to reserve. */
|
||||
);
|
||||
|
||||
/** Outputs the state of the slave configuration.
|
||||
*
|
||||
* Stores the state information in the given \a state structure.
|
||||
@@ -599,6 +636,62 @@ void ecrt_domain_state(
|
||||
information. */
|
||||
);
|
||||
|
||||
/*****************************************************************************
|
||||
* Sdo request methods.
|
||||
****************************************************************************/
|
||||
|
||||
/** Set the timeout for an Sdo request.
|
||||
*
|
||||
* If the request cannot be processed in the specified time, if will be marked
|
||||
* as failed.
|
||||
*/
|
||||
void ecrt_sdo_request_timeout(
|
||||
ec_sdo_request_t *req, /**< Sdo request. */
|
||||
uint32_t timeout /**< Timeout in milliseconds. */
|
||||
);
|
||||
|
||||
/** Access to the Sdo request's data.
|
||||
*
|
||||
* \attention The return value is invalid during (ecrt_sdo_request_state() !=
|
||||
* EC_REQUEST_COMPLETE) a read operation, because the internal Sdo data
|
||||
* memory could be re-allocated.
|
||||
*
|
||||
* \return Pointer to the internal Sdo data memory.
|
||||
*/
|
||||
uint8_t *ecrt_sdo_request_data(
|
||||
ec_sdo_request_t *req /**< Sdo request. */
|
||||
);
|
||||
|
||||
/** Get the current state of the Sdo request.
|
||||
*
|
||||
* \return Request state.
|
||||
*/
|
||||
ec_request_state_t ecrt_sdo_request_state(
|
||||
const ec_sdo_request_t *req /**< Sdo request. */
|
||||
);
|
||||
|
||||
/** Get the error code of the Sdo request.
|
||||
*/
|
||||
ec_sdo_request_error_t ecrt_sdo_request_error(
|
||||
const ec_sdo_request_t *req /**< Sdo request. */
|
||||
);
|
||||
|
||||
/** Schedule an Sdo write operation.
|
||||
*/
|
||||
void ecrt_sdo_request_write(
|
||||
ec_sdo_request_t *req /**< Sdo request. */
|
||||
);
|
||||
|
||||
/** Schedule an Sdo read operation .
|
||||
*
|
||||
* \attention After calling this function, the return value of
|
||||
* ecrt_sdo_request_data() will be invalid until ecrt_sdo_request_state()
|
||||
* is EC_REQUEST_COMPLETE.
|
||||
*/
|
||||
void ecrt_sdo_request_read(
|
||||
ec_sdo_request_t *req /**< Sdo request. */
|
||||
);
|
||||
|
||||
/******************************************************************************
|
||||
* Bitwise read/write macros
|
||||
*****************************************************************************/
|
||||
|
||||
@@ -182,7 +182,7 @@ void ec_fsm_coe_map_action_next_dir(
|
||||
ec_pdo_mapping_clear_pdos(&fsm->mapping);
|
||||
|
||||
ec_sdo_request_address(&fsm->request, fsm->sync_sdo_index, 0);
|
||||
ec_sdo_request_read(&fsm->request);
|
||||
ecrt_sdo_request_read(&fsm->request);
|
||||
fsm->state = ec_fsm_coe_map_state_pdo_count;
|
||||
ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request);
|
||||
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
|
||||
@@ -238,7 +238,7 @@ void ec_fsm_coe_map_action_next_pdo(
|
||||
if (fsm->sync_subindex <= fsm->sync_subindices) {
|
||||
ec_sdo_request_address(&fsm->request, fsm->sync_sdo_index,
|
||||
fsm->sync_subindex);
|
||||
ec_sdo_request_read(&fsm->request);
|
||||
ecrt_sdo_request_read(&fsm->request);
|
||||
fsm->state = ec_fsm_coe_map_state_pdo;
|
||||
ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request);
|
||||
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
|
||||
@@ -295,7 +295,7 @@ void ec_fsm_coe_map_state_pdo(
|
||||
list_add_tail(&fsm->pdo->list, &fsm->mapping.pdos);
|
||||
|
||||
ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0);
|
||||
ec_sdo_request_read(&fsm->request);
|
||||
ecrt_sdo_request_read(&fsm->request);
|
||||
fsm->state = ec_fsm_coe_map_state_pdo_entry_count;
|
||||
ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request);
|
||||
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
|
||||
@@ -342,7 +342,7 @@ void ec_fsm_coe_map_action_next_pdo_entry(
|
||||
{
|
||||
if (fsm->pdo_subindex <= fsm->pdo_subindices) {
|
||||
ec_sdo_request_address(&fsm->request, fsm->pdo->index, fsm->pdo_subindex);
|
||||
ec_sdo_request_read(&fsm->request);
|
||||
ecrt_sdo_request_read(&fsm->request);
|
||||
fsm->state = ec_fsm_coe_map_state_pdo_entry;
|
||||
ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request);
|
||||
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "globals.h"
|
||||
#include "master.h"
|
||||
#include "mailbox.h"
|
||||
#include "slave_config.h"
|
||||
#ifdef EC_EOE
|
||||
#include "ethernet.h"
|
||||
#endif
|
||||
@@ -376,9 +377,39 @@ int ec_fsm_master_action_process_sdo(
|
||||
{
|
||||
ec_master_t *master = fsm->master;
|
||||
ec_master_sdo_request_t *request;
|
||||
ec_sdo_request_t *req;
|
||||
ec_slave_t *slave;
|
||||
|
||||
// search the first request to be processed
|
||||
// search for internal requests to be processed
|
||||
list_for_each_entry(slave, &master->slaves, list) {
|
||||
if (!slave->config)
|
||||
continue;
|
||||
list_for_each_entry(req, &slave->config->sdo_requests, list) {
|
||||
if (req->state == EC_REQUEST_QUEUED) {
|
||||
req->state = EC_REQUEST_IN_PROGRESS;
|
||||
|
||||
if (slave->current_state == EC_SLAVE_STATE_INIT ||
|
||||
slave->error_flag) {
|
||||
req->state = EC_REQUEST_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (master->debug_level)
|
||||
EC_DBG("Processing Sdo request for slave %u...\n",
|
||||
slave->ring_position);
|
||||
|
||||
fsm->idle = 0;
|
||||
fsm->sdo_request = req;
|
||||
fsm->slave = slave;
|
||||
fsm->state = ec_fsm_master_state_sdo_request;
|
||||
ec_fsm_coe_upload(&fsm->fsm_coe, slave, req);
|
||||
ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// search the first external request to be processed
|
||||
while (1) {
|
||||
down(&master->sdo_sem);
|
||||
if (list_empty(&master->slave_sdo_requests)) {
|
||||
@@ -410,7 +441,8 @@ int ec_fsm_master_action_process_sdo(
|
||||
|
||||
// Start uploading Sdo
|
||||
fsm->idle = 0;
|
||||
fsm->sdo_request = request;
|
||||
fsm->sdo_request = &request->req;
|
||||
fsm->slave = slave;
|
||||
fsm->state = ec_fsm_master_state_sdo_request;
|
||||
ec_fsm_coe_upload(&fsm->fsm_coe, slave, &request->req);
|
||||
ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
|
||||
@@ -499,7 +531,7 @@ void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for a pending Sdo request
|
||||
// Check for pending Sdo requests
|
||||
if (ec_fsm_master_action_process_sdo(fsm))
|
||||
return;
|
||||
|
||||
@@ -1026,25 +1058,25 @@ void ec_fsm_master_state_sdodict(ec_fsm_master_t *fsm /**< master state machine
|
||||
void ec_fsm_master_state_sdo_request(ec_fsm_master_t *fsm /**< master state machine */)
|
||||
{
|
||||
ec_master_t *master = fsm->master;
|
||||
ec_master_sdo_request_t *request = fsm->sdo_request;
|
||||
ec_sdo_request_t *request = fsm->sdo_request;
|
||||
|
||||
if (ec_fsm_coe_exec(&fsm->fsm_coe)) return;
|
||||
|
||||
if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
|
||||
EC_DBG("Failed to process Sdo request for slave %i.\n",
|
||||
EC_DBG("Failed to process Sdo request for slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
request->req.state = EC_REQUEST_FAILURE;
|
||||
request->state = EC_REQUEST_FAILURE;
|
||||
wake_up(&master->sdo_queue);
|
||||
fsm->state = ec_fsm_master_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// Sdo request finished
|
||||
request->req.state = EC_REQUEST_COMPLETE;
|
||||
request->state = EC_REQUEST_COMPLETE;
|
||||
wake_up(&master->sdo_queue);
|
||||
|
||||
if (master->debug_level)
|
||||
EC_DBG("Finished Sdo request for slave %i.\n",
|
||||
EC_DBG("Finished Sdo request for slave %u.\n",
|
||||
fsm->slave->ring_position);
|
||||
|
||||
// check for another Sdo request
|
||||
|
||||
@@ -97,7 +97,7 @@ struct ec_fsm_master {
|
||||
ec_slave_t *slave; /**< current slave */
|
||||
ec_eeprom_write_request_t *eeprom_request; /**< EEPROM write request */
|
||||
off_t eeprom_index; /**< index to EEPROM write request data */
|
||||
ec_master_sdo_request_t *sdo_request; /**< Sdo request to process. */
|
||||
ec_sdo_request_t *sdo_request; /**< Sdo request to process. */
|
||||
|
||||
ec_fsm_slave_config_t fsm_slave_config; /**< slave state machine */
|
||||
ec_fsm_slave_scan_t fsm_slave_scan; /**< slave state machine */
|
||||
|
||||
@@ -214,7 +214,7 @@ void ec_fsm_pdo_config_next_pdo(
|
||||
EC_WRITE_U8(&fsm->request.data, 0);
|
||||
fsm->request.data_size = 1;
|
||||
ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0);
|
||||
ec_sdo_request_write(&fsm->request);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Setting entry count to zero for Pdo 0x%04X.\n",
|
||||
fsm->pdo->index);
|
||||
@@ -254,7 +254,7 @@ void ec_fsm_pdo_config_add_entry(
|
||||
EC_WRITE_U32(&fsm->request.data, value);
|
||||
fsm->request.data_size = 4;
|
||||
ec_sdo_request_address(&fsm->request, fsm->pdo->index, fsm->entry_count);
|
||||
ec_sdo_request_write(&fsm->request);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Configuring Pdo entry %08X at position %u.\n",
|
||||
value, fsm->entry_count);
|
||||
@@ -320,7 +320,7 @@ void ec_fsm_pdo_config_state_add_entry(
|
||||
EC_WRITE_U8(&fsm->request.data, fsm->entry_count);
|
||||
fsm->request.data_size = 1;
|
||||
ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0);
|
||||
ec_sdo_request_write(&fsm->request);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Setting number of Pdo entries to %u.\n",
|
||||
fsm->entry_count);
|
||||
|
||||
@@ -205,7 +205,7 @@ void ec_fsm_pdo_mapping_next_dir(
|
||||
EC_WRITE_U8(&fsm->request.data, 0); // zero Pdos mapped
|
||||
fsm->request.data_size = 1;
|
||||
ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, 0);
|
||||
ec_sdo_request_write(&fsm->request);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Setting Pdo count to zero for SM%u.\n", fsm->sync->index);
|
||||
|
||||
@@ -248,7 +248,7 @@ void ec_fsm_pdo_mapping_add_pdo(
|
||||
fsm->request.data_size = 2;
|
||||
ec_sdo_request_address(&fsm->request,
|
||||
0x1C10 + fsm->sync->index, fsm->pdo_count);
|
||||
ec_sdo_request_write(&fsm->request);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Mapping Pdo 0x%04X at position %u.\n",
|
||||
fsm->pdo->index, fsm->pdo_count);
|
||||
@@ -314,7 +314,7 @@ void ec_fsm_pdo_mapping_state_add_pdo(
|
||||
EC_WRITE_U8(&fsm->request.data, fsm->pdo_count);
|
||||
fsm->request.data_size = 1;
|
||||
ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, 0);
|
||||
ec_sdo_request_write(&fsm->request);
|
||||
ecrt_sdo_request_write(&fsm->request);
|
||||
if (fsm->slave->master->debug_level)
|
||||
EC_DBG("Setting number of mapped Pdos to %u.\n",
|
||||
fsm->pdo_count);
|
||||
|
||||
@@ -450,7 +450,7 @@ void ec_fsm_slave_config_enter_sdo_conf(ec_fsm_slave_config_t *fsm /**< slave st
|
||||
fsm->state = ec_fsm_slave_config_state_sdo_conf;
|
||||
fsm->request = list_entry(fsm->slave->config->sdo_configs.next,
|
||||
ec_sdo_request_t, list);
|
||||
ec_sdo_request_write(fsm->request);
|
||||
ecrt_sdo_request_write(fsm->request);
|
||||
ec_fsm_coe_download(&fsm->fsm_coe, fsm->slave, fsm->request);
|
||||
ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
|
||||
}
|
||||
@@ -479,7 +479,7 @@ void ec_fsm_slave_config_state_sdo_conf(
|
||||
if (fsm->request->list.next != &fsm->slave->config->sdo_configs) {
|
||||
fsm->request = list_entry(fsm->request->list.next, ec_sdo_request_t,
|
||||
list);
|
||||
ec_sdo_request_write(fsm->request);
|
||||
ecrt_sdo_request_write(fsm->request);
|
||||
ec_fsm_coe_download(&fsm->fsm_coe, fsm->slave, fsm->request);
|
||||
ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
|
||||
return;
|
||||
|
||||
@@ -191,17 +191,6 @@ typedef struct {
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Master request state.
|
||||
*/
|
||||
typedef enum {
|
||||
EC_REQUEST_QUEUED,
|
||||
EC_REQUEST_IN_PROGRESS,
|
||||
EC_REQUEST_COMPLETE,
|
||||
EC_REQUEST_FAILURE
|
||||
} ec_request_state_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Origin type.
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
@@ -269,7 +269,7 @@ ssize_t ec_sdo_entry_read_value(
|
||||
request.slave = entry->sdo->slave;
|
||||
ec_sdo_request_init(&request.req);
|
||||
ec_sdo_request_address(&request.req, entry->sdo->index, entry->subindex);
|
||||
ec_sdo_request_read(&request.req);
|
||||
ecrt_sdo_request_read(&request.req);
|
||||
|
||||
// schedule request.
|
||||
down(&master->sdo_sem);
|
||||
|
||||
@@ -148,26 +148,54 @@ int ec_sdo_request_copy_data(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Realtime interface.
|
||||
****************************************************************************/
|
||||
|
||||
void ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout)
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Start an Sdo read operation (Sdo upload).
|
||||
*/
|
||||
void ec_sdo_request_read(
|
||||
ec_sdo_request_t *req /**< Sdo request. */
|
||||
)
|
||||
uint8_t *ecrt_sdo_request_data(ec_sdo_request_t *req)
|
||||
{
|
||||
return req->data;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
ec_request_state_t ecrt_sdo_request_state(const ec_sdo_request_t *req)
|
||||
{
|
||||
return req->state;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
ec_sdo_request_error_t ecrt_sdo_request_error(const ec_sdo_request_t *req)
|
||||
{
|
||||
return EC_SDO_REQUEST_SUCCESS; // FIXME
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void ecrt_sdo_request_read(ec_sdo_request_t *req)
|
||||
{
|
||||
req->state = EC_REQUEST_QUEUED;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Start an Sdo write operation (Sdo download).
|
||||
*/
|
||||
void ec_sdo_request_write(
|
||||
ec_sdo_request_t *req /**< Sdo request. */
|
||||
)
|
||||
void ecrt_sdo_request_write(ec_sdo_request_t *req)
|
||||
{
|
||||
req->state = EC_REQUEST_QUEUED;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
EXPORT_SYMBOL(ecrt_sdo_request_timeout);
|
||||
EXPORT_SYMBOL(ecrt_sdo_request_data);
|
||||
EXPORT_SYMBOL(ecrt_sdo_request_state);
|
||||
EXPORT_SYMBOL(ecrt_sdo_request_error);
|
||||
EXPORT_SYMBOL(ecrt_sdo_request_read);
|
||||
EXPORT_SYMBOL(ecrt_sdo_request_write);
|
||||
|
||||
@@ -43,13 +43,15 @@
|
||||
|
||||
#include <linux/list.h>
|
||||
|
||||
#include "../include/ecrt.h"
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** CANopen Sdo request.
|
||||
*/
|
||||
typedef struct {
|
||||
struct ec_sdo_request {
|
||||
struct list_head list; /**< List item. */
|
||||
uint16_t index; /**< Sdo index. */
|
||||
uint8_t subindex; /**< Sdo subindex. */
|
||||
@@ -57,7 +59,7 @@ typedef struct {
|
||||
size_t mem_size; /**< Size of Sdo data memory. */
|
||||
size_t data_size; /**< Size of Sdo data. */
|
||||
ec_request_state_t state; /**< Sdo request state. */
|
||||
} ec_sdo_request_t;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -68,9 +70,6 @@ void ec_sdo_request_address(ec_sdo_request_t *, uint16_t, uint8_t);
|
||||
int ec_sdo_request_alloc(ec_sdo_request_t *, size_t);
|
||||
int ec_sdo_request_copy_data(ec_sdo_request_t *, const uint8_t *, size_t);
|
||||
|
||||
void ec_sdo_request_read(ec_sdo_request_t *);
|
||||
void ec_sdo_request_write(ec_sdo_request_t *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif
|
||||
|
||||
@@ -105,6 +105,7 @@ int ec_slave_config_init(ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
ec_pdo_mapping_init(&sc->mapping[dir]);
|
||||
|
||||
INIT_LIST_HEAD(&sc->sdo_configs);
|
||||
INIT_LIST_HEAD(&sc->sdo_requests);
|
||||
|
||||
sc->used_fmmus = 0;
|
||||
|
||||
@@ -174,6 +175,13 @@ void ec_slave_config_clear(struct kobject *kobj /**< kobject of the config. */)
|
||||
kfree(req);
|
||||
}
|
||||
|
||||
// free all Sdo requests
|
||||
list_for_each_entry_safe(req, next_req, &sc->sdo_requests, list) {
|
||||
list_del(&req->list);
|
||||
ec_sdo_request_clear(req);
|
||||
kfree(req);
|
||||
}
|
||||
|
||||
kfree(sc);
|
||||
}
|
||||
|
||||
@@ -276,6 +284,16 @@ ssize_t ec_slave_config_info(
|
||||
buf += sprintf(buf, "\n");
|
||||
}
|
||||
|
||||
// type-cast to avoid warnings on some compilers
|
||||
if (!list_empty((struct list_head *) &sc->sdo_requests)) {
|
||||
buf += sprintf(buf, "\nSdo requests:\n");
|
||||
|
||||
list_for_each_entry(req, &sc->sdo_requests, list) {
|
||||
buf += sprintf(buf, " 0x%04X:%u\n", req->index, req->subindex);
|
||||
}
|
||||
buf += sprintf(buf, "\n");
|
||||
}
|
||||
|
||||
return buf - buffer;
|
||||
}
|
||||
|
||||
@@ -672,6 +690,32 @@ int ecrt_slave_config_sdo32(ec_slave_config_t *slave, uint16_t index,
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
ec_sdo_request_t *ecrt_slave_config_create_sdo_request(ec_slave_config_t *sc,
|
||||
uint16_t index, uint8_t subindex, size_t size)
|
||||
{
|
||||
ec_sdo_request_t *req;
|
||||
|
||||
if (!(req = (ec_sdo_request_t *)
|
||||
kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate Sdo request memory!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ec_sdo_request_init(req);
|
||||
ec_sdo_request_address(req, index, subindex);
|
||||
|
||||
if (ec_sdo_request_alloc(req, size)) {
|
||||
ec_sdo_request_clear(req);
|
||||
kfree(req);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_add_tail(&req->list, &sc->sdo_requests);
|
||||
return req;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** \cond */
|
||||
|
||||
EXPORT_SYMBOL(ecrt_slave_config_pdo);
|
||||
@@ -681,6 +725,7 @@ EXPORT_SYMBOL(ecrt_slave_config_reg_pdo_entry);
|
||||
EXPORT_SYMBOL(ecrt_slave_config_sdo8);
|
||||
EXPORT_SYMBOL(ecrt_slave_config_sdo16);
|
||||
EXPORT_SYMBOL(ecrt_slave_config_sdo32);
|
||||
EXPORT_SYMBOL(ecrt_slave_config_create_sdo_request);
|
||||
|
||||
/** \endcond */
|
||||
|
||||
|
||||
@@ -71,7 +71,8 @@ struct ec_slave_config {
|
||||
|
||||
ec_pdo_mapping_t mapping[2]; /**< Output and input Pdo mapping. */
|
||||
|
||||
struct list_head sdo_configs; /**< Sdo configurations. */
|
||||
struct list_head sdo_configs; /**< List of Sdo configurations. */
|
||||
struct list_head sdo_requests; /**< List of Sdo requests. */
|
||||
|
||||
ec_fmmu_config_t fmmu_configs[EC_MAX_FMMUS]; /**< FMMU configurations. */
|
||||
uint8_t used_fmmus; /**< Number of FMMUs used. */
|
||||
|
||||
Reference in New Issue
Block a user