BMP280 send wrong values - c

I try to read temperature from BMP280 but I take a wrong values. Temperature in my room approximately 22 degrees so I expect to receive approximately 2200. But my program send me 715.
I use SPI connection. CS pin is set by shift register. I am sure that it work. And this is my code:
main.c
/* USER CODE BEGIN Header */
/**
******************************************************************************
* #file : main.c
* #brief : Main program body
******************************************************************************
* #attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "func.h"
#include "BMP280.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi2;
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI2_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
/* 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 */
/* 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_SPI2_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
Init();
uint8_t id = 0;
BMP280_Data data;
uint8_t s[30] = {0};
uint8_t len = 0;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
ReadId(&id);
ReadAll(&data);
len = sprintf((char *)s, "Id: %i Temperature: %li ", id, data.temp);
HAL_UART_Transmit(&huart1, s, len, 0x1000);
HAL_Delay(2000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/**
* #brief SPI2 Initialization Function
* #param None
* #retval None
*/
static void MX_SPI2_Init(void)
{
/* USER CODE BEGIN SPI2_Init 0 */
/* USER CODE END SPI2_Init 0 */
/* USER CODE BEGIN SPI2_Init 1 */
/* USER CODE END SPI2_Init 1 */
/* SPI2 parameter configuration*/
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI2_Init 2 */
/* USER CODE END SPI2_Init 2 */
}
/**
* #brief USART1 Initialization Function
* #param None
* #retval None
*/
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
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();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
/**
* #brief GPIO Initialization Function
* #param None
* #retval None
*/
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_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, SR_OE_Pin|SR_L_Pin, GPIO_PIN_RESET);
/*Configure GPIO pins : SR_OE_Pin SR_L_Pin */
GPIO_InitStruct.Pin = SR_OE_Pin|SR_L_Pin;
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);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* #brief This function is executed in case of error occurrence.
* #retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* #brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* #param file: pointer to the source file name
* #param line: assert_param error line source number
* #retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
func.c
#include "func.h"
void sr(uint8_t *confBuf){
HAL_GPIO_WritePin(SR_OE_GPIO_Port, SR_OE_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_SPI_Transmit(&hspi2, confBuf, 2, 0x1000);
HAL_Delay(1);
HAL_GPIO_WritePin(SR_L_GPIO_Port, SR_L_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(SR_L_GPIO_Port, SR_L_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(SR_OE_GPIO_Port, SR_OE_Pin, GPIO_PIN_RESET);
HAL_Delay(10);
}
void dc(Devices d){
uint8_t ConfBuf[2] = {0b11111111, 0b11111111};
switch(d){
case(LSM6DSL_):
ConfBuf[0] = 0b11111110;
ConfBuf[1] = 0b11101110;
break;
case(BMP280_):
ConfBuf[0] = 0b11111101;
ConfBuf[1] = 0b11111010;
break;
default:
ConfBuf[0] = 0b11111111;
ConfBuf[1] = 0b11111111;
break;
}
sr(ConfBuf);
}
void spi_read_reg(Devices d, uint8_t Reg, uint8_t *Data, uint8_t len){
for(int i = 0; i < len; i++){
Reg |= 0b10000000;
dc(d);
HAL_SPI_Transmit(&hspi2, &Reg, 1, 0x1000);
HAL_SPI_Receive(&hspi2, Data, 1, 0x1000);
dc(0);
Reg++;
Data++;
}
}
void spi_write_reg(Devices d, uint8_t Reg, uint8_t *Data, uint8_t len){
for(int i = 0; i < len; i++){
Reg &= 0b01111111;
dc(d);
HAL_SPI_Transmit(&hspi2, &Reg, 1, 0x1000);
HAL_SPI_Transmit(&hspi2, Data, 1, 0x1000);
dc(0);
Reg++;
Data++;
}
}
func.h
#ifndef FUNC_H
#define FUNC_H
#include "main.h"
extern SPI_HandleTypeDef hspi2;
typedef enum {LSM6DSL_ = 1, BMP280_} Devices;
void sr(uint8_t *confBuf);
void dc(Devices d);
void spi_read_reg(Devices d, uint8_t Reg, uint8_t *Data, uint8_t len);
void spi_write_reg(Devices d, uint8_t Reg, uint8_t *Data, uint8_t len);
#endif
bmp280.c
#include "BMP280.h"
#include <stdio.h>
void Init(){
uint8_t conf[2] = {0b00100111, 0b00100000};
spi_write_reg(BMP280_, (uint8_t)CONFIG_L_REG, conf, 2);
}
void Reset(){
uint8_t data = (uint8_t)0xB6;
spi_write_reg(BMP280_, (uint8_t)RES_REG, &data, 1);
}
void ReadId(uint8_t *id){
spi_read_reg(BMP280_, (uint8_t)ID_REG, id, 1);
}
//0x88 / 0x89 dig_T1 unsigned short
//0x8A / 0x8B dig_T2 signed short
//0x8C / 0x8D dig_T3 signed short
//0x8E / 0x8F dig_P1 unsigned short
//0x90 / 0x91 dig_P2 signed short
//0x92 / 0x93 dig_P3 signed short
//0x94 / 0x95 dig_P4 signed short
//0x96 / 0x97 dig_P5 signed short
//0x98 / 0x99 dig_P6 signed short
//0x9A / 0x9B dig_P7 signed short
//0x9C / 0x9D dig_P8 signed short
//0x9E / 0x9F dig_P9 signed short
//0xA0 / 0xA reserved reserved
void ReadV(){
uint8_t Dig_T1[2] = {0};
uint8_t Dig_T2[2] = {0};
uint8_t Dig_T3[2] = {0};
uint8_t Dig_P1[2] = {0};
uint8_t Dig_P2[2] = {0};
uint8_t Dig_P3[2] = {0};
uint8_t Dig_P4[2] = {0};
uint8_t Dig_P5[2] = {0};
uint8_t Dig_P6[2] = {0};
uint8_t Dig_P7[2] = {0};
uint8_t Dig_P8[2] = {0};
uint8_t Dig_P9[2] = {0};
uint8_t Raw_data[6] = {0};
spi_read_reg(BMP280_, DIG_T1_L_REG, Dig_T1, 2);
dig_T1 = (Dig_T1[1] << 8) | Dig_T1[0];
spi_read_reg(BMP280_, DIG_T2_L_REG, Dig_T2, 2);
dig_T2 = (Dig_T2[1] << 8) | Dig_T2[0];
spi_read_reg(BMP280_, DIG_T3_L_REG, Dig_T3, 2);
dig_T3 = (Dig_T3[1] << 8) | Dig_T3[0];
spi_read_reg(BMP280_, DIG_P1_L_REG, Dig_P1, 2);
dig_P1 = (Dig_P1[1] << 8) | Dig_P1[0];
spi_read_reg(BMP280_, DIG_P2_L_REG, Dig_P2, 2);
dig_P2 = (Dig_P2[1] << 8) | Dig_P2[0];
spi_read_reg(BMP280_, DIG_P3_L_REG, Dig_P3, 2);
dig_P3 = (Dig_P3[1] << 8) | Dig_P3[0];
spi_read_reg(BMP280_, DIG_P4_L_REG, Dig_P4, 2);
dig_P4 = (Dig_P4[1] << 8) | Dig_P4[0];
spi_read_reg(BMP280_, DIG_P5_L_REG, Dig_P5, 2);
dig_P5 = (Dig_P5[1] << 8) | Dig_P5[0];
spi_read_reg(BMP280_, DIG_P6_L_REG, Dig_P6, 2);
dig_P6 = (Dig_P6[1] << 8) | Dig_P6[0];
spi_read_reg(BMP280_, DIG_P7_L_REG, Dig_P7, 2);
dig_P7 = (Dig_P7[1] << 8) | Dig_P7[0];
spi_read_reg(BMP280_, DIG_P8_L_REG, Dig_P8, 2);
dig_P8 = (Dig_P8[1] << 8) | Dig_P8[0];
spi_read_reg(BMP280_, DIG_P9_L_REG, Dig_P9, 2);
dig_P9 = (Dig_P9[1] << 8) | Dig_P9[0];
spi_read_reg(BMP280_, DATA_L_REG, &Raw_data[0], 1);
spi_read_reg(BMP280_, DATA_L_REG+1, &Raw_data[1], 1);
spi_read_reg(BMP280_, DATA_L_REG+2, &Raw_data[2], 1);
spi_read_reg(BMP280_, DATA_L_REG+3, &Raw_data[3], 1);
spi_read_reg(BMP280_, DATA_L_REG+4, &Raw_data[4], 1);
spi_read_reg(BMP280_, DATA_L_REG+5, &Raw_data[5], 1);
raw_temp = Raw_data[0] << 12 | Raw_data[1] << 4 | Raw_data[2]>>4;
raw_pres = Raw_data[3] << 12 | Raw_data[4] << 4 | Raw_data[5]>>4;
}
int32_t CompensateTemp(int32_t adc_T){
int32_t var1, var2, T;
var1 = ((((adc_T>>3) - ((int32_t)dig_T1<<1))) * ((int32_t)dig_T2)) >> 11;
var2 = (((((adc_T>>4) - ((int32_t)dig_T1)) * ((adc_T>>4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}
int32_t CompensatePres(int32_t adc_P){
int64_t var1, var2, p;
var1 = ((int64_t)t_fine) - 128000;
var2 = var1 * var1 * (int64_t)dig_P6;
var2 = var2 + ((var1*(int64_t)dig_P5)<<17);
var2 = var2 + (((int64_t)dig_P4)<<35);
var1 = ((var1 * var1 * (int64_t)dig_P3)>>8) + ((var1 * (int64_t)dig_P2)<<12);
var1 = (((((int64_t)1)<<47)+var1))*((int64_t)dig_P1)>>33;
if(var1 == 0){
return 0; // avoid exception caused by division by zero
}
p = 1048576-adc_P;
p = (((p<<31)-var2)*3125)/var1;
var1 = (((int64_t)dig_P9) * (p>>13) * (p>>13)) >> 25;
var2 = (((int64_t)dig_P8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((int64_t)dig_P7)<<4);
return (uint32_t)p;
}
void ReadAll(BMP280_Data *data){
ReadV();
data->raw_temp = raw_temp;
data->raw_pres = raw_pres;
data->temp = CompensateTemp(raw_temp);
data->pres = CompensatePres(raw_pres);
}
bmp280.h
#ifndef BMP280_H
#define BMP280_H
#include "func.h"
extern UART_HandleTypeDef huart1;
#define ID_REG 0xD0
#define RES_REG 0x0E
#define DIG_T1_L_REG 0x88
#define DIG_T2_L_REG 0x8A
#define DIG_T3_L_REG 0x8C
#define DIG_P1_L_REG 0x8E
#define DIG_P2_L_REG 0x90
#define DIG_P3_L_REG 0x92
#define DIG_P4_L_REG 0x94
#define DIG_P5_L_REG 0x96
#define DIG_P6_L_REG 0x98
#define DIG_P7_L_REG 0x9A
#define DIG_P8_L_REG 0x9C
#define DIG_P9_L_REG 0x9E
#define DATA_L_REG 0xF7
#define CONFIG_L_REG 0xF4
#define TEMP_DIF 0
#define TEMP_COF 4
#define RES_DIF 0
#define PRES_COF 1
//0x88 / 0x89 dig_T1 unsigned short
//0x8A / 0x8B dig_T2 signed short
//0x8C / 0x8D dig_T3 signed short
//0x8E / 0x8F dig_P1 unsigned short
//0x90 / 0x91 dig_P2 signed short
//0x92 / 0x93 dig_P3 signed short
//0x94 / 0x95 dig_P4 signed short
//0x96 / 0x97 dig_P5 signed short
//0x98 / 0x99 dig_P6 signed short
//0x9A / 0x9B dig_P7 signed short
//0x9C / 0x9D dig_P8 signed short
//0x9E / 0x9F dig_P9 signed short
//0xA0 / 0xA reserved reserved
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
int32_t t_fine;
int32_t raw_temp;
int64_t raw_pres;
typedef struct{
int32_t raw_temp;
int32_t raw_pres;
int32_t temp;
int32_t pres;
}BMP280_Data;
void Reset();
void Init();
void ReadId(uint8_t *id);
void ReadV();
void ReadAll();
int32_t CompensateTemp(int32_t adc_T);
int32_t CompensatePres(int32_t adc_P);
#endif
I use Compensate formula from BMP280 datasheet.
Please help me and sorry for my bad english.

Related

Functions return successfully but BMX160 sensor does produce any data

I am implementing the bmi160 and bmm150 drivers from Bosch in order to get data from the BMX160 (pinout board made by DFRobot) because from what I have gathered. I changed the chip id to match the bmx160 chip id. Upon all the initializations I am given valid returns of 0 yet when I get to reading the data, I do not get good data from the chip. I have made sure the device is getting voltage and is found by my board (STM32F0). I2C clock is set to the standard mode with a default clock speed.
/* USER CODE BEGIN Header */
/**
******************************************************************************
* #file : main.c
* #brief : Main program body
******************************************************************************
* #attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "bmm150.h"
#include "bmi160.h"
#include <stdio.h>
// #include "stm32f0xx_hal_uart.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;
// UART_HandleTypeDef huart1;
struct bmi160_dev bmi;
struct bmm150_dev bmm;
struct bmm150_settings bmm_settings;
struct bmm150_mag_data mag;
struct bmi160_sensor_data accel;
struct bmi160_sensor_data gyro;
int8_t rslt, rslt1, rslt2, rslt3, rslt4, rslt5, rslt6, rslt7;
int8_t rslt_data, rslt_data1, rslt_data2;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
// static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
/* Auxiliary function declarations */
int8_t bmm150_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, void *intf_ptr);
int8_t bmm150_aux_write(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, void *intf_ptr);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t Buffer[25] = {0};
uint8_t Space[] = " - ";
uint8_t StartMSG[] = "Starting I2C Scanning: \r\n";
uint8_t EndMSG[] = "Done! \r\n\r\n";
int8_t user_i2c_read(uint8_t id, uint8_t reg_addr, uint8_t *data, uint16_t len)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
HAL_StatusTypeDef status = HAL_OK;
while (HAL_I2C_IsDeviceReady(&hi2c1, (uint8_t)(id << 1), 3, 100) != HAL_OK)
{
rslt = 0;
}
status = HAL_I2C_Master_Transmit(&hi2c1, (uint8_t)(id << 1), &reg_addr, 1, 1000);
if (status != HAL_OK)
{
rslt = (-1);
}
HAL_Delay(100);
status = HAL_I2C_Master_Receive(&hi2c1, (uint8_t)(id << 1), data, len, 10000);
if (status != HAL_OK)
{
rslt = (-1);
}
return rslt;
}
int8_t user_i2c_write(uint8_t id, uint8_t reg_addr, uint8_t *data, uint16_t len)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
HAL_StatusTypeDef status = HAL_OK;
while (HAL_I2C_IsDeviceReady(&hi2c1, (uint8_t)(id << 1), 3, 100) != HAL_OK)
{
}
uint8_t tx_buffer[len + 1];
tx_buffer[0] = reg_addr;
memcpy(&tx_buffer[1], data, len);
status = HAL_I2C_Master_Transmit(&hi2c1, (uint8_t)(id << 1), tx_buffer, len + 1, 1000);
if (status != HAL_OK)
{
rslt = (-1);
}
return rslt;
}
void user_delay_ms(uint32_t period)
{
HAL_Delay(period);
}
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t i = 0, ret;
/* 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_I2C1_Init();
// rslt = i2c_ping_device(&hi2c1, 0x00);
/* USER CODE BEGIN 2 */
bmi.id = BMI160_I2C_ADDR;
bmi.chip_id = BMI160_CHIP_ID;
bmi.intf = BMI160_I2C_INTF;
bmi.read = &user_i2c_read;
bmi.write = &user_i2c_write;
bmi.delay_ms = &user_delay_ms;
bmm.chip_id = BMM150_DEFAULT_I2C_ADDRESS;
bmm.intf = BMM150_I2C_INTF;
bmm.read = (bmm150_read_fptr_t)bmm150_aux_read;
bmm.write = (bmm150_write_fptr_t)bmm150_aux_write;
bmm.delay_us = &user_delay_ms;
bmm.intf_ptr = bmm.chip_id;
rslt = bmi160_init(&bmi);
// pingStatus = i2cs_ping_device(BMI160_I2C_ADDR);
bmi.aux_cfg.aux_sensor_enable = BMI160_ENABLE;
bmi.aux_cfg.aux_i2c_addr = bmm.chip_id;
bmi.aux_cfg.manual_enable = BMI160_ENABLE;
bmi.aux_cfg.aux_rd_burst_len = BMI160_AUX_READ_LEN_3;
rslt1 = bmi160_aux_init(&bmi);
rslt2 = bmm150_init(&bmm);
bmi.accel_cfg.odr = BMI160_ACCEL_ODR_100HZ;
bmi.accel_cfg.range = BMI160_ACCEL_RANGE_2G;
bmi.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
bmi.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
bmi.gyro_cfg.odr = BMI160_GYRO_ODR_100HZ;
bmi.gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS;
bmi.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
bmi.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE;
rslt3 = bmi160_set_sens_conf(&bmi);
bmm_settings.preset_mode = BMM150_PRESETMODE_REGULAR;
rslt4 = bmm150_set_presetmode(&bmm_settings, &bmm);
bmm_settings.pwr_mode = BMM150_POWERMODE_FORCED;
rslt5 = bmm150_set_op_mode(&bmm_settings, &bmm);
uint8_t aux_addr = 0x42;
uint8_t mag_data[8] = {0};
uint8_t index;
bmi.aux_cfg.aux_odr = 8;
rslt6 = bmi160_config_aux_mode(&bmi);
rslt7 = bmi160_set_aux_auto_mode(BMM150_REG_CHIP_ID, &bmi);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
user_delay_ms(100);
rslt_data = bmi160_get_sensor_data((BMI160_ACCEL_SEL | BMI160_GYRO_SEL), &accel, &gyro, &bmi);
rslt_data1 = bmi160_read_aux_data_auto_mode(mag_data, &bmi);
rslt_data2 = bmm150_aux_mag_data(mag_data, &mag, &bmm);
/* USER CODE END WHILE */
printf("****************\n");
printf("ACC X: %d, Y: %d, Z: %d\n", accel.x, accel.y, accel.z);
printf("GYRO X: %d, Y: %d, Z: %d\n", gyro.x, gyro.y, gyro.z);
printf("MAG X : %d Y : %d Z : %d\n", mag.x, mag.y, mag.z);
printf("################\n");
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_SYSCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/**
* #brief I2C1 Initialization Function
* #param None
* #retval None
*/
static void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x200009FE;
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();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
// static void MX_USART1_UART_Init(void)
// {
// /* USER CODE BEGIN USART1_Init 0 */
// /* USER CODE END USART1_Init 0 */
// /* USER CODE BEGIN USART1_Init 1 */
// /* USER CODE END USART1_Init 1 */
// 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;
// huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
// huart1.Init.OverSampling = UART_OVERSAMPLING_16;
// if (HAL_UART_Init(&huart1) != HAL_OK)
// {
// Error_Handler();
// }
// /* USER CODE BEGIN USART1_Init 2 */
// /* USER CODE END USART1_Init 2 */
// }
/**
* #brief GPIO Initialization Function
* #param None
* #retval None
*/
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* #brief This function is executed in case of error occurrence.
* #retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
int8_t bmm150_aux_read(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, void *intf_ptr)
{
int8_t rslt;
rslt = bmi160_aux_read(reg_addr, reg_data, len, &bmi);
return rslt;
}
int8_t bmm150_aux_write(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, void *intf_ptr)
{
int8_t rslt;
rslt = bmi160_aux_write(reg_addr, reg_data, len, &bmi);
return rslt;
}
#ifdef USE_FULL_ASSERT
/**
* #brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* #param file: pointer to the source file name
* #param line: assert_param error line source number
* #retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
The print statements in the while loop are supposed to provide the results. The Accel data and Gyro data both are 0 for x,y,z and 0 on the sensor time. The mag data provides -32768 for the x,y,z values. I have checked that all functions return 0 several times but still I am confused on why I am not getting good data. I am also using the latest code from Bosch's github repo for both the bmi160 and bmm150.
Here is the I2C configure that is called by the MX_12C1_INIT().
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (hi2c->Instance == I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
/**I2C1 GPIO Configuration
PB8 ------> I2C1_SCL
PB9 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
}
This is using a STM32F030R8T6 Processor that is supplied voltage by a st-link-v2.
When creating circuitry, a number of issues could arise during the process which we are not aware of. A common issue is powering one are of the circuit with one voltage and communicating with the circuit using a different voltage. Both sensor and PLC need to be running on same voltage over the comms channel / pins.
The next step to debugging a circuit in this case would be to ensure that your "breakout board" or the sensor have pull up resistors. I have always found (40-50 different samples) that I do not need to add pull up resistors to break out boards. I have never had to add any.
The next issue I usually run into is addressing. Most ICs / sensors have a mechanism which allows you to select which address to use. If you hold the voltage low (0v), it will have a certain address while if you hold the voltage high (3.3v or 5v or whatever) it might be a different address. If you failed to add any connector to the pin (floating), it will be invalid and sensor will not start.
Another common issue is protocol. Some chips enable certain protocols by default and you may need to modify the internal settings in order to change them. By protocol, I am referring to either I2C, SPI or U(S)ART. This is unlikely but I've added it for completeness.
The issue most people think is happening is that the sensor is fried due to ESD. The likelyhood of your circuit being damaged is wildly low and it is certainly stronger than you think. I doubt you have damaged the circuit in any way.
To answer further, i would certainly require a picture of your circuit as the driver code should not be an issue at all. I generally find that driver code, even when outdated or for an earlier model, will generally still gather simple data relative to the ealier model.

The function pointer is changing its own address

I am first time using function pointers and ran into a weird problem. I am writing a code for STM32G4xx. The main idea is to transmit and receive data through LPUART. I have implemented simple FSM to handle TX and RX. LPUART configured in DMA interrupt mode. I have typedef the function pointer and declared the three function pointer variables (ISR handles) in main.h file as follow:
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
/* USER CODE BEGIN ET */
typedef void (*_func_clbck)(void);
/* USER CODE END ET */
_func_clbck lpuart_tx_tc_isr_clback;
//_func_clbck lpuart_rx_rne_isr_clback;
_func_clbck lpuart_dma_tx_tc_isr_clback;
_func_clbck lpuart_dma_rx_tc_isr_clback;
/* USER CODE END Private defines */
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
The definition of the function pointer is in function MX_LPUART1_UART_Init() in the main.c file.
#include "main.h"
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
/* System interrupt init*/
/* SysTick_IRQn interrupt configuration */
NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),1, 0));
/** Configure the internal voltage reference buffer voltage scale
*/
LL_VREFBUF_SetVoltageScaling(LL_VREFBUF_VOLTAGE_SCALE1);
/** Enable the Internal Voltage Reference buffer
*/
LL_VREFBUF_Enable();
/** Configure the internal voltage reference buffer high impedance mode
*/
LL_VREFBUF_DisableHIZ();
/** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral
*/
LL_PWR_DisableUCPDDeadBattery();
/* 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_DMA_Init();
MX_LPUART1_UART_Init();
MX_RTC_Init();
/* USER CODE BEGIN 2 */
#ifdef LPUART_TEST
lpuart_init_test();
#endif
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
LL_GPIO_ResetOutputPin(GPIOC,LL_GPIO_PIN_6);
//LL_GPIO_SetOutputPin(GPIOC,LL_GPIO_PIN_6);
LL_mDelay(1);
uint8_t buf[9] ={'a','d','v',' ','l','o','w','\r','\n'};
//uint8_t buf[9] ={1,2,3,4,5,6,7,8,9};
#ifdef LPUART_TEST
uint16_t len_test[19] = {0,16,17,65535, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
for(uint16_t i = 0 ; i<19 ; i++){
set_len_rx_dma_buff(len_test[i]);
lpuart_rx_test();
}
#endif
static uint8_t once = 1;
while (1)
{
lpuart_task();
//delay_ms_DWT(1);
/*if(once){
once = 0;
lpuart_start_tx(buf, 9);
LL_mDelay(100);
}*/
if(1){
//lpuart_start_tx(buf, 9);
if(!lpuart_isTxBusy()){
lpuart_start_tx(buf, 9);
delay_ms_DWT(1);
if(!lpuart_isRxBusy()){
rxOldIndex += rxIndex;
if(rxOldIndex > 255){
rxOldIndex = 0;
rxIndex = 0;
}
rxIndex = RingBuffer_available(&lpuart_RX_ring_buff);
for(i = rxOldIndex ; i < (rxIndex+rxOldIndex) ; i++ ){
rxBuff[i] = RingBuffer_readMeas(&lpuart_RX_ring_buff);
}
}
}
}
//}
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* USER CODE END 3 */
}
static void MX_LPUART1_UART_Init(void)
{
/* USER CODE BEGIN LPUART1_Init 0 */
/* USER CODE END LPUART1_Init 0 */
LL_LPUART_InitTypeDef LPUART_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Peripheral clock enable */
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
/**LPUART1 GPIO Configuration
PB10 ------> LPUART1_RX
PB11 ------> LPUART1_TX
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_8;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_11;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_8;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* LPUART1 DMA Init */
/* LPUART1_TX Init */
LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_1, LL_DMAMUX_REQ_LPUART1_TX);
LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_HIGH);
LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_NORMAL);
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_BYTE);
LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_BYTE);
/* LPUART1_RX Init */
LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_2, LL_DMAMUX_REQ_LPUART1_RX);
LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_2, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PRIORITY_HIGH);
LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MODE_CIRCULAR);
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PDATAALIGN_BYTE);
LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MDATAALIGN_BYTE);
/* LPUART1 interrupt Init */
NVIC_SetPriority(LPUART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(LPUART1_IRQn);
/* USER CODE BEGIN LPUART1_Init 1 */
/* USER CODE END LPUART1_Init 1 */
LPUART_InitStruct.PrescalerValue = LL_LPUART_PRESCALER_DIV1;
LPUART_InitStruct.BaudRate = 9600;
LPUART_InitStruct.DataWidth = LL_LPUART_DATAWIDTH_8B;
LPUART_InitStruct.StopBits = LL_LPUART_STOPBITS_1;
LPUART_InitStruct.Parity = LL_LPUART_PARITY_NONE;
LPUART_InitStruct.TransferDirection = LL_LPUART_DIRECTION_TX_RX;
LPUART_InitStruct.HardwareFlowControl = LL_LPUART_HWCONTROL_NONE;
LL_LPUART_Init(LPUART1, &LPUART_InitStruct);
LL_LPUART_SetTXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8);
LL_LPUART_SetRXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8);
LL_LPUART_DisableFIFO(LPUART1);
LL_LPUART_SetTXRXSwap(LPUART1, LL_LPUART_TXRX_SWAPPED);
// LL_LPUART_EnableOverrunDetect(LPUART1);
// LL_LPUART_EnableDMADeactOnRxErr(LPUART1);
/* USER CODE BEGIN WKUPType LPUART1 */
/* USER CODE END WKUPType LPUART1 */
LL_LPUART_Enable(LPUART1);
/* Polling LPUART1 initialisation */
while((!(LL_LPUART_IsActiveFlag_TEACK(LPUART1))) || (!(LL_LPUART_IsActiveFlag_REACK(LPUART1))))
{
}
/* USER CODE BEGIN LPUART1_Init 2 */
//LL_LPUART_EnableIT_TXE_TXFNF(LPUART1);
/* Enable TC interrupts for RX */
/* Enable HT & TC interrupts for TX */
// LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
lpuart_tx_tc_isr_clback = LPUART_TX_TC_ISR_CALLBACK;
//lpuart_rx_rne_isr_clback = &LPUART_RX_RXNE_ISR_CALLBACK;
lpuart_dma_tx_tc_isr_clback = LPUART_DMA_TX_TC_CALLBACK;
lpuart_dma_rx_tc_isr_clback = LPUART_DMA_RX_TC_CALLBACK;
//LL_LPUART_EnableDirectionRx(LPUART1);
LL_LPUART_EnableDirectionTx(LPUART1);
//LL_LPUART_EnableIT_RXNE_RXFNE(LPUART1);
/* USER CODE END LPUART1_Init 2 */
}
In main function, in while loop, I am calling the lpuart_start_tx(buf, 9); function just after the if(!lpuart_isTxBusy()) statement. This causes change of the address of the function pointer lpuart_dma_rx_tc_isr_clback but other two function pointers don't change its addresses and work fine. When an intrrupt raised on the reception of the data, it tried to execute lpuart_dma_rx_tc_isr_clback which causes the hard fault because its address was modified. Note that if I call lpuart_start_tx(buf, 9); before if(!lpuart_isTxBusy()), then everything works fine. I don't understand what could be an issue.
I have checked the CFSR register and every time different flag was raised. I have noticed that out of three flags, such as IBUSERR, IACCVOIL, and INVSTATE, one of them was raised. I have not included the full main.c file.
LPUART FSM implementation is as follow:
lpuart.h file
#ifndef INC_LPUART_H_
#define INC_LPUART_H_
#include "ring_buffer.h"
#ifdef USE_FULL_ASSERT
#include "stm32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
uint8_t lpuart_start_tx(uint8_t* buff, uint16_t len );
uint8_t LPUART_isTxFinished(void);
void LPUART_clear_tx_finishedFlag();
uint8_t lpuart_isRxBusy(void);
uint8_t lpuart_isTxBusy(void);
void lpuart_task();
void LPUART_TX_TC_ISR_CALLBACK(void);
void LPUART_DMA_TX_TC_CALLBACK(void);
void LPUART_DMA_RX_TC_CALLBACK(void);
#endif /* INC_LPUART_H_ */
lpuart.c
#include "lpuart.h"
#include "string.h"
#include "stm32g4xx_ll_lpuart.h"
#include "stm32g4xx_ll_dma.h"
#define SIZE_TX_BUFF 256
#define SIZE_RX_BUFF 256
#define SIZE_DMA_RX_BUFF 64
static uint8_t rxBuf[SIZE_RX_BUFF];
static uint8_t rxDMA_Buf[SIZE_DMA_RX_BUFF];
static uint8_t txBuf[SIZE_TX_BUFF];
RingBuffer lpuart_RX_ring_buff;
static uint8_t* tempTxBuf;
static uint16_t txLen = 0;
static void setTxDataLengthDMA(uint16_t len);
static void lpuart_transmit();
static void lpuart_finished_tx();
static void no_action();
static void lpuart_rx();
static void check_rx_dma_buff();
static uint8_t ev_no_event(void);
static uint8_t ev_txtc(void);
static uint8_t ev_start_tx(void);
static uint8_t ev_dmatxtc(void);
static uint8_t ev_rx_read(void);
static uint8_t ev_buff_full(void);
typedef uint8_t (*t_event_func)(void);
typedef void(*t_action_func)(void);
typedef struct{
uint16_t txtc:1;
uint16_t tx_busy:1;
uint16_t dmatxtc:1;
uint16_t dmarxtc:1;
uint16_t start_tx:1;
uint16_t rx_read:1;
uint16_t buff_full:1;
uint16_t is_fsm_table_init:1;
uint16_t ext_rxBusyFlag:1;
}t_event;
typedef enum {INIT, READY, BUSY, COMPLETE, LPUART_ERROR}t_state;
typedef struct{
t_state present_state;
t_event_func event1;
t_event_func event2;
t_action_func action1;
t_action_func action2;
t_state next_state;
}t_fsm_row;
typedef struct{
t_state current_state;
t_state previous_state;
t_fsm_row stt_row[7];
uint16_t number_of_rows;
}t_fsm_table;
t_event lpuart_event;
uint8_t lpuart_isTxBusy(void){
return lpuart_event.tx_busy;
}
uint8_t lpuart_isRxBusy(){
return lpuart_event.ext_rxBusyFlag;
}
uint8_t ev_no_event(void){
return 1;
}
uint8_t ev_txtc(void){
return lpuart_event.txtc;
}
uint8_t ev_start_tx(void){
return lpuart_event.start_tx;
}
uint8_t ev_dmatxtc(void){
return lpuart_event.dmatxtc;
}
uint8_t ev_rx_read(void){
return lpuart_event.rx_read || lpuart_event.dmarxtc;
}
uint8_t ev_buff_full(void){
return lpuart_event.buff_full;
}
void no_action(){
return;
}
void lpuart_init(void){
memset(rxBuf, 0, (size_t)SIZE_RX_BUFF );
memset(rxDMA_Buf, 0, (size_t)SIZE_DMA_RX_BUFF );
memset(txBuf, 0, (size_t)SIZE_TX_BUFF );
RingBuffer_init(&lpuart_RX_ring_buff,rxBuf , (uint16_t)SIZE_RX_BUFF);
LL_LPUART_DisableIT_TC(LPUART1);
LL_LPUART_DisableIT_RXNE_RXFNE(LPUART1);
LL_LPUART_DisableDirectionRx(LPUART1);
LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_1); //tx
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1); //tx
LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_2); //rx
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2); //rx
/*TX buffer address attached to DMA channel1 */
LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_1,
(uint32_t)txBuf,
LL_LPUART_DMA_GetRegAddr(LPUART1, LL_LPUART_DMA_REG_DATA_TRANSMIT),
LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1));
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, SIZE_TX_BUFF);
/*RX buffer address attached to DMA channel2 */
LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_2,
LL_LPUART_DMA_GetRegAddr(LPUART1, LL_LPUART_DMA_REG_DATA_RECEIVE),
(uint32_t)rxDMA_Buf,
LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_2));
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, SIZE_DMA_RX_BUFF);
LL_LPUART_EnableDMAReq_RX(LPUART1);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_2); //rx
LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2); //rx
LL_LPUART_EnableDirectionRx(LPUART1);
lpuart_event.tx_busy = 0;
}
uint8_t lpuart_start_tx(uint8_t* buff, uint16_t len ){
if(!lpuart_event.tx_busy){
lpuart_event.tx_busy = 1;
if(len < SIZE_TX_BUFF){
lpuart_event.start_tx = 1;
tempTxBuf = buff;
txLen = len;
}else{
/* lpuart_event.start_tx = 0;
lpuart_event.buff_full = 1;*/
return 0;
}
return 1;
}else{
return 0;
}
}
void lpuart_transmit(){
memcpy(txBuf, tempTxBuf, txLen);
setTxDataLengthDMA(txLen);
LL_LPUART_EnableDMAReq_TX(LPUART1);
LL_LPUART_EnableDirectionTx(LPUART1);
LL_LPUART_EnableIT_TC(LPUART1);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
}
void lpuart_finished_tx(){
LL_LPUART_DisableIT_TC(LPUART1);
LL_LPUART_DisableDirectionTx(LPUART1);
LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DisableIT_TE(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
lpuart_event.txtc = 0;
lpuart_event.dmatxtc = 0;
lpuart_event.start_tx = 0;
lpuart_event.tx_busy = 0;
}
void setTxDataLengthDMA(uint16_t len){
LL_LPUART_DisableDirectionTx(LPUART1);
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
/* Clear all flags */
LL_DMA_ClearFlag_TC1(DMA1);
LL_DMA_ClearFlag_TE1(DMA1);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, len);
}
void check_rx_dma_buff(){
static uint16_t old_len = SIZE_DMA_RX_BUFF;
uint16_t current_len = LL_DMA_GetDataLength(DMA1, LL_DMA_CHANNEL_2);
if(old_len != current_len ){
if(current_len > 0){
lpuart_event.rx_read = 1;
}
}
old_len = current_len;
}
static uint16_t old_pos = 0;
uint16_t pos = 0;
void lpuart_rx(){
lpuart_event.ext_rxBusyFlag = 1;
if(lpuart_event.dmarxtc){
lpuart_event.dmarxtc = 0;
}
if(lpuart_event.rx_read){
lpuart_event.rx_read = 0;
}
pos = (uint16_t)SIZE_DMA_RX_BUFF - LL_DMA_GetDataLength(DMA1, LL_DMA_CHANNEL_2);
if(pos > SIZE_DMA_RX_BUFF ){
pos = SIZE_DMA_RX_BUFF;
}
if(pos != old_pos /* || (pos == 0 && old_pos == 0)*/){
if (pos > old_pos) {
RingBuffer_writeMeasBlock(&lpuart_RX_ring_buff,&rxDMA_Buf[old_pos],(pos - old_pos));
}else{
RingBuffer_writeMeasBlock(&lpuart_RX_ring_buff,&rxDMA_Buf[old_pos],((uint16_t)SIZE_DMA_RX_BUFF - old_pos));
if(pos > 0){
RingBuffer_writeMeasBlock(&lpuart_RX_ring_buff,&rxDMA_Buf[0],pos);
}
}
}
old_pos = pos;
lpuart_event.ext_rxBusyFlag = 0;
}
t_fsm_row rowInit = {INIT,ev_no_event, ev_no_event, lpuart_init, no_action, READY };
t_fsm_row rowReady = {READY,ev_start_tx, ev_no_event, lpuart_transmit, no_action, BUSY };
t_fsm_row rowBusy = {BUSY,ev_dmatxtc, ev_txtc, lpuart_finished_tx, no_action, READY};
t_fsm_table lpuart_fsm_table = {INIT,INIT, {}};
void fsm_table_init(){
lpuart_fsm_table.current_state = INIT;
lpuart_fsm_table.stt_row[0] = rowInit;
lpuart_fsm_table.stt_row[1] = rowReady;
lpuart_fsm_table.stt_row[2] = rowBusy;
lpuart_event.is_fsm_table_init = 1;
lpuart_fsm_table.number_of_rows = 3;
}
void lpuar_tx_fsm(){
uint8_t ev = 0;
for(uint16_t rowIndex = 0; rowIndex < lpuart_fsm_table.number_of_rows; rowIndex++){
if(lpuart_fsm_table.current_state == lpuart_fsm_table.stt_row[rowIndex].present_state){
ev = lpuart_fsm_table.stt_row[rowIndex].event1() && lpuart_fsm_table.stt_row[rowIndex].event2();
if(ev){
lpuart_fsm_table.stt_row[rowIndex].action1();
lpuart_fsm_table.stt_row[rowIndex].action2();
lpuart_fsm_table.current_state = lpuart_fsm_table.stt_row[rowIndex].next_state;
lpuart_fsm_table.previous_state = lpuart_fsm_table.stt_row[rowIndex].present_state;
}
}
}
}
void lpuar_read_task(){
check_rx_dma_buff();
if(ev_rx_read()){
lpuart_rx();
}
}
void lpuart_task(){
if(!lpuart_event.is_fsm_table_init){
fsm_table_init();
}
//else{
lpuar_tx_fsm();
lpuar_read_task();
//}
}
void LPUART_TX_TC_ISR_CALLBACK(void){
lpuart_event.txtc = 1;
LL_LPUART_ClearFlag_TC(LPUART1);
}
void LPUART_DMA_TX_TC_CALLBACK(void){
lpuart_event.dmatxtc = 1;
LL_DMA_ClearFlag_TC1(DMA1);
}
void LPUART_DMA_RX_TC_CALLBACK(void){
if(LL_DMA_IsActiveFlag_TC2(DMA1)){
LL_DMA_ClearFlag_TC2(DMA1);
lpuart_event.dmarxtc = 1;
lpuart_rx();
}
if(LL_DMA_IsActiveFlag_TE2(DMA1)){
LL_DMA_ClearFlag_TE2(DMA1);
}
}
Intrrupt routine file stm32g4xx_it.c:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32g4xx_it.h"
#include "lpuart.h"
extern _func_clbck lpuart_tx_tc_isr_clback;
//_func_clbck lpuart_rx_rne_isr_clback = LPUART_RX_RXNE_ISR_CALLBACK;
extern _func_clbck lpuart_dma_tx_tc_isr_clback;
extern _func_clbck lpuart_dma_rx_tc_isr_clback;
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
void DMA1_Channel2_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel2_IRQn 0 */
lpuart_dma_rx_tc_isr_clback();
//LPUART_DMA_RX_TC_CALLBACK();
/* USER CODE END DMA1_Channel2_IRQn 0 */
/* USER CODE BEGIN DMA1_Channel2_IRQn 1 */
/* USER CODE END DMA1_Channel2_IRQn 1 */
}
Some of the code I have ommitted here. I am sure that I have not fully understood how function pointers work. Could you please give me suggestions or a solution.
I am using:
language: C11
Compiler/build tools: GNU tools for STM32 (7-2018-q2-update)
IDE: STM32CubeIDE
Please let me know if you require more info. Thanks in advance.
As per #Lundin's suggestion, I have put a watchpoint on lpuart_dma_rx_tc_isr_clback function pointer variable. It exposed the out of index bug in my code. The bug is inside while loop in main.c.
rxIndex = RingBuffer_available(&lpuart_RX_ring_buff);
for(i = rxOldIndex ; i < (rxIndex+rxOldIndex) ; i++ ){
rxBuff[i] = RingBuffer_readMeas(&lpuart_RX_ring_buff);
....
}
It was also pointed out that function pointer variable shouldn't be in flash.

