One Wire Drivers
Interfacing multiple devices of the same family on the same bus
1Wire is a bus and thus the driver should allow to specify the device the application should interface. Also the driver should allow to scan the whole bus for available devices. The proper way should involve a background thread continuously scanning the bus and possibly registering them in a filesystem.
But this would probably too much of an overkill, and thus a much simpler solution is to
call a scanning ioctl
, obtain available devices, select the one we want and tell that
to the driver.
-
ONEWIREIOC_GETFAMILYROMS
An
ioctl
call that returns all scanned devices’ ROMs of the same family (the family depends on the driver). All of the records are stored to thestruct onewire_availroms_s
object (supplied by the application). Usage:ioctl(fd, ONEWIREIOC_GETFAMILYROMS, (unsigned long *)&query)
-
struct onewire_availroms_s
struct onewire_availroms_s
{
uint64_t *roms;
int maxroms;
int actual;
};
The number of maximum records the driver can provide is specified by the user
in the maxroms
field. The user must also specify the uint64_t
buffer
into the roms
field where the driver can store the scanned devices.
The number of scanned devices is set in the actual
field by the driver.
-
ONEWIREIOC_SETROM
Set the ROM of the device the driver should interface. Please note the
ROM argument is a pointer to a uint64_t
variable, and not a uint64_t
value, the reason being arg
in ioctl
is unsigned long
, which
is 32bits on many architectures.
Usage: ioctl(fd, ONEWIREIOC_SETROM, (unsigned long *)&romcode)
.
Maxim/Analog Devices DS2XXX EEPROM driver
This driver can be used to interface the following EEPROMS with a scratchpad
(also specified in enum ds2xxx_eeproms_e
in include/nuttx/1wire/1wire_ds2xxx.h
):
DS2430: 32 bytes, 8 byte scratchpad,
DS2431: 128 bytes, 8 byte scratchpad,
DS2432: 128 bytes, 8 byte scratchpad,
DS2433: 512 bytes, 32 byte scratchpad,
DS28E04: 512 bytes, 32 byte scratchpad,
DS28E07: 128 bytes, 8 byte scratchpad,
DS28EC20: 2560 bytes, 32 byte scratchpad.
Each driver’s instance can interface only one EEPROM type. If you want to interface
multiple eeproms on the same bus, you need to have two drivers (e.g. two /dev
files).
Currently, only basic read/write operations on the EEPROMs are implemented.
Special ioctl calls locking respective pages (or possibly any other EEPROM features)
are still not yet implemented.
As the EEPROM driver is character based, you can move around the EEPROM using lseek
.
Scratchpad unaligned reads and writes are possible.
Driver’s API
-
enum ds2xxx_eeproms_e
enum ds2xxx_eeproms_e
{
EEPROM_DS2430 = 0,
EEPROM_DS2431,
EEPROM_DS2432,
EEPROM_DS2433,
EEPROM_DS28E04,
EEPROM_DS28E07,
EEPROM_DS28EC20,
EEPROM_DS_COUNT
};
The enum of all supported EEPROMS (besides EEPROM_DS_COUNT
).
-
int ds2xxx_initialize(FAR struct onewire_dev_s *dev, enum ds2xxx_eeproms_e devtype, FAR char *devname)
Bind a
onewire_dev_s
struct to this driver, capable of interfacing DS2XXX 1Wire EEPROMs. The user must specify the device type and also the name of the device (e.g./dev/ds2xxx
).- Parameters:
dev – a pointer to the lowerhalf struct
devtype – the type of EEPROMs to be interfaced
devname – the name of the registered file
- Returns:
0 on success and a registered driver, negated errno on failure
Example usage
Registering a driver (STM32 BSP, DS2431 memory):
struct onewire_dev_s *lwhalf;
lwhalf = stm32_1wireinitialize(0);
ds2xxx_initialize(lwhalf, EEPROM_DS2431, "/dev/ds2431");
Application usage (suppose all calls are successful):
/* Write to a specific EEPROM */
int fd = open("/dev/ds2xxx", O_RDWR);
struct onewire_availroms_s query;
uint64_t romarr[8];
query.roms = romarr;
query.maxroms = 8;
ioctl(fd, ONEWIREIOC_GETFAMILYROMS, (unsigned long *)&query);
/* Suppose the driver returns 3 in query.actual. We want the last
* device to be accessed.
*/
ioctl(fd, ONEWIREIOC_SETROM, (unsigned long *)&query.roms[query.actual - 1]);
lseek(fd, 10, SEEK_SET);
write(fd, "HELLO", 5);