From: Ian Abbott Date: Thu, 5 Jul 2007 17:15:59 +0000 (+0000) Subject: Replaced direct memory accesses with I/O memory access functions. X-Git-Tag: r0_7_74~63 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=a3e86ca3b791448a5dc4b0fd47a5a164586424f9;p=comedi.git Replaced direct memory accesses with I/O memory access functions. Anders Blomdell replaced bitfield types with enum types. --- diff --git a/comedi/drivers/jr3_pci.c b/comedi/drivers/jr3_pci.c index 25174fe9..8937398b 100644 --- a/comedi/drivers/jr3_pci.c +++ b/comedi/drivers/jr3_pci.c @@ -175,7 +175,7 @@ static poll_delay_t poll_delay_min_max(int min, int max) static int is_complete(volatile jr3_channel_t *channel) { - return get_s16(channel->command_word0) == 0; + return get_s16(&channel->command_word0) == 0; } typedef struct { @@ -253,24 +253,24 @@ static void set_full_scales(volatile jr3_channel_t *channel, static six_axis_t get_min_full_scales(volatile jr3_channel_t *channel) { six_axis_t result; - result.fx = get_s16(channel->min_full_scale.fx); - result.fy = get_s16(channel->min_full_scale.fy); - result.fz = get_s16(channel->min_full_scale.fz); - result.mx = get_s16(channel->min_full_scale.mx); - result.my = get_s16(channel->min_full_scale.my); - result.mz = get_s16(channel->min_full_scale.mz); + result.fx = get_s16(&channel->min_full_scale.fx); + result.fy = get_s16(&channel->min_full_scale.fy); + result.fz = get_s16(&channel->min_full_scale.fz); + result.mx = get_s16(&channel->min_full_scale.mx); + result.my = get_s16(&channel->min_full_scale.my); + result.mz = get_s16(&channel->min_full_scale.mz); return result; } static six_axis_t get_max_full_scales(volatile jr3_channel_t *channel) { six_axis_t result; - result.fx = get_s16(channel->max_full_scale.fx); - result.fy = get_s16(channel->max_full_scale.fy); - result.fz = get_s16(channel->max_full_scale.fz); - result.mx = get_s16(channel->max_full_scale.mx); - result.my = get_s16(channel->max_full_scale.my); - result.mz = get_s16(channel->max_full_scale.mz); + result.fx = get_s16(&channel->max_full_scale.fx); + result.fy = get_s16(&channel->max_full_scale.fy); + result.fz = get_s16(&channel->max_full_scale.fz); + result.mx = get_s16(&channel->max_full_scale.mx); + result.my = get_s16(&channel->max_full_scale.my); + result.mz = get_s16(&channel->max_full_scale.mz); return result; } @@ -290,7 +290,8 @@ static int jr3_pci_ai_insn_read(comedi_device *dev, comedi_subdevice *s, result = insn->n; if (p->state != state_jr3_done || - (get_u16(p->channel->errors) & 0xe800) != 0) { + (get_u16(&p->channel->errors) & (watch_dog | watch_dog2 | + sensor_change))) { /* No sensor or sensor changed */ if (p->state == state_jr3_done) { /* Restart polling */ @@ -310,28 +311,28 @@ static int jr3_pci_ai_insn_read(comedi_device *dev, comedi_subdevice *s, int F = 0; switch (axis) { case 0: { - F = get_s16(p->channel->filter[filter].fx); + F = get_s16(&p->channel->filter[filter].fx); } break; case 1: { - F = get_s16(p->channel->filter[filter].fy); + F = get_s16(&p->channel->filter[filter].fy); } break; case 2: { - F = get_s16(p->channel->filter[filter].fz); + F = get_s16(&p->channel->filter[filter].fz); } break; case 3: { - F = get_s16(p->channel->filter[filter].mx); + F = get_s16(&p->channel->filter[filter].mx); } break; case 4: { - F = get_s16(p->channel->filter[filter].my); + F = get_s16(&p->channel->filter[filter].my); } break; case 5: { - F = get_s16(p->channel->filter[filter].mz); + F = get_s16(&p->channel->filter[filter].mz); } break; case 6: { - F = get_s16(p->channel->filter[filter].v1); + F = get_s16(&p->channel->filter[filter].v1); } break; case 7: { - F = get_s16(p->channel->filter[filter].v2); + F = get_s16(&p->channel->filter[filter].v2); } break; } data[i] = F + 0x4000; @@ -340,13 +341,13 @@ static int jr3_pci_ai_insn_read(comedi_device *dev, comedi_subdevice *s, if (p->state != state_jr3_done) { data[i] = 0; } else { - data[i] = get_u16(p->channel->model_no); + data[i] = get_u16(&p->channel->model_no); } } else if (channel == 57) { if (p->state != state_jr3_done) { data[i] = 0; } else { - data[i] = get_u16(p->channel->serial_no); + data[i] = get_u16(&p->channel->serial_no); } } } @@ -480,22 +481,23 @@ static poll_delay_t jr3_pci_poll_subdevice(comedi_subdevice *s) if (p) { volatile jr3_channel_t *channel = p->channel; - int errors = get_u16(channel->errors); + int errors = get_u16(&channel->errors); if (errors != p->errors) { printk("Errors: %x -> %x\n", p->errors, errors); p->errors = errors; } - if ((errors & 0xe800) != 0) { + if (errors & (watch_dog | watch_dog2 | sensor_change)) { // Sensor communication lost, force poll mode p->state = state_jr3_poll; } switch (p->state) { case state_jr3_poll: { - u16 model_no = get_u16(channel->model_no); - u16 serial_no = get_u16(channel->serial_no); - if ((errors & 0xe000) != 0 || model_no == 0 || serial_no == 0) { + u16 model_no = get_u16(&channel->model_no); + u16 serial_no = get_u16(&channel->serial_no); + if ((errors & (watch_dog | watch_dog2)) || + model_no == 0 || serial_no == 0) { // Still no sensor, keep on polling. Since it takes up to // 10 seconds for offsets to stabilize, polling each // second should suffice. @@ -514,8 +516,8 @@ static poll_delay_t jr3_pci_poll_subdevice(comedi_subdevice *s) } else { transform_t transf; - p->model_no = get_u16(channel->model_no); - p->serial_no = get_u16(channel->serial_no); + p->model_no = get_u16(&channel->model_no); + p->serial_no = get_u16(&channel->serial_no); printk("Setting transform for channel %d\n", p->channel_no); printk("Sensor Model = %i\n", p->model_no); @@ -584,22 +586,22 @@ static poll_delay_t jr3_pci_poll_subdevice(comedi_subdevice *s) // Use ranges in kN or we will overflow arount 2000N! full_scale = &channel->full_scale; - p->range[0].range.min = -get_s16(full_scale->fx) * 1000; - p->range[0].range.max = get_s16(full_scale->fx) * 1000; - p->range[1].range.min = -get_s16(full_scale->fy) * 1000; - p->range[1].range.max = get_s16(full_scale->fy) * 1000; - p->range[2].range.min = -get_s16(full_scale->fz) * 1000; - p->range[2].range.max = get_s16(full_scale->fz) * 1000; - p->range[3].range.min = -get_s16(full_scale->mx) * 100; - p->range[3].range.max = get_s16(full_scale->mx) * 100; - p->range[4].range.min = -get_s16(full_scale->my) * 100; - p->range[4].range.max = get_s16(full_scale->my) * 100; - p->range[5].range.min = -get_s16(full_scale->mz) * 100; - p->range[5].range.max = get_s16(full_scale->mz) * 100; - p->range[6].range.min = -get_s16(full_scale->v1) * 100; // ?? - p->range[6].range.max = get_s16(full_scale->v1) * 100; // ?? - p->range[7].range.min = -get_s16(full_scale->v2) * 100; // ?? - p->range[7].range.max = get_s16(full_scale->v2) * 100; // ?? + p->range[0].range.min = -get_s16(&full_scale->fx) * 1000; + p->range[0].range.max = get_s16(&full_scale->fx) * 1000; + p->range[1].range.min = -get_s16(&full_scale->fy) * 1000; + p->range[1].range.max = get_s16(&full_scale->fy) * 1000; + p->range[2].range.min = -get_s16(&full_scale->fz) * 1000; + p->range[2].range.max = get_s16(&full_scale->fz) * 1000; + p->range[3].range.min = -get_s16(&full_scale->mx) * 100; + p->range[3].range.max = get_s16(&full_scale->mx) * 100; + p->range[4].range.min = -get_s16(&full_scale->my) * 100; + p->range[4].range.max = get_s16(&full_scale->my) * 100; + p->range[5].range.min = -get_s16(&full_scale->mz) * 100; + p->range[5].range.max = get_s16(&full_scale->mz) * 100; + p->range[6].range.min = -get_s16(&full_scale->v1) * 100; // ?? + p->range[6].range.max = get_s16(&full_scale->v1) * 100; // ?? + p->range[7].range.min = -get_s16(&full_scale->v2) * 100; // ?? + p->range[7].range.max = get_s16(&full_scale->v2) * 100; // ?? p->range[8].range.min = 0; p->range[8].range.max = 65535; @@ -623,12 +625,12 @@ static poll_delay_t jr3_pci_poll_subdevice(comedi_subdevice *s) result = poll_delay_min_max(20, 100); } else { printk("Default offsets %d %d %d %d %d %d\n", - get_s16(channel->offsets.fx), - get_s16(channel->offsets.fy), - get_s16(channel->offsets.fz), - get_s16(channel->offsets.mx), - get_s16(channel->offsets.my), - get_s16(channel->offsets.mz)); + get_s16(&channel->offsets.fx), + get_s16(&channel->offsets.fy), + get_s16(&channel->offsets.fz), + get_s16(&channel->offsets.mx), + get_s16(&channel->offsets.my), + get_s16(&channel->offsets.mz)); set_s16(&channel->offsets.fx, 0); set_s16(&channel->offsets.fy, 0); @@ -829,7 +831,7 @@ static int jr3_pci_attach(comedi_device *dev, comedi_devconfig *it) // as much as we can read firmware version msleep_interruptible(25); for (i=0 ; i < 0x18 ; i++){ - printk("%c", get_u16(devpriv->iobase->channel[0].data.copyright[i])>>8); + printk("%c", get_u16(&devpriv->iobase->channel[0].data.copyright[i])>>8); } // Start card timer diff --git a/comedi/drivers/jr3_pci.h b/comedi/drivers/jr3_pci.h index dcb0c9bf..03b37bc0 100644 --- a/comedi/drivers/jr3_pci.h +++ b/comedi/drivers/jr3_pci.h @@ -1,43 +1,27 @@ // Helper types to take care of the fact that the DSP card memory // is 16 bits, but aligned on a 32 bit PCI boundary -typedef union { - u8 as_u8; - u16 as_u16; - u32 as_u32; -} u_val_t; - -typedef union { - s8 as_s8; - s16 as_s16; - s32 as_s32; -} s_val_t; - -static inline u16 get_u16(volatile u_val_t val) +typedef u32 u_val_t; + +typedef s32 s_val_t; + +static inline u16 get_u16(volatile const u_val_t *p) { - u_val_t tmp; - tmp.as_u32 = le32_to_cpu(val.as_u32); - return tmp.as_u16; + return (u16)readl(p); } static inline void set_u16(volatile u_val_t *p, u16 val) { - u_val_t tmp; - tmp.as_u16 = val; - p->as_u32 = cpu_to_le32(tmp.as_u32); + writel(val, p); } -static inline s16 get_s16(volatile s_val_t val) +static inline s16 get_s16(volatile const s_val_t *p) { - s_val_t tmp; - tmp.as_s32 = le32_to_cpu(val.as_s32); - return tmp.as_s16; + return (s16)readl(p); } static inline void set_s16(volatile s_val_t *p, s16 val) { - s_val_t tmp; - tmp.as_s16 = val; - p->as_s32 = cpu_to_le32(tmp.as_s32); + writel(val, p); } // The raw data is stored in a format which facilitates rapid @@ -90,75 +74,116 @@ typedef struct six_axis_array s_val_t mz; } six_axis_array_t; -// VECT_BITS -// Indicates which axis are to be used when computing the vectors. A vector -// is composed by 3 components and its "magnitude" is placed in V1 and V2. -// V1 defaults to a force vector and V2 defaults to a moment vector. -// Setting changeV1 or changeV2 will change that vector to be the opposite of -// its default. - -// *** Check this norby *** -// This is badly defined at JR3 Manual. Correct definition follows: -typedef struct vect_bits -{ - unsigned fx : 1; - unsigned fy : 1; - unsigned fz : 1; - unsigned mx : 1; - unsigned my : 1; - unsigned mz : 1; - unsigned changeV1 : 1; - unsigned changeV2 : 1; - unsigned reserved : 8; -} vect_bits; - -// WARNINGS -// Bit pattern for the warning word: xx_near_sat means that a near saturation -// has been reached or exceeded. -typedef struct warning_bits -{ - unsigned fx_near_sat : 1; - unsigned fy_near_sat : 1; - unsigned fz_near_sat : 1; - unsigned mx_near_sat : 1; - unsigned my_near_sat : 1; - unsigned mz_near_sat : 1; - unsigned reserved : 10; -} warning_bits; +// VECT_BITS +// The vect_bits structure shows the layout for indicating +// which axes to use in computing the vectors. Each bit signifies +// selection of a single axis. The V1x axis bit corresponds to a hex +// value of 0x0001 and the V2z bit corresponds to a hex value of +// 0x0020. Example: to specify the axes V1x, V1y, V2x, and V2z the +// pattern would be 0x002b. Vector 1 defaults to a force vector and +// vector 2 defaults to a moment vector. It is possible to change one +// or the other so that two force vectors or two moment vectors are +// calculated. Setting the changeV1 bit or the changeV2 bit will +// change that vector to be the opposite of its default. Therefore to +// have two force vectors, set changeV1 to 1. + +typedef enum { + fx = 0x0001, + fy = 0x0002, + fz = 0x0004, + mx = 0x0008, + my = 0x0010, + mz = 0x0020, + changeV2 = 0x0040, + changeV1 = 0x0080 +} vect_bits_t; + +// WARNING_BITS +// The warning_bits structure shows the bit pattern for the warning +// word. The bit fields are shown from bit 0 (lsb) to bit 15 (msb). +// +// XX_NEAR_SET +// The xx_near_sat bits signify that the indicated axis has reached or +// exceeded the near saturation value. + +typedef enum { + fx_near_sat = 0x0001, + fy_near_sat = 0x0002, + fz_near_sat = 0x0004, + mx_near_sat = 0x0008, + my_near_sat = 0x0010, + mz_near_sat = 0x0020 +} warning_bits_t; // ERROR_BITS -// Bit pattern for the error word: -// 1. xx_sat means that a near saturation has been reached or exceeded. -// 2. memory_error indicates RAM memory error during power up. -// 3. sensor_change indicates that the sensor plugged in (different from the -// original one) has passed CRC check. The user must reset this bit. -// 4. system_busyindicates system busy: transf. change, new full scale or new -// sennsor plugged in. -// 5. cal_crc_bad means that it was a problem transmiting the calibration data -// stored inside the sensor. If this bit does not come to zero 2s after the -// sensor has been plugged in, there is a problem with the sensor's calibra- -// tion data. -// 6. watch_dog2 indicates that sensor data and clock are being received. -// 7. watch_dog indicates that data line seems to be acting correctly. -// If either watch dog barks, the sensor data is not beig receive correctly. -#if 0 -typedef struct error_bits -{ - unsigned fx_sat : 1; - unsigned fy_sat : 1; - unsigned fz_sat : 1; - unsigned mx_sat : 1; - unsigned my_sat : 1; - unsigned mz_sat : 1; - unsigned reserved : 4; - unsigned memory_error : 1; - unsigned sensor_change : 1; - unsigned system_busy : 1; - unsigned cal_crc_bad : 1; - unsigned watch_dog2 : 1; - unsigned watch_dog : 1; -} error_bits; -#endif +// XX_SAT +// MEMORY_ERROR +// SENSOR_CHANGE +// +// The error_bits structure shows the bit pattern for the error word. +// The bit fields are shown from bit 0 (lsb) to bit 15 (msb). The +// xx_sat bits signify that the indicated axis has reached or exceeded +// the saturation value. The memory_error bit indicates that a problem +// was detected in the on-board RAM during the power-up +// initialization. The sensor_change bit indicates that a sensor other +// than the one originally plugged in has passed its CRC check. This +// bit latches, and must be reset by the user. +// +// SYSTEM_BUSY +// +// The system_busy bit indicates that the JR3 DSP is currently busy +// and is not calculating force data. This occurs when a new +// coordinate transformation, or new sensor full scale is set by the +// user. A very fast system using the force data for feedback might +// become unstable during the approximately 4 ms needed to accomplish +// these calculations. This bit will also become active when a new +// sensor is plugged in and the system needs to recalculate the +// calibration CRC. +// +// CAL_CRC_BAD +// +// The cal_crc_bad bit indicates that the calibration CRC has not +// calculated to zero. CRC is short for cyclic redundancy code. It is +// a method for determining the integrity of messages in data +// communication. The calibration data stored inside the sensor is +// transmitted to the JR3 DSP along with the sensor data. The +// calibration data has a CRC attached to the end of it, to assist in +// determining the completeness and integrity of the calibration data +// received from the sensor. There are two reasons the CRC may not +// have calculated to zero. The first is that all the calibration data +// has not yet been received, the second is that the calibration data +// has been corrupted. A typical sensor transmits the entire contents +// of its calibration matrix over 30 times a second. Therefore, if +// this bit is not zero within a couple of seconds after the sensor +// has been plugged in, there is a problem with the sensor's +// calibration data. +// +// WATCH_DOG +// WATCH_DOG2 +// +// The watch_dog and watch_dog2 bits are sensor, not processor, watch +// dog bits. Watch_dog indicates that the sensor data line seems to be +// acting correctly, while watch_dog2 indicates that sensor data and +// clock are being received. It is possible for watch_dog2 to go off +// while watch_dog does not. This would indicate an improper clock +// signal, while data is acting correctly. If either watch dog barks, +// the sensor data is not being received correctly. + +typedef enum { + fx_sat = 0x0001, + fy_sat = 0x0002, + fz_sat = 0x0004, + mx_sat = 0x0008, + my_sat = 0x0010, + mz_sat = 0x0020, + memory_error = 0x0400, + sensor_change = 0x0800, + system_busy = 0x1000, + cal_crc_bad = 0x2000, + watch_dog2 = 0x4000, + watch_dog = 0x8000 +} error_bits_t; + // THRESH_STRUCT // This structure shows the layout for a single threshold packet inside of a