STM32F4 - Losting samples of FIFO data from max30100 - stm32

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);
}

Related

PWM input capture and repeat. STM32F4

guys.
I generated PWM signal with timer TIM1.
I want get this PWM from TIM1 with timer TIM2 and repeat it on the some GPIO pin.
I used Standart Peripheral Library.
PWM has generated on pin PA8 with timer TIM1 successfully, but i can't receive this PWM signal from PA0 pin with TIM2.
(PA8 и PA0 i connected with cable.)
Help me, please.
type here
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_tim.h"
#include "misc.h"
#include <stdio.h>
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM1_TimeBaseStruct;
TIM_OCInitTypeDef TIM1_OCInitStruct;
TIM_ICInitTypeDef TIM_ICInitStruct;
volatile uint16_t capture1 = 0, capture2 = 0;
volatile uint8_t capture_is_first = 1, capture_is_ready = 0;
const uint32_t myPeriod = 61538 - 1;
const uint32_t myPrescaler = 1 - 1;
const uint32_t myPulse = 5000;
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// Generate PWM on PA8
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// Input capture PWM on PA0
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1);
TIM1_TimeBaseStruct.TIM_Period = myPeriod;
TIM1_TimeBaseStruct.TIM_Prescaler = myPrescaler;
TIM1_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM1_TimeBaseStruct);
TIM1_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM1_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM1_OCInitStruct.TIM_Pulse = myPulse;
TIM1_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM1_OCInitStruct.TIM_OCNPolarity = TIM_OutputState_Disable;
TIM1_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1, &TIM1_OCInitStruct);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
TIM_Cmd(TIM1, ENABLE);
TIM_TimeBaseInitTypeDef timer_base;
TIM_TimeBaseStructInit(&timer_base);
timer_base.TIM_Prescaler = 24000 - 1;
TIM_ICInitTypeDef timer_ic;
timer_ic.TIM_Channel = TIM_Channel_1;
timer_ic.TIM_ICPolarity = TIM_ICPolarity_Rising;
timer_ic.TIM_ICSelection = TIM_ICSelection_DirectTI;
timer_ic.TIM_ICPrescaler = TIM_ICPSC_DIV1;
timer_ic.TIM_ICFilter = 0;
TIM_ICInit(TIM2, &timer_ic);
TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
NVIC_EnableIRQ(TIM2_IRQn);
/* Включаем таймер */
TIM_Cmd(TIM2, ENABLE);
while (1)
{
}
} // main
void TIM2_IRQHandler(void)
{
int i = 0;
i++;
printf("I'm TIM2 IRQ Handler.");
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
capture1 = capture2;
capture2 = TIM_GetCapture1(TIM2);
if (!capture_is_first)
capture_is_ready = 1;
capture_is_first = 0;
if (TIM_GetFlagStatus(TIM2, TIM_FLAG_CC1OF) != RESET)
{
TIM_ClearFlag(TIM2, TIM_FLAG_CC1OF);
// ...
}
}
}
I wrote the receive (input capture) PWM signal code using examples from the Internet, but i can't debug this. Help please. I'm new to embedded dev.

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.

Why USART transmits incorrect data as the APB1 frequency changes. (RCC <= 21MHz)

