├── readme.md ├── sw_i2c.c ├── sw_i2c.h ├── sw_i2c_port_stm32.c └── sw_i2c_port_unisoc_8850.c /readme.md: -------------------------------------------------------------------------------- 1 | # Soft I2C 2 | 3 | That is Edited version of [Original version](https://schkorea.tistory.com/437) for stm32 4 | 5 | 原作者:https://schkorea.tistory.com/437 6 | 7 | 精简了部分代码,增加8/16bit寄存器地址的突发(连续)读写函数 8 | 9 | 移植到展锐8850平台 -------------------------------------------------------------------------------- /sw_i2c.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "sw_i2c.h" 4 | 5 | #ifndef TRUE 6 | #define TRUE 1 7 | #endif 8 | #ifndef FALSE 9 | #define FALSE 0 10 | #endif 11 | 12 | // sw_i2c 初始化 13 | void SW_I2C_initial(sw_i2c_t *d) 14 | { 15 | if (d) 16 | { 17 | d->hal_init(); 18 | } 19 | } 20 | 21 | static void sda_out(sw_i2c_t *d, uint8_t out) 22 | { 23 | if(out) 24 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_HIGH, NULL); 25 | else 26 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_LOW, NULL); 27 | } 28 | 29 | static void i2c_clk_data_out(sw_i2c_t *d) 30 | { 31 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_HIGH, NULL); 32 | d->hal_delay_us(SW_I2C_WAIT_TIME); 33 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_LOW, NULL); 34 | } 35 | 36 | static void i2c_port_initial(sw_i2c_t *d) 37 | { 38 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_HIGH, NULL); 39 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_HIGH, NULL); 40 | } 41 | 42 | 43 | static uint8_t SW_I2C_ReadVal_SDA(sw_i2c_t *d) 44 | { 45 | 46 | return d->hal_io_ctl(HAL_IO_OPT_GET_SDA_LEVEL, NULL); 47 | } 48 | 49 | #if 0 50 | static uint8_t SW_I2C_ReadVal_SCL(sw_i2c_t *d) 51 | { 52 | 53 | return d->hal_io_ctl(HAL_IO_OPT_GET_SCL_LEVEL, NULL); 54 | } 55 | #endif 56 | 57 | static void i2c_start_condition(sw_i2c_t *d) 58 | { 59 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_HIGH, NULL); 60 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_HIGH, NULL); 61 | d->hal_delay_us(SW_I2C_WAIT_TIME); 62 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_LOW, NULL); 63 | d->hal_delay_us(SW_I2C_WAIT_TIME); 64 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_LOW, NULL); 65 | d->hal_delay_us(SW_I2C_WAIT_TIME << 1); 66 | } 67 | 68 | static void i2c_stop_condition(sw_i2c_t *d) 69 | { 70 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_LOW, NULL); 71 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_HIGH, NULL); 72 | d->hal_delay_us(SW_I2C_WAIT_TIME); 73 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_HIGH, NULL); 74 | d->hal_delay_us(SW_I2C_WAIT_TIME); 75 | } 76 | 77 | static uint8_t i2c_check_ack(sw_i2c_t *d) 78 | { 79 | uint8_t ack; 80 | int i; 81 | unsigned int temp; 82 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_INPUT, NULL); 83 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_HIGH, NULL); 84 | ack = 0; 85 | d->hal_delay_us(SW_I2C_WAIT_TIME); 86 | for (i = 10; i > 0; i--) 87 | { 88 | temp = !(SW_I2C_ReadVal_SDA(d)); 89 | if (temp) 90 | { 91 | ack = 1; 92 | break; 93 | } 94 | } 95 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_LOW, NULL); 96 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_OUTPUT, NULL); 97 | d->hal_delay_us(SW_I2C_WAIT_TIME); 98 | return ack; 99 | } 100 | 101 | static void i2c_check_not_ack(sw_i2c_t *d) 102 | { 103 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_INPUT, NULL); 104 | i2c_clk_data_out(d); 105 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_OUTPUT, NULL); 106 | d->hal_delay_us(SW_I2C_WAIT_TIME); 107 | } 108 | 109 | static void i2c_slave_address(sw_i2c_t *d, uint8_t IICID, uint8_t readwrite) 110 | { 111 | int x; 112 | 113 | if (readwrite) 114 | { 115 | IICID |= I2C_READ; 116 | } 117 | else 118 | { 119 | IICID &= ~I2C_READ; 120 | } 121 | 122 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_LOW, NULL); 123 | 124 | for (x = 7; x >= 0; x--) 125 | { 126 | sda_out(d, IICID & (1 << x)); 127 | d->hal_delay_us(SW_I2C_WAIT_TIME); 128 | i2c_clk_data_out(d); 129 | 130 | } 131 | } 132 | 133 | static void i2c_register_address(sw_i2c_t *d, uint8_t addr) 134 | { 135 | int x; 136 | 137 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_LOW, NULL); 138 | 139 | for (x = 7; x >= 0; x--) 140 | { 141 | sda_out(d, addr & (1 << x)); 142 | d->hal_delay_us(SW_I2C_WAIT_TIME); 143 | i2c_clk_data_out(d); 144 | } 145 | } 146 | 147 | static void i2c_send_ack(sw_i2c_t *d) 148 | { 149 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_OUTPUT, NULL); 150 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_LOW, NULL); 151 | d->hal_delay_us(SW_I2C_WAIT_TIME); 152 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_HIGH, NULL); 153 | d->hal_delay_us(SW_I2C_WAIT_TIME << 1); 154 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_LOW, NULL); 155 | d->hal_delay_us(SW_I2C_WAIT_TIME << 1); 156 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_LOW, NULL); 157 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_OUTPUT, NULL); 158 | d->hal_delay_us(SW_I2C_WAIT_TIME); 159 | } 160 | 161 | static void SW_I2C_Write_Data(sw_i2c_t *d, uint8_t data) 162 | { 163 | int x; 164 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_LOW, NULL); 165 | for (x = 7; x >= 0; x--) 166 | { 167 | sda_out(d, data & (1 << x)); 168 | d->hal_delay_us(SW_I2C_WAIT_TIME); 169 | i2c_clk_data_out(d); 170 | } 171 | } 172 | 173 | static uint8_t SW_I2C_Read_Data(sw_i2c_t *d) 174 | { 175 | int x; 176 | uint8_t readdata = 0; 177 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_INPUT, NULL); 178 | for (x = 8; x--;) 179 | { 180 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_HIGH, NULL); 181 | readdata <<= 1; 182 | if (SW_I2C_ReadVal_SDA(d)) 183 | readdata |= 0x01; 184 | d->hal_delay_us(SW_I2C_WAIT_TIME); 185 | d->hal_io_ctl(HAL_IO_OPT_SET_SCL_LOW, NULL); 186 | d->hal_delay_us(SW_I2C_WAIT_TIME); 187 | } 188 | d->hal_io_ctl(HAL_IO_OPT_SET_SDA_OUTPUT, NULL); 189 | return readdata; 190 | } 191 | 192 | uint8_t SW_I2C_Read_8addr(sw_i2c_t *d, uint8_t IICID, uint8_t regaddr, uint8_t *pdata, uint8_t rcnt) 193 | { 194 | uint8_t returnack = TRUE; 195 | uint8_t index; 196 | 197 | if(d==NULL) return FALSE; 198 | 199 | if(!rcnt) return FALSE; 200 | 201 | i2c_port_initial(d); 202 | i2c_start_condition(d); 203 | i2c_slave_address(d, IICID, WRITE_CMD); 204 | if (!i2c_check_ack(d)) { returnack = FALSE; } 205 | d->hal_delay_us(SW_I2C_WAIT_TIME); 206 | i2c_register_address(d, regaddr); 207 | if (!i2c_check_ack(d)) { returnack = FALSE; } 208 | d->hal_delay_us(SW_I2C_WAIT_TIME); 209 | i2c_start_condition(d); 210 | i2c_slave_address(d, IICID, READ_CMD); 211 | if (!i2c_check_ack(d)) { returnack = FALSE; } 212 | if(rcnt > 1) 213 | { 214 | for ( index = 0 ; index < (rcnt - 1) ; index++) 215 | { 216 | d->hal_delay_us(SW_I2C_WAIT_TIME); 217 | pdata[index] = SW_I2C_Read_Data(d); 218 | i2c_send_ack(d); 219 | } 220 | } 221 | d->hal_delay_us(SW_I2C_WAIT_TIME); 222 | pdata[rcnt-1] = SW_I2C_Read_Data(d); 223 | i2c_check_not_ack(d); 224 | i2c_stop_condition(d); 225 | 226 | return returnack; 227 | } 228 | 229 | uint8_t SW_I2C_Read_16addr(sw_i2c_t *d, uint8_t IICID, uint16_t regaddr, uint8_t *pdata, uint8_t rcnt) 230 | { 231 | uint8_t returnack = TRUE; 232 | uint8_t index; 233 | 234 | if(d==NULL) return FALSE; 235 | 236 | if(!rcnt) return FALSE; 237 | 238 | i2c_port_initial(d); 239 | i2c_start_condition(d); 240 | //写ID 241 | i2c_slave_address(d, IICID, WRITE_CMD); 242 | if (!i2c_check_ack(d)) { returnack = FALSE; } 243 | d->hal_delay_us(SW_I2C_WAIT_TIME); 244 | //写高八位地址 245 | i2c_register_address(d, (uint8_t)(regaddr>>8)); 246 | if (!i2c_check_ack(d)) { returnack = FALSE; } 247 | d->hal_delay_us(SW_I2C_WAIT_TIME); 248 | //写低八位地址 249 | i2c_register_address(d, (uint8_t)regaddr); 250 | if (!i2c_check_ack(d)) { returnack = FALSE; } 251 | d->hal_delay_us(SW_I2C_WAIT_TIME); 252 | //重启I2C总线 253 | i2c_start_condition(d); 254 | //读ID 255 | i2c_slave_address(d, IICID, READ_CMD); 256 | if (!i2c_check_ack(d)) { returnack = FALSE; } 257 | //循环读数据 258 | if(rcnt > 1) 259 | { 260 | for ( index = 0 ; index < (rcnt - 1) ; index++) 261 | { 262 | d->hal_delay_us(SW_I2C_WAIT_TIME); 263 | pdata[index] = SW_I2C_Read_Data(d); 264 | i2c_send_ack(d); 265 | } 266 | } 267 | d->hal_delay_us(SW_I2C_WAIT_TIME); 268 | pdata[rcnt-1] = SW_I2C_Read_Data(d); 269 | i2c_check_not_ack(d); 270 | i2c_stop_condition(d); 271 | 272 | return returnack; 273 | } 274 | 275 | uint8_t SW_I2C_Write_8addr(sw_i2c_t *d, uint8_t IICID, uint8_t regaddr, uint8_t *pdata, uint8_t rcnt) 276 | { 277 | uint8_t returnack = TRUE; 278 | uint8_t index; 279 | 280 | if(d==NULL) return FALSE; 281 | 282 | if(!rcnt) return FALSE; 283 | 284 | i2c_port_initial(d); 285 | i2c_start_condition(d); 286 | i2c_slave_address(d, IICID, WRITE_CMD); 287 | if (!i2c_check_ack(d)) { returnack = FALSE; } 288 | d->hal_delay_us(SW_I2C_WAIT_TIME); 289 | i2c_register_address(d, regaddr); 290 | if (!i2c_check_ack(d)) { returnack = FALSE; } 291 | d->hal_delay_us(SW_I2C_WAIT_TIME); 292 | for ( index = 0 ; index < rcnt ; index++) 293 | { 294 | SW_I2C_Write_Data(d, pdata[index]); 295 | if (!i2c_check_ack(d)) { returnack = FALSE; } 296 | d->hal_delay_us(SW_I2C_WAIT_TIME); 297 | } 298 | i2c_stop_condition(d); 299 | return returnack; 300 | } 301 | 302 | uint8_t SW_I2C_Write_16addr(sw_i2c_t *d, uint8_t IICID, uint16_t regaddr, uint8_t *pdata, uint8_t rcnt) 303 | { 304 | uint8_t returnack = TRUE; 305 | uint8_t index; 306 | 307 | if(d==NULL) return FALSE; 308 | 309 | if(!rcnt) return FALSE; 310 | 311 | i2c_port_initial(d); 312 | i2c_start_condition(d); 313 | //写ID 314 | i2c_slave_address(d, IICID, WRITE_CMD); 315 | if (!i2c_check_ack(d)) { returnack = FALSE; } 316 | d->hal_delay_us(SW_I2C_WAIT_TIME); 317 | //写高八位地址 318 | i2c_register_address(d, (uint8_t)(regaddr>>8)); 319 | if (!i2c_check_ack(d)) { returnack = FALSE; } 320 | d->hal_delay_us(SW_I2C_WAIT_TIME); 321 | //写低八位地址 322 | i2c_register_address(d, (uint8_t)regaddr); 323 | if (!i2c_check_ack(d)) { returnack = FALSE; } 324 | d->hal_delay_us(SW_I2C_WAIT_TIME); 325 | //写数据 326 | for ( index = 0 ; index < rcnt ; index++) 327 | { 328 | SW_I2C_Write_Data(d, pdata[index]); 329 | if (!i2c_check_ack(d)) { returnack = FALSE; } 330 | d->hal_delay_us(SW_I2C_WAIT_TIME); 331 | } 332 | i2c_stop_condition(d); 333 | return returnack; 334 | } 335 | 336 | uint8_t SW_I2C_Check_SlaveAddr(sw_i2c_t *d, uint8_t IICID) 337 | { 338 | uint8_t returnack = TRUE; 339 | i2c_start_condition(d); 340 | i2c_slave_address(d, IICID, WRITE_CMD); 341 | if (!i2c_check_ack(d)) 342 | { 343 | i2c_stop_condition(d); 344 | returnack = FALSE; 345 | } 346 | i2c_stop_condition(d); 347 | return returnack; 348 | } 349 | -------------------------------------------------------------------------------- /sw_i2c.h: -------------------------------------------------------------------------------- 1 | #ifndef _SW_I2C_H_ 2 | #define _SW_I2C_H_ 3 | 4 | #include 5 | 6 | #define SW_I2C_WAIT_TIME 10 // 10us 100kHz 7 | 8 | 9 | 10 | #define I2C_READ 0x01 11 | #define READ_CMD 1 12 | #define WRITE_CMD 0 13 | 14 | typedef enum 15 | { 16 | HAL_IO_OPT_SET_SDA_LOW = 0, 17 | HAL_IO_OPT_SET_SDA_HIGH, 18 | HAL_IO_OPT_SET_SCL_LOW, 19 | HAL_IO_OPT_SET_SCL_HIGH, 20 | HAL_IO_OPT_SET_SDA_INPUT, 21 | HAL_IO_OPT_SET_SDA_OUTPUT, 22 | HAL_IO_OPT_SET_SCL_INPUT, 23 | HAL_IO_OPT_SET_SCL_OUTPUT, 24 | HAL_IO_OPT_GET_SDA_LEVEL, 25 | HAL_IO_OPT_GET_SCL_LEVEL, 26 | }hal_io_opt_e; 27 | 28 | typedef struct sw_i2c_s { 29 | int (*hal_init)(void); 30 | int (*hal_io_ctl)(hal_io_opt_e opt, void *arg); 31 | void (*hal_delay_us)(uint32_t us); 32 | } sw_i2c_t; 33 | 34 | 35 | /* functions */ 36 | void SW_I2C_initial(sw_i2c_t *d); 37 | uint8_t SW_I2C_Read_8addr(sw_i2c_t *d, uint8_t IICID, uint8_t regaddr, uint8_t *pdata, uint8_t rcnt); 38 | uint8_t SW_I2C_Read_16addr(sw_i2c_t *d, uint8_t IICID, uint16_t regaddr, uint8_t *pdata, uint8_t rcnt); 39 | uint8_t SW_I2C_Write_8addr(sw_i2c_t *d, uint8_t IICID, uint8_t regaddr, uint8_t *pdata, uint8_t rcnt); 40 | uint8_t SW_I2C_Write_16addr(sw_i2c_t *d, uint8_t IICID, uint16_t regaddr, uint8_t *pdata, uint8_t rcnt); 41 | uint8_t SW_I2C_Check_SlaveAddr(sw_i2c_t *d, uint8_t IICID); 42 | 43 | 44 | #endif /* __I2C_SW_H */ 45 | -------------------------------------------------------------------------------- /sw_i2c_port_stm32.c: -------------------------------------------------------------------------------- 1 | 2 | #include "sw_i2c.h" 3 | 4 | // #include "stm32f1xx_hal.h" 5 | #include "stm32f4xx_hal.h" 6 | 7 | #define SW_I2C1_SCL_PORT GPIOB 8 | #define SW_I2C1_SDA_PORT GPIOB 9 | #define SW_I2C1_SCL_PIN GPIO_PIN_6 10 | #define SW_I2C1_SDA_PIN GPIO_PIN_7 11 | 12 | 13 | //引脚置位 14 | static void GPIO_SetBits(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) 15 | { 16 | HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_SET); 17 | } 18 | 19 | //引脚复位 20 | static void GPIO_ResetBits(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) 21 | { 22 | HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_RESET); 23 | } 24 | 25 | //读引脚状态 26 | static uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) 27 | { 28 | return (uint8_t)HAL_GPIO_ReadPin(GPIOx, GPIO_Pin); 29 | } 30 | 31 | //SDA引脚切换输入模式 32 | static void sda_in_mode(void) 33 | { 34 | GPIO_InitTypeDef GPIO_InitStruct = {0}; 35 | GPIO_InitStruct.Mode = GPIO_MODE_INPUT; 36 | GPIO_InitStruct.Pull = GPIO_NOPULL; 37 | 38 | GPIO_InitStruct.Pin = SW_I2C1_SDA_PIN; 39 | HAL_GPIO_Init(SW_I2C1_SDA_PORT, &GPIO_InitStruct); 40 | } 41 | 42 | //SDA引脚切换输出模式 43 | static void sda_out_mode(void) 44 | { 45 | GPIO_InitTypeDef GPIO_InitStruct = {0}; 46 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 47 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; 48 | GPIO_InitStruct.Pull = GPIO_NOPULL; 49 | 50 | GPIO_InitStruct.Pin = SW_I2C1_SDA_PIN; 51 | HAL_GPIO_Init(SW_I2C1_SDA_PORT, &GPIO_InitStruct); 52 | } 53 | 54 | //SCL引脚切换输入模式 55 | static void scl_in_mode(void) 56 | { 57 | GPIO_InitTypeDef GPIO_InitStruct = {0}; 58 | GPIO_InitStruct.Mode = GPIO_MODE_INPUT; 59 | GPIO_InitStruct.Pull = GPIO_NOPULL; 60 | 61 | GPIO_InitStruct.Pin = SW_I2C1_SCL_PIN; 62 | HAL_GPIO_Init(SW_I2C1_SCL_PORT, &GPIO_InitStruct); 63 | } 64 | 65 | //SCL引脚切换输出模式 66 | static void scl_out_mode(void) 67 | { 68 | GPIO_InitTypeDef GPIO_InitStruct = {0}; 69 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 70 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; 71 | GPIO_InitStruct.Pull = GPIO_NOPULL; 72 | 73 | GPIO_InitStruct.Pin = SW_I2C1_SCL_PIN; 74 | HAL_GPIO_Init(SW_I2C1_SCL_PORT, &GPIO_InitStruct); 75 | } 76 | 77 | static int sw_i2c_port_initial(void) 78 | { 79 | __HAL_RCC_GPIOB_CLK_ENABLE(); 80 | GPIO_InitTypeDef GPIO_InitStruct = {0}; 81 | GPIO_InitStruct.Pull = GPIO_NOPULL; 82 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; 83 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 84 | // i2c_sw SCL 85 | GPIO_InitStruct.Pin = SW_I2C1_SCL_PIN; 86 | HAL_GPIO_Init(SW_I2C1_SCL_PORT, &GPIO_InitStruct); 87 | // i2c_sw SDA 88 | GPIO_InitStruct.Pin = SW_I2C1_SDA_PIN; 89 | HAL_GPIO_Init(SW_I2C1_SDA_PORT, &GPIO_InitStruct); 90 | return 0; 91 | } 92 | 93 | static void sw_i2c_port_delay_us(uint32_t us) 94 | { 95 | uint32_t nCount = us/10*25; 96 | for (; nCount != 0; nCount--); 97 | } 98 | 99 | static int sw_i2c_port_io_ctl(uint8_t opt, void *param) 100 | { 101 | int ret = -1; 102 | switch (opt) 103 | { 104 | case HAL_IO_OPT_SET_SDA_HIGH: 105 | GPIO_SetBits(SW_I2C1_SDA_PORT, SW_I2C1_SDA_PIN); 106 | break; 107 | case HAL_IO_OPT_SET_SDA_LOW: 108 | GPIO_ResetBits(SW_I2C1_SDA_PORT, SW_I2C1_SDA_PIN); 109 | break; 110 | case HAL_IO_OPT_GET_SDA_LEVEL: 111 | ret = GPIO_ReadInputDataBit(SW_I2C1_SDA_PORT, SW_I2C1_SDA_PIN); 112 | break; 113 | case HAL_IO_OPT_SET_SDA_INPUT: 114 | sda_in_mode(); 115 | break; 116 | case HAL_IO_OPT_SET_SDA_OUTPUT: 117 | sda_out_mode(); 118 | break; 119 | case HAL_IO_OPT_SET_SCL_HIGH: 120 | GPIO_SetBits(SW_I2C1_SCL_PORT, SW_I2C1_SCL_PIN); 121 | break; 122 | case HAL_IO_OPT_SET_SCL_LOW: 123 | GPIO_ResetBits(SW_I2C1_SCL_PORT, SW_I2C1_SCL_PIN); 124 | break; 125 | case HAL_IO_OPT_GET_SCL_LEVEL: 126 | ret = GPIO_ReadInputDataBit(SW_I2C1_SCL_PORT, SW_I2C1_SCL_PIN); 127 | break; 128 | case HAL_IO_OPT_SET_SCL_INPUT: 129 | scl_in_mode(); 130 | break; 131 | case HAL_IO_OPT_SET_SCL_OUTPUT: 132 | scl_out_mode(); 133 | break; 134 | default: 135 | break; 136 | } 137 | return ret; 138 | } 139 | 140 | 141 | sw_i2c_t sw_i2c_stm32_f4 = { 142 | .hal_init = sw_i2c_port_initial, 143 | .hal_io_ctl = sw_i2c_port_io_ctl, 144 | .hal_delay_us = sw_i2c_port_delay_us, 145 | }; 146 | -------------------------------------------------------------------------------- /sw_i2c_port_unisoc_8850.c: -------------------------------------------------------------------------------- 1 | 2 | #include "sw_i2c.h" 3 | 4 | #include "ql_api_osi.h" 5 | #include "ql_gpio.h" 6 | 7 | #define AIP_SPI_DIO GPIO_35 8 | #define AIP_SPI_CLK GPIO_37 9 | 10 | #define SW_I2C1_SCL_PIN AIP_SPI_CLK 11 | #define SW_I2C1_SDA_PIN AIP_SPI_DIO 12 | 13 | 14 | static int sw_i2c_port_initial(void) 15 | { 16 | ql_gpio_init(AIP_SPI_DIO, GPIO_OUTPUT, PULL_NONE, LVL_HIGH); // DIO 17 | ql_gpio_init(AIP_SPI_CLK, GPIO_OUTPUT, PULL_NONE, LVL_HIGH); // CLK 18 | ql_delay_us(SW_I2C_WAIT_TIME); 19 | return 0; 20 | } 21 | 22 | static void sw_i2c_port_delay_us(uint32_t us) 23 | { 24 | ql_delay_us(us); 25 | } 26 | 27 | static int sw_i2c_port_io_ctl(uint8_t opt, void *param) 28 | { 29 | int ret = -1; 30 | ql_LvlMode l = 0; 31 | switch (opt) 32 | { 33 | case HAL_IO_OPT_SET_SDA_HIGH: 34 | ql_gpio_set_level(SW_I2C1_SDA_PIN, LVL_HIGH); 35 | break; 36 | case HAL_IO_OPT_SET_SDA_LOW: 37 | ql_gpio_set_level(SW_I2C1_SDA_PIN, LVL_LOW); 38 | break; 39 | case HAL_IO_OPT_GET_SDA_LEVEL: 40 | ql_gpio_get_level(SW_I2C1_SDA_PIN, &l); 41 | ret = l; 42 | break; 43 | case HAL_IO_OPT_SET_SDA_INPUT: 44 | ql_gpio_set_direction(SW_I2C1_SDA_PIN, GPIO_INPUT); 45 | ql_gpio_set_pull(SW_I2C1_SDA_PIN, PULL_NONE); 46 | break; 47 | case HAL_IO_OPT_SET_SDA_OUTPUT: 48 | ql_gpio_set_direction(SW_I2C1_SDA_PIN, GPIO_OUTPUT); 49 | break; 50 | case HAL_IO_OPT_SET_SCL_HIGH: 51 | ql_gpio_set_level(SW_I2C1_SCL_PIN, LVL_HIGH); 52 | break; 53 | case HAL_IO_OPT_SET_SCL_LOW: 54 | ql_gpio_set_level(SW_I2C1_SCL_PIN, LVL_LOW); 55 | break; 56 | case HAL_IO_OPT_GET_SCL_LEVEL: 57 | ql_gpio_get_level(SW_I2C1_SCL_PIN, &l); 58 | ret = l; 59 | break; 60 | case HAL_IO_OPT_SET_SCL_INPUT: 61 | ql_gpio_set_direction(SW_I2C1_SCL_PIN, GPIO_INPUT); 62 | ql_gpio_set_pull(SW_I2C1_SCL_PIN, PULL_NONE); 63 | break; 64 | case HAL_IO_OPT_SET_SCL_OUTPUT: 65 | ql_gpio_set_direction(SW_I2C1_SCL_PIN, GPIO_OUTPUT); 66 | break; 67 | default: 68 | break; 69 | } 70 | return ret; 71 | } 72 | 73 | 74 | sw_i2c_t sw_i2c_8850 = { 75 | .hal_init = sw_i2c_port_initial, 76 | .hal_io_ctl = sw_i2c_port_io_ctl, 77 | .hal_delay_us = sw_i2c_port_delay_us, 78 | }; 79 | --------------------------------------------------------------------------------