Merge remote-tracking branch 'refs/remotes/origin/I2C'

This commit is contained in:
Lennart Eriksson 2016-10-03 09:51:36 +02:00
commit 4d3801239c
6 changed files with 253 additions and 3 deletions

View File

@ -0,0 +1,111 @@
/***************************************************************************
* NAME: I2C.h *
* AUTHOR: Lennart Eriksson *
* PURPOSE: Enabole the I2C Communication channel on the Revo board *
* INFORMATION: *
* This file initilizes the I2C communication that can be used by barometer *
* communication etc. *
* *
* GLOBAL VARIABLES: *
* Variable Type Description *
* -------- ---- ----------- *
***************************************************************************/
#ifndef DRIVERS_I2C_H_
#define DRIVERS_I2C_H_
#include "stm32f4xx.h"
/******************************************************************************
* BRIEF: Configure the I2C bus to be used *
* INFORMATION: This function only implements I2C1 or I2C2 which are available *
* on the REVO board *
******************************************************************************/
bool i2c_configure(I2C_TypeDef* i2c,
I2C_HandleTypeDef* out_profile,
uint32_t my_address);
/******************************************************************************
* BRIEF: Get data over the I2C bus *
* INFORMATION: *
* Since this system uses a 7 bit addressing mode we send the slave address *
* in the first bytes 7 MSbs and then the LSb is set to 1 indicating that *
* it is a receive command, after that the slave responds with a 1 bit ack and *
* the data is sent one byte at a time with an acknowledge in between *
* every byte, as per the standard. Returns true if successful *
******************************************************************************/
bool i2c_receive(I2C_HandleTypeDef* profile,
uint8_t slave_address,
uint8_t* buffer,
uint32_t length);
/******************************************************************************
* BRIEF: Send data over the I2C bus *
* INFORMATION: *
* Since this system uses a 7 bit addressing mode we send the slave address *
* in the first bytes 7 MSbs and then the LSb is set to 0 indicating that *
* it is a send command, after that the slave responds with a 1 bit ack and *
* the data is sent one byte at a time with an acknowledge in between *
* every byte, as per the standard. Returns true if successful *
******************************************************************************/
bool i2c_send(I2C_HandleTypeDef* profile,
uint8_t slave_address,
uint8_t* data,
uint32_t length);
#endif /* DRIVERS_I2C_H_ */
// ---------------------- I2C Working with the compas on the REVO board ------------------------------
/*
int main(void)
{
// Initialize the Hardware Abstraction Layer
HAL_Init();
init_system();
I2C_HandleTypeDef i2c_profile;
//---- COMPAS WORKING ----
i2c_configure(I2C1, &i2c_profile, 0x56);
uint32_t address = 0b00011110;
uint8_t start_request_1[2] = { 0b00000000, 0b01110000 };
uint8_t start_request_2[2] = { 0b00000001, 0b10100000 };
uint8_t start_request_3[2] = { 0b00000010, 0b00000000 };
uint8_t request_data[1] = { 0b00000110 };
uint8_t reset_pointer_data[1] = { 0b00000011 };
uint8_t response_data[6] = { 0x0 };
// This sequence starts the compass by first initializing it with the first 2 send
// The third is there to say that the system should be continous communication
i2c_send(&i2c_profile, address, &start_request_1, 2);
i2c_send(&i2c_profile, address, &start_request_2, 2);
i2c_send(&i2c_profile, address, &start_request_3, 2);
// Delay for at least 6 ms for system startup to finish
HAL_Delay(10);
while (1)
{
i2c_send(&i2c_profile, address, &request_data, 1);
i2c_receive(&i2c_profile, address, &response_data, 6);
i2c_send(&i2c_profile, address, &reset_pointer_data, 1);
// HAL_Delay(100);
if(response_data[0] != 0)
response_data[0] = 0;
}
}
*/

View File

@ -82,6 +82,16 @@
#define USART6_TX_PORT GPIOC
/* I2C */
#define I2C1_SDA_PIN GPIO_PIN_9
#define I2C1_SCL_PIN GPIO_PIN_8
#define I2C1_PORT GPIOB
#define I2C2_SCL_PIN GPIO_PIN_10
#define I2C2_SDA_PIN GPIO_PIN_11
#define I2C2_PORT GPIOB
/* Gyro */
#define GYRO
#define MPU6000_CS_PIN GPIO_PIN_4

View File