I want to use the USART communication protocol in my project. Communication is provided but incorrect data is sent (STM> PC).
I'd try:
Boundrade bands are the same.
Suitable combinations of PLL Source Mux (HSI-HSE) and System Clock Mux (HSI-HSE-PLLCLK) were tested. Available: HSE and PLLCLK
APB1 Clock frequency was changed within the allowed range. It was observed that the data obtained at each change also changed. Sometimes STM sent very fast data.
The STM card was fed from a different source and tested by ground equalization.
Note-1: Codes do not include the entire project. In this case, the problem that I mentioned occurs.
#include "main.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "stm32f4xx_hal.h"
#include "defines.h"
#include "tm_stm32_disco.h"
#include "tm_stm32_delay.h"
#include "tm_stm32_lis302dl_lis3dsh.h"
#include "stm32f4xx.h"
#include "arm_math.h"
#define PID_PARAM_KP 100
#define PID_PARAM_KI 0.025
#define PID_PARAM_KD 0
float pid_error;
extern UART_HandleTypeDef huart1;
char* bufftr="Hello\n\r";
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
TM_LIS302DL_LIS3DSH_t Axes_Data;
MX_GPIO_Init();
MX_TIM1_Init();
MX_SPI1_Init();
MX_USART1_UART_Init();
__HAL_UART_ENABLE_IT(&huart1, UART_IT_TC);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
SystemInit();
TM_DELAY_Init();
TM_DISCO_LedInit();
if (TM_LIS302DL_LIS3DSH_Detect() == TM_LIS302DL_LIS3DSH_Device_LIS302DL) {
TM_DISCO_LedOn(LED_GREEN | LED_RED);
TM_LIS302DL_LIS3DSH_Init(TM_LIS302DL_Sensitivity_2_3G, TM_LIS302DL_Filter_2Hz);
} else if (TM_LIS302DL_LIS3DSH_Detect() == TM_LIS302DL_LIS3DSH_Device_LIS3DSH) {
TM_DISCO_LedOn(LED_BLUE | LED_ORANGE);
TM_LIS302DL_LIS3DSH_Init(TM_LIS3DSH_Sensitivity_2G, TM_LIS3DSH_Filter_800Hz);
} else {
TM_DISCO_LedOn(LED_GREEN | LED_RED | LED_BLUE | LED_ORANGE);
while (1);
}
Delayms(300);
TM_DISCO_LedOff(LED_ORANGE);
TM_DISCO_LedOff(LED_BLUE);
arm_pid_instance_f32 PID;
PID.Kp = PID_PARAM_KP;
PID.Ki = PID_PARAM_KI;
PID.Kd = PID_PARAM_KD;
arm_pid_init_f32(&PID, 1);
TM_GPIO_SetPinLow(GPIOD, GPIO_Pin_12);
TM_GPIO_SetPinLow(GPIOD, GPIO_Pin_14);
while (1){
HAL_UART_Transmit_IT(&huart1, (uint8_t *)bufftr, 8);
HAL_Delay(500);
}
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_SCALE1);
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 = 4;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
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_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK){
Error_Handler();
}
}
static void MX_USART1_UART_Init(void){
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK){
Error_Handler();
}
}
static void MX_GPIO_Init(void){
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
}
void Error_Handler(void){
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line){
}
#endif
Note-2: The problem does not occur when I create and run a project containing only USART when all the conditions are the same.
Note-3: I do not receive any error messages or warning messages.
SystemInit() should be called in the reset handler only
This function is supposed to reset the system clock to a default state, running directly from HSI at 16 MHz.
You are calling it in the middle of main(), when USART1 is already configured assuming a higher clock speed. There is no telling what the peripheral would do when its clock source is changed on the fly.

spi master fires uncontrollable dma tc interrupts without receiving nothing