STM32L496ZG, 7 segments display task, SysTick interrut not called?

I made progress with the last task of blinking all leds over and over again.
Now I'm trying to show actual time (two modes, one showing time in HHMM and the second MMSS) on my 7 segments displayer.
Segments from A to G are responsible arefor digit "parts", DP is dot.
Connection between segments and pins is represented on board as follows:
A → GPIO_G[0]
B → GPIO_G[1]
C → GPIO_G[2]
D → GPIO_G[3]
E → GPIO_G[4]
F → GPIO_G[5]
G → GPIO_G[6]
DP → GPIO_G[9]
Base transistors NPN responsible for seeing of the digit:
DIG_1 → GPIO_B[2]
DIG_2 → GPIO_B[3]
DIG_3 → GPIO_B[4]
DIG_4 → GPIO_B[5]
I'm using JOY_UP and JOY_DOWN for change of mode:
JOY_UP → GPIO_E[2]
JOY_DOWN → GPIO_E[3]
Here is my code:
main.c
/* USER CODE BEGIN Header */
/**
******************************************************************************
* #file : main.c
* #brief : Main program body
******************************************************************************
* #attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */
void switchInit(void);
void baseTransistInit(void);
void segmentsInit();
/* 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 */
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
HAL_PWREx_EnableVddIO2();
switchInit();
baseTransistInit();
segmentsInit();
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
SysTick_Config(SystemCoreClock / 1000); // SysTick_Handler() called within 1ms
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
Error_Handler();
}
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/**
* #brief GPIO Initialization Function
* #param None
* #retval None
*/
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
}
/* USER CODE BEGIN 4 */
void switchInit(void)
{
GPIO_InitTypeDef Joys;
Joys.Mode = GPIO_MODE_INPUT;
Joys.Pin = GPIO_PIN_2 /* JOY_UP */ | GPIO_PIN_3 /* JOY_DOWN */;
Joys.Pull = GPIO_PULLUP;
Joys.Speed = GPIO_SPEED_LOW;
Joys.Alternate = 0;
HAL_GPIO_Init(GPIOE, &Joys);
}
void baseTransistInit(void)
{
GPIO_InitTypeDef Transistors;
Transistors.Mode = GPIO_MODE_OUTPUT_PP;
Transistors.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
Transistors.Pull = GPIO_NOPULL;
Transistors.Speed = GPIO_SPEED_LOW;
Transistors.Alternate = 0;
HAL_GPIO_Init(GPIOB, &Transistors);
}
void segmentsInit()
{
GPIO_InitTypeDef Segments;
Segments.Mode = GPIO_MODE_OUTPUT_PP;
Segments.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_9;
Segments.Pull = GPIO_NOPULL;
Segments.Speed = GPIO_SPEED_LOW;
Segments.Alternate = 0;
HAL_GPIO_Init(GPIOG, &Segments);
}
/* USER CODE END 4 */
/**
* #brief This function is executed in case of error occurrence.
* #retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* #brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* #param file: pointer to the source file name
* #param line: assert_param error line source number
* #retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
stm32l4xx_it.c:
/* USER CODE BEGIN Header */
/**
******************************************************************************
* #file stm32l4xx_it.c
* #brief Interrupt Service Routines.
******************************************************************************
* #attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32l4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define SEG_A 0
#define SEG_B 1
#define SEG_C 2
#define SEG_D 3
#define SEG_E 4
#define SEG_F 5
#define SEG_G 6
#define SEG_DP 9
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
int hourFirst = 1, hourSecond = 5;
int minuteFirst = 3, minuteSecond = 0;
int secondFirst = 0, secondSecond = 0;
int showHHMM = 0, showMMSS = 0;
int buttonMs = 0;
int buttonDelay = 500;
int miliSeconds = 0;
const uint16_t tableOfSegments[] = {
1 << SEG_A | 1 << SEG_B | 1 << SEG_C | 1 << SEG_D | 1 << SEG_E | 1 << SEG_F, // DIGIT 0
1 << SEG_B | 1 << SEG_C, // DIGIT 1
1 << SEG_A | 1 << SEG_B | 1 << SEG_E | 1 << SEG_D | 1 << SEG_G, // DIGIT 2
1 << SEG_A | 1 << SEG_B | 1 << SEG_C | 1 << SEG_D | 1 << SEG_E, // DIGIT 3
1 << SEG_B | 1 << SEG_C | 1 << SEG_G | 1 << SEG_F, // DIGIT 4
1 << SEG_A | 1 << SEG_F | 1 << SEG_G | 1 << SEG_C | 1 << SEG_D, // DIGIT 5
1 << SEG_A | 1 << SEG_F | 1 << SEG_G | 1 << SEG_C | 1 << SEG_D | 1 << SEG_E, // DIGIT 6
1 << SEG_A | 1 << SEG_B | 1 << SEG_C, // DIGIT 7
1 << SEG_A | 1 << SEG_B | 1 << SEG_C | 1 << SEG_D | 1 << SEG_E | 1 << SEG_F | 1 << SEG_G, // DIGIT 8
1 << SEG_A | 1 << SEG_B | 1 << SEG_C | 1 << SEG_D | 1 << SEG_F | 1 << SEG_G, // DIGIT 9
};
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
void changeSeconds();
void changeMinutes();
void changeHours();
void inputHandling();
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void changeSeconds()
{
if(secondSecond < 9)
secondSecond++;
else if(secondSecond == 9)
{
if(secondFirst < 5)
{
secondSecond = 0;
secondFirst++;
}
else // secondSecond == 9 && secondFirst == 5
{
secondSecond = 0;
secondFirst = 0;
changeMinutes();
}
}
}
void changeMinutes()
{
if(minuteSecond < 9)
minuteSecond++;
else if(minuteSecond == 9)
{
if(minuteFirst < 5)
{
minuteSecond = 0;
minuteSecond++;
}
else // minutesSecond == 9 && minutesFirst == 5
{
minuteSecond = 0;
minuteFirst = 0;
changeHours();
}
}
}
void changeHours()
{
if(hourFirst <= 1 && hourSecond < 9)
hourSecond++;
else if(hourFirst <= 1 && hourSecond == 9)
{
hourSecond = 0;
hourFirst++;
}
else if(hourFirst == 2 && hourSecond < 3)
hourSecond++;
else
{
hourSecond = 0;
hourFirst = 0;
}
}
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* #brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
while (1)
{
}
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* #brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/**
* #brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}
/**
* #brief This function handles Prefetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
/* USER CODE END W1_BusFault_IRQn 0 */
}
}
/**
* #brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
/* USER CODE END W1_UsageFault_IRQn 0 */
}
}
/**
* #brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */
/* USER CODE END SVCall_IRQn 0 */
/* USER CODE BEGIN SVCall_IRQn 1 */
/* USER CODE END SVCall_IRQn 1 */
}
/**
* #brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/**
* #brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
}
/**
* #brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
miliSeconds++;
inputHandling();
if((miliSeconds % 1000) == 0 || miliSeconds == 1)
{
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5, GPIO_PIN_RESET);
if(showHHMM)
{
if(miliSeconds / 1000 == 0)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[hourFirst], GPIO_PIN_SET);
}
else if(miliSeconds / 1000 == 1)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[hourSecond], GPIO_PIN_SET);
}
else if(miliSeconds / 1000 == 2)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[minuteFirst], GPIO_PIN_SET);
}
else if(miliSeconds / 1000 == 3)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[minuteSecond], GPIO_PIN_SET);
return;
}
else if(miliSeconds / 1000 == 4)
{
miliSeconds = 0;
}
changeSeconds();
}
else if(showMMSS)
{
if(miliSeconds / 1000 == 0)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[minuteFirst], GPIO_PIN_SET);
}
else if(miliSeconds / 1000 == 1)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[minuteSecond], GPIO_PIN_SET);
}
else if(miliSeconds / 1000 == 2)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[secondFirst], GPIO_PIN_SET);
}
else if(miliSeconds / 1000 == 3)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[secondSecond], GPIO_PIN_SET);
return;
}
else if(miliSeconds / 1000 == 4)
{
miliSeconds = 0;
}
changeSeconds();
}
}
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32L4xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32l4xx.s). */
/******************************************************************************/
/* USER CODE BEGIN 1 */
void inputHandling()
{
buttonMs++;
if(buttonMs < buttonDelay)
return;
if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2 ) == GPIO_PIN_RESET)
{
buttonMs = 0;
showMMSS = 1;
showHHMM = 0;
return;
}
else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) == GPIO_PIN_RESET)
{
buttonMs = 0;
showMMSS = 0;
showHHMM = 1;
return;
}
}
/* USER CODE END 1 */
My code in SysTick_Handler is just for the start (in the beginning I want to see if digits are correctly seen one by one within 1 second of change from digit to digit).
But... it doesn't work. My board is showing no change in my displayer after running my code. I can only guess that SysTick_Handler() isn't called at all, but I can't be sure.
Maybe you know what the problem is? Thanks in advance for all answers.

