/* * Copyright (c) 2019-2023 Beijing Hanwei Innovation Technology Ltd. Co. and * its subsidiaries and affiliates (collectly called MKSEMI). * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form, except as embedded into an MKSEMI * integrated circuit in a product or a software update for such product, * 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. * * 3. Neither the name of MKSEMI nor the names of its contributors may be used * to endorse or promote products derived from this software without * specific prior written permission. * * 4. This software, with or without modification, must only be used with a * MKSEMI integrated circuit. * * 5. Any software provided in binary form under this license must not be * reverse engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY MKSEMI "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL MKSEMI 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 "mk_i2c.h" #include "mk_trace.h" #include "mk_reset.h" #include "mk_calib.h" #include "mk_wdt.h" #include "mk_misc.h" #include "libc_rom.h" #include "board.h" #define TARGET_ADDR 0x15 #define TEST_PORT I2C_ID0 #define SLAVE_TEST 0 volatile static uint8_t rx_done = 0; volatile static uint8_t tx_done = 0; static void i2c_read_callback(void *dev, uint32_t err_code) { rx_done = 1; if (err_code) { LOG_INFO(TRACE_MODULE_APP, "I2C read error code %x\r\n", err_code); } else { LOG_INFO(TRACE_MODULE_APP, "I2C read done\r\n"); } } static void i2c_write_callback(void *dev, uint32_t err_code) { tx_done = 1; if (err_code) { LOG_INFO(TRACE_MODULE_APP, "I2C write error code %x\r\n", err_code); } else { LOG_INFO(TRACE_MODULE_APP, "I2C write done\r\n"); } } #if SLAVE_TEST == 0 static uint32_t i2c_read(uint8_t slave_addr, uint16_t reg_addr) { uint8_t tx_buf[2]; uint8_t rx_buf[4]; tx_buf[0] = reg_addr & 0xff; tx_buf[1] = (reg_addr >> 8) & 0xff; #if 1 tx_done = 0; i2c_master_send(TEST_PORT, slave_addr, tx_buf, 2, i2c_write_callback); while (tx_done == 0) { } delay_us(1000); rx_done = 0; i2c_master_receive(TEST_PORT, slave_addr, rx_buf, 4, i2c_read_callback); while (rx_done == 0) { } #else rx_done = 0; i2c_master_transfer(TEST_PORT, slave_addr, tx_buf, 2, rx_buf, 4, i2c_read_callback); while (rx_done == 0) { } #endif return (uint32_t)((rx_buf[3] << 24) | (rx_buf[2] << 16) | (rx_buf[1] << 8) | rx_buf[0]); } static void i2c_write(uint8_t slave_addr, uint16_t reg_addr, uint32_t data) { uint8_t tx_buf[6]; tx_buf[0] = reg_addr & 0xff; tx_buf[1] = (reg_addr >> 8) & 0xff; tx_buf[2] = data & 0xff; tx_buf[3] = (data >> 8) & 0xff; tx_buf[4] = (data >> 16) & 0xff; tx_buf[5] = (data >> 24) & 0xff; tx_done = 0; i2c_master_send(TEST_PORT, slave_addr, tx_buf, 6, i2c_write_callback); while (tx_done == 0) { } } #endif int main(void) { board_clock_run(); board_pins_config(); board_debug_console_open(TRACE_PORT_UART0); // Reset reason reset_cause_get(); reset_cause_clear(); // Chip calibration calib_chip(); // Disable watchdog timer wdt_close(WDT_ID0); LOG_INFO(TRACE_MODULE_APP, "I2C example\r\n"); gpio_open(); board_configure(); struct I2C_CFG_T usr_i2c_cfg = { #if SLAVE_TEST .mode = I2C_SLAVE, .local_addr = TARGET_ADDR, .target_addr = MK_DEV_ADDRESS, #else .mode = I2C_MASTER, .local_addr = MK_DEV_ADDRESS, .target_addr = TARGET_ADDR, #endif .speed_mode = I2C_SPEED_STANDARD, .addr_mode = I2C_7BIT_ADDR, .rx_level = I2C_RXFIFO_CHAR_1, .tx_level = I2C_TXFIFO_CHAR_1, .int_rx = true, .int_tx = true, }; i2c_open(TEST_PORT, &usr_i2c_cfg); while (1) { #if SLAVE_TEST uint8_t rx_buf[6]; rx_done = 0; i2c_slave_receive(TEST_PORT, rx_buf, 6, i2c_read_callback); while (rx_done == 0) { } // receive 2bytes register address data rx_done = 0; i2c_slave_receive(TEST_PORT, rx_buf, 2, i2c_read_callback); while (rx_done == 0) { } tx_done = 0; i2c_slave_send(TEST_PORT, &rx_buf[2], 4, i2c_write_callback); while (tx_done == 0) { } #else i2c_write(TARGET_ADDR, 0x0, 0x11223344); delay_us(1000); uint32_t data = i2c_read(TARGET_ADDR, 0x0); if (data == 0x11223344) { LOG_INFO(TRACE_MODULE_APP, "I2C write and read success\r\n"); } else { LOG_INFO(TRACE_MODULE_APP, "I2C write and read mismatch %x\r\n", data); } delay_us(1000000); #endif } }