@ -0,0 +1,128 @@
/***************************************************************************
* NAME: I2C.c *
* AUTHOR: Lennart Eriksson *
* PURPOSE: Enabole the I2C Communication channel on the Revo board *
* INFORMATION: *
* This file initilizes the I2C communication that can be used by barometer *
* communication etc. *
* *
* GLOBAL VARIABLES: *
* Variable Type Description *
* -------- ---- ----------- *
***************************************************************************/
#include "drivers/I2C.h"
#include "stm32f4xx_revo.h"
/******************************************************************************
* BRIEF: Configure the I2C bus to be used *
* INFORMATION: *
******************************************************************************/
bool i2c_configure(I2C_TypeDef *i2c,
I2C_HandleTypeDef *out_profile,
uint32_t my_address)
{
uint8_t i2c_af;
uint16_t sda_pin, scl_pin;
GPIO_TypeDef *i2c_port;
// get the correct alternate function and pins for the selected I2C
// Only I2C1 and I2C2 is available on the REVO board
if(i2c == I2C1)
{
i2c_af = GPIO_AF4_I2C1;
i2c_port = I2C1_PORT;
sda_pin = I2C1_SDA_PIN;
scl_pin = I2C1_SCL_PIN;
if(__HAL_RCC_I2C1_IS_CLK_DISABLED())
__HAL_RCC_I2C1_CLK_ENABLE();
}
else if(i2c == I2C2)
{
i2c_af = GPIO_AF4_I2C2;
i2c_port = I2C2_PORT;
sda_pin = I2C2_SDA_PIN;
scl_pin = I2C2_SCL_PIN;
if(__HAL_RCC_I2C2_IS_CLK_DISABLED())
__HAL_RCC_I2C2_CLK_ENABLE();
}
else
return false; // The provided I2C is not correct
if(__HAL_RCC_GPIOB_IS_CLK_DISABLED())
__HAL_RCC_GPIOB_CLK_ENABLE();
//Initialize pins for SCL and SDA
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = sda_pin | scl_pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = i2c_af;
HAL_GPIO_Init(i2c_port, &GPIO_InitStruct);
//Initialize I2C communication
out_profile->Instance = i2c;
out_profile->Init.ClockSpeed = 100000;
out_profile->Init.DutyCycle = I2C_DUTYCYCLE_2;
out_profile->Init.OwnAddress1 = my_address;
out_profile->Init.OwnAddress2 = 0;
out_profile->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
out_profile->Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
out_profile->Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
out_profile->Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;
if(HAL_I2C_Init(out_profile) != HAL_OK)
return false;
return true;
}
/******************************************************************************
* BRIEF: Get data over the I2C bus *
* INFORMATION: *
* Since this system uses a 7 bit addressing mode we send the slave address *
* in the first bytes 7 MSbs and then the LSb is set to 1 indicating that *
* it is a receive command, after that the slave responds with a 1 bit ack and *
* the data is sent one byte at a time with an acknowledge in between *
* every byte, as per the standard. Returns true if successful *
******************************************************************************/
bool i2c_receive(I2C_HandleTypeDef* profile,
uint8_t slave_address,
uint8_t* buffer,
uint32_t length)
{
uint8_t i = 0;
while(HAL_I2C_Master_Receive(profile, (slave_address << 1) | 1, buffer, length, 1000)!= HAL_OK && i++ < 10)
{}
while (HAL_I2C_GetState(profile) != HAL_I2C_STATE_READY)
{}
return (i < 10);
}
/***************************************************************************
* BRIEF: Send data over the I2C bus *
* INFORMATION: *
* Since this system uses a 7 bit addressing mode we send the slave address *
* in the first bytes 7 MSbs and then the LSb is set to 0 indicating that *
* it is a send command, after that the slave responds with a 1 bit ack and *
* the data is sent one byte at a time with an acknowledge in between *
* every byte, as per the standard. Returns true if successful *
***************************************************************************/
bool i2c_send(I2C_HandleTypeDef* profile,
uint8_t slave_address,
uint8_t* data,
uint32_t length)
{
uint8_t i = 0;
// try to send the data 10 times and if no acknowledge is received during these 10 messages we stop trying so that
// the system don't gets stuck forever because a slave is unreachable
while(HAL_I2C_Master_Transmit(profile,(slave_address << 1), (uint8_t*)data, length, 1000) != HAL_OK && i++ < 10)
{}
//Wait til the I2C bus is done with all sending
while (HAL_I2C_GetState(profile) != HAL_I2C_STATE_READY){}
return (i < 10);
}

View File

@ -1,3 +1,4 @@
/**
******************************************************************************
* @file main.c
@ -100,4 +101,3 @@ int main(void)
for(;;);
}

View File

@ -392,7 +392,7 @@
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
#define assert_param(expr) ((expr) ? (void)0 : a,ssert_failed((uint8_t *)__FILE__ __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else

View File

@ -4763,7 +4763,8 @@ static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uin
/* Check for the Timeout */
if(Timeout != HAL_MAX_DELAY)
{
if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
uint32_t time = HAL_GetTick();
if((Timeout == 0U)||((time - tickstart ) > Timeout))
{
hi2c->PreviousState = I2C_STATE_NONE;
hi2c->State= HAL_I2C_STATE_READY;