STM32, STM32L4: add one bit read and write to 1-wire interface. This is needed for devices that require single bit timeslot generation and for 1-Wire search algorithm triplets.

This commit is contained in:
Juha Niskanen 2018-03-23 08:07:20 -06:00 committed by Gregory Nutt
parent 3810f9e942
commit 0f03ffc745
3 changed files with 182 additions and 6 deletions

View File

@ -82,7 +82,11 @@
#define WRITE_TX0 0x00
#define WRITE_TX1 0xFF
#if defined(CONFIG_STM32_STM32F10XX)
# define PIN_OPENDRAIN(GPIO) ((GPIO) | GPIO_CNF_OUTOD)
#else
# define PIN_OPENDRAIN(GPIO) ((GPIO) | GPIO_OPENDRAIN)
#endif
#if defined(CONFIG_STM32_STM32F10XX)
# define USART_CR3_ONEBIT (0)
@ -99,7 +103,9 @@ enum stm32_1wire_msg_e
ONEWIRETASK_NONE = 0,
ONEWIRETASK_RESET,
ONEWIRETASK_WRITE,
ONEWIRETASK_READ
ONEWIRETASK_READ,
ONEWIRETASK_WRITEBIT,
ONEWIRETASK_READBIT
};
struct stm32_1wire_msg_s
@ -169,6 +175,8 @@ static int stm32_1wire_read(FAR struct onewire_dev_s *dev, uint8_t *buffer,
static int stm32_1wire_exchange(FAR struct onewire_dev_s *dev, bool reset,
const uint8_t *txbuffer, int txbuflen,
uint8_t *rxbuffer, int rxbuflen);
static int stm32_1wire_writebit(FAR struct onewire_dev_s *dev, const uint8_t *bit);
static int stm32_1wire_readbit(FAR struct onewire_dev_s *dev, uint8_t *bit);
/****************************************************************************
* Private Data
@ -335,7 +343,9 @@ static const struct onewire_ops_s stm32_1wire_ops =
.reset = stm32_1wire_reset,
.write = stm32_1wire_write,
.read = stm32_1wire_read,
.exchange = stm32_1wire_exchange
.exchange = stm32_1wire_exchange,
.writebit = stm32_1wire_writebit,
.readbit = stm32_1wire_readbit
};
/****************************************************************************
@ -822,6 +832,7 @@ static int stm32_1wire_process(struct stm32_1wire_priv_s *priv,
break;
case ONEWIRETASK_WRITE:
case ONEWIRETASK_WRITEBIT:
/* Set baud rate */
priv->baud = TIMESLOT_BAUD;
@ -844,6 +855,7 @@ static int stm32_1wire_process(struct stm32_1wire_priv_s *priv,
break;
case ONEWIRETASK_READ:
case ONEWIRETASK_READBIT:
/* Set baud rate */
priv->baud = TIMESLOT_BAUD;
@ -968,6 +980,20 @@ static int stm32_1wire_isr(int irq, void *context, void *arg)
stm32_1wire_send(priv, READ_TX);
break;
case ONEWIRETASK_WRITEBIT:
*priv->byte = 0;
priv->msgs = NULL;
priv->result = OK;
nxsem_post(&priv->sem_isr);
break;
case ONEWIRETASK_READBIT:
*priv->byte = (dr == READ_RX1) ? 1 : 0;
priv->msgs = NULL;
priv->result = OK;
nxsem_post(&priv->sem_isr);
break;
}
}
}
@ -1136,6 +1162,50 @@ static int stm32_1wire_exchange(FAR struct onewire_dev_s *dev, bool reset,
return result;
}
/****************************************************************************
* Name: stm32_1wire_writebit
*
* Description:
* Write one bit of 1-Wire data
*
****************************************************************************/
static int stm32_1wire_writebit(FAR struct onewire_dev_s *dev, const uint8_t *bit)
{
struct stm32_1wire_priv_s *priv = ((struct stm32_1wire_inst_s *)dev)->priv;
const struct stm32_1wire_msg_s msgs[1] =
{
[0].task = ONEWIRETASK_WRITEBIT,
[0].buffer = (uint8_t *)bit,
[0].buflen = 1
};
DEBUGASSERT(*bit == 0 || *bit == 1);
return stm32_1wire_process(priv, msgs, 1);
}
/****************************************************************************
* Name: stm32_1wire_readbit
*
* Description:
* Sample one bit of 1-Wire data
*
****************************************************************************/
static int stm32_1wire_readbit(FAR struct onewire_dev_s *dev, uint8_t *bit)
{
struct stm32_1wire_priv_s *priv = ((struct stm32_1wire_inst_s *)dev)->priv;
const struct stm32_1wire_msg_s msgs[1] =
{
[0].task = ONEWIRETASK_READBIT,
[0].buffer = bit,
[0].buflen = 1
};
return stm32_1wire_process(priv, msgs, 1);
}
/****************************************************************************
* Public Functions
****************************************************************************/

View File

