STM32 I2C: Final fixes from Max Kriegleder et al.
This commit is contained in:
parent
8dbc4714c5
commit
5d3479bbec
@ -56,7 +56,8 @@
|
||||
* - Private: Private data of an I2C Hardware
|
||||
*
|
||||
* TODO
|
||||
* - Setup and test polled operation (CONFIG_I2C_POLLED)
|
||||
* - Trace events in polled operation fill trace table very quickly. Events 1111 and 1004 get traced
|
||||
* in an alternate fashion during polling causing multiple entries.
|
||||
* - Check for all possible deadlocks (as BUSY='1' I2C needs to be reset in HW using the I2C_CR1_SWRST)
|
||||
* - SMBus support (hardware layer timings are already supported) and add SMBA gpio pin
|
||||
* - Slave support with multiple addresses (on multiple instances):
|
||||
@ -206,38 +207,38 @@ enum stm32_intstate_e
|
||||
/* Trace events */
|
||||
|
||||
#ifdef CONFIG_I2C_TRACE
|
||||
static const uint32_t I2CEVENT_NONE = 0; /* No events have occurred with this status */
|
||||
static const uint32_t I2CEVENT_STATE_ERROR = 1000; /* No correct state detected, diver cannot handle state */
|
||||
static const uint32_t I2CEVENT_ISR_SHUTDOWN = 1001; /* ISR gets shutdown */
|
||||
static const uint32_t I2CEVENT_ISR_EMPTY_CALL = 1002; /* ISR gets called but no I2C logic comes into play */
|
||||
static const uint32_t I2CEVENT_MSG_HANDLING = 1003; /* Message Handling 1/1: advances the msg processing param = msgc*/
|
||||
static const uint32_t I2CEVENT_POLL_DEV_NOT_RDY = 1004; /* During polled operation if device is not ready yet */
|
||||
static const uint32_t I2CEVENT_ISR_CALL = 1111; /* ISR called*/
|
||||
static const uint16_t I2CEVENT_NONE = 0; /* No events have occurred with this status */
|
||||
static const uint16_t I2CEVENT_STATE_ERROR = 1000; /* No correct state detected, diver cannot handle state */
|
||||
static const uint16_t I2CEVENT_ISR_SHUTDOWN = 1001; /* ISR gets shutdown */
|
||||
static const uint16_t I2CEVENT_ISR_EMPTY_CALL = 1002; /* ISR gets called but no I2C logic comes into play */
|
||||
static const uint16_t I2CEVENT_MSG_HANDLING = 1003; /* Message Handling 1/1: advances the msg processing param = msgc*/
|
||||
static const uint16_t I2CEVENT_POLL_DEV_NOT_RDY = 1004; /* During polled operation if device is not ready yet */
|
||||
static const uint16_t I2CEVENT_ISR_CALL = 1111; /* ISR called*/
|
||||
|
||||
static const uint32_t I2CEVENT_SENDADDR = 5; /* Start/Master bit set and address sent, param = priv->msgv->addr(EV5 in reference manual) */
|
||||
static const uint32_t I2CEVENT_ADDR_HDL_READ_1 = 51; /* Read of length 1 address handling, param = 0 */
|
||||
static const uint32_t I2CEVENT_ADDR_HDL_READ_2 = 52; /* Read of length 2 address handling, param = 0 */
|
||||
static const uint32_t I2CEVENT_EMPTY_MSG = 5000; /* Empty message detected, param=0 */
|
||||
static const uint16_t I2CEVENT_SENDADDR = 5; /* Start/Master bit set and address sent, param = priv->msgv->addr(EV5 in reference manual) */
|
||||
static const uint16_t I2CEVENT_ADDR_HDL_READ_1 = 51; /* Read of length 1 address handling, param = 0 */
|
||||
static const uint16_t I2CEVENT_ADDR_HDL_READ_2 = 52; /* Read of length 2 address handling, param = 0 */
|
||||
static const uint16_t I2CEVENT_EMPTY_MSG = 5000; /* Empty message detected, param=0 */
|
||||
|
||||
static const uint32_t I2CEVENT_ADDRESS_ACKED = 6; /* Address has been ACKed(i.e. it's a valid address) param = address */
|
||||
static const uint32_t I2CEVENT_ADDRESS_ACKED_READ_1 = 63; /* Event when reading single byte just after address is beeing ACKed, param = 0 */
|
||||
static const uint32_t I2CEVENT_ADDRESS_ACKED_READ_2 = 61; /* Event when reading two bytes just after address is beeing ACKed, param = 0 */
|
||||
static const uint32_t I2CEVENT_ADDRESS_ACKED_WRITE = 681; /* Address has been ACKed(i.e. it's a valid address) in write mode and byte has been written */
|
||||
static const uint32_t I2CEVENT_ADDRESS_NACKED = 6000; /* Address has been NACKed(i.e. it's an invalid address) param = address */
|
||||
static const uint16_t I2CEVENT_ADDRESS_ACKED = 6; /* Address has been ACKed(i.e. it's a valid address) param = address */
|
||||
static const uint16_t I2CEVENT_ADDRESS_ACKED_READ_1 = 63; /* Event when reading single byte just after address is beeing ACKed, param = 0 */
|
||||
static const uint16_t I2CEVENT_ADDRESS_ACKED_READ_2 = 61; /* Event when reading two bytes just after address is beeing ACKed, param = 0 */
|
||||
static const uint16_t I2CEVENT_ADDRESS_ACKED_WRITE = 681; /* Address has been ACKed(i.e. it's a valid address) in write mode and byte has been written */
|
||||
static const uint16_t I2CEVENT_ADDRESS_NACKED = 6000; /* Address has been NACKed(i.e. it's an invalid address) param = address */
|
||||
|
||||
static const uint32_t I2CEVENT_READ = 7; /* RxNE = 1 therefore can be read, param = dcnt */
|
||||
static const uint32_t I2CEVENT_READ_3 = 72; /* EV7_2 reference manual, reading byte N-2 and N-1 when N >=3 */
|
||||
static const uint32_t I2CEVENT_READ_2 = 73; /* EV7_3 reference manual, reading byte 1 and 2 when N == 2 */
|
||||
static const uint32_t I2CEVENT_READ_SR_EMPTY = 79; /* DR is full but SR is empty, does not read DR and waits for SR to fill in next ISR */
|
||||
static const uint32_t I2CEVENT_READ_LAST_BYTE = 72; /* EV7_2 reference manual last two bytes are in SR and DR */
|
||||
static const uint32_t I2CEVENT_READ_ERROR = 7000; /* read mode error */
|
||||
static const uint16_t I2CEVENT_READ = 7; /* RxNE = 1 therefore can be read, param = dcnt */
|
||||
static const uint16_t I2CEVENT_READ_3 = 72; /* EV7_2 reference manual, reading byte N-2 and N-1 when N >=3 */
|
||||
static const uint16_t I2CEVENT_READ_2 = 73; /* EV7_3 reference manual, reading byte 1 and 2 when N == 2 */
|
||||
static const uint16_t I2CEVENT_READ_SR_EMPTY = 79; /* DR is full but SR is empty, does not read DR and waits for SR to fill in next ISR */
|
||||
static const uint16_t I2CEVENT_READ_LAST_BYTE = 72; /* EV7_2 reference manual last two bytes are in SR and DR */
|
||||
static const uint16_t I2CEVENT_READ_ERROR = 7000; /* read mode error */
|
||||
|
||||
static const uint32_t I2CEVENT_WRITE_TO_DR = 8; /* EV8 reference manual, writing into the data register param = byte to send */
|
||||
static const uint32_t I2CEVENT_WRITE_STOP = 82; /* EV8_2 reference manual, set stop bit after write is finished */
|
||||
static const uint32_t I2CEVENT_WRITE_RESTART = 83; /* Re-send start bit as next packet is a read */
|
||||
static const uint32_t I2CEVENT_WRITE_NO_RESTART = 84; /* don't restart as packet flag says so */
|
||||
static const uint32_t I2CEVENT_WRITE_ERROR = 8000; /* Error in write mode, param = 0 */
|
||||
static const uint32_t I2CEVENT_WRITE_FLAG_ERROR = 8001; /* Next message has unrecognized flag, param = priv->msgv->flags */
|
||||
static const uint16_t I2CEVENT_WRITE_TO_DR = 8; /* EV8 reference manual, writing into the data register param = byte to send */
|
||||
static const uint16_t I2CEVENT_WRITE_STOP = 82; /* EV8_2 reference manual, set stop bit after write is finished */
|
||||
static const uint16_t I2CEVENT_WRITE_RESTART = 83; /* Re-send start bit as next packet is a read */
|
||||
static const uint16_t I2CEVENT_WRITE_NO_RESTART = 84; /* don't restart as packet flag says so */
|
||||
static const uint16_t I2CEVENT_WRITE_ERROR = 8000; /* Error in write mode, param = 0 */
|
||||
static const uint16_t I2CEVENT_WRITE_FLAG_ERROR = 8001; /* Next message has unrecognized flag, param = priv->msgv->flags */
|
||||
#endif /* CONFIG_I2C_TRACE */
|
||||
|
||||
/* Trace data */
|
||||
@ -338,9 +339,9 @@ static inline void stm32_i2c_sem_destroy(FAR struct i2c_dev_s *dev);
|
||||
|
||||
#ifdef CONFIG_I2C_TRACE
|
||||
static void stm32_i2c_tracereset(FAR struct stm32_i2c_priv_s *priv);
|
||||
static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, uint32_t status);
|
||||
static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, uint16_t status);
|
||||
static void stm32_i2c_traceevent(FAR struct stm32_i2c_priv_s *priv,
|
||||
uint32_t event, uint32_t parm);
|
||||
uint16_t event, uint32_t parm);
|
||||
static void stm32_i2c_tracedump(FAR struct stm32_i2c_priv_s *priv);
|
||||
#endif /* CONFIG_I2C_TRACE */
|
||||
|
||||
@ -877,7 +878,7 @@ static void stm32_i2c_tracereset(FAR struct stm32_i2c_priv_s *priv)
|
||||
stm32_i2c_traceclear(priv);
|
||||
}
|
||||
|
||||
static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, uint32_t status)
|
||||
static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, uint16_t status)
|
||||
{
|
||||
struct stm32_trace_s *trace = &priv->trace[priv->tndx];
|
||||
|
||||
@ -917,7 +918,7 @@ static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, uint32_t statu
|
||||
}
|
||||
|
||||
static void stm32_i2c_traceevent(FAR struct stm32_i2c_priv_s *priv,
|
||||
uint32_t event, uint32_t parm)
|
||||
uint16_t event, uint32_t parm)
|
||||
{
|
||||
struct stm32_trace_s *trace;
|
||||
|
||||
@ -1285,10 +1286,9 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
|
||||
|
||||
if (priv->msgc == 0)
|
||||
{
|
||||
priv->msgv == NULL;
|
||||
|
||||
/* Good practice + done by last implementation when messages are finished
|
||||
* (compatibility)
|
||||
/* No more messages, don't need to increment msgv. This pointer will be set
|
||||
* to zero when reaching the termination of the ISR calls, i.e. Messages
|
||||
* handling(2/2).
|
||||
*/
|
||||
}
|
||||
else
|
||||
@ -1868,16 +1868,23 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
|
||||
|
||||
if (priv->dcnt == -1 && priv->msgc == 0)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
i2cvdbg("Shutting down I2C ISR\n");
|
||||
|
||||
stm32_i2c_traceevent(priv, I2CEVENT_ISR_SHUTDOWN, 0);
|
||||
|
||||
/* Clear internal pointer to the message content.
|
||||
* Good practice + done by last implementation when messages are finished
|
||||
* (compatibility concerns)
|
||||
*/
|
||||
|
||||
priv->msgv = NULL;
|
||||
|
||||
#ifdef CONFIG_I2C_POLLED
|
||||
priv->intstate = INTSTATE_DONE;
|
||||
#else
|
||||
/* clear all interrupts */
|
||||
/* Clear all interrupts */
|
||||
|
||||
uint32_t regval;
|
||||
regval = stm32_i2c_getreg(priv, STM32_I2C_CR2_OFFSET);
|
||||
regval &= ~I2C_CR2_ALLINTS;
|
||||
stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, regval);
|
||||
@ -2154,7 +2161,7 @@ static int stm32_i2c_process(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *ms
|
||||
* process the first message(first priv->msgv entry) correctly.
|
||||
*/
|
||||
|
||||
priv->dcnt = -1;
|
||||
priv->dcnt = -1;
|
||||
priv->status = 0;
|
||||
stm32_i2c_sendstart(priv);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user