diff --git a/arch/arm/src/stm32/stm32_i2c_alt.c b/arch/arm/src/stm32/stm32_i2c_alt.c index 8697e7f1908..5ff9a0da9f4 100755 --- a/arch/arm/src/stm32/stm32_i2c_alt.c +++ b/arch/arm/src/stm32/stm32_i2c_alt.c @@ -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);