I've already asked this question on the mbed forum, but I did not received an answer.
Introduction
I have two Nucleo L432kc board, I want to make them communicate with the SPI protocol using DMA.
In the following scheme you can see the actual hardware setup:
What works
If I send data from the master to the slave I receive them correctly and when the master is not transmitting the slave does not receive anything.
Master's code
#include <mbed.h>
uint8_t dma_buffer_tx[4];
uint8_t dma_buffer_rx[4];
uint8_t buff[4];
uint32_t receive_buff_length = 4;
unsigned int c = 0;
Serial pc(USBTX,USBRX,921600);
DigitalOut led(LED3);
SPI_HandleTypeDef hspi1;
DMA_HandleTypeDef hdma_spi1_rx;
DMA_HandleTypeDef hdma_spi1_tx;
void Error_Handler(){
led.write(1);
while(1){}
}
static void HAL_GPIO_Init(void){
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hspi1.Instance==SPI1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA1 ------> SPI1_SCK
PA11 ------> SPI1_MISO
PA12 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
else
Error_Handler();
}
static void SPI1_Init(void)
{
__HAL_RCC_SPI1_CLK_ENABLE();
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
/* SPI1 interrupt Init */
HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI1_IRQn);
}
static void DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* SPI1 DMA Init */
/* SPI1_RX Init */
hdma_spi1_rx.Instance = DMA1_Channel2;
hdma_spi1_rx.Init.Request = DMA_REQUEST_1;
hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_rx.Init.Mode = DMA_NORMAL;
hdma_spi1_rx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&hspi1,hdmarx,hdma_spi1_rx);
/* DMA interrupt init */
/* DMA1_Channel2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
/* SPI1 DMA Init */
/* SPI1_TX Init */
hdma_spi1_tx.Instance = DMA1_Channel3;
hdma_spi1_tx.Init.Request = DMA_REQUEST_1;
hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_tx.Init.Mode = DMA_NORMAL;
hdma_spi1_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_spi1_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&hspi1,hdmatx,hdma_spi1_tx);
/* DMA interrupt init */
/* DMA1_Channel3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
}
extern "C"{
void DMA1_Channel3_IRQHandler(void)
{
HAL_NVIC_ClearPendingIRQ(DMA1_Channel3_IRQn);
HAL_DMA_IRQHandler(&hdma_spi1_tx);
}
void DMA1_Channel2_IRQHandler(void)
{
HAL_NVIC_ClearPendingIRQ(DMA1_Channel2_IRQn);
HAL_DMA_IRQHandler(&hdma_spi1_rx);
}
void SPI1_IRQHandler(void)
{
HAL_SPI_IRQHandler(&hspi1);
}
}
void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi1){
for(int i = 0; i < receive_buff_length/2; i++){
buff[i] = dma_buffer_rx[i];
}
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi1){
for(int i = receive_buff_length/2; i < receive_buff_length; i++){
buff[i] = dma_buffer_rx[i];
}
printf("%u\n",*(unsigned int *)buff); // to understan when I am actually receiving data
memset(dma_buffer_rx,0,sizeof(dma_buffer_rx));
}
void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi1){
c += 5;
dma_buffer_tx[0] = c & 0xFF;
dma_buffer_tx[1] = (c >> 8) & 0xFF;
}
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi1){
dma_buffer_tx[2] = (c >> 16) & 0xFF;
dma_buffer_tx[3] = (c >> 24) & 0xFF;
}
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* SPI INIT */
SPI1_Init();
/* GPIO USART2 INIT */
HAL_GPIO_Init();
/* DMA INIT */
DMA_Init();
c = 1000;
dma_buffer_rx[0] = c & 0xFF;
dma_buffer_rx[1] = (c >> 8) & 0xFF;
dma_buffer_rx[2] = (c >> 16) & 0xFF;
dma_buffer_rx[3] = (c >> 24) & 0xFF;
while(true){
HAL_SPI_Transmit_DMA(&hspi1,dma_buffer_rx,receive_buff_length);
wait(0.001);
}
}
Slave's code
#include <mbed.h>
uint8_t dma_buffer_tx[4];
uint8_t dma_buffer_rx[4];
uint8_t buff[4];
uint32_t receive_buff_length = 4;
unsigned int c = 0;
Serial pc(USBTX,USBRX,921600);
DigitalOut led(LED3);
SPI_HandleTypeDef hspi1;
DMA_HandleTypeDef hdma_spi1_rx;
DMA_HandleTypeDef hdma_spi1_tx;
void Error_Handler(){
led.write(1);
while(1){}
}
static void HAL_GPIO_Init(void){
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hspi1.Instance==SPI1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA1 ------> SPI1_SCK
PA11 ------> SPI1_MISO
PA12 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
else
Error_Handler();
}
static void SPI1_Init(void)
{
__HAL_RCC_SPI1_CLK_ENABLE();
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_SLAVE;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
/* SPI1 interrupt Init */
HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI1_IRQn);
}
static void DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* SPI1 DMA Init */
/* SPI1_RX Init */
hdma_spi1_rx.Instance = DMA1_Channel2;
hdma_spi1_rx.Init.Request = DMA_REQUEST_1;
hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_rx.Init.Mode = DMA_NORMAL;
hdma_spi1_rx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&hspi1,hdmarx,hdma_spi1_rx);
/* DMA interrupt init */
/* DMA1_Channel2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
/* SPI1 DMA Init */
/* SPI1_TX Init */
hdma_spi1_tx.Instance = DMA1_Channel3;
hdma_spi1_tx.Init.Request = DMA_REQUEST_1;
hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_tx.Init.Mode = DMA_NORMAL;
hdma_spi1_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_spi1_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&hspi1,hdmatx,hdma_spi1_tx);
/* DMA interrupt init */
/* DMA1_Channel3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
}
extern "C"{
void DMA1_Channel3_IRQHandler(void)
{
HAL_NVIC_ClearPendingIRQ(DMA1_Channel3_IRQn);
HAL_DMA_IRQHandler(&hdma_spi1_tx);
}
void DMA1_Channel2_IRQHandler(void)
{
HAL_NVIC_ClearPendingIRQ(DMA1_Channel2_IRQn);
HAL_DMA_IRQHandler(&hdma_spi1_rx);
}
void SPI1_IRQHandler(void)
{
HAL_SPI_IRQHandler(&hspi1);
}
}
void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi1){
for(int i = 0; i < receive_buff_length/2; i++){
buff[i] = dma_buffer_rx[i];
}
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi1){
for(int i = receive_buff_length/2; i < receive_buff_length; i++){
buff[i] = dma_buffer_rx[i];
}
printf("%u\n",*(unsigned int *)buff); // to understan when I am actually receiving data
memset(dma_buffer_rx,0,sizeof(dma_buffer_rx));
}
void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi1){
c += 5;
dma_buffer_tx[0] = c & 0xFF;
dma_buffer_tx[1] = (c >> 8) & 0xFF;
}
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi1){
dma_buffer_tx[2] = (c >> 16) & 0xFF;
dma_buffer_tx[3] = (c >> 24) & 0xFF;
}
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* SPI INIT */
SPI1_Init();
/* GPIO USART2 INIT */
HAL_GPIO_Init();
/* DMA INIT */
DMA_Init();
c = 1000;
dma_buffer_rx[0] = c & 0xFF;
dma_buffer_rx[1] = (c >> 8) & 0xFF;
dma_buffer_rx[2] = (c >> 16) & 0xFF;
dma_buffer_rx[3] = (c >> 24) & 0xFF;
while(true){
HAL_SPI_Receive_DMA(&hspi1,dma_buffer_rx,receive_buff_length);
}
}
What does not work
If I change the role in the communication, so I send the data from the salve to the master swapping the following lines
[...]
HAL_SPI_Transmit_DMA(&hspi1,dma_buffer_rx,receive_buff_length);
wait(0.001);
[...]
with:
[...]
HAL_SPI_Receive_DMA(&hspi1,dma_buffer_rx,receive_buff_length);
[...]
Even if the slave is not powered up the master continusly receives interrupts and invokes the HAL_SPI_RxCpltCallback. If we power up the slave the master prints random numbers.
What I have already tried without success
I've tested the master code on a Nucleo F446 board.
I've set pull-down and pull-up resistors on the MISO pin.
I've tried different cable for the hw connection.
I've tried to directly use the HAL_SPI_TransmitReceive_DMA function, but the behaviour is the same.
Considerations
Walking throught the HAL_SPI_Receive_DMA source I've noticed that in the SPI_MODE_MASTER the HAL_SPI_TransmitReceive_DMA fuction is actually called.
I think that the same buffer is used for transmission and reception, but I don't know how to prove that.
I've also printed the hdma_spi1_rx.Instance->CNDTR and I've noticed that the value increments to 4 whitch is actually the number of bytes that we are going to receive.
SPI master always receives data when it is transmitting. This is how the SPI works. Even if the SPI is not transmitting, the master reads the data all the time.

