Core/Inc/i2c.h | ●●●●● patch | view | raw | blame | history | |
Core/Inc/stm32l4xx_hal_conf.h | ●●●●● patch | view | raw | blame | history | |
Core/Src/board/i2c_bitbang.c | ●●●●● patch | view | raw | blame | history | |
Core/Src/board/i2c_bitbang.h | ●●●●● patch | view | raw | blame | history | |
Core/Src/board/sht20.c | ●●●●● patch | view | raw | blame | history | |
Core/Src/i2c.c | ●●●●● patch | view | raw | blame | history | |
Core/Src/main.c | ●●●●● patch | view | raw | blame | history | |
ISKBoard.ioc | ●●●●● patch | view | raw | blame | history |
Core/Inc/i2c.h
File was deleted Core/Inc/stm32l4xx_hal_conf.h
@@ -40,7 +40,7 @@ /*#define HAL_CRYP_MODULE_ENABLED */ /*#define HAL_CAN_MODULE_ENABLED */ /*#define HAL_COMP_MODULE_ENABLED */ #define HAL_I2C_MODULE_ENABLED /*#define HAL_I2C_MODULE_ENABLED */ /*#define HAL_CRC_MODULE_ENABLED */ /*#define HAL_CRYP_MODULE_ENABLED */ /*#define HAL_DAC_MODULE_ENABLED */ Core/Src/board/i2c_bitbang.c
New file @@ -0,0 +1,341 @@ /********************************************************************** * Copyright: (C)2024 LingYun IoT System Studio * Author: GuoWenxue<guowenxue@gmail.com> * * Description: The purpose of this code is to provide a simple C library, * which providing software bit-bang of the I2C protocol on * any GPIO pins for ISKBoard. * * ChangeLog: * Version Date Author Description * V1.0.0 2024.08.29 GuoWenxue Release initial version * ***********************************************************************/ #include "i2c_bitbang.h" #include "miscdev.h" /* udelay() implement by TIM6 */ /* *+---------------------------------+ *| I2C GPIO port Level functions | *+---------------------------------+ */ #define mdelay(x) HAL_Delay(x) enum { LOW, HIGH, }; i2c_bus_t i2c_bus = { /* Addr SCL_Pin SDA_Pin */ 0x00, {GPIOB, GPIO_PIN_6 }, {GPIOB, GPIO_PIN_7 }, }; static inline void SDA_IN(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = i2c_bus.sda.pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(i2c_bus.sda.group, &GPIO_InitStruct); } static inline void SDA_OUT(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = i2c_bus.sda.pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(i2c_bus.sda.group, &GPIO_InitStruct); } static inline void SCL_OUT(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = i2c_bus.scl.pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(i2c_bus.scl.group, &GPIO_InitStruct); } static inline void SCL_SET(int level) { HAL_GPIO_WritePin(i2c_bus.scl.group, i2c_bus.scl.pin, level?GPIO_PIN_SET:GPIO_PIN_RESET); } static inline void SDA_SET(int level) { HAL_GPIO_WritePin(i2c_bus.sda.group, i2c_bus.sda.pin, level?GPIO_PIN_SET:GPIO_PIN_RESET); } static inline GPIO_PinState SCL_GET(void) { return HAL_GPIO_ReadPin(i2c_bus.scl.group, i2c_bus.scl.pin); } static inline GPIO_PinState SDA_GET(void) { return HAL_GPIO_ReadPin(i2c_bus.sda.group, i2c_bus.sda.pin); } /* *+--------------------------------+ *| I2C Low Level API functions | *+--------------------------------+ */ void I2C_StartCondition(void) { SDA_OUT(); SCL_OUT(); /* Start Condition Clock Sequence: ______ SCL: |___ _____ SDA: |_____ */ SDA_SET(HIGH); SCL_SET( HIGH); udelay(1); SDA_SET(LOW); udelay(1); // hold time start condition (t_HD;STA) SCL_SET(LOW); udelay(1); } void I2C_StopCondition(void) { SDA_OUT(); /* SCL Stop Condition Clock Sequence: _______ SCL: ___| _____ SDA: _____| */ SCL_SET(LOW); SDA_SET(LOW); udelay(1); SCL_SET(HIGH); SDA_SET(HIGH); udelay(1); } int I2C_SendAddress(uint8_t dir) { uint8_t addr; uint8_t rv; if( I2C_WR == dir ) { addr = W_ADDR(i2c_bus.addr); } else { addr = R_ADDR(i2c_bus.addr); } rv=I2C_WriteByte(addr); return rv; } void I2C_Ack(uint8_t ack) { if(ACK_NONE == ack) return ; SCL_SET(LOW); SDA_OUT(); if( ACK==ack ) SDA_SET(LOW); else if( NAK==ack ) SDA_SET(HIGH); udelay(1); SCL_SET( HIGH); udelay(1); SCL_SET(LOW); } int I2C_WriteByte(uint8_t txByte) { int error = 0; uint8_t mask; SDA_OUT(); SCL_SET(LOW); /* start send 8 bits data, MSB */ for(mask=0x80; mask>0; mask>>=1) { if((mask & txByte) == 0) SDA_SET(LOW); else SDA_SET(HIGH); udelay(1); // data set-up time (t_SU;DAT) SCL_SET(HIGH); udelay(1); // SCL high time (t_HIGH) SCL_SET(LOW); udelay(1); // data hold time(t_HD;DAT) } /* Wait for ACK/NAK */ SDA_IN(); SCL_SET(HIGH); // clk #9 for ack udelay(1); // data set-up time (t_SU;DAT) /* High level means NAK */ if( SDA_GET() ) error = -ERROR_ACK; SCL_SET(LOW); udelay(1); return error; } static inline int I2C_WaitWhileClockStreching(uint8_t timeout) { while( SCL_GET()== 0) { if(timeout-- == 0) return -ERROR_TIMEOUT; udelay(10); } return ERROR_NONE; } int I2C_ReadByte(uint8_t *rxByte, uint8_t ack, uint32_t timeout) { uint8_t error = 0; uint8_t mask; *rxByte = 0x00; SDA_IN(); /* start read 8 bits data, MSB */ for(mask = 0x80; mask > 0; mask >>= 1) { SCL_SET(HIGH); // start clock on SCL-line udelay(1); // clock set-up time (t_SU;CLK) // wait while clock streching error = I2C_WaitWhileClockStreching(timeout); udelay(1); // SCL high time (t_HIGH) if( SDA_GET() ) *rxByte |= mask; // read bit SCL_SET(LOW); udelay(1); // data hold time(t_HD;DAT) } I2C_Ack(ack); return error; } /* *+--------------------------------+ *| I2C High Level API functions | *+--------------------------------+ */ int i2c_lock(uint8_t addr) { /* I2C bus already be used */ while( i2c_bus.addr && i2c_bus.addr!=addr ) { mdelay(10); } i2c_bus.addr = addr; return 0; } void i2c_free(void) { i2c_bus.addr = 0x0; } int i2c_write(uint8_t *data, int bytes) { int i; int rv = 0; if( !data ) { return -ERROR_PARM; } /* send start condition */ I2C_StartCondition(); /* send device address for write */ if( (rv=I2C_SendAddress(I2C_WR)) < 0 ) goto OUT; /* send data to slave device */ for (i=0; i<bytes; i++) { if( (rv=I2C_WriteByte(data[i])) < 0 ) { break; } } OUT: /* send stop condition */ I2C_StopCondition(); return rv; } int i2c_read(uint8_t *buf, int size) { int i; int rv = ERROR_NONE; uint8_t byte; /* send start condition */ I2C_StartCondition(); /* send device address for read */ if( (rv=I2C_SendAddress(I2C_RD)) < 0 ) goto OUT; /* read data from slave device */ for (i=0; i<size; i++) { if( (rv=I2C_ReadByte(&byte, ACK, I2C_CLK_STRETCH_TIMEOUT)) < 0 ) goto OUT; buf[i] = byte; } OUT: /* send stop condition */ I2C_StopCondition(); return rv; } Core/Src/board/i2c_bitbang.h
New file @@ -0,0 +1,106 @@ /********************************************************************** * Copyright: (C)2024 LingYun IoT System Studio * Author: GuoWenxue<guowenxue@gmail.com> * * Description: The purpose of this code is to provide a simple C library, * which providing software bit-bang of the I2C protocol on * any GPIO pins for ISKBoard. * * ChangeLog: * Version Date Author Description * V1.0.0 2024.08.29 GuoWenxue Release initial version * ***********************************************************************/ #ifndef __I2C_BITBANG_H_ #define __I2C_BITBANG_H_ #include "stm32l4xx_hal.h" #define I2C_CLK_STRETCH_TIMEOUT 6000 /* *+---------------------------------+ *| I2C GPIO port Level functions | *+---------------------------------+ */ /* GPIO port for I2C typedef */ typedef struct i2c_gpio_s { GPIO_TypeDef *group; /* GPIO group */ uint16_t pin; /* GPIO pin */ } i2c_gpio_t; /* I2C bus typedef */ typedef struct i2c_bus_s { uint8_t addr; /* 7-bits slave address */ i2c_gpio_t scl; /* SCL GPIO pin */ i2c_gpio_t sda; /* SDA GPIO pin */ } i2c_bus_t; /* *+--------------------------------+ *| I2C High Level API functions | *+--------------------------------+ */ /* I2C bus error number */ enum { ERROR_NONE = 0x00, // no error ERROR_PARM = 0x01, // parameter out of range error ERROR_ACK = 0x02, // no acknowledgment error ERROR_TIMEOUT = 0x03, // timeout error ERROR_CHECKSUM = 0x04, // checksum mismatch error }; /* Set I2C slave device 7-bits address in the bus to lock it */ extern int i2c_lock(uint8_t addr); /* Clear I2C slave device 7-bits address in the bus to free it */ extern void i2c_free(void); /* write data by to slave device */ extern int i2c_write(uint8_t *data, int bytes); /* read data from slave device */ extern int i2c_read(uint8_t *buf, int size); /* *+--------------------------------+ *| I2C Low Level API functions | *+--------------------------------+ */ /* Send I2C start condition */ extern void I2C_StartCondition(void); /* Send I2C stop condition */ extern void I2C_StopCondition(void); /* Send I2C slave device 8-bits address */ #define W_ADDR(x) ((x)<<1 ) /* I2C address bit[0]=0 means write */ #define R_ADDR(x) ((x)<<1 | 1) /* I2C address bit[0]=1 means read */ enum { I2C_WR, /* Direction for write */ I2C_RD, /* Direction for read */ }; extern int I2C_SendAddress(uint8_t dir); /* Write a byte data to I2C slave device */ extern int I2C_WriteByte(uint8_t txByte); /* Read a byte data from I2C slave device */ enum { ACK_NONE, /* ACK None */ ACK, /* ACK */ NAK, /* NAK */ }; extern int I2C_ReadByte(uint8_t *rxByte, uint8_t ack, uint32_t timeout); #endif /* __I2C_BITBANG_H_ */ Core/Src/board/sht20.c
@@ -11,7 +11,7 @@ ***********************************************************************/ #include <stdio.h> #include <string.h> #include "i2c.h" #include "i2c_bitbang.h" #include "sht20.h" #define CONFIG_DEBUG_SHT2X /* Enable SHT20 debug */ @@ -61,6 +61,8 @@ float temp, rh; int rv; i2c_lock(SHT2X_CHIPADDR); if( sht2x_softreset() < 0 ) { sht2x_print("SHT20 soft reset failed.\r\n"); @@ -94,6 +96,7 @@ *humdity=rh; OUT: i2c_free(); return rv; } @@ -104,8 +107,8 @@ sht2x_print("Start soft reset sht2x\r\n"); rv=HAL_I2C_Master_Transmit(&hi2c1, SHT2X_CHIPADDR<<1, &command, 1, 0xFFFFFFFF); if( rv != HAL_OK ) rv=i2c_write(&command, 1); if( rv ) { sht2x_print("SHT2X send soft reset command 0x%0x failure: rv=0x%02x\r\n", command, rv); return -rv; @@ -161,7 +164,7 @@ return -2; } if( HAL_I2C_Master_Transmit(&hi2c1, SHT2X_CHIPADDR<<1, &command, 1, 0xFFFFFFFF) != HAL_OK ) if( i2c_write(&command, 1) < 0 ) { sht2x_print("SHT2X send measure command 0x%0x failure\r\n", command); return -3; @@ -176,7 +179,7 @@ { memset(buf, 0, 3); if( HAL_OK == HAL_I2C_Master_Receive(&hi2c1, SHT2X_CHIPADDR<<1|1, buf, 3, 0xFFFFFFFF) ) if( !i2c_read(buf, 3) ) { break; } Core/Src/i2c.c
File was deleted Core/Src/main.c
@@ -19,7 +19,6 @@ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "adc.h" #include "i2c.h" #include "tim.h" #include "usart.h" #include "gpio.h" @@ -96,7 +95,6 @@ MX_ADC1_Init(); MX_TIM6_Init(); MX_TIM1_Init(); MX_I2C1_Init(); /* USER CODE BEGIN 2 */ beep_start(2, 300); /* USER CODE END 2 */ ISKBoard.ioc
@@ -18,20 +18,17 @@ CAD.provider= File.Version=6 GPIO.groupedBy=Group By Peripherals I2C1.IPParameters=Timing I2C1.Timing=0x10D19CE4 KeepUserPlacement=false Mcu.CPN=STM32L431RCT6 Mcu.Family=STM32L4 Mcu.IP0=ADC1 Mcu.IP1=I2C1 Mcu.IP2=NVIC Mcu.IP3=RCC Mcu.IP4=SYS Mcu.IP5=TIM1 Mcu.IP6=TIM6 Mcu.IP7=USART1 Mcu.IPNb=8 Mcu.IP1=NVIC Mcu.IP2=RCC Mcu.IP3=SYS Mcu.IP4=TIM1 Mcu.IP5=TIM6 Mcu.IP6=USART1 Mcu.IPNb=7 Mcu.Name=STM32L431R(B-C)Tx Mcu.Package=LQFP64 Mcu.Pin0=PH0-OSC_IN (PH0) @@ -40,10 +37,8 @@ Mcu.Pin11=PA10 Mcu.Pin12=PA11 Mcu.Pin13=PD2 Mcu.Pin14=PB6 Mcu.Pin15=PB7 Mcu.Pin16=VP_SYS_VS_Systick Mcu.Pin17=VP_TIM6_VS_ClockSourceINT Mcu.Pin14=VP_SYS_VS_Systick Mcu.Pin15=VP_TIM6_VS_ClockSourceINT Mcu.Pin2=PB0 Mcu.Pin3=PB1 Mcu.Pin4=PB2 @@ -52,7 +47,7 @@ Mcu.Pin7=PB14 Mcu.Pin8=PC6 Mcu.Pin9=PC9 Mcu.PinsNb=18 Mcu.PinsNb=16 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32L431RCTx @@ -104,10 +99,6 @@ PB2.Locked=true PB2.PinState=GPIO_PIN_SET PB2.Signal=GPIO_Output PB6.Mode=I2C PB6.Signal=I2C1_SCL PB7.Mode=I2C PB7.Signal=I2C1_SDA PC6.GPIOParameters=PinState PC6.Locked=true PC6.PinState=GPIO_PIN_SET @@ -154,7 +145,7 @@ ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= ProjectManager.UnderRoot=true ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_ADC1_Init-ADC1-false-HAL-true,5-MX_TIM6_Init-TIM6-false-HAL-true,6-MX_TIM1_Init-TIM1-false-HAL-true,7-MX_I2C1_Init-I2C1-false-HAL-true ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_ADC1_Init-ADC1-false-HAL-true,5-MX_TIM6_Init-TIM6-false-HAL-true,6-MX_TIM1_Init-TIM1-false-HAL-true RCC.ADCFreq_Value=12000000 RCC.AHBFreq_Value=80000000 RCC.APB1Freq_Value=80000000