STM32 CAN RX interrupt not triggering

I have two STM32L432 nucleos which communicate via CAN.
One STM32 is running FreeRTOS and the other isn't.
The one that isn't can both receive and transmit correctly via CAN.
The one that is running FreeRTOS can only transmit via CAN.
The CAN configuration on the two are identical.
Have tried calling NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); before osKernelInitialize(); is called as stated in https://www.freertos.org/RTOS-Cortex-M3-M4.html however the function isn't recognized so I've changed it to
NVIC_SetPriorityGrouping( NVIC_PRIORITYGROUP_4 ); which compiles.
So the question is why arren't the CAN RX interrupt triggering on the Nucleo running FreeRTOS?
Nucleo running FreeRTOS:
#include "main.h"
#include "cmsis_os.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "gpsdriver.h"
#include "DCMotorDriver.h"
#include "mpu6050_driver.h"
#include "Transmit_driver.h"
#include "partcl_driver.h"
#include "circle_queue.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define PACKAGE_SIZE 8
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan1;
I2C_HandleTypeDef hi2c1;
TIM_HandleTypeDef htim2;
UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
/* Definitions for taskGPS */
osThreadId_t taskGPSHandle;
const osThreadAttr_t taskGPS_attributes = {
.name = "taskGPS",
.stack_size = 500 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for taskDCMotor */
osThreadId_t taskDCMotorHandle;
const osThreadAttr_t taskDCMotor_attributes = {
.name = "taskDCMotor",
.stack_size = 500 * 4,
.priority = (osPriority_t) osPriorityLow,
};
/* Definitions for taskMpu6050 */
osThreadId_t taskMpu6050Handle;
const osThreadAttr_t taskMpu6050_attributes = {
.name = "taskMpu6050",
.stack_size = 500 * 4,
.priority = (osPriority_t) osPriorityLow,
};
/* Definitions for taskParTcl */
osThreadId_t taskParTclHandle;
const osThreadAttr_t taskParTcl_attributes = {
.name = "taskParTcl",
.stack_size = 512 * 4,
.priority = (osPriority_t) osPriorityLow,
};
/* USER CODE BEGIN PV */
CAN_TxHeaderTypeDef CanTxHeader;
CAN_RxHeaderTypeDef CanRxHeader;
CAN_FilterTypeDef CanFilter;
struct Queue queueCANRX ={0,0,{0}};
GPS_FIX_DATA data = { 0 };
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_CAN1_Init(void);
static void MX_I2C1_Init(void);
static void MX_TIM2_Init(void);
void task_gps(void *argument);
void task_dcmotor(void *argument);
void task_mpu6050(void *argument);
void task_partcl(void *argument);
/* USER CODE BEGIN PFP */
void WatchdogHandler(){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
HAL_Delay(10);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
}
// This function is called from the CAN1_RX0_IRQHandler in STM32L4xx_it.c file
void receiveData() {
uint8_t buffer[PACKAGE_SIZE] = {0};
while (HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0) > 0) {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
if (!QueueFull(&queueCANRX)) { // Hvis køen ikke er fuld - Hvis der er en plads til at modtage en besked
HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &CanRxHeader, buffer); // Modtag beskeden og læg den i buffer
placeData_1(buffer);
/*
for(int i = 0; i < PACKAGE_SIZE; i++){
EnterQueue(&queueCANRX, buffer[i]); // Læg buffer ind i modtager-queuen
}*/
}
}
}
void placeData_1(uint8_t *p){
}
/* 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 */
/* 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_DMA_Init();
MX_USART1_UART_Init();
MX_CAN1_Init();
MX_I2C1_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
NVIC_SetPriorityGrouping( NVIC_PRIORITYGROUP_4 ); //NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
//NVIC_SetPriorityGrouping( 0 );
HAL_CAN_Start(&hcan1);
/* USER CODE END 2 */
/* Init scheduler */
osKernelInitialize();
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* creation of taskGPS */
taskGPSHandle = osThreadNew(task_gps, NULL, &taskGPS_attributes);
/* creation of taskDCMotor */
taskDCMotorHandle = osThreadNew(task_dcmotor, NULL, &taskDCMotor_attributes);
/* creation of taskMpu6050 */
taskMpu6050Handle = osThreadNew(task_mpu6050, NULL, &taskMpu6050_attributes);
/* creation of taskParTcl */
taskParTclHandle = osThreadNew(task_partcl, NULL, &taskParTcl_attributes);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_EVENTS */
/* add events, ... */
/* USER CODE END RTOS_EVENTS */
/* Start scheduler */
osKernelStart();
/* We should never get here as control is now taken by the scheduler */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
gps_init(&huart1, hdma_usart1_rx.Instance);
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Configure LSE Drive Capability
*/
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 36;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
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_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_I2C1;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/** Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
Error_Handler();
}
/** Enable MSI Auto calibration
*/
HAL_RCCEx_EnableMSIPLLMode();
}
/**
* #brief CAN1 Initialization Function
* #param None
* #retval None
*/
static void MX_CAN1_Init(void)
{
/* USER CODE BEGIN CAN1_Init 0 */
uint32_t ext_id = 0x00000000; // Den største værdi der kan være på MSB er 1
uint32_t mask = 0xFFFFFFE0;
CanFilter.FilterMode = CAN_FILTERMODE_IDMASK; // Vi vælger at bruge mask mode
CanFilter.FilterIdHigh = (ext_id & 0x1FFFFFFF) >> 13; // (ext_id << 3) >> 16; // Da vi har 32 bit ID, er dette de 16 MSB af ID
CanFilter.FilterIdLow = (ext_id << 3) | CAN_ID_EXT; // Da vi har 32 bit ID, er dette de 16 LSB af ID
CanFilter.FilterMaskIdHigh = (mask & 0x1FFFFFFF) >> 13;// << 5; // Maskens 16 MSB
CanFilter.FilterMaskIdLow = (mask << 3);// << 5 | 0x10; // Maskens 16 LSB
CanFilter.FilterScale = CAN_FILTERSCALE_32BIT; // ID er et 32 bit-tal
CanFilter.FilterActivation = ENABLE; // Vi aktiverer filteret
CanFilter.FilterBank = 0; // Vi vælger filter 0 ud af 14 mulige filtre
CanFilter.FilterFIFOAssignment = CAN_FILTER_FIFO0; // Vi vælger FIFO0 til forskel for FIFO1
CanTxHeader.DLC = PACKAGE_SIZE; // Der kommer 8 byte som data i beskeden
CanTxHeader.ExtId = 0x00000000; // 32 bit ID (29 er identifier)
CanTxHeader.IDE = CAN_ID_EXT; // Vi har et extended ID = 32 bit til forskel fra standard på 16 bit (11 er identifier)
CanTxHeader.RTR = CAN_RTR_DATA; // Vi sender data
CanTxHeader.TransmitGlobalTime = DISABLE; // Der skal IKKE sendes et timestamp med hver besked
CanRxHeader.DLC = PACKAGE_SIZE;
CanRxHeader.ExtId = 0x0;
CanRxHeader.IDE = CAN_ID_EXT;
CanRxHeader.RTR = CAN_RTR_DATA;
CanRxHeader.FilterMatchIndex = 0x00;
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 18;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_7TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_8TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = ENABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = ENABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
while (HAL_CAN_ConfigFilter(&hcan1, &CanFilter) != HAL_OK) {}
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_CAN_Start(&hcan1);
/* USER CODE END CAN1_Init 2 */
}
/**
* #brief I2C1 Initialization Function
* #param None
* #retval None
*/
static void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x10808DD3;
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();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
/**
* #brief TIM2 Initialization Function
* #param None
* #retval None
*/
static void MX_TIM2_Init(void)
{
/* USER CODE BEGIN TIM2_Init 0 */
/* USER CODE END TIM2_Init 0 */
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
/* USER CODE BEGIN TIM2_Init 1 */
/* USER CODE END TIM2_Init 1 */
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 5000;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM2_Init 2 */
/* USER CODE END TIM2_Init 2 */
HAL_TIM_MspPostInit(&htim2);
}
/**
* #brief USART1 Initialization Function
* #param None
* #retval None
*/
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
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;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
}
/**
* #brief GPIO Initialization Function
* #param None
* #retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_RESET);
/*Configure GPIO pins : PA0 PA1 PA2 PA3
PA4 PA5 PA6 PA7 */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : PA8 */
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : LD3_Pin */
GPIO_InitStruct.Pin = LD3_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LD3_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PH3 */
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI3_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI3_IRQn);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/* USER CODE BEGIN Header_task_gps */
/**
* #brief Function implementing the taskGPS thread.
* #param argument: Not used
* #retval None
*/
/* USER CODE END Header_task_gps */
void task_gps(void *argument)
{
/* USER CODE BEGIN 5 */
gps_init(&huart1, hdma_usart1_rx.Instance);
/* Infinite loop */
for (;;) {
//sendGPS(&hcan1, &CanTxHeader);
//int8_t result = readGPS(&data);
osDelay(1000);
}
osThreadTerminate(NULL);
/* USER CODE END 5 */
}
/* USER CODE BEGIN Header_task_dcmotor */
/**
* #brief Function implementing the taskDCMotor thread.
* #param argument: Not used
* #retval None
*/
/* USER CODE END Header_task_dcmotor */
void task_dcmotor(void *argument)
{
/* USER CODE BEGIN task_dcmotor */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END task_dcmotor */
}
/* USER CODE BEGIN Header_task_mpu6050 */
/**
* #brief Function implementing the taskMpu6050 thread.
* #param argument: Not used
* #retval None
*/
/* USER CODE END Header_task_mpu6050 */
void task_mpu6050(void *argument)
{
/* USER CODE BEGIN task_mpu6050 */
HAL_StatusTypeDef status = MPU_Init(&hi2c1);
/* Infinite loop */
for (;;) {
float temp = MPU_Read_Temp();
Axes3 accel = MPU_Read_Accel();
Axes3 gyro = MPU_Read_Gyro();
osDelay(900);
}
/* USER CODE END task_mpu6050 */
}
/* USER CODE BEGIN Header_task_partcl */
/**
* #brief Function implementing the taskParTcl thread.
* #param argument: Not used
* #retval None
*/
/* USER CODE END Header_task_partcl */
void task_partcl(void *argument)
{
/* USER CODE BEGIN task_partcl */
partcl_init();
/* Infinite loop */
for(;;)
{
//partcl_update();
osDelay(1);
}
/* USER CODE END task_partcl */
}
/**
* #brief Period elapsed callback in non blocking mode
* #note This function is called when TIM7 interrupt took place, inside
* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
* a global variable "uwTick" used as application time base.
* #param htim : TIM handle
* #retval None
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* USER CODE BEGIN Callback 0 */
/* USER CODE END Callback 0 */
if (htim->Instance == TIM7) {
HAL_IncTick();
}
/* USER CODE BEGIN Callback 1 */
/* USER CODE END Callback 1 */
}
Nucleo NOT running FreeRTOS:
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "circle_queue.h"
#include "stdio.h"
#include "string.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define PACKAGE_SIZE 8
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan1;
UART_HandleTypeDef huart2;
/* USER CODE BEGIN PV */
CAN_FilterTypeDef CanFilter;
CAN_RxHeaderTypeDef CanRxHeader;
CAN_TxHeaderTypeDef CanTxHeader;
struct Queue queueCANRX ={0,0,{0}};
//GPS DATA ID'S
uint32_t GPS_ID1 = 0x1;
uint32_t GPS_ID2 = 0x2;
uint32_t GPS_ID3 = 0x3;
uint32_t GPS_ID4 = 0x4;
// Recieved GPS data from CubeSAT
float GPS_LAT = 0.;
char GPS_LAT_DIR = '$';
float GPS_LON = 0.;
char GPS_LON_DIR = '$';
uint8_t GPS_QUALITY = 0;
uint8_t GPS_HOURS = 0;
uint8_t GPS_MINUTES = 0;
uint8_t GPS_SEC = 0;
float GPS_HDOP = 0;
float GPS_ALTITUDE = 0.;
float GPS_H_GEOID = 0;
//Recieved MPU data from CubeSAT
float MPU_ACCELX = 0.;
float MPU_ACCELY = 0.;
float MPU_ACCELZ = 0.;
float MPU_GYROX = 0.;
float MPU_GYROY = 0.;
float MPU_GYROZ = 0.;
float MPU_TEMP = 0.;
//Recieved MOTOR data from CubeSAT
uint8_t MOTOR_DUTYCYCLE = 0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_CAN1_Init(void);
/* USER CODE BEGIN PFP */
/* 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 */
/* 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_USART2_UART_Init();
MX_CAN1_Init();
/* USER CODE BEGIN 2 */
// HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
uint8_t sendDataArray[PACKAGE_SIZE] = {2, 2, 2, 2, 2, 2, 2, 2};
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Configure LSE Drive Capability
*/
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 36;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
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_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/** Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
Error_Handler();
}
/** Enable MSI Auto calibration
*/
HAL_RCCEx_EnableMSIPLLMode();
}
/**
* #brief CAN1 Initialization Function
* #param None
* #retval None
*/
static void MX_CAN1_Init(void)
{
/* USER CODE BEGIN CAN1_Init 0 */
uint32_t ext_id = 0x00000000; // Den største værdi der kan være på MSB er 1
uint32_t mask = 0xFFFFFFE0;
CanFilter.FilterMode = CAN_FILTERMODE_IDMASK; // Vi vælger at bruge mask mode
CanFilter.FilterIdHigh = (ext_id & 0x1FFFFFFF) >> 13; // (ext_id << 3) >> 16; // Da vi har 32 bit ID, er dette de 16 MSB af ID
CanFilter.FilterIdLow = (ext_id << 3) | CAN_ID_EXT; // Da vi har 32 bit ID, er dette de 16 LSB af ID
CanFilter.FilterMaskIdHigh = (mask & 0x1FFFFFFF) >> 13;// << 5; // Maskens 16 MSB
CanFilter.FilterMaskIdLow = (mask << 3);// << 5 | 0x10; // Maskens 16 LSB
CanFilter.FilterScale = CAN_FILTERSCALE_32BIT; // ID er et 32 bit-tal
CanFilter.FilterActivation = ENABLE; // Vi aktiverer filteret
CanFilter.FilterBank = 0; // Vi vælger filter 0 ud af 14 mulige filtre
CanFilter.FilterFIFOAssignment = CAN_FILTER_FIFO0; // Vi vælger FIFO0 til forskel for FIFO1
CanRxHeader.DLC = PACKAGE_SIZE;
CanRxHeader.ExtId = 0x0;
CanRxHeader.IDE = CAN_ID_EXT;
CanRxHeader.RTR = CAN_RTR_DATA;
CanRxHeader.FilterMatchIndex = 0x00;
CanTxHeader.DLC = PACKAGE_SIZE; // Der kommer 8 byte som data i beskeden
CanTxHeader.ExtId = 0x00000000; // 32 bit ID (29 er identifier)
CanTxHeader.IDE = CAN_ID_EXT; // Vi har et extended ID = 32 bit til forskel fra standard på 16 bit (11 er identifier)
CanTxHeader.RTR = CAN_RTR_DATA; // Vi sender data
CanTxHeader.TransmitGlobalTime = DISABLE; // Der skal IKKE sendes et timestamp med hver besked
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
__HAL_RCC_CAN1_CLK_ENABLE();
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 18;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_7TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_8TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = ENABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = ENABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
while (HAL_CAN_ConfigFilter(&hcan1, &CanFilter) != HAL_OK) {}
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_CAN_Start(&hcan1);
/* USER CODE END CAN1_Init 2 */
}
/**
* #brief GPIO Initialization Function
* #param None
* #retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|LD3_Pin|GPIO_PIN_7, GPIO_PIN_RESET);
/*Configure GPIO pin : PA6 */
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PB0 LD3_Pin PB7 */
GPIO_InitStruct.Pin = GPIO_PIN_0|LD3_Pin|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : PB6 */
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
void receiveData() {
uint8_t buffer[PACKAGE_SIZE] = {0};
while (HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0) > 0) {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
if (!QueueFull(&queueCANRX)) { // Hvis køen ikke er fuld - Hvis der er en plads til at modtage en besked
HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &CanRxHeader, buffer); // Modtag beskeden og læg den i buffer
placeData_1(buffer);
/*
for(int i = 0; i < PACKAGE_SIZE; i++){
EnterQueue(&queueCANRX, buffer[i]); // Læg buffer ind i modtager-queuen
}*/
}
}
}
void transmitData(struct Queue *Data)
{
int writePointer = Data -> pointWR;
int readPointer = Data -> pointRD;
char str[3] = {0};
uint8_t tempo = 0;
int bytesToRead = writePointer - readPointer;
for (int i = 0 ; i < bytesToRead ; i++){
if ((i % 255) == 0) HAL_UART_Transmit(&huart2, "___", 3, 100);
LeaveQueue(Data, &tempo);
sprintf(str, "%d", tempo);
HAL_UART_Transmit(&huart2, &str, strlen(str), 100);
}
}
/* USER CODE END 4 */

