Is this the right way to SPI? - stm32

I am currently trying to check with the function, if my SPI is working currectly.
This function should return 1, if everything is fine...but it always return 0. Maybe values in pTxData are wrong ?
uint8_t Gyro_CanReadWHOAMI() {
uint8_t pTxData[2] = {0x0F | 0x80, 0};
uint8_t pRxData[2] = {0, 0};
HAL_GPIO_WritePin(NCS_MEMS_SPI_GPIO_Port, NCS_MEMS_SPI_Pin, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi5, pTxData, pRxData, 2, HAL_MAX_DELAY);
HAL_GPIO_WritePin(NCS_MEMS_SPI_GPIO_Port, NCS_MEMS_SPI_Pin, GPIO_PIN_SET);
uint8_t test = pRxData[1] == 0x32;
return test;
}
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI5_Init();
uint32_t reads = 0;
while (1)
{
Gyro_CanReadWHOAMI();
}
}
Using STM32F429I-DISC1

Solved, wrong values
uint8_t Gyro_CanReadWHOAMI() {
uint8_t pTxData[2] = {0b10000000 | 0x0F, 0};
uint8_t pRxData[2] = {0, 0};
HAL_GPIO_WritePin(NCS_MEMS_SPI_GPIO_Port, NCS_MEMS_SPI_Pin, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi5, pTxData, pRxData, 2, HAL_MAX_DELAY);
HAL_GPIO_WritePin(NCS_MEMS_SPI_GPIO_Port, NCS_MEMS_SPI_Pin, GPIO_PIN_SET);
uint8_t test = pRxData[1] == 0xD4;
return test;
}

Related

Multiple write to external eeprom corrupts previous data