@ -96,7 +96,9 @@ enum stm32_1wire_msg_e
ONEWIRETASK_NONE = 0,
ONEWIRETASK_RESET,
ONEWIRETASK_WRITE,
ONEWIRETASK_READ
ONEWIRETASK_READ,
ONEWIRETASK_WRITEBIT,
ONEWIRETASK_READBIT
};
struct stm32_1wire_msg_s
@ -173,6 +175,8 @@ static int stm32_1wire_read(FAR struct onewire_dev_s *dev, uint8_t *buffer,
static int stm32_1wire_exchange(FAR struct onewire_dev_s *dev, bool reset,
const uint8_t *txbuffer, int txbuflen,
uint8_t *rxbuffer, int rxbuflen);
static int stm32_1wire_writebit(FAR struct onewire_dev_s *dev, const uint8_t *bit);
static int stm32_1wire_readbit(FAR struct onewire_dev_s *dev, uint8_t *bit);
#ifdef CONFIG_PM
static int stm32_1wire_pm_prepare(FAR struct pm_callback_s *cb, int domain,
enum pm_state_e pmstate);
@ -301,7 +305,9 @@ static const struct onewire_ops_s stm32_1wire_ops =
.reset = stm32_1wire_reset,
.write = stm32_1wire_write,
.read = stm32_1wire_read,
.exchange = stm32_1wire_exchange
.exchange = stm32_1wire_exchange,
.writebit = stm32_1wire_writebit,
.readbit = stm32_1wire_readbit
};
/****************************************************************************
@ -751,6 +757,7 @@ static int stm32_1wire_process(struct stm32_1wire_priv_s *priv,
break;
case ONEWIRETASK_WRITE:
case ONEWIRETASK_WRITEBIT:
/* Set baud rate */
priv->baud = TIMESLOT_BAUD;
@ -773,6 +780,7 @@ static int stm32_1wire_process(struct stm32_1wire_priv_s *priv,
break;
case ONEWIRETASK_READ:
case ONEWIRETASK_READBIT:
/* Set baud rate */
priv->baud = TIMESLOT_BAUD;
@ -897,6 +905,20 @@ static int stm32_1wire_isr(int irq, void *context, void *arg)
stm32_1wire_send(priv, READ_TX);
break;
case ONEWIRETASK_WRITEBIT:
*priv->byte = 0;
priv->msgs = NULL;
priv->result = OK;
nxsem_post(&priv->sem_isr);
break;
case ONEWIRETASK_READBIT:
*priv->byte = (dr == READ_RX1) ? 1 : 0;
priv->msgs = NULL;
priv->result = OK;
nxsem_post(&priv->sem_isr);
break;
}
}
}
@ -1052,6 +1074,50 @@ static int stm32_1wire_exchange(FAR struct onewire_dev_s *dev, bool reset,
return result;
}
/****************************************************************************
* Name: stm32_1wire_writebit
*
* Description:
* Write one bit of 1-Wire data
*
****************************************************************************/
static int stm32_1wire_writebit(FAR struct onewire_dev_s *dev, const uint8_t *bit)
{
struct stm32_1wire_priv_s *priv = ((struct stm32_1wire_inst_s *)dev)->priv;
const struct stm32_1wire_msg_s msgs[1] =
{
[0].task = ONEWIRETASK_WRITEBIT,
[0].buffer = (uint8_t *)bit,
[0].buflen = 1
};
DEBUGASSERT(*bit == 0 || *bit == 1);
return stm32_1wire_process(priv, msgs, 1);
}
/****************************************************************************
* Name: stm32_1wire_readbit
*
* Description:
* Sample one bit of 1-Wire data
*
****************************************************************************/
static int stm32_1wire_readbit(FAR struct onewire_dev_s *dev, uint8_t *bit)
{
struct stm32_1wire_priv_s *priv = ((struct stm32_1wire_inst_s *)dev)->priv;
const struct stm32_1wire_msg_s msgs[1] =
{
[0].task = ONEWIRETASK_READBIT,
[0].buffer = bit,
[0].buflen = 1
};
return stm32_1wire_process(priv, msgs, 1);
}
/************************************************************************************
* Name: stm32_1wire_pm_prepare
*

View File

@ -111,7 +111,7 @@
*
* Description:
* Reset pulse and presence detect, send a block of data and receive a block
* of data from 1-Wir. Each write operational will be an 'atomic'
* of data from 1-Wire. Each write operational will be an 'atomic'
* operation in the sense that any other 1-Wire actions will be serialized
* and pend until this write completes.
*
@ -130,6 +130,44 @@
#define ONEWIRE_EXCHANGE(d,r,tx,tl,rx,rl) ((d)->ops->exchange(d,r,tx,tl,rx,rl))
/****************************************************************************
* Name: ONEWIRE_WRITEBIT
*
* Description:
* Send a single bit on 1-Wire. Each write operational will be an 'atomic'
* operation in the sense that any other 1-Wire actions will be serialized
* and pend until this write completes.
*
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to the read-only 1 byte buffer for the bit value
*
* Returned Value:
* 0: success, <0: A negated errno
*
****************************************************************************/
#define ONEWIRE_WRITEBIT(d,b) ((d)->ops->writebit(d,b))
/****************************************************************************
* Name: ONEWIRE_READBIT
*
* Description:
* Sample a single bit from 1-Wire. Each read operational will be an 'atomic'
* operation in the sense that any other 1-Wire actions will be serialized
* and pend until this read completes.
*
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to a 1 byte buffer for the bit value
*
* Returned Value:
* 0: success, <0: A negated errno
*
****************************************************************************/
#define ONEWIRE_READBIT(d,b) ((d)->ops->readbit(d,b))
/****************************************************************************
* Public Types
****************************************************************************/
@ -147,6 +185,8 @@ struct onewire_ops_s
int (*exchange)(FAR struct onewire_dev_s *dev, bool reset,
FAR const uint8_t *txbuffer, int txbuflen,
FAR uint8_t *rxbuffer, int rxbuflen);
int (*writebit)(FAR struct onewire_dev_s *dev, FAR const uint8_t *bit);
int (*readbit)(FAR struct onewire_dev_s *dev, FAR uint8_t *bit);
};
/* 1-Wire private data. This structure only defines the initial fields of the