stm32f4 CAN receiver_IT issue

Next in my little project(stm32f407vg) is to receive can messages from another hardware(PIC 18L25K80)
I currently have working an UART to my computer so I can easily debug the chip via UART.
The problem is that I receive the message, the interruption gets triggered but what I read from rxMessage is non sense.
Test Procedure:
Simulating the emitter I use Microchip CAN BUS Analayzer, here is the screenshot of the window:
And here is what I see in the UART:
And this is what I see if I debug (I'm using Coocox 1.7.8):
Why the values of rxMessage doesn't change neither inside the HAL driver or in my code (can.c).
Thanks.
---------------------------- main.c-------------------------
#include "globals.h"
#include "stm32f4xx_hal.h"
#include "syscfg.h"
#include "can.h"
#include "usart.h"
#include "gpio.h"
#include "kernel.h"
#include <stdio.h>
int main(void){
SysIniCfg();
while (1){
kernelMotor();
usartMotor();
canMotor();
HAL_GPIO_TogglePin(LED_G_GPIO_Port,LED_G_Pin);
}
}
------------------------- end main.c -----------------------
---------------------------- syscfg.c-------------------------
#include "syscfg.h"
#include "syscfg.h"
#include "can.h"
#include "usart.h"
#include "gpio.h"
#include "kernel.h"
/*
* System Init configuration
*/
void SysIniCfg(){
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN1_Init();
MX_USART1_UART_Init();
/* Initialize interrupts */
MX_NVIC_Init();
kernelInit();
}
------------------------- end syscfg.c -----------------------
---------------------------- can.h-------------------------
#include "stm32f4xx_hal.h"
#include "globals.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
typedef struct
{
CAN_HandleTypeDef Handle;
HAL_CAN_StateTypeDef *pState;
uint32_t *pErrorCode;
} t_can_control;
typedef enum{
CM_STOPPED = 0,
CM_INIT = 1,
CM_IDLE = 10,
CM_ERROR = 255
}uint8_t_canStates;
uint8_t_canStates canMotorStates;
extern CAN_HandleTypeDef hcan1;
t_can_control can_ctrl;
CanTxMsgTypeDef sTxMsg;
CanRxMsgTypeDef sRxMsg;
/* USER CODE END Private defines */
/* USER CODE BEGIN Prototypes */
extern void Error_Handler(void);
void MX_CAN1_Init(void);
------------------------- end can.h -----------------------
---------------------------- can.c-------------------------
#include "can.h"
#include "usart.h"
#include "gpio.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
CAN_HandleTypeDef hcan1;
/* CAN1 init function */
void MX_CAN1_Init(void)
{
CAN_FilterConfTypeDef sFilterConfig;
canMotorStates = CM_STOPPED;
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 20;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SJW = CAN_SJW_1TQ;
hcan1.Init.BS1 = CAN_BS1_13TQ;
hcan1.Init.BS2 = CAN_BS2_2TQ;
hcan1.Init.TTCM = DISABLE;
hcan1.Init.ABOM = DISABLE;
hcan1.Init.AWUM = DISABLE;
hcan1.Init.NART = DISABLE;
hcan1.Init.RFLM = DISABLE;
hcan1.Init.TXFP = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK){
Error_Handler();
}
sFilterConfig.FilterNumber = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = 0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 14;
if(HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK){
Error_Handler();
}
}
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */
/* USER CODE END CAN1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_CAN1_CLK_ENABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = 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_AF9_CAN1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN CAN1_MspInit 1 */
canMotorStates = CM_INIT;
/* USER CODE END CAN1_MspInit 1 */
}
}
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspDeInit 0 */
/* USER CODE END CAN1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CAN1_CLK_DISABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* Peripheral interrupt Deinit*/
HAL_NVIC_DisableIRQ(CAN1_TX_IRQn);
HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
HAL_NVIC_DisableIRQ(CAN1_SCE_IRQn);
}
/* USER CODE BEGIN CAN1_MspDeInit 1 */
canMotorStates = CM_STOPPED;
/* USER CODE END CAN1_MspDeInit 1 */
}
/**
* #brief Sends order for reading and reads an amount of data in no-blocking mode with Interrupt.
* #param u8can: Number of CAN instance
* #param u16std_id: CAN standard identifier
* #param pstate: Pointer to CAN state
* #param pu32error: Pointer to CAN error code
* #retval HAL status
*/
HAL_StatusTypeDef CAN_Read_wInt(uint8_t u8can, uint16_t u16std_id, HAL_CAN_StateTypeDef *pstate, uint32_t *pu32error){
HAL_StatusTypeDef status = HAL_OK;
if ((*pu32error) == HAL_CAN_ERROR_NONE)
{
/* Set Rx Message structure */
sRxMsg.StdId = (uint32_t)u16std_id;
sRxMsg.IDE = CAN_ID_STD;
sRxMsg.RTR = CAN_RTR_DATA;
sRxMsg.DLC = (uint8_t)8;
sRxMsg.FIFONumber = CAN_FIFO0;
sRxMsg.FMI = 1;
/* Put structure in the handle */
can_ctrl.Handle.pRxMsg = &sRxMsg;
/* Order to transmit in non-blocking mode */
status = HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0);
if (status == HAL_OK)
{
/* Link external pointers to CAN local pointer */
can_ctrl.pState = pstate;
can_ctrl.pErrorCode = pu32error;
/* Update CAN State */
*(can_ctrl.pState) = HAL_CAN_STATE_BUSY_RX;
}
}
else
{
status = HAL_BUSY;
}
return status;
}
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle)
{
HAL_GPIO_TogglePin(LED_Y_GPIO_Port,LED_Y_Pin);
char canOutBuffer[100];
sprintf(canOutBuffer,"-- %d : %d --", CanHandle->pRxMsg->StdId,CanHandle->pRxMsg->Data[0]);
usartPutString(canOutBuffer);
if(HAL_CAN_Receive_IT(CanHandle, CAN_FIFO0) != HAL_OK){
Error_Handler();
}
}
------------------------- end can.c -----------------------
---------------------------- main.c-------------------------
------------------------- end main.c -----------------------
I found what I was missing, in the definition of the can handle was specified the tx and rx message, so I suppose that the HAL drivers didn't do the initialization of this structures
void MX_CAN1_Init(void) {
CAN_FilterConfTypeDef sFilterConfig;
static CanTxMsgTypeDef TxMessage;
static CanRxMsgTypeDef RxMessage;
canMotorStates = CM_STOPPED;
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 20;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SJW = CAN_SJW_1TQ;
hcan1.Init.BS1 = CAN_BS1_13TQ;
hcan1.Init.BS2 = CAN_BS2_2TQ;
hcan1.Init.TTCM = DISABLE;
hcan1.Init.ABOM = DISABLE;
hcan1.Init.AWUM = DISABLE;
hcan1.Init.NART = DISABLE;
hcan1.Init.RFLM = DISABLE;
hcan1.Init.TXFP = DISABLE;
hcan1.pRxMsg = &RxMessage;
hcan1.pTxMsg = &TxMessage;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
sFilterConfig.FilterNumber = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = 0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 14;
if(HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
}
}

Resources