I am interfacing AT24C02 external eeprom using stm32f401 nucleo. I am facing few issues.
Lets consider some address
/* 24c02 Device Address */
#define EEPROM_ADDRESS (uint8_t)0xA0
/*Demo addr*/
#define DEMO_BYTE_ADDR (uint16_t)0x01
#define DEMO_WORD_ADDR (uint16_t)0x02
#define DEMO_FLOAT_ADDR (uint16_t)0x06
#define DEMO_STRING_ADDR (uint16_t)0x0A
1. Writing and reading simultaneously.
I am able to write and read data to and from eeprom simultaneously.
/*Writing Byte*/
uint8_t byte;
eep_write_byte(DEMO_BYTE_ADDR, 50);
eep_read_byte(DEMO_BYTE_ADDR, &byte);
/*Wrinting word*/
uint32_t word;
eep_write_word(DEMO_WORD_ADDR, 123456789);
word = eep_read_word(DEMO_WORD_ADDR);
/*Writing float*/
float fData;
eep_write_float(DEMO_FLOAT_ADDR, 9876.54);
fData = eep_read_float(DEMO_FLOAT_ADDR);
This code works fine. Below is the snapshot of output.
2. Problems with writing string
After the above portion of code i have written some lines to write string and read string. As you can see in output buffer dest contains some value.
uint8_t dest[50] = {0};
eep_write_string(DEMO_STRING_ADDR, (uint8_t*)"Hello World!", strlen("Hello World!"));
eep_read_string(DEMO_STRING_ADDR, dest, strlen("Hello World!"));
3. After writing all these values the reading shows corrupted data
After the above portion of the code if i read back all the addresses i have wrote gives me corrupted data.
eep_read_byte(DEMO_BYTE_ADDR, &byte);
word = eep_read_word(DEMO_WORD_ADDR);
fData = eep_read_float(DEMO_FLOAT_ADDR);
eep_read_string(DEMO_STRING_ADDR, dest, strlen("Hello World!"));
Below is the snapshot of out for this code.
As you can see all the data is now corrupted.
you can find eeprom.c from this link https://pastebin.com/2vYWYhnw or just scroll below.
/*
* eeprom.c
*
* Created on: 04-Jan-2021
* Author: DEVJEET MANDAL
*/
#include "i2c.h"
#include "eeprom.h"
#include "stdio.h"
#include "stdlib.h"
/* Low Level function */
void eep_small_delay(void) {
for (uint32_t i = 0; i < 65535; i++)
__asm__("NOP");
}
void i2c_error(void) {
HAL_I2C_DeInit(&hi2c1); //De-init i2c bus
__asm__("NOP");
HAL_I2C_Init(&hi2c1); //re-init i2c bus
__asm__("NOP");
}
eep_status_t i2c_write(uint16_t u8_reg_addr, uint8_t *u8_data, uint16_t len) {
HAL_StatusTypeDef xStatus = HAL_ERROR;
xStatus = HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDRESS, u8_reg_addr, I2C_MEMADD_SIZE_16BIT, u8_data, len, 100);
HAL_Delay(5);
if (xStatus != HAL_OK) {i2c_error();}
return xStatus;
}
eep_status_t i2c_read(uint16_t u8_reg_addr, uint8_t *u8_data, uint16_t len) {
HAL_StatusTypeDef xStatus = HAL_ERROR;
xStatus = HAL_I2C_Mem_Read(&hi2c1, EEPROM_ADDRESS, u8_reg_addr, I2C_MEMADD_SIZE_16BIT, u8_data, len, 100);
eep_small_delay();
if (xStatus != HAL_OK) {i2c_error();}
return xStatus;
}
/* High Level Functions */
eep_status_t eep_write_byte(uint16_t u8_reg_addr, uint8_t u8_data) {
return i2c_write(u8_reg_addr, &u8_data, 1);
}
eep_status_t eep_read_byte(uint16_t u8_reg_addr, uint8_t *u8_data) {
return i2c_read(u8_reg_addr, u8_data, 1);
}
eep_status_t eep_is_data_avaiable(void) {
eep_status_t xStatus = EEP_ERROR;
uint8_t data = 0;
eep_read_byte(EEPROM_DATA_AVAILABLE_ADDR, &data);
if (data == 0) {xStatus = EEP_ERROR;}
else if (data == 1) {xStatus = EEP_OK;}
else {xStatus = EEP_ERROR;}
return xStatus;
}
eep_status_t eep_set_data_available(uint8_t val) {
return eep_write_byte(EEPROM_DATA_AVAILABLE_ADDR, val);
}
eep_status_t eep_write_word(uint16_t reg_addr, uint32_t value) {
uint8_t val_byte[4] = {0};
val_byte[0] = (value >> 24) & 0xFF;
val_byte[1] = (value >> 16) & 0xFF;
val_byte[2] = (value >> 8) & 0xFF;
val_byte[3] = (value >> 0) & 0xFF;
return i2c_write(reg_addr, val_byte, 4);
}
eep_status_t eep_write_float(uint16_t reg_addr, float value) {
union FtoHex{
float fval;
uint32_t hval;
}float_to_hex;
float_to_hex.fval = value;
return eep_write_word(reg_addr, float_to_hex.hval);
}
uint32_t eep_read_word(uint16_t reg_addr) {
uint8_t val_buff[4] = {0};
i2c_read(reg_addr, val_buff, 4);
return ((val_buff[0] << 24) | (val_buff[1] << 16) | (val_buff[2] << 8) | (val_buff[3] << 0));
}
float eep_read_float(uint8_t reg_addr) {
union FtoHex{
float fval;
uint32_t hval;
}float_to_hex;
float_to_hex.hval = eep_read_word(reg_addr);
return float_to_hex.fval;
}
void eep_write_string(uint16_t reg_addr, uint8_t *src, uint16_t len) {
i2c_write(reg_addr, src, len);
}
void eep_read_string(uint16_t reg_addr, uint8_t *dest, uint16_t len) {
i2c_read(reg_addr, dest, len);
}
//---------------------------------------------------------------------
Almost forgot to mention i m running I2C #400Khz. Though i have tried 100KHz which results same.
Below is the HAL generated I2C init.
/* I2C1 init function */
void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 400000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
}
Now the question is why this problem. Basically the HAL should take care of all the situation and i will just send data to it. Any help will be appreciated.
Regards.
You missed that AT24C02 is organized in 16 byte (write) pages.
The corruption is caused by rollover/wrap # offset 0x0F when writing the string starting # offset 0x0A.
See the data sheet for details.

