summaryrefslogtreecommitdiff
path: root/examples/imx7d_val_m4/driver_examples/i2c_imx/i2c_polling_eeprom/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/imx7d_val_m4/driver_examples/i2c_imx/i2c_polling_eeprom/main.c')
-rw-r--r--examples/imx7d_val_m4/driver_examples/i2c_imx/i2c_polling_eeprom/main.c310
1 files changed, 310 insertions, 0 deletions
diff --git a/examples/imx7d_val_m4/driver_examples/i2c_imx/i2c_polling_eeprom/main.c b/examples/imx7d_val_m4/driver_examples/i2c_imx/i2c_polling_eeprom/main.c
new file mode 100644
index 0000000..459e702
--- /dev/null
+++ b/examples/imx7d_val_m4/driver_examples/i2c_imx/i2c_polling_eeprom/main.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o 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.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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 <stdint.h>
+#include <stdbool.h>
+#include "board.h"
+#include "debug_console_imx.h"
+#include "i2c_imx.h"
+
+#define EEPROM_ADDRESS (0x50)
+
+static bool compare(uint8_t* bufA, uint8_t* bufB, uint32_t length);
+
+static bool I2C_MasterSendDataPolling(I2C_Type *base,
+ const uint8_t *cmdBuff,
+ uint32_t cmdSize,
+ const uint8_t *txBuff,
+ uint32_t txSize);
+static bool I2C_MasterReceiveDataPolling(I2C_Type *base,
+ const uint8_t *cmdBuff,
+ uint32_t cmdSize,
+ uint8_t *rxBuff,
+ uint32_t rxSize);
+
+int main(void)
+{
+ /* Setup I2C init structure. */
+ i2c_init_config_t i2cInitConfig = {
+ .baudRate = 400000u,
+ .slaveAddress = 0x00
+ };
+ uint8_t txBuffer[5];
+ uint8_t rxBuffer[5];
+ uint8_t cmdBuffer[5];
+
+ /* Initialize board specified hardware. */
+ hardware_init();
+
+ /* Get current module clock frequency. */
+ i2cInitConfig.clockRate = get_i2c_clock_freq(BOARD_I2C_BASEADDR);
+
+ PRINTF("\n\r++++++++++++++++ I2C Send/Receive polling Example ++++++++++++++++\n\r");
+ PRINTF("This example will write data to on board EEPROM through I2C Bus\n\r");
+ PRINTF("and read them back to see if the EEPROM is programmed successfully. \n\r\n\r");
+
+ PRINTF("[1].Initialize the I2C module with initialize structure. \n\r");
+ I2C_Init(BOARD_I2C_BASEADDR, &i2cInitConfig);
+
+ /* Finally, enable the I2C module */
+ I2C_Enable(BOARD_I2C_BASEADDR);
+
+ PRINTF("[2].Launch a I2C write action to 0x0000 address. \n\r");
+ cmdBuffer[0] = EEPROM_ADDRESS << 1;
+ cmdBuffer[1] = 0x00;
+ cmdBuffer[2] = 0x00;
+
+ PRINTF("[3].Prepare Data for Sending. \n\r");
+ txBuffer[0] = 0x11;
+ txBuffer[1] = 0x22;
+ txBuffer[2] = 0x33;
+ txBuffer[3] = 0x44;
+ txBuffer[4] = 0x55;
+
+ PRINTF("[4].Write data to EEPROM and wait until transmission finished. \n\r");
+ I2C_MasterSendDataPolling(BOARD_I2C_BASEADDR, cmdBuffer, 3, txBuffer, 5);
+
+ PRINTF("[5].Launch a I2C read action from 0x0000 address. \n\r");
+ cmdBuffer[0] = EEPROM_ADDRESS << 1;
+ cmdBuffer[1] = 0x00;
+ cmdBuffer[2] = 0x00;
+ cmdBuffer[3] = (EEPROM_ADDRESS << 1) + 1;
+
+ PRINTF("[6].Read data from EEPROM and wait until transmission finished. \n\r");
+ I2C_MasterReceiveDataPolling(BOARD_I2C_BASEADDR, cmdBuffer, 4, rxBuffer, 5);
+
+ PRINTF("[7].Compare data between txBuf and rxBuf: \n\r");
+ if (compare(txBuffer, rxBuffer, 5))
+ PRINTF(" txBuf and rxBuf are same, example passed!!!\n\r");
+ else
+ PRINTF(" txBuf and rxBuf are different, example failed!!! \n\r");
+
+ while (true)
+ __WFI();
+}
+
+static bool compare(uint8_t* bufA, uint8_t* bufB, uint32_t length)
+{
+ for (uint32_t i = 0; i < length; i++)
+ {
+ if (bufA[i] != bufB[i])
+ return false;
+ }
+
+ return true;
+}
+
+static 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))
+ 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--;
+ }
+ }
+ }
+}
+
+static 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))
+ {
+ 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;
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+ * EOF
+ ******************************************************************************/