STM32 I2C: Final fixes from Max Kriegleder et al.

This commit is contained in:
Gregory Nutt 2014-05-23 08:42:14 -06:00
parent 8dbc4714c5
commit 5d3479bbec

View File

@ -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);