STM32F4 - Losting samples of FIFO data from max30100

I'm getting FIFO data from MAX30100 using the MCU STM32F4 to measure Heart Rate. In the signal received I can see the Heart Beat but also fails in the samples, as u can see below:
I'm dont have a filter working but the signal without filter was diferent when I did this on the Arduino board. Am I losting samples or it's normal? What I did wrong?
Datasheet MAX30100: https://img.filipeflop.com/files/download/Datasheet_MAX30100.pdf
Following my code:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_device.h"
/* Private define ------------------------------------------------------------*/
// FIFO registers
#define MAX30100_FIFO_W_POINTER 0x02
#define MAX30100_OVF_COUNTER 0x03
#define MAX30100_FIFO_R_POINTER 0x04
#define MAX30100_FIFO_DATA_REG 0x05
// configuration registers
#define MAX30100_MODE_CONFIG 0x06
#define MAX30100_SPO2_CONFIG 0x07
#define MAX30100_LED_CONFIG 0x09
// PART ID registers
#define MAX30100_PART_ID 0xFF
// MAX30100 I2C addresses
#define MAX30100_WADDRESS 0xAE // 8bit address converted to 7bit + W
#define MAX30100_RADDRESS 0xAF // 8bit address converted to 7bit + R
/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c3;
char buffer[30];
unsigned long ir_buff[16] = {0}, red_buff[16] = {0};
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C3_Init(void);
uint8_t CDC_Transmit_FS(char* Buf, uint16_t Len);
uint8_t MAX30100_getNumSamp(uint16_t* ir_buff, uint16_t* red_buff);
uint8_t MAX30100_getPartID(void);
void MAX30100_reset(void);
void MAX30100_wakeup(void);
void MAX30100_SetHR (void);
void MAX30100_InitFIFO (void);
void MAX30100_setLEDs(uint8_t ledCurrentRed, uint8_t ledCurrentIr);
void MAX30100_setSR(uint8_t sr);
void MAX30100_setPW (uint8_t pw);
uint8_t MAX30100_read (uint8_t device_register);
void MAX30100_write (uint8_t device_register, uint8_t reg_data);
int main(void)
{
uint8_t id;
uint8_t i;
uint8_t samples;
uint16_t ir_average = 0;
uint16_t red_average = 0;
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C3_Init();
MX_USB_DEVICE_Init();
HAL_Delay(10);
MAX30100_reset();
id = MAX30100_getPartID();
if (id == 0x11) //OK
// Set LED current
MAX30100_setLEDs(0x07, 0xFF);
// Set sample rate
MAX30100_setSR(0x00);
// Set pulse width
MAX30100_setPW(0x3);
// Set heart rate mode
MAX30100_SetHR ();
// Set RD and WR pointers to 0x00
MAX30100_InitFIFO();
// Wake up
MAX30100_wakeup();
while (1)
{
// Gets the number of samples in the FIFO and reads then
samples = MAX30100_getNumSamp((uint16_t*)ir_buff, (uint16_t*)red_buff);
if (samples > 0 )
{
// we have data in FIFO
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,1); //LED ON
ir_average = 0;
red_average = 0;
for (i = 0; i < samples; i++)
{
ir_average += (uint16_t)ir_buff[i];
red_average += (uint16_t)red_buff[i];
}
ir_average /= samples; // calculate the average value for this reading
red_average /= samples;
memset(buffer,0,sizeof(buffer));
sprintf(buffer, "HR: %d,", (uint16_t)ir_average);
CDC_Transmit_FS((char*)buffer, 20); //print the ir value to CDC
}
else
{
// There's no data in FIFO
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,0); //LED OFF
HAL_Delay(1); // Wait for samples to be aquired
}
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
}
static void MX_I2C3_Init(void)
{
hi2c3.Instance = I2C3;
hi2c3.Init.ClockSpeed = 400000;
hi2c3.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c3.Init.OwnAddress1 = 0;
hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c3.Init.OwnAddress2 = 0;
hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c3) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);
/*Configure GPIO pins : PC14 PC15 */
GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
// Reads from register 0xFF
// should return 0x11
uint8_t MAX30100_getPartID(void)
{
uint8_t reg;
reg = MAX30100_read (MAX30100_PART_ID);
return reg;
}
// Resets the MAX30100 IC
void MAX30100_reset(void)
{
uint8_t reg;
reg = MAX30100_read (MAX30100_MODE_CONFIG);
// RESET bit is B6
// 0x40 = 0100 0000
reg = (reg | 0x40); // Set reset bit to 1
MAX30100_write (MAX30100_MODE_CONFIG, reg);
}
// Wakes up the MAX30100
void MAX30100_wakeup(void)
{
uint8_t reg;
reg = MAX30100_read (MAX30100_MODE_CONFIG);
reg = reg & 0x7F; // Set SHDN bit to 0
MAX30100_write (MAX30100_MODE_CONFIG, reg);
}
// Sets Heart rate mode
// This means MODE{2:0} = 0b010 (or 0x02 in hexadecimal)
void MAX30100_SetHR (void)
{
uint8_t reg;
reg = MAX30100_read (MAX30100_MODE_CONFIG);
// RESET bit is B7
// First we clear bits 2:0
reg = reg & 0xF8;
// Then we set bits 2:0 to 0x02
reg = reg | 0x02;
MAX30100_write (MAX30100_MODE_CONFIG, reg);
}
// Initializes FIFO
// Sets RD and WR pointers to 0
// Clears OVF
void MAX30100_InitFIFO (void)
{
MAX30100_write (MAX30100_FIFO_W_POINTER, 0x00);
MAX30100_write (MAX30100_FIFO_R_POINTER, 0x00);
MAX30100_write (MAX30100_OVF_COUNTER, 0x00);
}
// Sets LED currents
void MAX30100_setLEDs(uint8_t ledCurrentRed, uint8_t ledCurrentIr)
{
uint8_t reg;
reg = ( ledCurrentRed << 4 ) | ledCurrentIr;
MAX30100_write (MAX30100_LED_CONFIG, reg);
}
// Sets sample rate
// sample rate is bits 4:2 of register MAX30100_SPO2_CONFIG
// bitmask is 0xE3
void MAX30100_setSR (uint8_t sr)
{
uint8_t reg;
reg = MAX30100_read (MAX30100_SPO2_CONFIG);
reg = reg & 0xE3;
reg = reg | (sr << 2);
MAX30100_write (MAX30100_SPO2_CONFIG, reg);
}
// Sets pulse width
// sample rate is bits 1:0 of register MAX30100_SPO2_CONFIG
void MAX30100_setPW (uint8_t pw)
{
uint8_t reg;
reg = MAX30100_read (MAX30100_SPO2_CONFIG);
reg = reg & 0xFC;
reg = reg | pw;
MAX30100_write (MAX30100_SPO2_CONFIG, reg);
}
// Gets number of samples in FIFO and read then
uint8_t MAX30100_getNumSamp(uint16_t* ir_buff, uint16_t* red_buff)
{
uint8_t wreg;
uint8_t rreg;
uint8_t sampleNum;
uint8_t samples[4];
wreg = MAX30100_read (MAX30100_FIFO_W_POINTER);
rreg = MAX30100_read (MAX30100_FIFO_R_POINTER);
sampleNum = (abs( 16 + wreg - rreg ) % 16);
if(sampleNum > 0)
{
//HAL_I2C_Mem_Read(&hi2c3,MAX30100_RADDRESS,MAX30100_FIFO_DATA_REG,4,(uint8_t*)samples,1,1000);
HAL_I2C_Mem_Read(&hi2c3,MAX30100_RADDRESS,MAX30100_FIFO_DATA_REG,1,&samples[0],1,250);
HAL_I2C_Mem_Read(&hi2c3,MAX30100_RADDRESS,MAX30100_FIFO_DATA_REG,1,&samples[1],1,250);
HAL_I2C_Mem_Read(&hi2c3,MAX30100_RADDRESS,MAX30100_FIFO_DATA_REG,1,&samples[2],1,250);
HAL_I2C_Mem_Read(&hi2c3,MAX30100_RADDRESS,MAX30100_FIFO_DATA_REG,1,&samples[3],1,250);
*(ir_buff) = (uint16_t)samples[1];
*(ir_buff++) |= (uint16_t)samples[0] << 8;
*(red_buff) = (uint16_t)samples[3];
*(red_buff++) |= (uint16_t) samples[2] << 8;
//HAL_Delay(7); // just test
}
return sampleNum;
}
// My I2C read and write functions
uint8_t MAX30100_read (uint8_t device_register )
{
uint8_t read_data;
HAL_I2C_Mem_Read(&hi2c3,MAX30100_RADDRESS,device_register,I2C_MEMADD_SIZE_8BIT,&read_data,1,250);
return read_data;
}
void MAX30100_write (uint8_t device_register, uint8_t reg_data)
{
HAL_I2C_Mem_Write(&hi2c3,MAX30100_WADDRESS,device_register,I2C_MEMADD_SIZE_8BIT,&reg_data,1,250);
}

