From f35617c92d4a49d12c46738a47a381efb4c60813 Mon Sep 17 00:00:00 2001 From: Jonas Holmberg Date: Tue, 25 Oct 2016 14:23:01 +0200 Subject: [PATCH] Working communication with the BARO Not a full implementation just a test that can get conntact with the BARO and no other calculations are made. This is not using the HAL but its a software implementation that simly sets pins high and low etc... --- UAV-ControlSystem/src/drivers/I2C.c | 14 +- UAV-ControlSystem/src/drivers/barometer.c | 350 +++++++++++++++++++++- UAV-ControlSystem/src/tasks_main.c | 26 +- 3 files changed, 357 insertions(+), 33 deletions(-) diff --git a/UAV-ControlSystem/src/drivers/I2C.c b/UAV-ControlSystem/src/drivers/I2C.c index c0120a2..092916f 100644 --- a/UAV-ControlSystem/src/drivers/I2C.c +++ b/UAV-ControlSystem/src/drivers/I2C.c @@ -57,20 +57,20 @@ bool i2c_configure(I2C_TypeDef *i2c, 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.Speed = GPIO_SPEED_FAST; GPIO_InitStruct.Alternate = i2c_af; HAL_GPIO_Init(i2c_port, &GPIO_InitStruct); //Initialize I2C communication out_profile->Instance = i2c; out_profile->Init.ClockSpeed = 400000; - out_profile->Init.DutyCycle = I2C_DUTYCYCLE_2; + out_profile->Init.DutyCycle = I2C_DUTYCYCLE_2/*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; + out_profile->Init.NoStretchMode = I2C_NOSTRETCH_DISABLED; if(HAL_I2C_Init(out_profile) != HAL_OK) return false; @@ -118,10 +118,10 @@ bool i2c_send(I2C_HandleTypeDef* profile, 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) -// {} - while(HAL_I2C_Master_Transmit(profile, slave_address, (uint8_t*)data, length, 5000) != HAL_OK && i++ < 10) - {} + while(HAL_I2C_Master_Transmit(profile,(slave_address << 1), (uint8_t*)data, length, 1000) != HAL_OK && i++ < 10) + {I2C1->CR1 |= (1 << 9);} +// while(HAL_I2C_Master_Transmit(profile, slave_address, (uint8_t*)data, length, 5000) != HAL_OK && i++ < 10) +// {} //Wait til the I2C bus is done with all sending while (HAL_I2C_GetState(profile) != HAL_I2C_STATE_READY){} diff --git a/UAV-ControlSystem/src/drivers/barometer.c b/UAV-ControlSystem/src/drivers/barometer.c index bd63463..932cec7 100644 --- a/UAV-ControlSystem/src/drivers/barometer.c +++ b/UAV-ControlSystem/src/drivers/barometer.c @@ -11,7 +11,7 @@ #define ADDR_WRITE 0xEE // Module address write mode #define ADDR_READ 0xEF // Module address read mode -#define ADDRESS_BARO 0x76 //0x77 +#define ADDRESS_BARO 0x77 //0x77 #define CMD_RESET 0x1E // ADC reset command #define CMD_ADC_READ 0x00 // ADC read command @@ -27,6 +27,9 @@ #define Device_address_1 0x56 +#define IO_CONFIG(mode, speed) ((mode) | (speed)) +#define IOCFG_OUT_OD IO_CONFIG(GPIO_Mode_Out_OD, GPIO_Speed_2MHz) + I2C_HandleTypeDef baroI2C_handle; double baro_Preassure; // compensated pressure value (mB) @@ -41,6 +44,212 @@ uint8_t cobuf[3]; * address: 7 = serial code and CRC */ uint32_t coefficients_arr[8]; //coefficient storage +void IOHi(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_SET); +} + +void IOLo(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_RESET); +} + +bool IORead(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + return !! (GPIOx->IDR & GPIO_Pin); +} + +static void TEST_I2C_delay(void) +{ + volatile int i = 7; + while (i) { + i--; + } +} + +void TEST_i2cInit() +{ + +// scl = IOGetByTag(IO_TAG(SOFT_I2C_SCL)); +// sda = IOGetByTag(IO_TAG(SOFT_I2C_SDA)); +// +// IOConfigGPIO(scl, IOCFG_OUT_OD); +// IOConfigGPIO(sda, IOCFG_OUT_OD); +} + +static bool TEST_I2C_Start(void) +{ + IOHi(I2C1_PORT, I2C1_SDA_PIN); + IOHi(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); + if (!IORead(I2C1_PORT, I2C1_SDA_PIN)) { + return false; + } + IOLo(I2C1_PORT, I2C1_SDA_PIN); + TEST_I2C_delay(); + if (IORead(I2C1_PORT, I2C1_SDA_PIN)) { + return false; + } + IOLo(I2C1_PORT, I2C1_SDA_PIN); + TEST_I2C_delay(); + return true; +} + +static void TEST_I2C_Stop(void) +{ + IOLo(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); + IOLo(I2C1_PORT, I2C1_SDA_PIN); + TEST_I2C_delay(); + IOHi(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); + IOHi(I2C1_PORT, I2C1_SDA_PIN); + TEST_I2C_delay(); +} + +static void TEST_I2C_Ack(void) +{ + IOLo(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); + IOLo(I2C1_PORT, I2C1_SDA_PIN); + TEST_I2C_delay(); + IOHi(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); + IOLo(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); +} + +static void TEST_I2C_NoAck(void) +{ + IOLo(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); + IOHi(I2C1_PORT, I2C1_SDA_PIN); + TEST_I2C_delay(); + IOHi(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); + IOLo(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); +} + +static bool TEST_I2C_WaitAck(void) +{ + IOLo(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); + IOHi(I2C1_PORT, I2C1_SDA_PIN); + TEST_I2C_delay(); + IOHi(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); + if (IORead(I2C1_PORT, I2C1_SDA_PIN)) { + IOLo(I2C1_PORT, I2C1_SCL_PIN); + return false; + } + IOLo(I2C1_PORT, I2C1_SCL_PIN); + return true; +} + +static void TEST_I2C_SendByte(uint8_t byte) +{ + uint8_t i = 8; + while (i--) { + IOLo(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); + if (byte & 0x80) { + IOHi(I2C1_PORT, I2C1_SDA_PIN); + } + else { + IOLo(I2C1_PORT, I2C1_SDA_PIN); + } + byte <<= 1; + TEST_I2C_delay(); + IOHi(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); + } + IOLo(I2C1_PORT, I2C1_SCL_PIN); +} + +static uint8_t TEST_I2C_ReceiveByte(void) +{ + uint8_t i = 8; + uint8_t byte = 0; + + IOHi(I2C1_PORT, I2C1_SDA_PIN); + while (i--) { + byte <<= 1; + IOLo(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); + IOHi(I2C1_PORT, I2C1_SCL_PIN); + TEST_I2C_delay(); + if (IORead(I2C1_PORT, I2C1_SDA_PIN)) { + byte |= 0x01; + } + } + IOLo(I2C1_PORT, I2C1_SCL_PIN); + return byte; +} + +bool TEST_i2cRead(I2C_HandleTypeDef *hi2c, uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf) +{ + //just send the addres 0x77 + //write = 0, read = 1 + + if (!TEST_I2C_Start()) { + return false; + } + + TEST_I2C_SendByte(addr << 1 | 0); + if (!TEST_I2C_WaitAck()) { + TEST_I2C_Stop(); + //i2cErrorCount++; + return false; + } + TEST_I2C_SendByte(reg); + TEST_I2C_WaitAck(); + TEST_I2C_Start(); + TEST_I2C_SendByte(addr << 1 | 1); + TEST_I2C_WaitAck(); + while (len) { + *buf = TEST_I2C_ReceiveByte(); + if (len == 1) { + TEST_I2C_NoAck(); + } + else { + TEST_I2C_Ack(); + } + buf++; + len--; + } + TEST_I2C_Stop(); + return true; +} + +bool TEST_i2cWrite(I2C_HandleTypeDef *hi2c, uint8_t addr, uint8_t reg, uint8_t data, uint8_t readWrite) +{ + //just send the addres 0x77 + //write = 0, read = 1 + + if (!TEST_I2C_Start()) { + return false; + } + + TEST_I2C_SendByte(addr << 1 | 0); + if (!TEST_I2C_WaitAck()) { + TEST_I2C_Stop(); + // i2cErrorCount++; + return false; + } + TEST_I2C_SendByte(reg); + TEST_I2C_WaitAck(); + TEST_I2C_SendByte(data); + TEST_I2C_WaitAck(); + TEST_I2C_Stop(); + return true; +} + + + + + + uint8_t crc4(uint32_t n_prom[]) { uint32_t n_rem; @@ -74,8 +283,8 @@ unsigned int barometer_cmd_prom(char coef_num) unsigned int rC = 0; cobuf[0] = 0; cobuf[1] = 0; - //i2c_send(&baroI2C_handle, ADDRESS_BARO, CMD_PROM_RD + coef_num * 2, 1); // send PROM READ command - m_i2c_send(CMD_PROM_RD + coef_num * 2); // send PROM READ command + i2c_send(&baroI2C_handle, ADDRESS_BARO, CMD_PROM_RD + coef_num * 2, 1); // send PROM READ command + //m_i2c_send(CMD_PROM_RD + coef_num * 2); // send PROM READ command i2c_receive(&baroI2C_handle, ADDRESS_BARO, cobuf, 3); //Read the adc values rC = cobuf[0] * 256 + cobuf[1]; return rC; @@ -120,18 +329,133 @@ void m_i2c_send(uint8_t cmd) bool barometer_init() { + //i2c_configure(I2C1, &baroI2C_handle, Device_address_1); + //Initialize pins for SCL and SDA + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.Pin = I2C1_SCL_PIN | I2C1_SDA_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + HAL_GPIO_Init(I2C1_PORT, &GPIO_InitStruct); + + bool ack = false; + uint8_t sig; +// ack = TEST_i2cRead(I2C1, ADDRESS_BARO, CMD_PROM_RD, 1, &sig); +// if (!ack) +// return false; + + TEST_i2cWrite(I2C1, ADDRESS_BARO, CMD_RESET, 1, 0); + HAL_Delay(2800); + for (int i = 0; i < 8; i++) + { + uint8_t rxbuf[2] = { 0, 0 }; + TEST_i2cRead(I2C1, ADDRESS_BARO, CMD_PROM_RD + i * 2, 2, rxbuf); // send PROM READ command + coefficients_arr[i] = rxbuf[0] << 8 | rxbuf[1]; + } + + + HAL_GPIO_DeInit(I2C1_PORT, I2C1_SCL_PIN); + HAL_GPIO_DeInit(I2C1_PORT, I2C1_SDA_PIN); + + return i2c_configure(I2C1, &baroI2C_handle, Device_address_1); } bool barometer_reset() { + + //Change to write mode and send reset command cobuf[0] = CMD_RESET; HAL_Delay(1000); - bool response = i2c_send(&baroI2C_handle, ADDR_WRITE, (uint8_t*)cobuf[0], 1); - m_i2c_send(CMD_RESET); - m_i2c_send(CMD_RESET); - m_i2c_send(CMD_RESET); + //ool response = i2c_send(&baroI2C_handle, ADDRESS_BARO, (uint8_t*)cobuf[0], 1); + int i = 0; + uint32_t TempaddressW = 0b11101110; + uint32_t TempaddressR = 0b11101110; + uint32_t testValueW = ((uint8_t)((TempaddressW) & (~0x00000001U))); + uint32_t testValR = ((uint8_t)((TempaddressR) | 0x00000001U)); + + HAL_I2C_Master_Transmit(&baroI2C_handle,TempaddressW,cobuf, 1,1000); + +// for (i = 0; i < 256; i ++) +// { +// if(HAL_I2C_Master_Transmit(&baroI2C_handle,i,cobuf, 1,1000) == HAL_OK) +// { +// uint32_t testValue = ((uint8_t)((i) & (~0x00000001U))); +// } +// else +// { +// +// } +// } + + + + + HAL_Delay(3000); + + for (int coef_num = 0; coef_num < 8; coef_num++) + { + HAL_Delay(50); + cobuf[0] = 0; + cobuf[1] = 0; + cobuf[2] = 0; + cobuf[0] = CMD_PROM_RD + (coef_num * 2); + HAL_I2C_Master_Transmit(&baroI2C_handle, TempaddressW, cobuf, 1, 1000); // send PROM READ command + cobuf[0] = 0; + HAL_I2C_Master_Receive(&baroI2C_handle, TempaddressR, cobuf, 2, 1000); //Read the adc values + uint32_t rC = (cobuf[0] << 8) | cobuf[1]; + coefficients_arr[coef_num] = rC; + } + //m_i2c_send(CMD_PROM_RD + coef_num * 2); // send PROM READ command + + +// +// while(true) +// { +// i++; +// //HAL_I2C_Mem_Write() +// I2C1->CR1 |= (1 << 8); +// HAL_Delay(10); +// I2C1->SR1; +// +// uint32_t Tempaddress = 0b11101100; +// I2C1->DR = Tempaddress; +// HAL_Delay(10); +// uint32_t compVal = (I2C1->SR1 & (1 << 10)); +// if (compVal != 0) +// { +// I2C1->SR1 &= ~(1 << 10); +// I2C1->CR1 |= (1 << 9); +// HAL_Delay(100); +// +// } +// else if (compVal == 0) +// { +// break; +// } +// } +// +// +// I2C1->SR2; +// +// I2C1->DR = CMD_RESET; + + //I2C1->CR1 |= (1 << 9); + + + HAL_Delay(1000); + + if(HAL_I2C_IsDeviceReady(&baroI2C_handle, ADDRESS_BARO, 10,1000) == HAL_OK) + { + return true; + } + + + +// m_i2c_send(CMD_RESET); +// m_i2c_send(CMD_RESET); +// m_i2c_send(CMD_RESET); //wait for the reset sequence HAL_Delay(5); @@ -200,22 +524,22 @@ void barometer_CaclulateValues() switch (currentCalculationState) { case CALCSTATE_D2_CALCULATION: - i2c_send(&baroI2C_handle, ADDRESS_BARO, CMD_ADC_CONV + (CMD_ADC_D2 + CMD_ADC_4096),1); // send conversion command + HAL_I2C_Master_Transmit(&baroI2C_handle, ADDRESS_BARO, CMD_ADC_CONV + (CMD_ADC_D2 + CMD_ADC_4096),1,1000); // send conversion command currentCalculationState = CALCSTATE_D2_READ; //change the state so we will go to D2 read next time function is called break; case CALCSTATE_D2_READ: - i2c_send(&baroI2C_handle, ADDRESS_BARO, CMD_ADC_READ, 1); //Tell the sensor we want to read - i2c_receive(&baroI2C_handle, ADDRESS_BARO, cobuf, 3); //Read the adc values + HAL_I2C_Master_Transmit(&baroI2C_handle, ADDRESS_BARO, CMD_ADC_READ, 1, 1000); //Tell the sensor we want to read + HAL_I2C_Master_Receive(&baroI2C_handle, ADDRESS_BARO, cobuf, 3, 1000); //Read the adc values D2 = (cobuf[0] << 16) + (cobuf[1] << 8) + cobuf[2]; //Shift the values to the correct position for the 24 bit D2 value currentCalculationState = CALCSTATE_D1_CALCULATION; break; case CALCSTATE_D1_CALCULATION: - i2c_send(&baroI2C_handle, ADDRESS_BARO, CMD_ADC_CONV + (CMD_ADC_D1 + CMD_ADC_4096),1); // send conversion command + HAL_I2C_Master_Transmit(&baroI2C_handle, ADDRESS_BARO, CMD_ADC_CONV + (CMD_ADC_D1 + CMD_ADC_4096),1, 1000); // send conversion command currentCalculationState = CALCSTATE_D1_READ; //change the state so we will go to D1 read next time function is called break; case CALCSTATE_D1_READ: - i2c_send(&baroI2C_handle, ADDRESS_BARO, CMD_ADC_READ, 1); //Tell the sensor we want to read - i2c_receive(&baroI2C_handle, ADDRESS_BARO, cobuf, 3); //Read the adc values + HAL_I2C_Master_Transmit(&baroI2C_handle, ADDRESS_BARO, CMD_ADC_READ, 1, 1000); //Tell the sensor we want to read + HAL_I2C_Master_Receive(&baroI2C_handle, ADDRESS_BARO, cobuf, 3, 1000); //Read the adc values D1 = (cobuf[0] << 16) + (cobuf[1] << 8) + cobuf[2]; //Shift the values to the correct position for the 24 bit D2 value currentCalculationState = CALCSTATE_CALCULATE_PTA; break; diff --git a/UAV-ControlSystem/src/tasks_main.c b/UAV-ControlSystem/src/tasks_main.c index ad801a9..03bc4b0 100644 --- a/UAV-ControlSystem/src/tasks_main.c +++ b/UAV-ControlSystem/src/tasks_main.c @@ -187,7 +187,7 @@ void systemTaskBaro(void) -// //read the barometer + //read the barometer // I2C_HandleTypeDef i2c_profile; // // //---- COMPAS WORKING ---- @@ -211,7 +211,7 @@ void systemTaskBaro(void) // // while (1) // { -// i2c_send(&i2c_profile, 0x3D, request_data, 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); // @@ -225,17 +225,17 @@ void systemTaskBaro(void) // int16_t y = (~(*(int16_t*)(response_data+4)))+1; // int stop = 5 *2; // } - - - - - - - - - - - +// +// +// +// +// +// +// +// +// +// +//