Kategorie-Daten aus EEPROM lesen.

This commit is contained in:
Florian Pose 2006-03-21 13:57:15 +00:00
parent 91fe54d513
commit f9c4eecee9
2 changed files with 243 additions and 3 deletions

View File

@ -18,6 +18,16 @@
/*****************************************************************************/ /*****************************************************************************/
int ec_slave_fetch_categories(ec_slave_t *);
int ec_slave_fetch_strings(ec_slave_t *, const uint8_t *);
void ec_slave_fetch_general(ec_slave_t *, const uint8_t *);
void ec_slave_fetch_fmmu(ec_slave_t *, const uint8_t *);
void ec_slave_fetch_sync(ec_slave_t *, const uint8_t *);
void ec_slave_fetch_txpdo(ec_slave_t *, const uint8_t *);
void ec_slave_fetch_rxpdo(ec_slave_t *, const uint8_t *);
/*****************************************************************************/
/** /**
EtherCAT-Slave-Konstruktor. EtherCAT-Slave-Konstruktor.
*/ */
@ -42,6 +52,8 @@ void ec_slave_init(ec_slave_t *slave, /**< EtherCAT-Slave */
slave->type = NULL; slave->type = NULL;
slave->registered = 0; slave->registered = 0;
slave->fmmu_count = 0; slave->fmmu_count = 0;
INIT_LIST_HEAD(&slave->cat_strings);
} }
/*****************************************************************************/ /*****************************************************************************/
@ -52,7 +64,13 @@ void ec_slave_init(ec_slave_t *slave, /**< EtherCAT-Slave */
void ec_slave_clear(ec_slave_t *slave /**< EtherCAT-Slave */) void ec_slave_clear(ec_slave_t *slave /**< EtherCAT-Slave */)
{ {
// Nichts freizugeben ec_slave_string_t *string, *next;
// Alle Strings freigeben
list_for_each_entry_safe(string, next, &slave->cat_strings, list) {
list_del(&string->list);
kfree(string);
}
} }
/*****************************************************************************/ /*****************************************************************************/
@ -114,6 +132,11 @@ int ec_slave_fetch(ec_slave_t *slave /**< EtherCAT-Slave */)
return -1; return -1;
} }
if (unlikely(ec_slave_fetch_categories(slave))) {
EC_ERR("Could not fetch category data!\n");
return -1;
}
return 0; return 0;
} }
@ -177,7 +200,7 @@ int ec_slave_sii_read(ec_slave_t *slave,
} }
if (unlikely((end - start) >= timeout)) { if (unlikely((end - start) >= timeout)) {
EC_ERR("SSI-read. Slave %i timed out!\n", slave->ring_position); EC_ERR("SII-read. Slave %i timed out!\n", slave->ring_position);
return -1; return -1;
} }
} }
@ -252,7 +275,7 @@ int ec_slave_sii_write(ec_slave_t *slave,
} }
if (unlikely((end - start) >= timeout)) { if (unlikely((end - start) >= timeout)) {
EC_ERR("SSI-write: Slave %i timed out!\n", slave->ring_position); EC_ERR("SII-write: Slave %i timed out!\n", slave->ring_position);
return -1; return -1;
} }
} }
@ -260,6 +283,201 @@ int ec_slave_sii_write(ec_slave_t *slave,
/*****************************************************************************/ /*****************************************************************************/
/**
Holt Daten aus dem EEPROM.
\return 0, wenn alles ok, sonst < 0
*/
int ec_slave_fetch_categories(ec_slave_t *slave /**< EtherCAT-Slave */)
{
uint16_t word_offset, header, word_count;
uint32_t value;
uint8_t *cat_data;
unsigned int i;
word_offset = 0x0040;
//EC_DBG("Slave %i...\n", slave->ring_position);
if (!(cat_data = (uint8_t *) kmalloc(0x10000, GFP_KERNEL))) {
EC_ERR("Failed to allocate 64k bytes for category data.\n");
return -1;
}
while (1) {
// read category header
if (ec_slave_sii_read(slave, word_offset, &value)) {
EC_ERR("Unable to read category header and size.\n");
kfree(cat_data);
return -1;
}
// Last category?
if ((value & 0xFFFF) == 0xFFFF) break;
header = value & 0x7FFF;
word_count = (value >> 16) & 0xFFFF;
// Fetch category data
for (i = 0; i < word_count; i++) {
if (ec_slave_sii_read(slave, word_offset + 2 + i, &value)) {
EC_ERR("Unable to read category data word %i.\n", i);
kfree(cat_data);
return -1;
}
cat_data[i * 2] = (value >> 0) & 0xFF;
cat_data[i * 2 + 1] = (value >> 8) & 0xFF;
// read second word "on the fly"
if (i + 1 < word_count) {
i++;
cat_data[i * 2] = (value >> 16) & 0xFF;
cat_data[i * 2 + 1] = (value >> 24) & 0xFF;
}
}
switch (header)
{
case 0x000A:
if (ec_slave_fetch_strings(slave, cat_data)) {
kfree(cat_data);
return -1;
}
break;
case 0x001E:
case 0x0001:
ec_slave_fetch_general(slave, cat_data);
break;
case 0x0028:
case 0x0002:
ec_slave_fetch_fmmu(slave, cat_data);
break;
case 0x0029:
case 0x0003:
ec_slave_fetch_sync(slave, cat_data);
break;
case 0x0032:
case 0x0004:
ec_slave_fetch_txpdo(slave, cat_data);
break;
case 0x0033:
case 0x0005:
ec_slave_fetch_rxpdo(slave, cat_data);
break;
default:
EC_WARN("Unknown category header 0x%04X in slave %i.\n",
header, slave->ring_position);
}
word_offset += 2 + word_count;
}
kfree(cat_data);
return 0;
}
/*****************************************************************************/
/**
Holt die Daten einer String-Kategorie.
\return 0 wenn alles ok, sonst < 0
*/
int ec_slave_fetch_strings(ec_slave_t *slave, /**< EtherCAT-Slave */
const uint8_t *data /**< Kategoriedaten */
)
{
unsigned int string_count, i;
size_t size;
off_t offset;
ec_slave_string_t *string;
string_count = data[0];
offset = 1;
for (i = 0; i < string_count; i++) {
size = data[offset];
// Speicher für String-Objekt und Daten in einem Rutsch allozieren
if (!(string = (ec_slave_string_t *) kmalloc(sizeof(ec_slave_string_t)
+ size + 1,
GFP_KERNEL))) {
EC_ERR("Failed to allocate string memory.\n");
return -1;
}
string->data = (char *) (string + sizeof(ec_slave_string_t));
memcpy(string->data, data + offset + 1, size);
string->data[size] = 0x00;
list_add_tail(&string->list, &slave->cat_strings);
offset += 1 + size;
}
return 0;
}
/*****************************************************************************/
/**
Holt die Daten einer General-Kategorie.
*/
void ec_slave_fetch_general(ec_slave_t *slave, /**< EtherCAT-Slave */
const uint8_t *data /**< Kategorie-Daten */
)
{
}
/*****************************************************************************/
/**
Holt die Daten einer FMMU-Kategorie.
*/
void ec_slave_fetch_fmmu(ec_slave_t *slave, /**< EtherCAT-Slave */
const uint8_t *data /**< Kategorie-Daten */
)
{
}
/*****************************************************************************/
/**
Holt die Daten einer Sync-Manager-Kategorie.
*/
void ec_slave_fetch_sync(ec_slave_t *slave, /**< EtherCAT-Slave */
const uint8_t *data /**< Kategorie-Daten */
)
{
}
/*****************************************************************************/
/**
Holt die Daten einer TXPDO-Kategorie.
*/
void ec_slave_fetch_txpdo(ec_slave_t *slave, /**< EtherCAT-Slave */
const uint8_t *data /**< Kategorie-Daten */
)
{
}
/*****************************************************************************/
/**
Holt die Daten einer RXPDO-Kategorie.
*/
void ec_slave_fetch_rxpdo(ec_slave_t *slave, /**< EtherCAT-Slave */
const uint8_t *data /**< Kategorie-Daten */
)
{
}
/*****************************************************************************/
/** /**
Bestätigt einen Fehler beim Zustandswechsel. Bestätigt einen Fehler beim Zustandswechsel.
@ -437,6 +655,8 @@ int ec_slave_set_fmmu(ec_slave_t *slave, /**< EtherCAT-Slave */
void ec_slave_print(const ec_slave_t *slave /**< EtherCAT-Slave */) void ec_slave_print(const ec_slave_t *slave /**< EtherCAT-Slave */)
{ {
ec_slave_string_t *string;
EC_INFO("--- EtherCAT slave information ---\n"); EC_INFO("--- EtherCAT slave information ---\n");
if (slave->type) { if (slave->type) {
@ -464,6 +684,11 @@ void ec_slave_print(const ec_slave_t *slave /**< EtherCAT-Slave */)
slave->sii_vendor_id, slave->sii_product_code); slave->sii_vendor_id, slave->sii_product_code);
EC_INFO(" Revision number: 0x%08X, Serial number: 0x%08X\n", EC_INFO(" Revision number: 0x%08X, Serial number: 0x%08X\n",
slave->sii_revision_number, slave->sii_serial_number); slave->sii_revision_number, slave->sii_serial_number);
EC_INFO(" EEPROM strings:\n");
list_for_each_entry(string, &slave->cat_strings, list) {
EC_INFO(" * \"%s\"\n", string->data);
}
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@ -51,6 +51,19 @@ ec_fmmu_t;
/*****************************************************************************/ /*****************************************************************************/
/**
EEPROM-String.
*/
typedef struct
{
struct list_head list;
char *data;
}
ec_slave_string_t;
/*****************************************************************************/
/** /**
EtherCAT-Slave EtherCAT-Slave
*/ */
@ -84,6 +97,8 @@ struct ec_slave
ec_fmmu_t fmmus[EC_MAX_FMMUS]; /**< FMMU-Konfigurationen */ ec_fmmu_t fmmus[EC_MAX_FMMUS]; /**< FMMU-Konfigurationen */
uint8_t fmmu_count; /**< Wieviele FMMUs schon benutzt sind. */ uint8_t fmmu_count; /**< Wieviele FMMUs schon benutzt sind. */
struct list_head cat_strings; /**< Strings im EEPROM */
}; };
/*****************************************************************************/ /*****************************************************************************/