MPU6050 not responding on address 0x68 but shows up in I2C Scanned addresses

When i run the I2C scanner on STM32F303, i see both devices connected to the bus. Names a device on address 0x3C (OLED) and address (0x68) MPU6050. Both addresses, specifically agree with what the datasheet says.
However, when i try to read the WHO_AM_I register on address 0x68 using HAL_I2C_IsDeviceReady, i realize that it even times out.
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init();
MX_SPI1_Init();
MX_TIM6_Init();
MX_USART1_UART_Init();
I2C_Scanner();
SSD1306_Init();
HAL_Delay (2000);
MPU6050_Init();
while (1)
{
}
}
Function (MPU6050_Init) to check if the device is ready
static void MPU6050_Init(void)
{
HAL_Delay(1);
SSD1306_Clear();
SSD1306_GotoXY (0, 0);
char OutputArray[50] = {0};
if(HAL_I2C_IsDeviceReady(&hi2c1, MPU6050_I2C_ADDR, 10, HAL_MAX_DELAY) != HAL_OK)
{
sprintf(OutputArray, "0x%02x : Not ready", MPU6050_I2C_ADDR);
}
else
{
HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_SET);
uint8_t check;
HAL_I2C_Mem_Read(&hi2c1, MPU6050_I2C_ADDR, WHO_AM_I_REG, 1, &check, 1, HAL_MAX_DELAY);
sprintf(OutputArray,"0x%02x", (uint16_t)check);
}
HAL_Delay(1);
SSD1306_Puts (OutputArray, &Font_7x10, SSD1306_COLOR_WHITE);
SSD1306_UpdateScreen();
}
Function (I2C_Scanner) to scan for I2C bus for available devices
static void I2C_Scanner(void)
{
HAL_StatusTypeDef result;
uint8_t i;
for (i = 1; i < 128; i++)
{
result = HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(i << 1), 1, HAL_MAX_DELAY);
char* period = ".";
char OutputArray[5];
if (result != HAL_OK) // HAL_ERROR or HAL_BUSY or HAL_TIMEOUT
{
HAL_UART_Transmit(&huart1, (uint8_t*)period, sizeof(period), HAL_MAX_DELAY);
}
if (result == HAL_OK)
{
sprintf(OutputArray, "0x%02x", i); // Received an ACK at that address
HAL_UART_Transmit(&huart1, (uint8_t*)OutputArray, sizeof(OutputArray), HAL_MAX_DELAY);
}
HAL_Delay(1);
}
}
Function (MC_I2C1_Init) to initialize the I2C
static void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x0000020B;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
Error_Handler();
}
}
The expected results would be to check that the device is available, ready and convey back the contents of the WHO_AM_I register
Found a solution. The problem was that i had defined the MPU6050 address as follows
#define MPU6050_I2C_ADDR 0x68
The correct definition should have been
#define MPU6050_I2C_ADDR 0x68 << 1
Which resulted in 0xD0

