TI中文支持网
TI专业的中文技术问题搜集分享网站

MSPM0G3507: MCU作为从机,I2C SCL短接到GND 1秒后松开,SCL无法恢复高电平

Part Number:MSPM0G3507

如题,本来MCU作为从机,I2C可以正常被外部主机读写,但是无意中把SCL短时间内拉低(如1秒),然后松开,SCL居然无法恢复。

经排查是3507这边的问题(重启主机无效,重启从机恢复)。

开启所有中断标志位,无法响应,甚至TimeoutA设置也无法响应。

目前看不知道这个问题出现的原因,且3507作为从机自身也没有标志位可感知此异常:

food chen:

补充:看现象3507作为从机把SCL给拉住了(0电平)

,

food chen:

SYSCONFIG_WEAK void SYSCFG_DL_I2C_init(void) {DL_I2C_setClockConfig(I2C_INST,(DL_I2C_ClockConfig *) &gI2CClockConfig);DL_I2C_disableAnalogGlitchFilter(I2C_INST);/* Configure Target Mode */DL_I2C_setTargetOwnAddress(I2C_INST, I2C_TARGET_OWN_ADDR);DL_I2C_setTargetTXFIFOThreshold(I2C_INST, DL_I2C_TX_FIFO_LEVEL_BYTES_1);DL_I2C_setTargetRXFIFOThreshold(I2C_INST, DL_I2C_RX_FIFO_LEVEL_BYTES_1);DL_I2C_enableTargetTXEmptyOnTXRequest(I2C_INST);DL_I2C_enableTargetClockStretching(I2C_INST);/* Configure Interrupts */DL_I2C_enableInterrupt(I2C_INST,DL_I2C_INTERRUPT_TARGET_RXFIFO_TRIGGER |DL_I2C_INTERRUPT_TARGET_START |DL_I2C_INTERRUPT_TARGET_STOP);/* Enable module */DL_I2C_enableTarget(I2C_INST);}/** Copyright (c) 2021, Texas Instruments Incorporated* All rights reserved.** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions* are met:** *Redistributions of source code must retain the above copyright*notice, this list of conditions and the following disclaimer.** *Redistributions in binary form must reproduce the above copyright*notice, this list of conditions and the following disclaimer in the*documentation and/or other materials provided with the distribution.** *Neither the name of Texas Instruments Incorporated nor the names of*its contributors may be used to endorse or promote products derived*from this software without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/#include "ti_msp_dl_config.h"/* Maximum size of TX packet */
#define I2C_TX_MAX_PACKET_SIZE (16)/* Maximum size of RX packet */
#define I2C_RX_MAX_PACKET_SIZE (16)/* Data sent to Controller in response to Read transfer */
uint8_t gTxPacket[I2C_TX_MAX_PACKET_SIZE] = {0x00};/* Counters for TX length and bytes sent */
uint32_t gTxLen, gTxCount;
uint32_t gTxFillNum;
/* Data received from Controller during a Write transfer */
uint8_t gRxPacket[I2C_RX_MAX_PACKET_SIZE];
/* Counters for TX length and bytes sent */
uint32_t gRxLen, gRxCount;int main(void)
{SYSCFG_DL_init();/* Set LED to indicate start of transfer */DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);/** Fill FIFO with data.* Note that transactions are initiated by the Controller, so this example* only fills the buffer and the Target device will send this data when* requested by the Controller.* The TX FIFO is initialized to zero and then it will echo the data sent by* Controller.*/gTxCount = 0;gTxLen= I2C_TX_MAX_PACKET_SIZE;DL_I2C_setTimeoutACount(I2C_INST,2);DL_I2C_setTimeoutBCount(I2C_INST,2);DL_I2C_enableTimeoutA(I2C_INST);//DL_I2C_enableTimeoutB(I2C_INST);DL_I2C_disableTargetTXEmptyOnTXRequest(I2C_INST);DL_I2C_enableInterrupt(I2C_INST, DL_I2C_INTERRUPT_TARGET_RXFIFO_OVERFLOW|DL_I2C_TARGET_INTERRUPT_OVERFLOW|DL_I2C_INTERRUPT_TARGET_TXFIFO_UNDERFLOW|DL_I2C_INTERRUPT_TARGET_TXFIFO_EMPTY |DL_I2C_INTERRUPT_TIMEOUT_A |DL_I2C_INTERRUPT_TIMEOUT_B|DL_I2C_INTERRUPT_TARGET_PEC_RX_ERROR|DL_I2C_INTERRUPT_TARGET_RX_DONE|DL_I2C_INTERRUPT_TARGET_ARBITRATION_LOST|DL_I2C_INTERRUPT_TARGET_GENERAL_CALL|DL_I2C_INTERRUPT_TARGET_STOP|DL_I2C_INTERRUPT_TARGET_RXFIFO_FULL|DL_I2C_INTERRUPT_TARGET_TXFIFO_TRIGGER|DL_I2C_INTERRUPT_TARGET_TX_DONE);/* Initialize variables to receive data inside RX ISR */gRxCount = 0;gRxLen= I2C_RX_MAX_PACKET_SIZE;DL_I2C_enableTargetACKOverride(I2C_INST);NVIC_EnableIRQ(I2C_INST_INT_IRQN);DL_SYSCTL_enableSleepOnExit();/* Go to STOP, the device will wake-up on address match */while (1) {__WFI();}
}
int aa;
int f1= 0;
int f2= 0;
int tmt_flag= 0;
int rvflag= 0;
void I2C_INST_IRQHandler(void)
{static bool dataRx = false;aa = DL_I2C_getPendingInterrupt(I2C_INST);switch (aa) {case DL_I2C_IIDX_TARGET_START:/* Initialize RX or TX after Start condition is received */gTxCount = 0;gRxCount = 0;dataRx= false;rvflag= 0;/* Flush TX FIFO to refill it */DL_I2C_flushTargetTXFIFO(I2C_INST);break;case DL_I2C_IIDX_TARGET_RXFIFO_TRIGGER:/* Store received data in buffer */dataRx = true;while (DL_I2C_isTargetRXFIFOEmpty(I2C_INST) != true) {if (gRxCount < gRxLen) {gRxPacket[gRxCount++] = DL_I2C_receiveTargetData(I2C_INST);} else {/* Prevent overflow and just ignore data */DL_I2C_receiveTargetData(I2C_INST);}if(gRxCount >= 2){DL_I2C_enableTargetACKOverride(I2C_INST);DL_I2C_setTargetACKOverrideValue(I2C_INST,DL_I2C_TARGET_RESPONSE_OVERRIDE_VALUE_NACK);f1 = 1;}else{DL_I2C_enableTargetACKOverride(I2C_INST);DL_I2C_setTargetACKOverrideValue(I2C_INST,DL_I2C_TARGET_RESPONSE_OVERRIDE_VALUE_ACK);f2 = 1;}}break;case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER:/* Fill TX FIFO if there are more bytes to send */if (gTxCount < gTxLen) {gTxFillNum = DL_I2C_fillTargetTXFIFO(I2C_INST, &gTxPacket[gTxCount], 1);gTxCount += gTxFillNum;} else {/** Fill FIFO with 0x00 if more data is requested than* expected gTxLen*/while (DL_I2C_transmitTargetDataCheck(I2C_INST, 0x88) != false);}break;case DL_I2C_IIDX_TARGET_STOP:/* If data was received, echo to TX buffer */if (dataRx == true) {for (uint16_t i = 0;(i < gRxCount) && (i < I2C_TX_MAX_PACKET_SIZE); i++) {gTxPacket[i] = gRxPacket[i];DL_I2C_flushTargetTXFIFO(I2C_INST);}dataRx = false;}/* Toggle LED to indicate successful RX or TX */DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);break;case DL_I2C_IIDX_TARGET_TXFIFO_EMPTY:/* Fill TX FIFO if there are more bytes to send */if (gTxCount < 8) {gTxFillNum = DL_I2C_fillTargetTXFIFO(I2C_INST, &gTxPacket[gTxCount], 1);gTxCount += gTxFillNum;} else {/** Fill FIFO with 0x00 if more data is requested than* expected gTxLen*/while (DL_I2C_transmitTargetDataCheck(I2C_INST, 0x99) != false);}break;case DL_I2C_IIDX_TARGET_RX_DONE:rvflag++;break;/* Not used for this example */case DL_I2C_IIDX_TARGET_RXFIFO_FULL:/* Not used for this example */case DL_I2C_IIDX_TARGET_GENERAL_CALL:/* Not used for this example */case DL_I2C_IIDX_TARGET_EVENT1_DMA_DONE:/* Not used for this example */case DL_I2C_IIDX_TARGET_EVENT2_DMA_DONE:/* Not used for this example */break;case DL_I2C_IIDX_TARGET_PEC_RX_ERROR:aa = 100;break;case DL_I2C_IIDX_TARGET_ARBITRATION_LOST:case DL_I2C_IIDX_TIMEOUT_A:case DL_I2C_IIDX_TIMEOUT_B:case DL_I2C_IIDX_TARGET_TXFIFO_UNDERFLOW:case DL_I2C_IIDX_TARGET_RXFIFO_OVERFLOW:case DL_I2C_IIDX_INTERRUPT_OVERFLOW:tmt_flag = 1;break;default:break;}
}

,

food chen:

急急急!! 

这是有什么处理办法?还是说是这个芯片的硬伤(无法解决?)。

,

food chen:

有没有TI工程师可以解答一下。我感觉这有点像是芯片bug。

,

food chen:

求解答!!!

,

food chen:

哪位能帮忙看下这个问题?

,

food chen:

求解!

,

food chen:

求解!!!

,

food chen:

有会的吗?

,

Vivian Gao:

您好 

您可以尝试disable SCLKSTRETCH

赞(0)
未经允许不得转载:TI中文支持网 » MSPM0G3507: MCU作为从机,I2C SCL短接到GND 1秒后松开,SCL无法恢复高电平
分享到: 更多 (0)