#include "rtapi_ctype.h"
#include "rtapi.h"
#include "rtapi_app.h"
#include "hal.h"
#define FASTIO
#ifdef FASTIO
#define rtapi_inb inb
#define rtapi_outb outb
#include <asm/io.h>
#endif
MODULE_AUTHOR("Martin Kuhnle");
MODULE_DESCRIPTION("SIEMENS-EVOREG Driver for EMC HAL");
MODULE_LICENSE("GPL");
typedef struct {
void *io_base;
hal_float_t *dac_out[3];
hal_float_t *position[3];
hal_bit_t *digital_in[47];
hal_bit_t *digital_out[25];
__u16 raw_counts_old[3];
__s32 counts[3];
hal_float_t pos_scale;
} evoreg_t;
static evoreg_t *port_data_array;
static int comp_id;
static int num_ports;
static void update_port(void *arg, long period);
#define MAX_PORTS 8
#define MAX_DAC 3
#define MAX_ENC 3
#define MAX_TOK ((MAX_PORTS*2)+3)
int rtapi_app_main(void)
{
char name[HAL_NAME_LEN + 1];
int n,i , retval, num_dac, num_enc;
unsigned int base=0x300;
num_ports = 1;
n = 0;
#define ISA_BASE 0xC9000
#define ISA_MAX 0x100000
comp_id = hal_init("hal_evoreg");
if (comp_id < 0) {
rtapi_print_msg(RTAPI_MSG_ERR,
"EVOREG: ERROR: hal_init() failed\n");
return -1;
}
port_data_array = hal_malloc(num_ports * sizeof(evoreg_t));
if (port_data_array == 0) {
rtapi_print_msg(RTAPI_MSG_ERR,
"EVOREG: ERROR: hal_malloc() failed\n");
hal_exit(comp_id);
return -1;
}
port_data_array->io_base = ioremap(ISA_BASE, ISA_MAX - ISA_BASE);
rtapi_print_msg(RTAPI_MSG_ERR,"EVOREG: io_base: %p \n", port_data_array->io_base);
outw(0x82c9,base);
writew(0, port_data_array->io_base + 0x20);
writew(0, port_data_array->io_base + 0x40);
writew(0, port_data_array->io_base + 0x60);
writew(0, port_data_array->io_base + 0x80);
writew(0, port_data_array->io_base + 0xa0);
writew(0, port_data_array->io_base + 0x02);
writew(0, port_data_array->io_base + 0x0a);
writew(0, port_data_array->io_base + 0x12);
for ( num_dac=1; num_dac<=MAX_DAC; num_dac++) {
retval = hal_pin_float_newf(HAL_IN, &(port_data_array->dac_out[num_dac-1]),
comp_id, "evoreg.%d.dac-%02d-out", 1, num_dac);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR,
"EVOREG: ERROR: port %d var export failed with err=%i\n", n + 1,
retval);
hal_exit(comp_id);
return -1;
}
}
for ( num_enc=1; num_enc<=MAX_ENC; num_enc++) {
retval = hal_pin_float_newf(HAL_OUT, &(port_data_array->position[num_enc - 1]),
comp_id, "evoreg.%d.position-%02d-in", 1, num_enc);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR,
"EVOREG: ERROR: port %d var export failed with err=%i\n", n + 1,
retval);
hal_exit(comp_id);
return -1;
}
}
for ( i=0; i<=45;i++) {
retval += hal_pin_bit_newf(HAL_OUT, &(port_data_array->digital_in[i]),
comp_id, "evoreg.%d.pin-%02d-in", 1, i);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR,
"EVOREG: ERROR: port %d var export failed with err=%i\n", n + 1,
retval);
hal_exit(comp_id);
return -1;
}
}
for ( i=0; i<=23;i++) {
retval += hal_pin_bit_newf(HAL_IN, &(port_data_array->digital_out[i]),
comp_id, "evoreg.%d.pin-%02d-out", 1, i);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR,
"EVOREG: ERROR: port %d var export failed with err=%i\n", n + 1,
retval);
hal_exit(comp_id);
return -1;
}
}
retval = hal_param_float_newf(HAL_RW, &(port_data_array->pos_scale),
comp_id, "evoreg.%d.position-scale", 1);
if (retval != 0) {
return retval;
}
rtapi_snprintf(name, sizeof(name), "evoreg.%d.update", n + 1);
retval = hal_export_funct(name, update_port, &(port_data_array[n]), 1, 0,
comp_id);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR,
"EVOREG: ERROR: port %d write funct export failed\n", n + 1);
hal_exit(comp_id);
return -1;
}
rtapi_print_msg(RTAPI_MSG_INFO,
"EVOREG: installed driver for %d card(s)\n", num_ports);
hal_ready(comp_id);
return 0;
}
void rtapi_app_exit(void)
{
outw(0x0,0x300);
hal_exit(comp_id);
}
static void update_port(void *arg, long period)
{
evoreg_t *port;
int pin;
unsigned char tmp, mask;
__u16 raw_counts[3];
port = arg;
writew((*(port->dac_out[0])/10 * 0x7fff), port->io_base + 0x60);
writew((*(port->dac_out[1])/10 * 0x7fff), port->io_base + 0x80);
writew((*(port->dac_out[2])/10 * 0x7fff), port->io_base + 0xa0);
raw_counts[0] = (__u16) readw(port->io_base);
raw_counts[1] = (__u16) readw(port->io_base + 0x08 );
raw_counts[2] = (__u16) readw(port->io_base + 0x10 );
port->counts[0] += (__s16) (raw_counts[0] - port->raw_counts_old[0]);
port->raw_counts_old[0] = raw_counts[0];
port->counts[1] += (__s16) (raw_counts[1] - port->raw_counts_old[1]);
port->raw_counts_old[1] = raw_counts[1];
port->counts[2] += (__s16) (raw_counts[2] - port->raw_counts_old[2]);
port->raw_counts_old[2] = raw_counts[2];
*port->position[0] = port->counts[0] * port->pos_scale;
*port->position[1] = port->counts[1] * port->pos_scale;
*port->position[2] = port->counts[2] * port->pos_scale;
tmp = readw(port->io_base + 0x20);
mask = 0x01;
for (pin=0 ; pin < 16 ; pin++) {
*port->digital_in[pin] = (tmp & mask) ? 1:0 ;
mask <<= 1;
}
tmp = readw(port->io_base + 0x40);
mask = 0x01;
for (pin=16 ; pin < 32 ; pin++) {
*port->digital_in[pin] = (tmp & mask) ? 1:0 ;
mask <<= 1;
}
tmp = readw(port->io_base + 0x60);
mask = 0x01;
for (pin=32 ; pin < 46 ; pin++) {
*port->digital_in[pin] = (tmp & mask) ? 1:0 ;
mask <<= 1;
}
tmp = 0x0;
mask = 0x01;
for (pin=0; pin < 16; pin++) {
if (port->digital_out[pin]) {
tmp |= mask;
mask <<= 1;
}
}
writew( tmp, port->io_base + 0x20);
tmp = 0x0;
mask = 0x01;
for (pin=16; pin < 24; pin++) {
if (port->digital_out[pin]) {
tmp |= mask;
mask <<= 1;
}
}
writew( tmp, port->io_base + 0x40);
}