How to Interface STM32F302R8 with ADS1256 using spi communication?

I've tried interfacing the Nucleo-F302R8 and the High precision AD/DA waveshare board using SPI communication. While do so I'm unable to transmit or receive data. I've used spi3 for communication and gave a i/o for chip select pin. the spi_clk pin is not generating any clock pulse. I tried debugging spi through loop back and found that reception is happening at mosi pin but the again the clock is empty (checked using digital oscilloscope. I'm new to this environment and in need of great help. I've shared snippet my code below.
Spi configuration: 2lines, 8bit, polarity low, phase 1edge, msb first
void adc_write(uint8_t address, uint8_t value)
{
uint8_t data[3];
data[0] = 0x50|address;
data[1] = 0x01;
data[2] = value;
HAL_GPIO_WritePin(GPIOC, CHIP_SELECT_Pin, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi3, data,receive, 3, 50);
//DWT_Delay(10);
HAL_GPIO_WritePin(GPIOC, CHIP_SELECT_Pin, GPIO_PIN_SET);
}
void adc_write_command(uint8_t command)
{
HAL_GPIO_WritePin(GPIOC, CHIP_SELECT_Pin, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi3,&command,receive,1,50);
//DWT_Delay(10);
HAL_GPIO_WritePin(GPIOC, CHIP_SELECT_Pin, GPIO_PIN_SET);
}
int adc_read()
{
uint8_t datacon;
uint32_t convert = 0x00;
HAL_GPIO_WritePin(GPIOC, CHIP_SELECT_Pin, GPIO_PIN_RESET);
adc_write_command(0x01); //read
for(int i=0;i<3;i++)
{
HAL_SPI_TransmitReceive(&hspi3,0x00,&datacon,1,50);
convert |= datacon;
convert<<=8;
}
//DWT_Delay(10);
HAL_GPIO_WritePin(GPIOC, CHIP_SELECT_Pin, GPIO_PIN_SET);
return convert;
}
float volt(uint32_t data2)
{
float v;
v =(float) data2*0.000000596046; // 8388607 = +5.000v reference voltage
return v;
}
void adc_read_regis(uint8_t address1)
{
uint8_t data1[3];
data1[0] = 0x50|address1;
data1[1] = 0x01;
HAL_GPIO_WritePin(GPIOC, CHIP_SELECT_Pin, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi3, data1,receive, 2, 50);
HAL_SPI_TransmitReceive(&hspi3,0x00, &data1[2],1,50);
//DWT_Delay(10);
HAL_GPIO_WritePin(GPIOC, CHIP_SELECT_Pin, GPIO_PIN_SET);
}
void adc_reset()
{
HAL_GPIO_WritePin(GPIOC, CHIP_SELECT_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC, RESET_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOC, RESET_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, CHIP_SELECT_Pin, GPIO_PIN_SET);
}
void adc_init()
{
adc_write(0x00, 0x03); //status
adc_write(0x02, 0x20); //adcon
adc_write(0x03, 0x82); //drate 100sps
adc_read_regis(0x00); //verification
adc_write_command(0xF0); //selfcab of adc
adc_write(0x01, 0x0F); //mux for channel 0 positive
adc_write_command(0xFC); //sync
adc_write_command(0x00); //wake up
HAL_Delay(500);
}
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint32_t adc_data_ch0, adc_data_ch1;
float voltage_ch0, voltage_ch1;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI3_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
MX_GPIO_Init();
HAL_GPIO_WritePin(GPIOC, CHIP_SELECT_Pin, GPIO_PIN_RESET);
adc_reset();
HAL_Delay(500);
MX_SPI3_Init();
HAL_Delay(500);
adc_write_command(0xFE); //reset to power up values
adc_write_command(0xFC); //sync
adc_write_command(0x00); //wake up
//DWT_Delay(10);
adc_init();
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET); //confirm configuration
MX_USART2_UART_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_WritePin(GPIOC, CHIP_SELECT_Pin, GPIO_PIN_RESET);
while(HAL_GPIO_ReadPin(DRDY_GPIO_Port,DRDY_Pin));
adc_write(0x01, 0x1F); //mux for ch1 positive channel
adc_write_command(0xFC); //sync
adc_write_command(0x00); //wake up
adc_data_ch0 = adc_read();
voltage_ch0 = volt(adc_data_ch0);
HAL_Delay(100);
while(HAL_GPIO_ReadPin(DRDY_GPIO_Port,DRDY_Pin));
adc_write(0x01, 0x0F); //mux for ch0 positive channel
adc_write_command(0xFC); //sync
adc_write_command(0x00); //wake up
adc_data_ch1 = adc_read();
voltage_ch1 = volt(adc_data_ch1);
//frequency_in_ch1 = freq(voltage_in_ch1);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOC, CHIP_SELECT_Pin, GPIO_PIN_SET);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* USER CODE END 3 */
}

