Moved I2C related functions to i2c.c
This commit is contained in:
		
							
								
								
									
										44
									
								
								fw/Core/Inc/i2c.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								fw/Core/Inc/i2c.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * i2c.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jun 8, 2021
 | 
				
			||||||
 | 
					 *      Author: user
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef INC_I2C_H_
 | 
				
			||||||
 | 
					#define INC_I2C_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "stdint.h"
 | 
				
			||||||
 | 
					#include "stm32l0xx_ll_i2c.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Defines & macros
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NULL 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Return values for I2C functions
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define I2C_OK 0
 | 
				
			||||||
 | 
					#define I2C_ERROR -1 // generic error
 | 
				
			||||||
 | 
					#define I2C_ERROR_NACK -2 // NACK was received during transfer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Type definitions
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						I2C_TypeDef *i2c;
 | 
				
			||||||
 | 
					} i2c_context_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Function declarations
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int i2c_init(i2c_context_t *context);
 | 
				
			||||||
 | 
					int i2c_transmit(uint8_t address, uint8_t *buffer, int len);
 | 
				
			||||||
 | 
					int i2c_receive(uint8_t address, uint8_t *buffer, int len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* INC_I2C_H_ */
 | 
				
			||||||
@@ -49,6 +49,7 @@ extern "C" {
 | 
				
			|||||||
/* Private includes ----------------------------------------------------------*/
 | 
					/* Private includes ----------------------------------------------------------*/
 | 
				
			||||||
/* USER CODE BEGIN Includes */
 | 
					/* USER CODE BEGIN Includes */
 | 
				
			||||||
#include "led.h"
 | 
					#include "led.h"
 | 
				
			||||||
 | 
					#include "i2c.h"
 | 
				
			||||||
#include "sht4x.h"
 | 
					#include "sht4x.h"
 | 
				
			||||||
/* USER CODE END Includes */
 | 
					/* USER CODE END Includes */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "stdint.h"
 | 
					#include "stdint.h"
 | 
				
			||||||
#include "stm32l0xx_ll_i2c.h"
 | 
					#include "stm32l0xx_ll_i2c.h"
 | 
				
			||||||
 | 
					#include "i2c.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Defines & macros
 | 
					 * Defines & macros
 | 
				
			||||||
@@ -18,12 +19,15 @@
 | 
				
			|||||||
#define SHT4X_I2C_ADDRESS 0x44
 | 
					#define SHT4X_I2C_ADDRESS 0x44
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Data types
 | 
					 * Return values
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					#define SHT4X_OK 0
 | 
				
			||||||
	I2C_TypeDef *i2c;
 | 
					#define SHT4X_ERROR -1 // generic error
 | 
				
			||||||
} sht4x_context_t;
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Data types
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
	START_MEAS_HIGH_PRECISION = 0xFD,
 | 
						START_MEAS_HIGH_PRECISION = 0xFD,
 | 
				
			||||||
@@ -43,7 +47,6 @@ typedef enum {
 | 
				
			|||||||
 * Function prototypes
 | 
					 * Function prototypes
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int sht4x_init(sht4x_context_t *context);
 | 
					 | 
				
			||||||
int sht4x_send_cmd(sht4x_cmd_t cmd);
 | 
					int sht4x_send_cmd(sht4x_cmd_t cmd);
 | 
				
			||||||
int sht4x_read_data(uint8_t *buffer, int len);
 | 
					int sht4x_read_data(uint8_t *buffer, int len);
 | 
				
			||||||
int sht4x_measure(int *temperature, int *relative_humidity);
 | 
					int sht4x_measure(int *temperature, int *relative_humidity);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										55
									
								
								fw/Core/Src/i2c.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								fw/Core/Src/i2c.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * i2c.c
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jun 8, 2021
 | 
				
			||||||
 | 
					 *      Author: user
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "i2c.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					i2c_context_t *i2c_context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int i2c_init(i2c_context_t *context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (context == NULL) {
 | 
				
			||||||
 | 
							return I2C_ERROR;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						i2c_context = context;
 | 
				
			||||||
 | 
						return I2C_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int i2c_transmit(uint8_t address, uint8_t *buffer, int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						LL_I2C_HandleTransfer(i2c_context->i2c, address, LL_I2C_ADDRESSING_MODE_7BIT, len,
 | 
				
			||||||
 | 
								LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
 | 
				
			||||||
 | 
						int i = 0;
 | 
				
			||||||
 | 
						while (!LL_I2C_IsActiveFlag_STOP(i2c_context->i2c)) {
 | 
				
			||||||
 | 
							if (LL_I2C_IsActiveFlag_TXE(i2c_context->i2c)) {
 | 
				
			||||||
 | 
								if (i < len) {
 | 
				
			||||||
 | 
									LL_I2C_TransmitData8(i2c_context->i2c, buffer[i++]);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						LL_I2C_ClearFlag_STOP(i2c_context->i2c);
 | 
				
			||||||
 | 
						if (LL_I2C_IsActiveFlag_NACK(i2c_context->i2c)) {
 | 
				
			||||||
 | 
							return I2C_ERROR_NACK;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return I2C_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int i2c_receive(uint8_t address, uint8_t *buffer, int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						LL_I2C_HandleTransfer(i2c_context->i2c, address, LL_I2C_ADDRESSING_MODE_7BIT, len,
 | 
				
			||||||
 | 
									LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
 | 
				
			||||||
 | 
						int i = 0;
 | 
				
			||||||
 | 
						while (!LL_I2C_IsActiveFlag_STOP(i2c_context->i2c)) {
 | 
				
			||||||
 | 
							if (LL_I2C_IsActiveFlag_RXNE(i2c_context->i2c)) {
 | 
				
			||||||
 | 
								if (i < len) {
 | 
				
			||||||
 | 
									buffer[i++] = LL_I2C_ReceiveData8(i2c_context->i2c);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						LL_I2C_ClearFlag_STOP(i2c_context->i2c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return I2C_OK; // TODO error detection
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -108,10 +108,10 @@ int main(void)
 | 
				
			|||||||
  led_context.blue_led_pin = LED_B_Pin;
 | 
					  led_context.blue_led_pin = LED_B_Pin;
 | 
				
			||||||
  led_init(&led_context, 50, 1000);
 | 
					  led_init(&led_context, 50, 1000);
 | 
				
			||||||
  led_set_color(80, 0, 0);
 | 
					  led_set_color(80, 0, 0);
 | 
				
			||||||
  /* SHT4x context init */
 | 
					  /* I2C context init (for SHT4x and SCD4x) */
 | 
				
			||||||
  sht4x_context_t sht4x_context;
 | 
					  i2c_context_t i2c_context;
 | 
				
			||||||
  sht4x_context.i2c = I2C1;
 | 
					  i2c_context.i2c = I2C1;
 | 
				
			||||||
  sht4x_init(&sht4x_context);
 | 
					  i2c_init(&i2c_context);
 | 
				
			||||||
  /* USER CODE END 2 */
 | 
					  /* USER CODE END 2 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Infinite loop */
 | 
					  /* Infinite loop */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,43 +7,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "sht4x.h"
 | 
					#include "sht4x.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sht4x_context_t *sht4x_context;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int sht4x_init(sht4x_context_t *context)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	sht4x_context = context;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i2c_transmit(uint8_t address, uint8_t *buffer, int len)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	LL_I2C_HandleTransfer(sht4x_context->i2c, address, LL_I2C_ADDRESSING_MODE_7BIT, len,
 | 
					 | 
				
			||||||
			LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
 | 
					 | 
				
			||||||
	int i = 0;
 | 
					 | 
				
			||||||
	while (!LL_I2C_IsActiveFlag_STOP(sht4x_context->i2c)) {
 | 
					 | 
				
			||||||
		if (LL_I2C_IsActiveFlag_TXE(sht4x_context->i2c)) {
 | 
					 | 
				
			||||||
			if (i < len) {
 | 
					 | 
				
			||||||
				LL_I2C_TransmitData8(sht4x_context->i2c, buffer[i++]);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	LL_I2C_ClearFlag_STOP(sht4x_context->i2c);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void i2c_receive(uint8_t address, uint8_t *buffer, int len)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	LL_I2C_HandleTransfer(sht4x_context->i2c, address, LL_I2C_ADDRESSING_MODE_7BIT, len,
 | 
					 | 
				
			||||||
				LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
 | 
					 | 
				
			||||||
	int i = 0;
 | 
					 | 
				
			||||||
	while (!LL_I2C_IsActiveFlag_STOP(sht4x_context->i2c)) {
 | 
					 | 
				
			||||||
		if (LL_I2C_IsActiveFlag_RXNE(sht4x_context->i2c)) {
 | 
					 | 
				
			||||||
			if (i < len) {
 | 
					 | 
				
			||||||
				buffer[i++] = LL_I2C_ReceiveData8(sht4x_context->i2c);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	LL_I2C_ClearFlag_STOP(sht4x_context->i2c);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int sht4x_send_cmd(sht4x_cmd_t cmd)
 | 
					int sht4x_send_cmd(sht4x_cmd_t cmd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -57,17 +20,22 @@ int sht4x_read_data(uint8_t *buffer, int len)
 | 
				
			|||||||
int sht4x_measure(int *temperature, int *relative_humidity)
 | 
					int sht4x_measure(int *temperature, int *relative_humidity)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint8_t buffer[32];
 | 
						uint8_t buffer[32];
 | 
				
			||||||
 | 
						int result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// start measurement
 | 
						// start measurement
 | 
				
			||||||
	buffer[0] = START_MEAS_HIGH_PRECISION;
 | 
						buffer[0] = START_MEAS_HIGH_PRECISION;
 | 
				
			||||||
	i2c_transmit(SHT4X_I2C_ADDRESS, buffer, 1);
 | 
						result = i2c_transmit(SHT4X_I2C_ADDRESS, buffer, 1);
 | 
				
			||||||
	// delay TODO
 | 
						if (result != I2C_OK) {
 | 
				
			||||||
	volatile int j,k;
 | 
							return SHT4X_ERROR;
 | 
				
			||||||
	for (j = 0; j < 100000; j++);
 | 
						}
 | 
				
			||||||
 | 
						// busy delay (LL_mDelay uses SysTick which doesn't work at the moment) TODO
 | 
				
			||||||
 | 
						for (volatile int j = 0; j < 100000; j++);
 | 
				
			||||||
	// read out
 | 
						// read out
 | 
				
			||||||
	i2c_receive(SHT4X_I2C_ADDRESS, buffer, 6);
 | 
						result = i2c_receive(SHT4X_I2C_ADDRESS, buffer, 6);
 | 
				
			||||||
	// TODO
 | 
						if (result != I2C_OK) {
 | 
				
			||||||
 | 
							return SHT4X_ERROR;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Convert to T and RH; taken directly from pseudocode in SHT4x datasheet, page 3
 | 
				
			||||||
	uint32_t t_ticks = (buffer[0] << 8) + buffer[1];
 | 
						uint32_t t_ticks = (buffer[0] << 8) + buffer[1];
 | 
				
			||||||
	uint32_t rh_ticks = (buffer[3] << 8) + buffer[4];
 | 
						uint32_t rh_ticks = (buffer[3] << 8) + buffer[4];
 | 
				
			||||||
	int t_degC = -45 + 175 * t_ticks / 65535;
 | 
						int t_degC = -45 + 175 * t_ticks / 65535;
 | 
				
			||||||
@@ -80,4 +48,6 @@ int sht4x_measure(int *temperature, int *relative_humidity)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	*temperature = t_degC;
 | 
						*temperature = t_degC;
 | 
				
			||||||
	*relative_humidity = rh_pRH;
 | 
						*relative_humidity = rh_pRH;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return SHT4X_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user