Other Parts Discussed in Thread: MSPM0G3507-Q1
器件型号: MSPM0G3507-Q1
我遇到了一个问题、尝试将 MSPM0G3507-Q1 与 TI-Drivers 和 FreeRTOS 配合使用。 具体来说、我尝试将 16K 缓冲区传递到 I2C_transfe 函数、以执行连续写入...数据...停止事务。
问题在于、在事务过程中、MSPM0+似乎提供了突发长度 (255)……的重复起始 我的外围设备不喜欢的项目:

通过查看实现代码(特别是 I2CMSPM0.c)、我认为问题出在中 I2CMSPM0_primeWriteBurst 功能:
static void I2CMSPM0_primeWriteBurst(
I2CMSPM0_Object *object, I2CMSPM0_HWAttrs const *hwAttrs)
{
/* Wait until bus is available */
I2C_waitTillBusAvailable(hwAttrs);
/* Disable the burst before setting up the new transaction */
DL_I2C_disableControllerBurst(hwAttrs->i2c);
/* Determine the size of this burst */
if (object->writeCount > I2CMSPM0_MAX_BURST) {
object->burstCount = I2CMSPM0_MAX_BURST;
} else {
object->burstCount = object->writeCount;
}
/* Write burst length */
DL_I2C_setTransactionLength(hwAttrs->i2c, object->burstCount);
/* If we will be sending multiple bursts */
if (object->readCount || object->writeCount > I2CMSPM0_MAX_BURST) {
DL_I2C_disableStopCondition(hwAttrs->i2c);
} else {
DL_I2C_enableStopCondition(hwAttrs->i2c);
}
/* Only generate a start condition if the burst hasn't started */
if (!object->burstStarted) {
object->burstStarted = true;
}
/*Before filling the FIFO, we need to clear the interrupt else it will trigger interrupt immediately*/
DL_I2C_clearInterruptStatus(
hwAttrs->i2c, DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER);
/* Fill transmit FIFO. This will modify the object counts */
I2CMSPM0_fillTransmitFifo(object, hwAttrs);
/* Enable TXFIFOEMPTY interrupt and other standard transfer interrupts */
DL_I2C_enableInterrupt(hwAttrs->i2c,
DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER |
DL_I2C_INTERRUPT_CONTROLLER_TX_DONE |
DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_EMPTY | I2CMSPM0_TRANSFER_INTS);
/* Set the target Address */
DL_I2C_setTargetAddress(
hwAttrs->i2c, object->currentTransaction->targetAddress);
/* Set the controller direction */
DL_I2C_setControllerDirection(
hwAttrs->i2c, DL_I2C_CONTROLLER_DIRECTION_TX);
/* Enable the start condition */
DL_I2C_enableStartCondition(hwAttrs->i2c);
/* Disable the manual ACK, hardware will ack automatically */
DL_I2C_disableControllerACK(hwAttrs->i2c);
/* Enable the burst run */
DL_I2C_enableControllerBurst(hwAttrs->i2c);
}
具体而言、 BurstStarted 被设置、但它实际上不会在任何地方被检查/使用。 不管怎样、始终会调用 DL_I2C_enableStartCondition 函数。 如果我将其更改为:
/*
* ======== I2CMSPM0_primeWriteBurst =======
*/
static void I2CMSPM0_primeWriteBurst(
I2CMSPM0_Object *object, I2CMSPM0_HWAttrs const *hwAttrs)
{
/* Wait until bus is available */
I2C_waitTillBusAvailable(hwAttrs);
/* Disable the burst before setting up the new transaction */
DL_I2C_disableControllerBurst(hwAttrs->i2c);
/* Determine the size of this burst */
if (object->writeCount > I2CMSPM0_MAX_BURST) {
object->burstCount = I2CMSPM0_MAX_BURST;
} else {
object->burstCount = object->writeCount;
}
/* Write burst length */
DL_I2C_setTransactionLength(hwAttrs->i2c, object->burstCount);
/* If we will be sending multiple bursts */
if (object->readCount || object->writeCount > I2CMSPM0_MAX_BURST) {
DL_I2C_disableStopCondition(hwAttrs->i2c);
} else {
DL_I2C_enableStopCondition(hwAttrs->i2c);
}
/* Only generate a start condition if the burst hasn't started */
if(object->burstStarted == true)
{
DL_I2C_disableStartCondition(hwAttrs->i2c);
}
else
{
DL_I2C_enableStartCondition(hwAttrs->i2c);
}
if (!object->burstStarted) {
object->burstStarted = true;
}
/*Before filling the FIFO, we need to clear the interrupt else it will trigger interrupt immediately*/
DL_I2C_clearInterruptStatus(
hwAttrs->i2c, DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER);
/* Fill transmit FIFO. This will modify the object counts */
I2CMSPM0_fillTransmitFifo(object, hwAttrs);
/* Enable TXFIFOEMPTY interrupt and other standard transfer interrupts */
DL_I2C_enableInterrupt(hwAttrs->i2c,
DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER |
DL_I2C_INTERRUPT_CONTROLLER_TX_DONE |
DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_EMPTY | I2CMSPM0_TRANSFER_INTS);
/* Set the target Address */
DL_I2C_setTargetAddress(
hwAttrs->i2c, object->currentTransaction->targetAddress);
/* Set the controller direction */
DL_I2C_setControllerDirection(
hwAttrs->i2c, DL_I2C_CONTROLLER_DIRECTION_TX);
/* Enable the start condition */
/* Disable the manual ACK, hardware will ack automatically */
DL_I2C_disableControllerACK(hwAttrs->i2c);
/* Enable the burst run */
DL_I2C_enableControllerBurst(hwAttrs->i2c);
}
... 具体添加以下内容:
/* Only generate a start condition if the burst hasn't started */
if(object->burstStarted == true)
{
DL_I2C_disableStartCondition(hwAttrs->i2c);
}
else
{
DL_I2C_enableStartCondition(hwAttrs->i2c);
}
if (!object->burstStarted) {
object->burstStarted = true;
}
... 一切似乎工作,我可以写整个 16K 没有问题. 我只需将 I2CMSPM0.c 文件复制到我的工作区、所有符号都会覆盖 SDK 库中的符号。
我只是想确保我一开始没有遗漏任何东西或误用驱动程序。 对于固件更新、我通常必须在不重复启动/停止的情况下写入>256 字节的事务。
此致、
Tim