This is a long response with lots of technical stuff.
For the casual reader, here is the short version:
I propose:
* memory-map based interface
* pre-defined 'drivers' for different functionality
* keep driver interfaces as close to uC hardware implementation as possible
* drivers can and should be cross-platform if generic (eg 8 bit counter, pio,
etc)
read on for excruciating detail...
> Sorry to be blunt, but this is exactly what I want to avoid.
no problem, rather be straightforward than beat around bushes :)
> Just because you are implementing your DAC in one form doesn't mean
> that others will.
My primary goal is to implement/expose as much functionality of the AVR chips
as possible, using a 1-wire slave interface.
I don't know if it will be productive to try and fit that into a generic
interaction: typically one tries to be as minimal as possible for
microcontrollers; tight timing, optimized code, etc.
OWFS's role is to abstract the functionality of the actual hardware to various
user-accessible interfaces. For example, there are lots of different chips that
do temperature reading, and many of them have slightly different decoding
algorithms and access commands. OWFS just gives you a 'temperature' reading.
I guess what i'm saying is that the host system running owfs probably has a lot
more resources and it will be cheaper and simpler in the long run to implement
the differences between BAE/PIC/AVR or whatever platform we work on in an OWFS
driver for that chip, vs trying to make a generic driver interface for all
microcontroller based chips, and make the uC's do the translation.
> Also, I think we want a given address so that what the board returns
> is what it is currently doing and not what it is capable of.
I think we want both. If we do not have a capabilities function, then OWFS has
to have some sort of map in its driver which tells it which functionalities a
given hardware type has. This means that the driver has to be customized for
each chip, which is the opposite of what we are attempting, i think.
> If I have a common pin as a BLAH, OWFS doesn't want to know about pins or what
> other things that pin could do or what other things other pins can do. It
> wants to say that this address is currently offering a BLAH and here
> are the register offsets for standard BLAH control.
OWFS typically presents all of the possible functions of a device in the
directory for that device, eg take my DS2780: It has a high-sensitivity ADC
which can be used to measure tiny voltages. Those tiny voltages can also be
interpreted functionally, as a thermocouple output, or as a direct voltage
reading. The Vis, TypeJ, TypeK, etc nodes are all presented, so it is clearly
showing all of the possible interpretations of the data. Same for the
'humidity' node on some other types, which have ADC's on them.
By the same token, OWFS doesn't hide the PIO write functionality when the pio
pin is in input mode.
> There's some minor fun with this, because the capabilities can in
> theory be changed on the fly. How often is capability polling required for
> this dynamic situation?
Not sure i follow this. Once setup, most things probably will not be changed,
but it's not beyond the realm of possibility. If a device loses power, OWFS
will have to change it back to a known/desired state.
> I think this argues against a persistent object index.
I wasn't recommending a persistent object index; not sure if that statement was
in response to my suggestion or just thinking out loud.
> The best thing right now is to come up with common and wild ideas for
> possible devices.
Or implement a methodology that allows easily adding new functions/hardware
features, so it's not a big deal if someone wants to try something new.
> We need what things the device is doing
yep
> and what kind of common controls would make
> sense.
I would argue that for most use cases, the hardware is sufficiently different
and control methods for the hardware disparate enough that this sort of thing
is better standardized at the OWFS/driver level and let the microcontroller
interface be as simple as possible
I have written drivers for MPEG encoders in the past, and when it came to
creating a system interface (IOCTL) for all the widely varied codec parameters
and card-specific tweaks, it became a huge undertaking. That sort of logic does
not belong on tiny microcontrollers. The implementation of the control
interface should be as close to the actual hardware implementation as possible.
I do not disagree that standard interfaces are useful, and where possible, they
should absolutely be used (eg counter, ADC, etc), it's just not worth it to try
and make EVERY function have a standard interface
After some thought, i think my initial stab at a command for discovery is not
the right path. This would probably be better implemented as a memory-map, with
something akin to a network packet encoding scheme.
This would be defined with functionality/driver types, which OWFS would map to
internal control structures, eg for an 8 bit counter, it would know what the
size of the structure is, and where to read the counter value. If a chip has
multiple 8 bit counters, it would just read the counter_base address plus the
driver offset to the counter value for the one it wanted, etc.
Allow me to go into more details for my proposal, taking your IANA suggestion
as a list of #define statements.
/* known capability types, 1 byte max */
#define SYSINFO 0x01
#define PWM_AVR_8 0x02
#define COUNTER_8 0x03
#define PIO_BIT_TS 0x04
#define SYSINFO_LEN 0x02 /* 2 data bytes for a sysinfo type */
#define PWM_AVR_8_LEN 0x04 /* 4 bytes to control it */
#define COUNTER_8_LEN 0x01 /* 1 byte for counter, read to get value, write to
set to desired value */
/* no PIO_BIT_TS length field, special case: will be the pin map of the entire
device times 2 */
The memory map would look like this:
BYTE: sysinfo (0x01)
BYTE: # of bytes used to describe pins
BYTE: # of capabilities to read
Then come the individual capabilities
BYTE: function type
N-BYTES: possible pins on which this feature can be used, defined by sysinfo
bytes field
N-BYTES: which pins are active for this function
BYTE: bitmask: bit0: EX (exclusive) if set, means that all indicated pins
will be claimed when feature is active
bit1: BUSY: is the chip busy updating this value? 0 == no
bit2-7: reserved
Specific example:
//sysinfo:2 bytes for pin bitmap, 3 functions to scan
0x01 0x02 0x03
//function1:PWM_AVR_8:pins 8,9 possible, active, exclusive, control bits are
all 0
0x02 0x0300 0x0300 0x01 0x00000000
//function2:COUNTER_8:tick source is pin 8, inactive, exclusive, counter value 0
0x03 0x0100 0x0000 0x01 0x00
//function3:PIO_BIT_TS:pins 0-15 possible, all but 8,9 active
// :non-exclusive, pins set to input, reading 0 on all pins
0x04 0xffff 0xfcff 0x00 0x0000 0x0000
Note that the length of each function will vary depending on the sysinfo 'bytes
per pin' setting.
I am not sure if it is necessary to track the pins in all cases, this could be
abstracted totally from the user, if the individual functions are given names,
eg PWM0, PWM1, etc. It would then be the responsibility of the firmware to
provide documentation about which function maps to which physical pin. I think
i prefer the explicit pin mappings though.
In this case, if a DAC is desired, it could be implemented with PWM or
PIO_BIT_TS at the user's discretion
If a function has a max value, eg a 10 bit DAC, one could have the value set to
max when the function is disabled, if this cannot be built into the OWFS driver
ahead of time.
Another Example:
Say you had an 8-pin PIC or similar with a built in DAC pin; well no problem,
you'd just do the following:
#define PIC_DAC_8 0x05
#define PIC_DAC_8_LEN 0x02 /* 2 bytes to control it */
//sysinfo:1 byte for pins:3 functions
0x01 0x01 0x03
//function1:PIC_DAC_8:pin7 possible, active, exclusive, outputting '0xea', gain
'0x0f'
0x05 0x80 0x80 0x01 0xea 0x0f
//function2:COUNTER_8:pin 1 possible, active, exclusive, counter value 0xa1
0x03 0x01 0x01 0x01 0xa1
//function3:PIO_BIT_TS:pins 0-7 possible, 1-6 active
// :non-exclusive, pin 4 set to output, others set to input
// :reading 1 on pin 0, reading 0 on other pins, writing 1 to pin 4
0x04 0xff 0x7e 0x00 0x08 0x09
It would be the responsibility of owfs to handle the resource management, since
1w-slaves do not really have a way of reporting an error.
This system is very flexible: one could present multiple PWM drivers (eg fast
PWM vs servo) on the same pins as different functionality types to OWFS, while
in the background they would use the same HW, just have certain hard-coded
parameters. This could also be abstracted by OWFS :)
Note that the memory does not need to be an actual memory map. It *could* be
implemented that way, or it could be implemented in such a way that the user
could send commands to the device to turn functionality on/off (outside the
scope of this email) which would enable different functionality.
For example, on an AVR, a 128 bit software counter could easily be written to
track pulses on every pin of a 'port' (8 pins). With the memory-map above, that
would result in 16 bytes per pin * 8 pins (= 128 bytes) that would have to be
read each time the master reads the memory map, plus the overhead of the
metadata for the function. If the user does not wish to use software counters,
that feature could be disabled, and the memory map would not contain those 128+
bytes.
Of course this may be of limited benefit, as the usual case would be to issue a
"read:offset,bytes" command, which would jump straight to the data in question.
For this, it would be advantageous to have the memory map be static, but the
option is there if desired.
Night,
-tmk
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Owfs-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/owfs-developers