I2c communication stm32f3 how can i solve?

i want to read touch activity from the touchscreen.If i touch, i want to led blink. Some my definitions in below code but generally i want to get my activity with i2c
Some definitions:
uint8_t deviceaddr;
static uint32_t touch_i2c_read(uint8_t DeviceAddr, uint8_t RegAddr, uint8_t *pBuffer, uint16_t len);
static const int I2C_TIMEOUT = 65536;
unsigned char i2c_buffer[256];
uint32_t res;
This is my i2c read code:
static uint32_t touch_i2c_read(uint8_t DeviceAddr, uint8_t RegAddr, uint8_t *pBuffer, uint16_t len)
{ //uint8_t deviceaddr ,0x00,(uint8_t *)&buf, sizeof(buf)
uint32_t timeout = I2C_TIMEOUT;
while (I2C_GetFlagStatus(I2C1, I2C_ISR_BUSY) != RESET)
{
if ((timeout--) == 0)
return 0;
}
I2C_TransferHandling(I2C1, DeviceAddr << 1, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
/* !!! Wait until TXIS flag is set !!! */
timeout = I2C_TIMEOUT;
while (I2C_GetFlagStatus(I2C1, I2C_ISR_TXIS) == RESET)
{
if ((timeout--) == 0)
return 0;
}
}
This is my settings
void configure_interrupt_pins()
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
/*ENABLE CLOCK FOR GPIOX*/
RCC_APB1PeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
// ENABLE CLOCK FOR SYSCFG
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
//SET PIN AS INPUT
// init_pin(EX_NCVIC_PORT, EX_NCVIC_Pin, GPIO_MODE_INPUT, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP);
//TELL THE SYSTEM THAT YOU WILL USE PXX FOR EXTI_LineX
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOx, EXTI_PinSourcex);
//CONFIGIRATION of exti
EXTI_InitStruct.EXTI_Line = EXTI_Linex; //pxx connect to line x
EXTI_InitStruct.EXTI_LineCmd = ENABLE; //enable interrupt
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; //interrupt mode
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //triggers on rising and failing edge
EXTI_Init(&EXTI_InitStruct); //add to exti
//CONFIGURATION of nvic
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
This is my interrupt
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus((EXTI_Line0) != RESET))
{
res = touch_i2c_read(0x42, 0x00, i2c_buffer, 22);
printf("deneme");
if (!res)
{
GPIO_SetBits(GPIOE, GPIO_Pin_13);
}
else
{
GPIO_SetBits(GPIOE, GPIO_Pin_13);
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
But my code not working. Stm32 dont understand touch activity how can i solve this.
Edit i change line 1 every external interupts but i have res value 0 how can i fix this it must be different 0
Using a while() loop in an interrupt will cause problems, because the controller will never exit the loop. Try to use your i2c read Function in main() (with other words, a not-interrupt-context) and look if it works there.
I solved this error.
I hadn't any signal pb7 and pb6 so i changed codes as below:
// enable APB1 peripheral clock for I2C1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
// enable clock for SCL and SDA pins
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
And then,
Device adress of the FT6236 was mising. it is not include at datasheet so i used debugging. I found the device adress which is the (0x32). And than my code working succesfully.