apps/spitool: Support multiple trans

By adding a parameter -r, spitool can exchange multiple transactions.
example:
spi exch -b 1 -t 0 -n 0 -f 3000000 -m 1 -w 32 -x 1 -r 2 f001fff1 0000ff35

Signed-off-by: yangsong8 <yangsong8@xiaomi.com>
This commit is contained in:
yangsong8 2025-11-03 16:51:53 +08:00 committed by Xiang Xiao
parent 74293114aa
commit dbc99dbf35
5 changed files with 45 additions and 16 deletions

View file

@ -78,4 +78,11 @@ config SPITOOL_DEFWORDS
---help---
Number of words to be transferred (default 1)
config SPITOOL_DEFTRANS
int "Number of transfer"
default 1
range 1 255
---help---
Number of transfer to be transferred (default 1)
endif # SYSTEM_SPITOOL

View file

@ -174,12 +174,12 @@ int spitool_common_args(FAR struct spitool_s *spitool, FAR char **arg)
case 'r':
ret = arg_decimal(arg, &value);
if (value < 0)
if (value < 0 || value > UINT8_MAX)
{
goto out_of_range;
}
spitool->count = (uint32_t)value;
spitool->trans_count = (uint8_t)value;
return ret;
case 'u':

View file

@ -64,7 +64,7 @@ int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv)
};
uint8_t *txdatap = txdata;
struct spi_trans_s trans;
FAR struct spi_trans_s *trans;
struct spi_sequence_s seq;
uint32_t d;
@ -93,7 +93,7 @@ int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv)
/* There may be transmit data on the command line */
if (argc - argndx > spitool->count)
if (argc - argndx > spitool->count * spitool->trans_count)
{
spitool_printf(spitool, g_spitoomanyargs, argv[0]);
return ERROR;
@ -120,7 +120,7 @@ int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv)
}
spitool_printf(spitool, "Sending:\t");
for (d = 0; d < spitool->count; d++)
for (d = 0; d < spitool->count * spitool->trans_count; d++)
{
if (spitool->width <= 8)
{
@ -138,12 +138,20 @@ int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv)
spitool_printf(spitool, "\n");
trans = malloc(sizeof(struct spi_trans_s) * spitool->trans_count);
if (!trans)
{
spitool_printf(spitool, "Failed to allocate trans memory\n");
return ERROR;
}
/* Get a handle to the SPI bus */
fd = spidev_open(spitool->bus);
if (fd < 0)
{
spitool_printf(spitool, "Failed to get bus %d\n", spitool->bus);
free(trans);
return ERROR;
}
@ -153,8 +161,8 @@ int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv)
seq.mode = spitool->mode;
seq.nbits = spitool->width;
seq.frequency = spitool->freq;
seq.ntrans = 1;
seq.trans = &trans;
seq.ntrans = spitool->trans_count;
seq.trans = trans;
#ifdef CONFIG_SPI_DELAY_CONTROL
seq.a = 0;
@ -163,21 +171,25 @@ int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv)
seq.c = 0;
#endif
trans.deselect = true;
for (d = 0; d < spitool->trans_count; d++)
{
trans[d].deselect = true;
#ifdef CONFIG_SPI_CMDDATA
trans.cmd = spitool->command;
trans[d].cmd = spitool->command;
#endif
trans.delay = spitool->udelay;
trans.nwords = spitool->count;
trans.txbuffer = txdata;
trans.rxbuffer = rxdata;
trans[d].delay = spitool->udelay;
trans[d].nwords = spitool->count;
trans[d].txbuffer = &txdata[d * spitool->count * seq.nbits / 8];
trans[d].rxbuffer = &rxdata[d * spitool->count * seq.nbits / 8];
#ifdef CONFIG_SPI_HWFEATURES
trans.hwfeat = 0;
trans[d].hwfeat = 0;
#endif
}
ret = spidev_transfer(fd, &seq);
close(fd);
free(trans);
if (ret)
{
@ -185,7 +197,7 @@ int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv)
}
spitool_printf(spitool, "Received:\t");
for (d = 0; d < spitool->count; d++)
for (d = 0; d < spitool->count * spitool->trans_count; d++)
{
if (spitool->width <= 8)
{

View file

@ -152,6 +152,10 @@ static int spicmd_help(FAR struct spitool_s *spitool, int argc,
"Default: %d Current: %" PRIu32 " Max: %d\n",
CONFIG_SPITOOL_DEFWORDS, spitool->count, MAX_XDATA);
spitool_printf(spitool, " [-r trans_count] Trans to exchange "
"Default: %d Current: %d Max: %d\n",
CONFIG_SPITOOL_DEFTRANS, spitool->trans_count, UINT8_MAX);
spitool_printf(spitool, "\nNOTES:\n");
#ifndef CONFIG_DISABLE_ENVIRON
spitool_printf(spitool, "o An environment variable like $PATH may be used "
@ -159,7 +163,7 @@ static int spicmd_help(FAR struct spitool_s *spitool, int argc,
#endif
spitool_printf(spitool, "o Arguments are \"sticky\". "
"For example, once the SPI address is\n");
spitool_printf(spitool, " specified, that address will be re-used "
spitool_printf(spitool, " specified, that address will be reused "
"until it is changed.\n");
spitool_printf(spitool, "\nWARNING:\n");
spitool_printf(spitool, "o The SPI commands may have bad side effects "
@ -400,6 +404,11 @@ int main(int argc, FAR char *argv[])
g_spitool.devtype = SPIDEVTYPE_USER;
}
if (g_spitool.trans_count == 0)
{
g_spitool.trans_count = CONFIG_SPITOOL_DEFTRANS;
}
/* Parse and process the command line */
spi_setup(&g_spitool);

View file

@ -140,6 +140,7 @@ struct spitool_s
bool command; /* [-c 0|1] Send as command or data? */
useconds_t udelay; /* [-u udelay] Delay in uS after transfer */
uint8_t mode; /* [-m mode] Mode to use for transfer */
uint8_t trans_count; /* [-r trans count] No of trans to exchange */
/* Output streams */