| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596 |
- /**
- * @file HW_I2C_ATY.c
- *
- * @param Project DEVICE_GENERAL_ATY_LIB
- *
- * @author ATY
- *
- * @copyright
- * - Copyright 2017 - 2023 MZ-ATY
- * - This code follows:
- * - MZ-ATY Various Contents Joint Statement -
- * <a href="https://mengze.top/MZ-ATY_VCJS">
- * https://mengze.top/MZ-ATY_VCJS</a>
- * - CC 4.0 BY-NC-SA -
- * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
- * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
- * - Your use will be deemed to have accepted the terms of this statement.
- *
- * @brief Familiar functions of I2C for all embedded device
- *
- * @version
- * - 1_01_220602 > ATY
- * -# Preliminary version, first Release
- * - 1_02_220804 > ATY
- * -# Change delay flow
- * -# Change SDA set function
- * -# Add Read/Write function
- * -Undone: hardware not test
- ********************************************************************************
- */
- #ifndef __HW_I2C_ATY_C
- #define __HW_I2C_ATY_C
- #include "HW_I2C_ATY.h"
- /******************************* For user *************************************/
- void OLED_Delay(uint8_t t)
- {
- while(t--);
- }
- /******************************************************************************/
- #ifndef __I2C_HARDWARE_ATY
- // 1: Out, 0: In, config default out
- uint8_t i2c_SdaDir = 1;
- /**
- * @brief Set SDA output
- */
- void I2C_SDA_SetOut(void)
- {
- if(i2c_SdaDir == 0)
- {
- i2c_SdaDir = 1;
- GPIO_SET_OUT(I2C_SDA_PORT, I2C_SDA_PIN);
- }
- }
- /**
- * @brief Set SDA input
- */
- void I2C_SDA_SetIn(void)
- {
- if(i2c_SdaDir == 1)
- {
- i2c_SdaDir = 0;
- GPIO_SET_IN(I2C_SDA_PORT, I2C_SDA_PIN);
- }
- }
- /**
- * @brief Star I2C bus
- * @note START:when CLK is high,DATA change form high to low
- */
- void I2C_Start(void)
- {
- I2C_SDA_SET_OUT;
- OLED_Delay(SHORT_DELAY);
- I2C_SDA_SET_H;
- I2C_SCL_SET_H;
- OLED_Delay(SHORT_DELAY);
- I2C_SDA_SET_L;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_L;
- }
- /**
- * @brief Stop I2C bus
- * @note STOP:when CLK is high DATA change form low to high
- */
- void I2C_Stop(void)
- {
- I2C_SDA_SET_OUT;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_L;
- I2C_SDA_SET_L;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_H;
- OLED_Delay(SHORT_DELAY);
- I2C_SDA_SET_H;
- }
- /**
- * @brief I2C ack
- */
- void I2C_Ack(void)
- {
- I2C_SDA_SET_OUT;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_L;
- I2C_SDA_SET_L;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_H;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_L;
- }
- /**
- * @brief I2C no ack
- */
- void I2C_NoAck(void)
- {
- I2C_SDA_SET_OUT;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_L;
- I2C_SDA_SET_H;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_H;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_L;
- }
- /**
- * @brief Wait ack coming
- * @param maxErrTime max time to wait until fail
- * @return 0 success, !0: fail
- */
- uint8_t I2C_WaitAck(uint16_t maxErrTime)
- {
- uint16_t errTime = 0;
- I2C_SDA_SET_IN;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_H;
- OLED_Delay(SHORT_DELAY);
- while(I2C_SDA_GET_H)
- {
- errTime++;
- OLED_Delay(2);
- if(errTime > maxErrTime)
- {
- I2C_Stop();
- return 1;
- }
- }
- I2C_SCL_SET_L;
- return 0;
- }
- /**
- * @brief I2C send one byte
- * @param byte data to send
- */
- void I2C_WriteByte(uint8_t byte)
- {
- uint8_t isb_i;
- I2C_SDA_SET_OUT;
- OLED_Delay(LONG_DELAY);
- I2C_SCL_SET_L;
- for(isb_i = 0; isb_i < 8; isb_i++)
- {
- OLED_Delay(SHORT_DELAY);
- if((byte & 0x80) >> 7)
- I2C_SDA_SET_H;
- else
- I2C_SDA_SET_L;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_H;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_L;
- byte <<= 1;
- }
- OLED_Delay(SHORT_DELAY);
- I2C_SDA_SET_H;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_H;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_L;
- }
- /**
- * @brief I2C read one byte
- * @param ack if send ACK or not
- * @return data to read
- */
- uint8_t I2C_ReadByte(uint8_t ack)
- {
- uint8_t irb_i, byte = 0;
- I2C_SDA_SET_IN;
- OLED_Delay(LONG_DELAY);
- for(irb_i = 0; irb_i < 8; irb_i++)
- {
- I2C_SCL_SET_L;
- OLED_Delay(SHORT_DELAY);
- I2C_SCL_SET_H;
- OLED_Delay(SHORT_DELAY);
- byte <<= 1;
- if(I2C_SDA_GET_H) byte++;
- }
- I2C_SCL_SET_L;
- if(ack)
- I2C_Ack();
- else
- I2C_NoAck();
- return byte;
- }
- /**
- * @brief Write serial data to reg
- * @param addr slave machine address
- * @param data_t data to write(uint8)
- * @param len length of write data(uint8)
- * @return 0: success, !0: error
- */
- uint8_t I2C_Write(uint8_t addr, uint8_t* data_t, uint8_t len)
- {
- uint8_t i = 0;
- I2C_Start();
- I2C_WriteByte(addr << 1 | 0);
- if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
- return 1;
- for(i = 0; i < len; i++)
- {
- I2C_WriteByte(data_t[i]);
- if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
- return 1;
- }
- I2C_Stop();
- return 0;
- }
- /**
- * @brief Write serial data to reg
- * @param addr slave machine address
- * @param data_t data to write(uint8)
- * @param len length of write data(uint8)
- * @return 0: success, !0: error
- */
- uint8_t I2C_Write_NoStop(uint8_t addr, uint8_t* data_t, uint8_t len)
- {
- uint8_t i = 0;
- I2C_Start();
- I2C_WriteByte(addr << 1 | 0);
- if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
- return 1;
- for(i = 0; i < len; i++)
- {
- I2C_WriteByte(data_t[i]);
- if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
- return 1;
- }
- return 0;
- }
- /**
- * @brief Read serial data to reg
- * @param addr slave machine address
- * @param data_t data to read(uint8)
- * @param len length of read data(uint8)
- * @return 0: success, !0: error
- */
- uint8_t I2C_Read(uint8_t addr, uint8_t* data_t, uint8_t len)
- {
- I2C_Start();
- I2C_WriteByte(addr << 1 | 1);
- if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
- return 1;
- while(len--)
- {
- if(len > 0)
- *data_t++ = I2C_ReadByte(1);
- else
- *data_t++ = I2C_ReadByte(0);
- }
- I2C_Stop();
- return 0;
- }
- /**
- * @brief Write serial data to reg
- * @param addr slave machine address
- * @param reg reg addr to write
- * @param data_t data to write(uint8)
- * @param len length of write data(uint8)
- * @return 0: success, !0: error
- */
- uint8_t I2C_WriteReg(uint8_t addr, uint8_t reg, uint8_t* data_t, uint8_t len)
- {
- uint8_t i = 0;
- I2C_Start();
- I2C_WriteByte(addr << 1 | 0);
- if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
- {
- I2C_Stop();
- return 1;
- }
- if(reg != 0)
- {
- I2C_WriteByte(reg);
- I2C_WaitAck(I2C_WAIT_ACK_TIME);
- }
- for(i = 0; i < len; i++)
- {
- I2C_WriteByte(data_t[i]);
- if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
- {
- I2C_Stop();
- return 1;
- }
- }
- I2C_Stop();
- return 0;
- }
- /**
- * @brief Read serial data to reg
- * @param addr slave machine address
- * @param reg reg addr to read
- * @param data_t data to read(uint8)
- * @param len length of read data(uint8)
- * @return 0: success, !0: error
- */
- uint8_t I2C_ReadReg(uint8_t addr, uint8_t reg, uint8_t* data_t, uint8_t len)
- {
- I2C_Start();
- I2C_WriteByte(addr << 1 | 0);
- if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
- {
- I2C_Stop();
- return 1;
- }
- I2C_WriteByte(reg);
- I2C_WaitAck(I2C_WAIT_ACK_TIME);
- I2C_Stop();
- I2C_Start();
- I2C_WriteByte(addr << 1 | 1);
- I2C_WaitAck(I2C_WAIT_ACK_TIME);
- while(len)
- {
- if(len == 1)
- *data_t = I2C_ReadByte(0);
- else
- *data_t = I2C_ReadByte(1);
- len--;
- data_t++;
- }
- I2C_Stop();
- return 0;
- }
- #else
- #if defined(__STM32_HAL_ATY)
- #include "i2c.h"
- /**
- * @brief Eliminate HAL_I2C bug
- * @warning Put "__HAL_RCC_I2C1_CLK_ENABLE();" before GPIO init
- */
- //void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
- //{
- // GPIO_InitTypeDef GPIO_InitStruct = {0};
- // if(hi2c->Instance==I2C1)
- // {
- // /* USER CODE BEGIN I2C1_MspInit 0 */
- // __HAL_RCC_I2C1_CLK_ENABLE();
- // /* USER CODE END I2C1_MspInit 0 */
- //
- // __HAL_RCC_GPIOB_CLK_ENABLE();
- // /**I2C1 GPIO Configuration
- // PB6 ------> I2C1_SCL
- // PB7 ------> I2C1_SDA
- // */
- // GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
- // GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
- // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
- // HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
- //
- // /* Peripheral clock enable */
- // //__HAL_RCC_I2C1_CLK_ENABLE();
- // /* USER CODE BEGIN I2C1_MspInit 1 */
- //
- // /* USER CODE END I2C1_MspInit 1 */
- // }
- //
- //}
- /**
- * @brief Write serial data to reg
- * @param addr slave machine address
- * @param data_t data to write(uint8)
- * @param len length of write data(uint8)
- * @return 0: success, !0: error
- */
- uint8_t I2C_Write(uint8_t addr, uint8_t* data_t, uint8_t len)
- {
- uint8_t i = 3;
- while(i--)
- {
- if(HAL_I2C_Master_Transmit(&I2CH_N, addr << 1 | 0, data_t, len, 1000) == HAL_OK)
- return 0;
- }
- return 1;
- }
- /**
- * @brief Read serial data to reg
- * @param addr slave machine address
- * @param data_t data to read(uint8)
- * @param len length of read data(uint8)
- * @return 0: success, !0: error
- */
- uint8_t I2C_Read(uint8_t addr, uint8_t* data_t, uint8_t len)
- {
- uint8_t i = 3;
- while(i--)
- {
- if(HAL_I2C_Master_Receive(&I2CH_N, addr << 1 | 1, data_t, len, 1000) == HAL_OK)
- return 0;
- }
- return 1;
- }
- #elif defined(__ESP8266_RTOS_ATY)
- #include "driver/i2c.h"
- #define I2C_EXAMPLE_MASTER_SCL_IO 2 /*!< gpio number for I2C master clock */
- #define I2C_EXAMPLE_MASTER_SDA_IO 14 /*!< gpio number for I2C master data */
- #define I2C_EXAMPLE_MASTER_NUM I2C_NUM_0 /*!< I2C port number for master dev */
- #define I2C_EXAMPLE_MASTER_TX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
- #define I2C_EXAMPLE_MASTER_RX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
- /**
- * @brief i2c master initialization
- */
- static esp_err_t i2c_example_master_init()
- {
- int i2c_master_port = I2CH_N;
- i2c_config_t conf;
- conf.mode = I2C_MODE_MASTER;
- conf.sda_io_num = I2C_EXAMPLE_MASTER_SDA_IO;
- conf.sda_pullup_en = 1;
- conf.scl_io_num = I2C_EXAMPLE_MASTER_SCL_IO;
- conf.scl_pullup_en = 1;
- conf.clk_stretch_tick = 300; // 300 ticks, Clock stretch is about 210us, you can make changes according to the actual situation.
- ESP_ERROR_CHECK(i2c_driver_install(i2c_master_port, conf.mode));
- ESP_ERROR_CHECK(i2c_param_config(i2c_master_port, &conf));
- return ESP_OK;
- }
- /**
- * @brief Write serial data to reg
- * @param addr slave machine address
- * @param data_t data to write(uint8)
- * @param len length of write data(uint8)
- * @return 0: success, !0: error
- */
- uint8_t I2C_Write(uint8_t addr, uint8_t* data_t, uint8_t len)
- {
- int ret;
- i2c_cmd_handle_t cmd = i2c_cmd_link_create();
- i2c_master_start(cmd);
- i2c_master_write_byte(cmd, addr << 1 | 0, ACK_CHECK_EN);
- i2c_master_write(cmd, data_t, len, ACK_CHECK_EN);
- i2c_master_stop(cmd);
- ret = i2c_master_cmd_begin(I2CH_N, cmd, 1000 / portTICK_RATE_MS);
- i2c_cmd_link_delete(cmd);
- return ret;
- }
- /**
- * @brief Read serial data to reg
- * @param addr slave machine address
- * @param data_t data to read(uint8)
- * @param len length of read data(uint8)
- * @return 0: success, !0: error
- */
- uint8_t I2C_Read(uint8_t addr, uint8_t* data_t, uint8_t len)
- {
- int ret;
- i2c_cmd_handle_t cmd = i2c_cmd_link_create();
- i2c_master_start(cmd);
- i2c_master_write_byte(cmd, addr << 1 | 0, ACK_CHECK_EN);
- i2c_master_stop(cmd);
- ret = i2c_master_cmd_begin(I2CH_N, cmd, 1000 / portTICK_RATE_MS);
- i2c_cmd_link_delete(cmd);
- if(ret != ESP_OK) {
- return ret;
- }
- cmd = i2c_cmd_link_create();
- i2c_master_start(cmd);
- i2c_master_write_byte(cmd, addr << 1 | 1, ACK_CHECK_EN);
- i2c_master_read(cmd, data_t, len, LAST_NACK_VAL);
- i2c_master_stop(cmd);
- ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);
- i2c_cmd_link_delete(cmd);
- return ret;
- }
- // void Wait()
- // {
- // while(!(I2CMSST & 0x40));
- // I2CMSST &= ~0x40;
- // }
- // void Start()
- // {
- // I2CMSCR = 0x01; //发送START命令
- // Wait();
- // }
- // void SendData(char dat)
- // {
- // I2CTXD = dat; //写数据到数据缓冲区
- // I2CMSCR = 0x02; //发送SEND命令
- // Wait();
- // }
- // void RecvACK()
- // {
- // I2CMSCR = 0x03; //发送读ACK命令
- // Wait();
- // }
- // char RecvData()
- // {
- // I2CMSCR = 0x04; //发送RECV命令
- // Wait();
- // return I2CRXD;
- // }
- // void SendACK()
- // {
- // I2CMSST = 0x00; //设置ACK信号
- // I2CMSCR = 0x05; //发送ACK命令
- // Wait();
- // }
- // void SendNAK()
- // {
- // I2CMSST = 0x01; //设置NAK信号
- // I2CMSCR = 0x05; //发送ACK命令
- // Wait();
- // }
- // void Stop()
- // {
- // I2CMSCR = 0x06; //发送STOP命令
- // Wait();
- // }
- // void Delay()
- // {
- // int i;
- // for(i = 0; i < 3000; i++)
- // {
- // _nop_();
- // _nop_();
- // _nop_();
- // _nop_();
- // }
- // }
- #endif /* PLATFORM */
- #endif /* __I2C_HARDWARE_ATY */
- #endif /* __HW_I2C_ATY_C */
- /******************************** End Of File *********************************/
|