drivers/1wire: capture scanned roms of onewire_search, standartized ioctls

This commit introduces 2 new fields in the onewire_master_s struct:
uint64_t selected_rom,
uint64_t *available_roms.

The key point behind this is to allow onewire_search to capture all
devices on the bus into the kernel struct. While this commit is keeping
the old API (for the sake of not messing everything up), you don't have
to reimplement the search of all roms in very strange ways
(such as custom callbacks into the userspace).

Instead of that, a generic ioctl (only a function to be called from
the device driver) was implemented, that searches
the bus (for a particular 1wire family), saves it and then copies it
in a standard way to your application. The ioctl is called
ONEWIREIOC_GETFAMILYROMS.

Also as 1wire can interface multiple devices, a API telling the
driver which ROM to interface was missing, this commit fixes
this with the ONEWIREIOC_SETROM call.

The example usage is you first get all the devices on the bus
using ONEWIREIOC_GETFAMILYROMS. In your application, you choose
the correct device you want to talk to. Then you call
ONEWIREIOC_SETROM. And then writes, reads, ...

Signed-off-by: Stepan Pressl <pressl.stepan@gmail.com>
This commit is contained in:
Stepan Pressl
2025-10-09 18:55:18 +02:00
committed by Alin Jerpelea
parent 138228b0f3
commit d1e1643b84
3 changed files with 110 additions and 0 deletions
+65
View File
@@ -106,6 +106,29 @@ static inline uint32_t onewire_leuint32(uint32_t x)
}
#endif
/****************************************************************************
* Name: onewire_addslave_on_search
*
* Description:
* A default callback used to save scanned romcodes into
* the onewire_master_s struct. Currently used in GETFAMILYROMS.
*
****************************************************************************/
static void onewire_addslave_on_search(int family, uint64_t romcode,
FAR void *arg)
{
DEBUGASSERT(arg != NULL);
FAR struct onewire_master_s *master = (FAR struct onewire_master_s *)arg;
DEBUGASSERT(master->available_roms != NULL);
if (master->nslaves < master->maxslaves)
{
master->available_roms[master->nslaves] = romcode;
master->nslaves += 1;
}
}
/****************************************************************************
* Name: onewire_pm_prepare
*
@@ -607,6 +630,37 @@ int onewire_removeslave(FAR struct onewire_master_s *master,
return OK;
}
int onewire_ioctl_setrom(FAR struct onewire_master_s *master, uint64_t rom)
{
DEBUGASSERT(master != NULL);
master->selected_rom = rom;
return OK;
}
int onewire_ioctl_getfamilyroms(FAR struct onewire_master_s *master,
FAR struct onewire_availroms_s *avail,
int family)
{
DEBUGASSERT(master != NULL && avail != NULL);
/* Perform scan of the bus, but first restore the count */
master->nslaves = 0;
onewire_search(master, family, false, onewire_addslave_on_search, master);
/* Very secure for loop! */
avail->actual = 0;
for (int i = 0; (i < master->nslaves) && (i < avail->maxroms) &&
(i < master->maxslaves); ++i)
{
avail->roms[i] = master->available_roms[i];
avail->actual += 1;
}
return OK;
}
/****************************************************************************
* Name: onewire_initialize
*
@@ -623,6 +677,7 @@ FAR struct onewire_master_s *
onewire_initialize(FAR struct onewire_dev_s *dev, int maxslaves)
{
FAR struct onewire_master_s *master;
FAR uint64_t *roms_array;
DEBUGASSERT(dev != NULL);
DEBUGASSERT(maxslaves > 0);
@@ -635,6 +690,14 @@ onewire_initialize(FAR struct onewire_dev_s *dev, int maxslaves)
return NULL;
}
roms_array = (FAR uint64_t *)kmm_malloc(sizeof(uint64_t) * maxslaves);
if (roms_array == NULL)
{
i2cerr("ERROR: Failed to allocate\n");
kmm_free(master);
return NULL;
}
/* Initialize the device structure */
master->dev = dev;
@@ -642,6 +705,7 @@ onewire_initialize(FAR struct onewire_dev_s *dev, int maxslaves)
master->nslaves = 0;
master->maxslaves = maxslaves;
master->insearch = false;
master->available_roms = roms_array;
#ifdef CONFIG_PM
master->pm_cb.prepare = onewire_pm_prepare;
@@ -676,6 +740,7 @@ int onewire_uninitialize(FAR struct onewire_master_s *master)
/* Release resources. This does not touch the underlying onewire_dev_s */
nxrmutex_destroy(&master->devlock);
kmm_free(master->available_roms);
kmm_free(master);
return OK;
}
+25
View File
@@ -37,7 +37,10 @@
* Public Types
****************************************************************************/
/* Forward declarations. */
struct onewire_dev_s;
struct onewire_availroms_s;
struct onewire_master_s
{
@@ -46,6 +49,8 @@ struct onewire_master_s
int nslaves; /* Number of 1-wire slaves */
int maxslaves; /* Maximum number of 1-wire slaves */
bool insearch; /* If we are in middle of 1-wire search */
uint64_t selected_rom; /* Currently selected ROM */
uint64_t *available_roms; /* Available ROMS */
#ifdef CONFIG_PM
struct pm_callback_s pm_cb; /* PM callbacks */
#endif
@@ -72,6 +77,26 @@ int onewire_addslave(FAR struct onewire_master_s *master,
int onewire_removeslave(FAR struct onewire_master_s *master,
FAR struct onewire_slave_s *slave);
/****************************************************************************
* Name: onewire_ioctl_setrom
*
* Description: implementation of the ONEWIREIOC_SETROM ioctl
*
****************************************************************************/
int onewire_ioctl_setrom(FAR struct onewire_master_s *master, uint64_t rom);
/****************************************************************************
* Name: onewire_ioctl_getfamilyroms
*
* Description: implementation of the ONEWIREIOC_GETFAMILYROMS ioctl
*
****************************************************************************/
int onewire_ioctl_getfamilyroms(FAR struct onewire_master_s *master,
FAR struct onewire_availroms_s *avail,
int family);
/****************************************************************************
* Name: onewire_reset_resume
*
+20
View File
@@ -31,6 +31,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <nuttx/fs/ioctl.h>
/****************************************************************************
* Pre-processor Definitions
@@ -48,6 +49,11 @@
#define ONEWIRE_CMD_MATCH_ROM 0x55
#define ONEWIRE_CMD_RESUME 0xa5
/* Supported ioctl commands */
#define ONEWIREIOC_SETROM _1WIREIOC(0x0001)
#define ONEWIREIOC_GETFAMILYROMS _1WIREIOC(0x0002)
/****************************************************************************
* Name: ONEWIRE_RESET
*
@@ -202,6 +208,20 @@ struct onewire_dev_s
FAR const struct onewire_ops_s *ops; /* 1-Wire vtable */
};
/* A struct to be passed to the ONEWIREIOC_GETFAMILYROMS ioctl call.
* The user fills in the target roms array in the userspace application
* to get all the available roms. The user can limit the number obtained
* roms using the maxroms field. The actual count of roms on the bus
* is then stored in the actual field.
*/
struct onewire_availroms_s
{
uint64_t *roms;
int maxroms;
int actual;
};
/****************************************************************************
* Public Functions Definitions
****************************************************************************/