STM32F4 Discovery Board as I2C Master - Can not get anything going through the SCL and SDA Lines

I am trying to use the STM32F4 discovery board as a master to communicate to a sensor using I2C. I am using the std periph library to do this but for some reason I am unable to get anything going through the SCL and SDA lines. From reading through the stf periph header files and other examples I have seen online it does not seem that I am doing anything wrong or forgetting a step. Below I have Included all of my I2C code:
#define I2CTransmitter 0
#define I2CReciever 1
#define I2CAckEnable 1
#define I2CAckDisable 0
void I2CInit() {
I2C_InitTypeDef I2CInitStruct;
GPIO_InitTypeDef GPIO;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOB, ENABLE);
//Configure and initialize the GPIOs
GPIO.GPIO_Pin = GPIO_Pin_6;
GPIO.GPIO_Mode = GPIO_Mode_AF;
GPIO.GPIO_Speed = GPIO_Speed_100MHz;
GPIO.GPIO_OType = GPIO_OType_OD;
GPIO.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO);
GPIO.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &GPIO);
//Connect GPIO pins to peripheral
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
I2CInitStruct.I2C_ClockSpeed = 100000;
I2CInitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2CInitStruct.I2C_Mode = I2C_Mode_I2C;
I2CInitStruct.I2C_OwnAddress1 = 0x00;
I2CInitStruct.I2C_Ack = I2C_Ack_Enable;
I2CInitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_Init(I2C1, &I2CInitStruct);
I2C_Cmd(I2C1, ENABLE);
}
uint8_t I2CRead(uint8_t address, uint8_t reg) {
uint8_t data;
I2CStart(address, I2CTransmitter, I2CAckEnable);
I2CWriteData(reg);
I2CStart(address, I2CReciever, I2CAckDisable);
data = I2CReadNAck();
I2CStop();
return data;
}
void I2CWrite(uint8_t address, uint8_t reg, uint8_t data) {
I2CStart(address, I2CTransmitter, I2CAckEnable);
I2CWriteData(reg);
I2CWriteData(data);
I2CStop();
}
void I2CStart(uint8_t address, uint8_t direction, uint8_t ack) {
I2C_GenerateSTART(I2C1, ENABLE);
I2C_Send7bitAddress(I2C1, address, direction);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_SLAVE_BYTE_RECEIVED));
}
void I2CStop() {
I2C_GenerateSTOP(I2C1, ENABLE);
}
void I2CWriteData(uint8_t data) {
I2C_SendData(I2C1, data);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_SLAVE_BYTE_RECEIVED));
}
uint8_t I2CReadAck() {
uint8_t data;
I2C_AcknowledgeConfig(I2C1, ENABLE);
while( !I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED) );
data = I2C_ReceiveData(I2C1);
return data;
}
uint8_t I2CReadNAck() {
uint8_t data;
I2C_AcknowledgeConfig(I2C1, DISABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
while( !I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED) );
data = I2C_ReceiveData(I2C1);
return data;
}
The code is used in the main function by simply calling I2CInit() and then calling I2CWrite() in a while loop for testing. Thank you in advance for any help!