Hi Andy,
unfortunately I still get a busy flag …
I’ve unplugged everything from my Evaluation Board (except USB, Serial).
I’ve used standard Toradex Linux as base
When Starting the module I stop the Auto Boot and entering following Commands:
fatload mmc 0:1 ${loadaddr} SPI.elf
bootaux ${loadaddr}
Here is my code:
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
#define APP_TASK_STACK_SIZE 256
static uint8_t txBuffer[5];
static uint8_t rxBuffer[7];
static uint8_t cmdBuffer[5];
/* I2C information for this board */
#define BOARD_I2C_RDC_PDAP rdcPdapI2c4
#define BOARD_I2C_CCM_ROOT ccmRootI2c4
#define BOARD_I2C_CCM_CCGR ccmCcgrGateI2c4
#define BOARD_I2C_BASEADDR I2C4
#define BOARD_I2C_IRQ_NUM I2C4_IRQn
#define BOARD_I2C_HANDLER I2C4_Handler
#define BOARD_I2C_FXAS21002_ADDR (0x20)
#define BOARD_I2C_FXOS8700_ADDR (0x1E)
#define BOARD_I2C_MAX30100_ADDR (0XAE)
#define BOARD_I2C_M41T0_ADDR (0x68)
bool I2C_MasterSendDataPolling(I2C_Type *base,
const uint8_t *cmdBuff,
uint32_t cmdSize,
const uint8_t *txBuff,
uint32_t txSize)
{
if (I2C_GetStatusFlag(base, i2cStatusBusBusy)){
PRINTF("I2C::SEND Received Busy Flag! \r\n");
return false;
}
/* Set I2C work under Tx mode */
I2C_SetDirMode(base, i2cDirectionTransmit);
/* Switch to Master Mode and Send Start Signal. */
I2C_SetWorkMode(base, i2cModeMaster);
/* Send first byte */
if (0 != cmdSize)
{
I2C_WriteByte(base, *cmdBuff++);
cmdSize--;
}
else
{
I2C_WriteByte(base, *txBuff++);
txSize--;
}
while (1)
{
/* Wait I2C transmission status flag assert. */
while (!I2C_GetStatusFlag(base, i2cStatusInterrupt));
/* Clear I2C transmission status flag. */
I2C_ClearStatusFlag(base, i2cStatusInterrupt);
/* Transmit complete. */
if ((I2C_GetStatusFlag(base, i2cStatusReceivedAck)) ||
((0 == txSize) && (0 == cmdSize)))
{
/* Switch to Slave mode and Generate a Stop Signal. */
I2C_SetWorkMode(base, i2cModeSlave);
/* Switch back to Rx direction. */
I2C_SetDirMode(base, i2cDirectionReceive);
return true;
}
else
{
if (0 != cmdSize)
{
I2C_WriteByte(base, *cmdBuff++);
cmdSize--;
}
else
{
I2C_WriteByte(base, *txBuff++);
txSize--;
}
}
}
}
bool I2C_MasterReceiveDataPolling(I2C_Type *base,
const uint8_t *cmdBuff,
uint32_t cmdSize,
uint8_t *rxBuff,
uint32_t rxSize)
{
uint32_t currentDir = i2cDirectionReceive;
/* Clear I2C interrupt flag to avoid spurious interrupt */
I2C_ClearStatusFlag(base, i2cStatusInterrupt);
if (I2C_GetStatusFlag(base, i2cStatusBusBusy))
{
PRINTF("I2C::RECEIVE Received Busy Flag! \r\n");
return false;
}
/* Set I2C work under Tx mode */
I2C_SetDirMode(base, i2cDirectionTransmit);
/* Switch to Master Mode and Send Start Signal. */
I2C_SetWorkMode(base, i2cModeMaster);
if (0 != cmdSize)
{
currentDir = i2cDirectionTransmit;
if (1 == cmdSize)
I2C_SendRepeatStart(base);
I2C_WriteByte(base, *cmdBuff++);
cmdSize--;
}
else
{
/* Change to receive state. */
I2C_SetDirMode(base, i2cDirectionReceive);
if (1 == rxSize)
/* Send Nack */
I2C_SetAckBit(base, false);
else
/* Send Ack */
I2C_SetAckBit(base, true);
/* dummy read to clock in 1st byte */
*rxBuff = I2C_ReadByte(base);
}
while (1)
{
/* Wait I2C transmission status flag assert. */
while (!I2C_GetStatusFlag(base, i2cStatusInterrupt));
/* Clear I2C transmission status flag. */
I2C_ClearStatusFlag(base, i2cStatusInterrupt);
if (i2cDirectionTransmit == currentDir)
{
if (0 < cmdSize)
{
if (I2C_GetStatusFlag(base, i2cStatusReceivedAck))
{
/* Switch to Slave mode and Generate a Stop Signal. */
I2C_SetWorkMode(base, i2cModeSlave);
/* Switch back to Rx direction. */
I2C_SetDirMode(base, i2cDirectionReceive);
return false;
}
else
{
if (1 == cmdSize)
I2C_SendRepeatStart(base);
I2C_WriteByte(base, *cmdBuff++);
cmdSize--;
}
}
else
{
/* Change to receive state. */
I2C_SetDirMode(base, i2cDirectionReceive);
currentDir = i2cDirectionReceive;
if (1 == rxSize)
/* Send Nack */
I2C_SetAckBit(base, false);
else
/* Send Ack */
I2C_SetAckBit(base, true);
/* dummy read to clock in 1st byte */
*rxBuff = I2C_ReadByte(base);
}
}
else
{
/* Normal read operation. */
if (2 == rxSize)
/* Send Nack */
I2C_SetAckBit(base, false);
else
/* Send Nack */
I2C_SetAckBit(base, true);
if (1 == rxSize)
/* Switch back to Tx direction to avoid additional I2C bus read. */
I2C_SetDirMode(base, i2cDirectionTransmit);
*rxBuff = I2C_ReadByte(base);
rxBuff++;
rxSize--;
/* receive finished. */
if (0 == rxSize)
{
/* Switch to Slave mode and Generate a Stop Signal. */
I2C_SetWorkMode(base, i2cModeSlave);
/* Switch back to Rx direction. */
I2C_SetDirMode(base, i2cDirectionReceive);
return true;
}
}
}
}
void hardware_init(void)
{
/* Board specific RDC settings */
BOARD_RdcInit();
/* Board specific clock settings */
BOARD_ClockInit();
/* initialize debug uart */
dbg_uart_init();
/* Configure GPIOS */
/* In this example, we need to grasp board I2C exclusively */
RDC_SetPdapAccess(RDC, BOARD_I2C_RDC_PDAP, 3 << (BOARD_DOMAIN_ID * 2), false, false);
/* Select I2C clock derived from OSC clock(24M) */
CCM_UpdateRoot(CCM, BOARD_I2C_CCM_ROOT, ccmRootmuxI2cOsc24m, 0, 0);
/* Enable I2C clock */
CCM_EnableRoot(CCM, BOARD_I2C_CCM_ROOT);
CCM_ControlGate(CCM, BOARD_I2C_CCM_CCGR, ccmClockNeededRunWait);
/* I2C Pin setting */
configure_i2c_pins(BOARD_I2C_BASEADDR);
}
int main(void)
{
/* Setup I2C init structure. */
i2c_init_config_t i2cInitConfig = {
.baudRate = 400000u,
.slaveAddress = 0x00
};
//uint8_t i;
hardware_init();
PRINTF("[1].Initialize the I2C module with initialize structure. \n\r");
I2C_Init(BOARD_I2C_BASEADDR, &i2cInitConfig);
PRINTF("[2].Enable the I2C module at BOARD_I2C_BASEADDR. \n\r");
I2C_Enable(BOARD_I2C_BASEADDR);
cmdBuffer[0] = BOARD_I2C_M41T0_ADDR << 1;
cmdBuffer[1] = 0x00;
txBuffer[0] = 0x01;
I2C_MasterSendDataPolling(BOARD_I2C_BASEADDR, cmdBuffer, 2, txBuffer, 1);
cmdBuffer[0] = BOARD_I2C_M41T0_ADDR << 1;
cmdBuffer[1] = 0x01;
txBuffer[0] = 0x80;
I2C_MasterSendDataPolling(BOARD_I2C_BASEADDR, cmdBuffer, 2, txBuffer, 1);
PRINTF("[ERR] Schedule Broke!. \n\r");
}
Kind regards
Patrick