2010-08-03 13:55:23 How to integrate the ade7758 driver into the IIO archetecture
Allister Mannion (AFGHANISTAN)
Message: 92118
Dear 'Meter Driver Experts' (Mr. Song?),
Could you point me in the right direction to achieve the following with you ade7758 and IIO driver architecture.
I need to internally (driver side) catch the zero-crossing interrupt and then read the (a) waveform register for a complete cycle (depending on the sampling frequency, 256-512 samples per cycle, where a cycle lasts 20ms - 50Hz). The same interrupt (that signaled the zero-crossing) can be used to signal 'waveform register ready to read'. Does this make any sense?
The goal here is that on the user-side (user space) I would:
1. Set sample frequency (write to the register is sysfs?)
2. Set the waveform source (IRMS, VRMS, etc.)
3. Issue a waveform register read which would:
3a: (Kernel side) Enable zero crossing interrupt
3b: (Kernel side) On zero crossing interrupt, enable waveform register ready interrupt
3c: (Kernal side) On waveform register ready interrupt read and buffer
3d: (Kernal side) After 256/512/whatever waveform register ready interrupts/reads satisfy user read
4. Read returns with 256/512/whatever waveform values.
I'm assuming 3 has to happen in the driver due to latency. I (maybe wrongly) believe the IIO architecture is designed to solve such problems: multiple-transactions with IO chips (ADCs, etc.) to satisfy single user-space IOs. I'm just having trouble seeing how best to plug the ade7758 driver into the architecture.
Help! Where do I start?
QuoteReplyEditDelete
2010-08-04 03:05:29 Re: How to integrate the ade7758 driver into the IIO archetecture
Barry Song (CHINA)
Message: 92131
Dear 'Meter Driver Users' (Mr. Mannion?),
I am sorry ADE7758 driver hasn't been tested and has no enough interface for you to finish the function you require now.
To implement it, you need a trigger using interrupt and add ring buffer interface.
Device ADIS16220 (https://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:adis16220) has an internal HW buffer, which can hold a lot of data. But ADE7758 has no, so you need to add ring like other IIO driver.
Thanks
Barry
QuoteReplyEditDelete
2010-08-10 03:37:20 Re: How to integrate the ade7758 driver into the IIO archetecture
Sonic Zhang (CHINA)
Message: 92282
Barry will take a look after he finishes the other task.
QuoteReplyEditDelete
2010-08-10 06:34:56 Re: How to integrate the ade7758 driver into the IIO archetecture
Allister Mannion (AFGHANISTAN)
Message: 92286
Dear Mr. Song & M. Zhang,
Many thanks for your input. I will attempt to get a better understanding of the required IIO support required in the ade7758 driver from existing ADC drivers that currently use IIO. I will no doubt have some questions :-( Hopefully, Mr. Song can guide me to ensure I do nothing (to his driver) that isn't consistient with his own work (i.e. he can't use).
We are a large(ish) user of the ADE7758 (1000s), and are anxious to use it in our next Linux-based product (6 x ADE7758 in each unit for 18 channels capability). Already we can read/write registers (thanks to Mr. Song's driver), we just have the bulk-read (from the waveform register) requirement to resolve (and the interrupt structure which I'm working on as I type).
Again, many thanks for your help,
Allister Mannion
QuoteReplyEditDelete
2010-08-18 03:12:20 Re: How to integrate the ade7758 driver into the IIO archetecture
Barry Song (CHINA)
Message: 92531
Hi Allister,
i have added this feature in ade7758 driver in trunk , and i will try to test it.
-barry
QuoteReplyEditDelete
2010-08-18 07:41:41 Re: How to integrate the ade7758 driver into the IIO archetecture
Allister Mannion (AFGHANISTAN)
Message: 92554
Dear Barry,
This is excellent. I'd already started this (adapted the lis3l02dq examples with just a _core.c and _ring.c file), but since you've been so quick will switch to your source immediately (already compiled - starting testing now).
There's one patch I'd like to sibmit now:
in ade7758_core.c, function ade7758_write_frequency, the shift should be 5, not 3. The waveform mode register uses bit 5 and 6 for sample rate:
reg &= ~(3 << 3);
reg |= t << 3;
needs to be:
reg &= ~(3 << 5);
reg |= t << 5;
The read_frequency is flawed for this AND another reason. You add 1 to t, but the frequency halves in speed by each increment of one. Not being clever I changed this:
t = (t >> 3) & 0x3;
sps = 26000 / (1 + t);
to this:
t = (t >> 5) & 0x3;
switch(t)
{
case 0:
sps = 26040;
break;
case 1:
sps = 13020;
break;
case 2:
sps = 6510;
break;
case 3:
sps = 3250;
break;
default:
sps = -1;
break;
}
I'll let you know how my testing goes, and once again MANY, MANY thanks,
Allister
QuoteReplyEditDelete
2010-08-19 03:52:55 Re: How to integrate the ade7758 driver into the IIO archetecture
Barry Song (CHINA)
Message: 92575
yes, you are right. i think this patch finish what you want?
--- drivers/staging/iio/meter/ade7758_core.c (revision 9090)
+++ drivers/staging/iio/meter/ade7758_core.c (working copy)
@@ -497,8 +497,8 @@
if (ret)
return ret;
- t = (t >> 3) & 0x3;
- sps = 26000 / (1 + t);
+ t = (t >> 5) & 0x3;
+ sps = 26040 / (1 << t);
len = sprintf(buf, "%d SPS\n", sps);
return len;
@@ -521,9 +521,9 @@
mutex_lock(&indio_dev->mlock);
- t = (26000 / val);
+ t = (26040 / val);
if (t > 0)
- t--;
+ t >>= 1;
if (t > 1)
st->us->max_speed_hz = ADE7758_SPI_SLOW;
@@ -536,8 +536,8 @@
if (ret)
goto out;
- reg &= ~(3 << 3);
- reg |= t << 3;
+ reg &= ~(5 << 3);
+ reg |= t << 5;
-barry
QuoteReplyEditDelete
2010-08-19 06:29:56 Re: How to integrate the ade7758 driver into the IIO archetecture
Allister Mannion (AFGHANISTAN)
Message: 92580
Dear Barry,
Very grateful for the iio integration pointers. Yes, I now know exactly (?) what's to do. I'm creating a patch list as I test. Some of the stuff I'm doing is too application specific to be included in your driver, and some is hardware dependant (I'm working on an atmel AT91 platform), but I'll post those things I think generically wrong over the next few days.
Many thanks,
Allister