toggling stm32 led using structure types - c

hello i am new with the stm32 board i am trying to toggle the user led that is connected to port A pin 5 (nucleo l476rg board) , I wrote this program from scratch using structure types but unfortunately the led is not blinking … I double checked all the addresses because i tried it without the structures and it worked , can any one tell me what’s the problem here ? here's the code:
// Port A
// pin 5
#include <stdint.h>
#define periph_base (0x40000000UL)
#define ahb2_offset (0x08000000UL)
#define ahb2_base (periph_base + ahb2_offset)
#define ahb1_offset (0x20000UL)
#define ahb1_base (periph_base + ahb1_offset)
#define gpioa_offset (0x000000UL)
#define gpioa_base (ahb2_base + gpioa_offset)
#define rcc_offset (0X1000UL)
#define rcc_base (ahb1_base + rcc_offset)
#define rcc_ahb2enr_offset (0x4CUL)
#define rcc_ahb2enr (*(volatile unsigned int *)(rcc_base +rcc_ahb2enr_offset))
#define gpioa_moder_offset (0x00UL)
#define gpioa_moder (*(volatile unsigned int*)(gpioa_base +gpioa_moder_offset))
#define odr_offset (0X14UL)
#define odr (*(volatile unsigned int*)(gpioa_base + odr_offset))
#define gpioa_en (1U<<0)
#define pin5 (1U<<5)
#define led_pin pin5
typedef struct
{
volatile uint32_t MODER;
volatile uint32_t DUMMY[4];
volatile uint32_t ODR;
}gpio_Typedef;
typedef struct
{
volatile uint32_t DUMMY[16];
volatile uint32_t AHB2ENR;
}rcc_Typedef;
#define RCC ((rcc_Typedef*) rcc_base)
#define GPIOA ((gpio_Typedef*) gpioa_base)
int main(void)
{
RCC->AHB2ENR |= gpioa_en;
GPIOA->MODER |= (1U<<10);
GPIOA->MODER &=~ (1U<<11);
while(1)
{
GPIOA->ODR ^= led_pin;
for(long int i =0; i<100000;i++){}
}
}

It appears that i had the wrong reference manual , in the rcc_Typedef Structure the dummy array should have 19 as size not 16 , there are 19 registers before the rcc_ahb2enr .

Related

Why don't I get HIGH on output pins of MCP23S17?

I use a STM32 connected with SPI to a MCP23S17 16 bit I/O port expander.
I want to make all 16 I/0 pins as output and just making them all LOW or HIGH.
I used an oscilloscope to check is SPI transmit the signals right, and it does.
The only thing is that on the I/O pins I get around 0.4V. Not 5V.
Sometimes I get a value of 1.4V but it goes away, weird thing...
Can somebody check my code and tell me where is my mistake? I am pretty sure I did the code wrong somewhere.
MCP23S17.h:
#ifndef INC_MCP23S17_H_
#define INC_MCP23S17_H_
#include "stm32f1xx_hal_conf.h"
extern SPI_HandleTypeDef hspi2;
void MCP23S17_SPI_Write(uint8_t reg_addr, uint8_t data);
uint8_t MCP23S17_SPI_Read(uint8_t data);
#define CS_HIGH() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
#define CS_LOW() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
#define MCP23S17_AAA ((uint8_t)0x0E)
#define MCP23S17_ADDRESS ((uint8_t)0x40)
#define MCP23S17_W ((uint8_t)0x00)
#define MCP23S17_R ((uint8_t)0x01)
#define MCP23S17_IODIRA ((uint8_t)0x00)
#define MCP23S17_IPOLA ((uint8_t)0x02)
#define MCP23S17_GPINTENA ((uint8_t)0x04)
#define MCP23S17_DEFVALA ((uint8_t)0x06)
#define MCP23S17_INTCONA ((uint8_t)0x08)
#define MCP23S17_IOCONA ((uint8_t)0x0A)
#define MCP23S17_GPPUA ((uint8_t)0x0C)
#define MCP23S17_INTFA ((uint8_t)0x0E)
#define MCP23S17_INTCAPA ((uint8_t)0x10)
#define MCP23S17_GPIOA ((uint8_t)0x12)
#define MCP23S17_OLATA ((uint8_t)0x14)
#define MCP23S17_IODIRB ((uint8_t)0x01)
#define MCP23S17_IPOLB ((uint8_t)0x03)
#define MCP23S17_GPINTENB ((uint8_t)0x05)
#define MCP23S17_DEFVALB ((uint8_t)0x07)
#define MCP23S17_INTCONB ((uint8_t)0x09)
//#define MCP23S17_IOCONB ((uint8_t)0x0B)
#define MCP23S17_GPPUB ((uint8_t)0x0D)
#define MCP23S17_INTFB ((uint8_t)0x0F)
#define MCP23S17_INTCAPB ((uint8_t)0x11)
#define MCP23S17_GPIOB ((uint8_t)0x13)
#define MCP23S17_OLATB ((uint8_t)0x15)
//#define MCP23S17_INT_ERR ((uint8_t)255)
//#define BANK ((uint8_t)0x80) //bit 7 of IOCON
//#define MIRROR ((uint8_t)0x40) //bit 6 of IOCON
//#define SEQOP ((uint8_t)0x20) //bit 5 of IOCON
//#define DISSLW ((uint8_t)0x10) //bit 4 of IOCON
//#define HAEN ((uint8_t)0x08) //bit 3 of IOCON
//#define ODR ((uint8_t)0x04) //bit 2 of IOCON
//#define INTPOL ((uint8_t)0x02) //bit 1 of IOCON
//#define unused ((uint8_t)0x00) //bit 0 of IOCON
//-----------------------
#define MCP23S17_MODERA_W(x) MCP23S17_SPI_Write(MCP23S17_IODIRA, ((uint8_t)x))
#define MCP23S17_MODERA_R() MCP23S17_SPI_Read(MCP23S17_IODIRA)
#define MCP23S17_IPOLA_W(x) MCP23S17_SPI_Write(MCP23S17_IPOLA, ((uint8_t)x))
#define MCP23S17_ODRA_W(x) MCP23S17_SPI_Write(MCP23S17_OLATA, ((uint8_t)x))
#define MCP23S17_ODRA_R() MCP23S17_SPI_Read(MCP23S17_OLATA)
#define MCP23S17_IDRA_R() MCP23S17_SPI_Read(MCP23S17_GPIOA) // Reflect the value of the port A
#define MCP23S17_PUDA_W(x) MCP23S17_SPI_Write(MCP23S17_GPPUA, ((uint8_t)x))
#define MCP23S17_PUDA_R() MCP23S17_SPI_Read(MCP23S17_GPPUA)
#define MCP23S17_SETUP_W(x) MCP23S17_SPI_Write(MCP23S17_IOCONA, ((uint8_t)x))
#define MCP23S17_SETUP_R() MCP23S17_SPI_Read(MCP23S17_IOCONA))
#define MCP23S17_MODERB_W(x) MCP23S17_SPI_Write(MCP23S17_IODIRB, ((uint8_t)x))
#define MCP23S17_MODERB_R() MCP23S17_SPI_Read(MCP23S17_IODIRB)
#define MCP23S17_IPOLB_W(x) MCP23S17_SPI_Write(MCP23S17_IPOLB, ((uint8_t)x))
#define MCP23S17_ODRB_W(x) MCP23S17_SPI_Write(MCP23S17_OLATB, ((uint8_t)x))
#define MCP23S17_ODRB_R() MCP23S17_SPI_Read(MCP23S17_OLATB)
#define MCP23S17_IDRB_R() MCP23S17_SPI_Read(MCP23S17_GPIOB) // Reflect the value of the port B
#define MCP23S17_PUDB_W(x) MCP23S17_SPI_Write(MCP23S17_GPPUB, ((uint8_t)x))
#define MCP23S17_PUDB_R() MCP23S17_SPI_Read(MCP23S17_GPPUB)
//-----------------------
void GPIO_Write_Pins(uint16_t);
void GPIO_Expander_Init();
void MCP23S17_SPI_Write(uint8_t reg_addr, uint8_t data);
#endif /* INC_MCP23S17_H_ */
MCP23S17.c
#include "main.h"
#include "MCP23S17.h"
void MCP23S17_SPI_Write(uint8_t reg_addr, uint8_t data)
{
uint8_t pBuff[3];
pBuff[0] = MCP23S17_ADDRESS|MCP23S17_AAA|MCP23S17_W; //optocode that contain 0100 + 111 + 0 (read command)
pBuff[1] = reg_addr; // register address
pBuff[2] = data; // the value that is modified on the register, check datasheet
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi2, pBuff, 3); //transmit on the spi2 the optocode, register adress and the value for the register
for(uint32_t i = 0; i < 85; i++) //delay
{}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
}
void GPIO_Expander_Init()
{
MCP23S17_SETUP_W(0x00);
MCP23S17_MODERA_W(0x00);
MCP23S17_MODERB_W(0x00);
MCP23S17_PUDA_W(0x00);
MCP23S17_PUDB_W(0x00);
//MCP23S17_IPOLA_W(0x00);
//MCP23S17_IPOLB_W(0x00);
}
void GPIO_Write_Pins(uint16_t dataspi)
{
//16 to 8 and 8
uint8_t data_half[2];
data_half[0]=*((uint8_t*)&(dataspi)+1); //split the first half of the data
data_half[1]=*((uint8_t*)&(dataspi)+0); //split the second half of the data
MCP23S17_ODRA_W(data_half[0]); //first half
MCP23S17_ODRB_W(data_half[1]); //second half
}
and in main.c
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
GPIO_Expander_Init();
GPIO_Write_Pins(0xFFFF);
while(1)
{
}
The only thing is that on the I/O pins I get around 0.4V
This is likely because GPIOs are not initialized.
You also have a different problem to deal with.
for(uint32_t i = 0; i < 85; i++) //delay
{}
This loop is very likely to be optimize away by the compiler. This is because, it doesn't do anything.
There are more sophisticated ways of generating delays in a microcontroller. The best possible solution would be to use a timer module.
So coming back with the solution, the code was good, 2 first gpio expanders that I tried were purely burned. For a much shorter working code just comment here asking for it. Thank everyone for advices cause I took them in consideration in the final form of code.

uint32_t does not name a type - VSCode with STM32 in Windows

I am currently writing code for a project, specifically interfacing with sensors via an STM32 Nucleo F411RE board. I set the pins/peripherals etc. using STM32CubeMX, then generated the code with the Makefile toolchain for programming in Visual Studio Code. Everything is compiling fine, but the IDE/Intellisense for some reason doesn't pick up any use of uint32_t; any occurences are red-squiggled, with the error reading variable "uint32_t" is not a type name.
I have #include <stdint.h> at the top, and uint16_t and uint8_t are both recognized in the same file. Peeking the definition of those reveals their lines in stdint.h, while the same does not work for uint32_t. I have attempted the solutions suggested here and here, neither of which worked.
I am working in C11 (not c++, which isn't an option for my project) on Windows, here is my c_cpp_properties.json file (with all the extra defines cut out for compactness):
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"databaseFilename": "${workspaceFolder}/.vscode/browse.vc.db",
"windowsSdkVersion": "10.0.17763.0",
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx64/x64/cl.exe",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64",
"compileCommands": "${workspaceFolder}/compile_commands.json"
}
],
"version": 4
}
Here is <stdint.h> - all types are clearly declared together, with no apparent condition for uint32_t:
#pragma once
#define _STDINT
#ifndef RC_INVOKED
#include <vcruntime.h>
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef signed char int_least8_t;
typedef short int_least16_t;
typedef int int_least32_t;
typedef long long int_least64_t;
typedef unsigned char uint_least8_t;
typedef unsigned short uint_least16_t;
typedef unsigned int uint_least32_t;
typedef unsigned long long uint_least64_t;
typedef signed char int_fast8_t;
typedef int int_fast16_t;
typedef int int_fast32_t;
typedef long long int_fast64_t;
typedef unsigned char uint_fast8_t;
typedef unsigned int uint_fast16_t;
typedef unsigned int uint_fast32_t;
typedef unsigned long long uint_fast64_t;
typedef long long intmax_t;
typedef unsigned long long uintmax_t;
// These macros must exactly match those in the Windows SDK's intsafe.h.
#define INT8_MIN (-127i8 - 1)
#define INT16_MIN (-32767i16 - 1)
#define INT32_MIN (-2147483647i32 - 1)
#define INT64_MIN (-9223372036854775807i64 - 1)
#define INT8_MAX 127i8
#define INT16_MAX 32767i16
#define INT32_MAX 2147483647i32
#define INT64_MAX 9223372036854775807i64
#define UINT8_MAX 0xffui8
#define UINT16_MAX 0xffffui16
#define UINT32_MAX 0xffffffffui32
#define UINT64_MAX 0xffffffffffffffffui64
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST16_MIN INT32_MIN
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MAX INT32_MAX
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT32_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
#ifdef _WIN64
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
#define UINTPTR_MAX UINT64_MAX
#else
#define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT32_MAX
#define UINTPTR_MAX UINT32_MAX
#endif
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
#define PTRDIFF_MIN INTPTR_MIN
#define PTRDIFF_MAX INTPTR_MAX
#ifndef SIZE_MAX
#define SIZE_MAX UINTPTR_MAX
#endif
#define SIG_ATOMIC_MIN INT32_MIN
#define SIG_ATOMIC_MAX INT32_MAX
#define WCHAR_MIN 0x0000
#define WCHAR_MAX 0xffff
#define WINT_MIN 0x0000
#define WINT_MAX 0xffff
#define INT8_C(x) (x)
#define INT16_C(x) (x)
#define INT32_C(x) (x)
#define INT64_C(x) (x ## LL)
#define UINT8_C(x) (x)
#define UINT16_C(x) (x)
#define UINT32_C(x) (x ## U)
#define UINT64_C(x) (x ## ULL)
#define INTMAX_C(x) INT64_C(x)
#define UINTMAX_C(x) UINT64_C(x)
#endif // RC_INVOKED
/*
* Copyright (c) 1992-2012 by P.J. Plauger. ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
V6.00:0009 */
Both uint_fast16_t and uint_fast32_t have no problems when I use them, which rules out type being an issue - they are both unsigned int, the same as uint32_t.
EDIT: While making an MCVE, I narrowed the problem down to #include-ing "stm32f4xx_hal.h" - without this #include, a uint32_t declares fine. Here is a file that demonstrates the problem (changing the order of the includes does not make a difference):
#pragma once
#include <stdint.h>
#include "stm32f4xx_hal.h"
#define MA302_READ_MASK 0x4000
#define MA302_WRITE_MASK 0x8000
#define MA302_ADDRESS_MASK 0x1F
#define MA302_READ_BLANK_VALUE 0x0000
typedef struct {
uint32_t tester; // 'variable "uint32_t" is not a type name"'
uint16_t current_raw_16; // declares fine
uint8_t current_raw_8; // declares fine
float current_angle;
} ma302gq_p_t;
uint8_t ma302_read_register(SPI_HandleTypeDef *hndlr, uint8_t address);
float ma302_get_angle(SPI_HandleTypeDef *hndlr);
float ma302_raw_to_degrees(uint8_t raw_bit_size, uint16_t raw_angle);
void ma302_init(SPI_HandleTypeDef *hndlr);
"stm32f4xx_hal.h" is part of the code generated by STM32CubeMX, and itself #includes "stm32f4xx_hal_conf.h". Adding #include <stdint.h> to "stm32f4xx_hal.h" allows uint32_ts to temporarily declare in that file; however, switching to the above file and back in VSCode causes the declaration to glitch, and when hovered over, show <error-type> uint32_t
EDIT 2:
Here is the first problem file; I didn't include it before as it is automatically generated.
"stm32f4xx_hal.h":
/**
******************************************************************************
* #file stm32f4xx_hal.h
* #author MCD Application Team
* #brief This file contains all the functions prototypes for the HAL
* module driver.
******************************************************************************
* #attention
*
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4xx_HAL_H
#define __STM32F4xx_HAL_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal_conf.h"
/** #addtogroup STM32F4xx_HAL_Driver
* #{
*/
/** #addtogroup HAL
* #{
*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/** #defgroup HAL_Exported_Constants HAL Exported Constants
* #{
*/
/** #defgroup HAL_TICK_FREQ Tick Frequency
* #{
*/
typedef enum
{
HAL_TICK_FREQ_10HZ = 100U,
HAL_TICK_FREQ_100HZ = 10U,
HAL_TICK_FREQ_1KHZ = 1U,
HAL_TICK_FREQ_DEFAULT = HAL_TICK_FREQ_1KHZ
} HAL_TickFreqTypeDef;
/**
* #}
*/
/**
* #}
*/
/* Exported macro ------------------------------------------------------------*/
/** #defgroup HAL_Exported_Macros HAL Exported Macros
* #{
*/
/** #brief Freeze/Unfreeze Peripherals in Debug mode
*/
#define __HAL_DBGMCU_FREEZE_TIM2() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM2_STOP))
#define __HAL_DBGMCU_FREEZE_TIM3() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM3_STOP))
#define __HAL_DBGMCU_FREEZE_TIM4() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM4_STOP))
#define __HAL_DBGMCU_FREEZE_TIM5() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM5_STOP))
#define __HAL_DBGMCU_FREEZE_TIM6() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM6_STOP))
#define __HAL_DBGMCU_FREEZE_TIM7() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM7_STOP))
#define __HAL_DBGMCU_FREEZE_TIM12() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM12_STOP))
#define __HAL_DBGMCU_FREEZE_TIM13() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM13_STOP))
#define __HAL_DBGMCU_FREEZE_TIM14() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM14_STOP))
#define __HAL_DBGMCU_FREEZE_RTC() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_RTC_STOP))
#define __HAL_DBGMCU_FREEZE_WWDG() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_WWDG_STOP))
#define __HAL_DBGMCU_FREEZE_IWDG() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_IWDG_STOP))
#define __HAL_DBGMCU_FREEZE_I2C1_TIMEOUT() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT))
#define __HAL_DBGMCU_FREEZE_I2C2_TIMEOUT() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_I2C2_SMBUS_TIMEOUT))
#define __HAL_DBGMCU_FREEZE_I2C3_TIMEOUT() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_I2C3_SMBUS_TIMEOUT))
#define __HAL_DBGMCU_FREEZE_CAN1() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_CAN1_STOP))
#define __HAL_DBGMCU_FREEZE_CAN2() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_CAN2_STOP))
#define __HAL_DBGMCU_FREEZE_TIM1() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM1_STOP))
#define __HAL_DBGMCU_FREEZE_TIM8() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM8_STOP))
#define __HAL_DBGMCU_FREEZE_TIM9() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM9_STOP))
#define __HAL_DBGMCU_FREEZE_TIM10() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM10_STOP))
#define __HAL_DBGMCU_FREEZE_TIM11() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM11_STOP))
#define __HAL_DBGMCU_UNFREEZE_TIM2() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM2_STOP))
#define __HAL_DBGMCU_UNFREEZE_TIM3() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM3_STOP))
#define __HAL_DBGMCU_UNFREEZE_TIM4() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM4_STOP))
#define __HAL_DBGMCU_UNFREEZE_TIM5() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM5_STOP))
#define __HAL_DBGMCU_UNFREEZE_TIM6() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM6_STOP))
#define __HAL_DBGMCU_UNFREEZE_TIM7() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM7_STOP))
#define __HAL_DBGMCU_UNFREEZE_TIM12() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM12_STOP))
#define __HAL_DBGMCU_UNFREEZE_TIM13() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM13_STOP))
#define __HAL_DBGMCU_UNFREEZE_TIM14() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM14_STOP))
#define __HAL_DBGMCU_UNFREEZE_RTC() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_RTC_STOP))
#define __HAL_DBGMCU_UNFREEZE_WWDG() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_WWDG_STOP))
#define __HAL_DBGMCU_UNFREEZE_IWDG() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_IWDG_STOP))
#define __HAL_DBGMCU_UNFREEZE_I2C1_TIMEOUT() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT))
#define __HAL_DBGMCU_UNFREEZE_I2C2_TIMEOUT() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_I2C2_SMBUS_TIMEOUT))
#define __HAL_DBGMCU_UNFREEZE_I2C3_TIMEOUT() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_I2C3_SMBUS_TIMEOUT))
#define __HAL_DBGMCU_UNFREEZE_CAN1() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_CAN1_STOP))
#define __HAL_DBGMCU_UNFREEZE_CAN2() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_CAN2_STOP))
#define __HAL_DBGMCU_UNFREEZE_TIM1() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM1_STOP))
#define __HAL_DBGMCU_UNFREEZE_TIM8() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM8_STOP))
#define __HAL_DBGMCU_UNFREEZE_TIM9() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM9_STOP))
#define __HAL_DBGMCU_UNFREEZE_TIM10() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM10_STOP))
#define __HAL_DBGMCU_UNFREEZE_TIM11() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM11_STOP))
/** #brief Main Flash memory mapped at 0x00000000
*/
#define __HAL_SYSCFG_REMAPMEMORY_FLASH() (SYSCFG->MEMRMP &= ~(SYSCFG_MEMRMP_MEM_MODE))
/** #brief System Flash memory mapped at 0x00000000
*/
#define __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH() do {SYSCFG->MEMRMP &= ~(SYSCFG_MEMRMP_MEM_MODE);\
SYSCFG->MEMRMP |= SYSCFG_MEMRMP_MEM_MODE_0;\
}while(0);
/** #brief Embedded SRAM mapped at 0x00000000
*/
#define __HAL_SYSCFG_REMAPMEMORY_SRAM() do {SYSCFG->MEMRMP &= ~(SYSCFG_MEMRMP_MEM_MODE);\
SYSCFG->MEMRMP |= (SYSCFG_MEMRMP_MEM_MODE_0 | SYSCFG_MEMRMP_MEM_MODE_1);\
}while(0);
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)
/** #brief FSMC Bank1 (NOR/PSRAM 1 and 2) mapped at 0x00000000
*/
#define __HAL_SYSCFG_REMAPMEMORY_FSMC() do {SYSCFG->MEMRMP &= ~(SYSCFG_MEMRMP_MEM_MODE);\
SYSCFG->MEMRMP |= (SYSCFG_MEMRMP_MEM_MODE_1);\
}while(0);
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) ||\
defined(STM32F469xx) || defined(STM32F479xx)
/** #brief FMC Bank1 (NOR/PSRAM 1 and 2) mapped at 0x00000000
*/
#define __HAL_SYSCFG_REMAPMEMORY_FMC() do {SYSCFG->MEMRMP &= ~(SYSCFG_MEMRMP_MEM_MODE);\
SYSCFG->MEMRMP |= (SYSCFG_MEMRMP_MEM_MODE_1);\
}while(0);
/** #brief FMC/SDRAM Bank 1 and 2 mapped at 0x00000000
*/
#define __HAL_SYSCFG_REMAPMEMORY_FMC_SDRAM() do {SYSCFG->MEMRMP &= ~(SYSCFG_MEMRMP_MEM_MODE);\
SYSCFG->MEMRMP |= (SYSCFG_MEMRMP_MEM_MODE_2);\
}while(0);
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
#if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F413xx) || defined(STM32F423xx)
/** #defgroup Cortex_Lockup_Enable Cortex Lockup Enable
* #{
*/
/** #brief SYSCFG Break Lockup lock
* Enables and locks the connection of Cortex-M4 LOCKUP (Hardfault) output to TIM1/8 input
* #note The selected configuration is locked and can be unlocked by system reset
*/
#define __HAL_SYSCFG_BREAK_PVD_LOCK() do {SYSCFG->CFGR2 &= ~(SYSCFG_CFGR2_PVD_LOCK); \
SYSCFG->CFGR2 |= SYSCFG_CFGR2_PVD_LOCK; \
}while(0)
/**
* #}
*/
/** #defgroup PVD_Lock_Enable PVD Lock
* #{
*/
/** #brief SYSCFG Break PVD lock
* Enables and locks the PVD connection with Timer1/8 Break Input, , as well as the PVDE and PLS[2:0] in the PWR_CR register
* #note The selected configuration is locked and can be unlocked by system reset
*/
#define __HAL_SYSCFG_BREAK_LOCKUP_LOCK() do {SYSCFG->CFGR2 &= ~(SYSCFG_CFGR2_LOCKUP_LOCK); \
SYSCFG->CFGR2 |= SYSCFG_CFGR2_LOCKUP_LOCK; \
}while(0)
/**
* #}
*/
#endif /* STM32F410Tx || STM32F410Cx || STM32F410Rx || STM32F413xx || STM32F423xx */
/**
* #}
*/
/** #defgroup HAL_Private_Macros HAL Private Macros
* #{
*/
#define IS_TICKFREQ(FREQ) (((FREQ) == HAL_TICK_FREQ_10HZ) || \
((FREQ) == HAL_TICK_FREQ_100HZ) || \
((FREQ) == HAL_TICK_FREQ_1KHZ))
/**
* #}
*/
/* Exported functions --------------------------------------------------------*/
/** #addtogroup HAL_Exported_Functions
* #{
*/
/** #addtogroup HAL_Exported_Functions_Group1
* #{
*/
/* Initialization and Configuration functions ******************************/
HAL_StatusTypeDef HAL_Init(void);
HAL_StatusTypeDef HAL_DeInit(void);
void HAL_MspInit(void);
void HAL_MspDeInit(void);
HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority);
/**
* #}
*/
/** #addtogroup HAL_Exported_Functions_Group2
* #{
*/
/* Peripheral Control functions ************************************************/
void HAL_IncTick(void);
void HAL_Delay(uint32_t Delay);
uint32_t HAL_GetTick(void);
uint32_t HAL_GetTickPrio(void);
HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq);
HAL_TickFreqTypeDef HAL_GetTickFreq(void);
void HAL_SuspendTick(void);
void HAL_ResumeTick(void);
uint32_t HAL_GetHalVersion(void);
uint32_t HAL_GetREVID(void);
uint32_t HAL_GetDEVID(void);
void HAL_DBGMCU_EnableDBGSleepMode(void);
void HAL_DBGMCU_DisableDBGSleepMode(void);
void HAL_DBGMCU_EnableDBGStopMode(void);
void HAL_DBGMCU_DisableDBGStopMode(void);
void HAL_DBGMCU_EnableDBGStandbyMode(void);
void HAL_DBGMCU_DisableDBGStandbyMode(void);
void HAL_EnableCompensationCell(void);
void HAL_DisableCompensationCell(void);
void HAL_GetUID(uint32_t *UID);
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) ||\
defined(STM32F469xx) || defined(STM32F479xx)
void HAL_EnableMemorySwappingBank(void);
void HAL_DisableMemorySwappingBank(void);
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
/**
* #}
*/
/**
* #}
*/
/* Private types -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/** #defgroup HAL_Private_Variables HAL Private Variables
* #{
*/
/**
* #}
*/
/* Private constants ---------------------------------------------------------*/
/** #defgroup HAL_Private_Constants HAL Private Constants
* #{
*/
/**
* #}
*/
/* Private macros ------------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* #}
*/
/**
* #}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32F4xx_HAL_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
STM has a huge web of files all #include-ing each other, there's only so much I can put in one post. Anyone with STM32CubeMX and VSCode should be able to replicate this.
The stm32f4xx_hal.h header will mess with your stdint.h types if you have not defined your MCU in the vscode workspace. In c_cpp_properties.json, make sure you include:
"defines": [
"STM32F411xx", // (or whatever your makefile defines)
(...)
],
New answer from vscode-cpptools issue. The same problem as mentioned by #vxhht: some STM32 library mass up the stdint.h. But it is not caused by missing MCU definition:
It's not a bug -- in core_cm3.h, it needs to have a compiler define set, such as __CC_ARM or it hits a "#error Unknown compiler".
So add __CC_ARM to defines section of c_cpp_properties.json solve the problem.
all you need to do is:
define your microcontroller
define USE_HAL_DRIVER
define your compiler __CC_ARM
in cpp_properties.json file
Oddly uint8_t and unit16_t types for declarations in Visual Studio 2019 C++14 are fine, but uint32_t is not. All these types are fine for IAR compiler cross compiled for STM32F413. But goal is to unit test the target code with Boost Test on Visual Studio C++. Preprocessor symbol STM32F413xx was added to Visual Studio project but did not improve situation.
It is true comment out the stm32f4*.h and #include <stdint.h> is fine for uint32_t
but must have the stm32f4*.h headers to BoostTest target code though #ifdef out hardware accesses. Previous answer does not say how stm32f4xx_hal.h messes with uint32_t.

I2C Not working with PCA9685

I'm using an Atmega168 I'm attempting to use I2C with my PCA9685 Servo driver.
I'm using this I2C library: https://github.com/g4lvanix/I2C-master-lib
I'm attempting to start the I2C connection with my PCA9685 (Address: 0x41).
For some reason the I2C Library is bouncing back an error because the acknowledge bit isn't being sent. What is wrong here? My SDA and SCL pins are hooked up to 10k pull up resistors, and they are connected to the PCA9685 correctly. Yet it still isn't working. Could it be my PCA9685 chip? I also know the address is 0x41 because I manually bridged an address connection to assign that address.
Here is my code:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/power.h>
#include "i2c.h"
#define SERVO_MIN 1000
#define SERVO_MAX 2000
#define SERVO_MID 1500
#define PCA9685_ADDR 0x40
#define PCA9685_MODE1 0x0
#define LED0_ON_L 0x6
#define LED0_ON_H 0x7
#define LED0_OFF_L 0x8
#define LED0_OFF_H 0x9
#define LED PB0
#define LED_DDR DDRB
#define LED_PORT PORTB
#define DELAYTIME 200
#define setBit(sfr, bit) (_SFR_BYTE(sfr) |= (1 << bit))
#define clearBit(sfr, bit) (_SFR_BYTE(sfr) &= ~(1 << bit))
#define toggleBit(sfr, bit) (_SFR_BYTE(sfr) ^= (1 << bit))
void setupController();
void setServo(uint8_t id, uint8_t start, uint8_t stop);
int main(void)
{
setBit(LED_DDR, LED);
clock_prescale_set(clock_div_1);
i2c_init();
uint8_t err = i2c_start(0x41);
while(err == 1) {
setBit(LED_PORT, LED);
uint8_t err = i2c_start(0x41);
}
clearBit(LED_PORT, LED);
while(1) {
}
return 0;
}
Thank you in advance!

Compiler error using AVR Atmel Studio library config files

// Created by lenovo on 8/27/2017.
//
#ifndef UART_UART_CFG_H
#define UART_UART_CFG_H
#define UART_BaudRate 1200 //9600UL
#define CLK 16
#define UART_Parity NONE
#define UART_TX EN_TX
#define UART_RX EN_RX
#define UART_STARTBITS 1
#define UART_STOPBITS 1
#define UART_DATABITS EightBits
#endif //UART_UART_CFG_H
This is the error "called object is not a function or pointer"
and this my private file that have all word's addresses inside the config file. The first file:
//
// Created by lenovo on 8/27/2017.
//
#ifndef UART_UART_PRIV_H
#define UART_UART_PRIV_H
/* Main PINS */
#define UCSRA *((volatile u8 *)0x2B)
#define UCSRB *((volatile u8 *)0x2A)
#define UCSRC *((volatile u8 *)0x40)
#define UBRRL *((volatile u8 *)0x29)
#define UBRRH *((volatile u8 *)0x40)
#define UDR *((volatile u8 *)0x2C)
/* END Main PINS */
#define NONE 0x00
#define twoBit 0x08
#define oneBit 0x00
/* Bits */
#define fiveBits 0x00
#define SixBits 0x02
#define SevenBits 0x04
#define EightBits 0x06
/* End Bits */
#define DIS 0 // Disable
#define EN 1 // Enable
#define UART_9600 9600UL
#endif //UART_UART_PRIV_H
Private file that have some addresses for my Microcontroller ATmega16. Moreover, my config file is reference to private file; which have keys that defined in private. For example, in UART_Partit I wrote NONE and NONE address defined in private but it shows error
You need to include your file with declarations.
#ifndef UART_UART_CFG_H
#define UART_UART_CFG_H
#include "uart_priv.h"
#define UART_BaudRate 1200 //9600UL
#define CLK 16
#define UART_Parity NONE
#define UART_TX EN_TX
#define UART_RX EN_RX
#define UART_STARTBITS 1
#define UART_STOPBITS 1
#define UART_DATABITS EightBits
#endif //UART_UART_CFG_H
and there are no EN_TX or EN_RX defines for these constants in your second file.

If clause for bit cheking replaced with bit manipulation using C

I have following chunk of code:
// **** CONTROL REGISTER 4 SETUP ****
ctrl|=(uint8_t)(LIS3DSH_InitStruct->CR4_Odr);
if(LIS3DSH_InitStruct->CR4_Bdu)
ctrl|=(1<<LIS3DSH_CR4_BDU_POSITION);
if(LIS3DSH_InitStruct->CR4_Zen)
ctrl|=(1<<LIS3DSH_CR4_Z_AXIS_POSITION);
if(LIS3DSH_InitStruct->CR4_Yen)
ctrl|=(1<<LIS3DSH_CR4_Y_AXIS_POSITION);
if(LIS3DSH_InitStruct->CR4_Xen)
ctrl|=(1<<LIS3DSH_CR4_X_AXIS_POSITION);
LIS3DSH_Write(&ctrl,
LIS3DSH_CTRL_REG4_ADDR,
sizeof(ctrl));
delay(1000000);
// **** END OF CONTROL REGISTER 4 SETUP ****
Now, I am pretty sure these if clauses (since this is embedded world) can be replaced with bit manipulation techniques, can someone show me how? I know this is pretty stupid question, but I've simply forgot these things ...
Here is header file with structure:
#ifndef __STM32F4_DISCOVERY_LIS3DS_H
#define __STM32F4_DISCOVERY_LIS3DS_H
#include "stm32f4xx.h"
#define LIS3DSH_CTRL_REG1_ADDR 0x21
#define LIS3DSH_CTRL_REG2_ADDR 0x22
#define LIS3DSH_CTRL_REG3_ADDR 0x23
#define LIS3DSH_CTRL_REG4_ADDR 0x20
#define LIS3DSH_CTRL_REG5_ADDR 0x24
#define LIS3DSH_CTRL_REG6_ADDR 0x25
#define LIS3DSH_INFO1_REG_ADDR 0x0d
#define LIS3DSH_INFO2_REG_ADDR 0x0e
#define LIS3DSH_WHOAMI_REG_ADDR 0x0f
#define LIS3DSH_STATUS_REG_ADDR 0x27
#define LIS3DSH_TEMPERATURE_REG_ADDR 0x0c
#define LIS3DSH_OUT_X_L_REG_ADDR 0x28
#define LIS3DSH_OUT_X_H_REG_ADDR 0x29
#define LIS3DSH_OUT_Y_L_REG_ADDR 0x2a
#define LIS3DSH_OUT_Y_H_REG_ADDR 0x2b
#define LIS3DSH_OUT_Z_L_REG_ADDR 0x2c
#define LIS3DSH_OUT_Z_H_REG_ADDR 0x2d
#define LIS3DSH_FLAG_ZXYOR ((uint8_t)0x00)
#define LIS3DSH_FLAG_ZOR ((uint8_t)0x01)
#define LIS3DSH_FLAG_YOR ((uint8_t)0x02)
#define LIS3DSH_FLAG_XOR ((uint8_t)0x03)
#define LIS3DSH_FLAG_ZXYDA ((uint8_t)0x04)
#define LIS3DSH_FLAG_ZDA ((uint8_t)0x05)
#define LIS3DSH_FLAG_YDA ((uint8_t)0x06)
#define LIS3DSH_FLAG_XDA ((uint8_t)0x07)
#define DEVICE_ID ((uint8_t)0x3f)
#define LIS3DSH_SM1_INT_TO_PIN_INT1 ((uint8_t)0x00)
#define LIS3DSH_SM1_INT_TO_PIN_INT2 ((uint8_t)0x01)
#define LIS3DSH_SM1_DISABLE ((uint8_t)0x00)
#define LIS3DSH_SM1_ENABLE ((uint8_t)0x01)
#define LIS3DSH_SM2_INT_TO_PIN_INT1 ((uint8_t)0x00)
#define LIS3DSH_SM2_INT_TO_PIN_INT2 ((uint8_t)0x01)
#define LIS3DSH_SM2_DISABLE ((uint8_t)0x00)
#define LIS3DSH_SM2_ENABLE ((uint8_t)0x01)
#define LIS3DSH_CR3_DREN_TO_INT1_DISABLE ((uint8_t)0x00)
#define LIS3DSH_CR3_DREN_TO_INT1_ENABLE ((uint8_t)0x01)
#define LIS3DSH_CR3_IEA_ACTIVE_LOW ((uint8_t)0x00)
#define LIS3DSH_CR3_IEA_ACTIVE_HIGH ((uint8_t)0x01)
#define LIS3DSH_CR3_IEL_LATCHED ((uint8_t)0x00)
#define LIS3DSH_CR3_IEL_PULSED ((uint8_t)0x01)
#define LIS3DSH_CR3_INT2_DISABLED ((uint8_t)0x00)
#define LIS3DSH_CR3_INT2_ENABLED ((uint8_t)0x01)
#define LIS3DSH_CR3_INT1_DISABLED ((uint8_t)0x00)
#define LIS3DSH_CR3_INT1_ENABLED ((uint8_t)0x01)
#define LIS3DSH_CR3_VFILT_DISABLED ((uint8_t)0x00)
#define LIS3DSH_CR3_VFILT_ENABLED ((uint8_t)0x01)
#define LIS3DSH_CR3_NO_SOFT_RESET ((uint8_t)0x00)
#define LIS3DSH_CR3_SOFT_RESET ((uint8_t)0x01)
#define LIS3DSH_CR4_ODR_POWER_DOWN ((uint8_t)0x00)
#define LIS3DSH_CR4_ODR_3f125HZ ((uint8_t)0x01)
#define LIS3DSH_CR4_ODR_6f25HZ ((uint8_t)0x02)
#define LIS3DSH_CR4_ODR_12f5HZ ((uint8_t)0x03)
#define LIS3DSH_CR4_ODR_25HZ ((uint8_t)0x04)
#define LIS3DSH_CR4_ODR_50HZ ((uint8_t)0x05)
#define LIS3DSH_CR4_ODR_100HZ ((uint8_t)0x06)
#define LIS3DSH_CR4_ODR_400HZ ((uint8_t)0x07)
#define LIS3DSH_CR4_ODR_800HZ ((uint8_t)0x08)
#define LIS3DSH_CR4_ODR_1600HZ ((uint8_t)0x09)
#define LIS3DSH_CR4_BDU_DISABLED ((uint8_t)0x00)
#define LIS3DSH_CR4_BDU_ENABLED ((uint8_t)0x01)
#define LIS3DSH_CR4_BDU_POSITION ((uint8_t)0x04)
#define LIS3DSH_CR4_Z_AXIS_DISABLED ((uint8_t)0x00)
#define LIS3DSH_CR4_Z_AXIS_ENABLED ((uint8_t)0x01)
#define LIS3DSH_CR4_Z_AXIS_POSITION ((uint8_t)0x05)
#define LIS3DSH_CR4_X_AXIS_DISABLED ((uint8_t)0x00)
#define LIS3DSH_CR4_X_AXIS_ENABLED ((uint8_t)0x01)
#define LIS3DSH_CR4_X_AXIS_POSITION ((uint8_t)0x07)
#define LIS3DSH_CR4_Y_AXIS_DISABLED ((uint8_t)0x00)
#define LIS3DSH_CR4_Y_AXIS_ENABLED ((uint8_t)0x01)
#define LIS3DSH_CR4_Y_AXIS_POSITION ((uint8_t)0x06)
#define LIS3DSH_CR5_BW_800HZ ((uint8_t)0x00)
#define LIS3DSH_CR5_BW_400HZ ((uint8_t)0x01)
#define LIS3DSH_CR5_BW_200HZ ((uint8_t)0x02)
#define LIS3DSH_CR5_BW_50HZ ((uint8_t)0x03)
#define LIS3DSH_CR5_FSCALE_2G ((uint8_t)0x00)
#define LIS3DSH_CR5_FSCALE_4G ((uint8_t)0x01)
#define LIS3DSH_CR5_FSCALE_6G ((uint8_t)0x02)
#define LIS3DSH_CR5_FSCALE_8G ((uint8_t)0x03)
#define LIS3DSH_CR5_FSCALE_16G ((uint8_t)0x04)
#define LIS3DSH_CR5_ST_DISABLE ((uint8_t)0x00)
#define LIS3DSH_CR5_ST_POSITIVE ((uint8_t)0x01)
#define LIS3DSH_CR5_ST_NEGATIVE ((uint8_t)0x02)
#define LIS3DSH_CR5_ST_NOT_ALLOWED ((uint8_t)0x03)
#define LIS3DSH_CR5_MODE_4_WIRE_INTERFACE ((uint8_t)0x00)
#define LIS3DSH_CR5_MODE_3_WIRE_INTERFACE ((uint8_t)0x01)
#define LIS3DSH_CR6_FORCE_REBOOT_DISABLE ((uint8_t)0x00)
#define LIS3DSH_CR6_FORCE_REBOOT_ENABLE ((uint8_t)0x01)
#define LIS3DSH_CR6_FIFO_DISABLED ((uint8_t)0x00)
#define LIS3DSH_CR6_FIFO_ENABLED ((uint8_t)0x01)
#define LIS3DSH_CR6_WTM_DISABLED ((uint8_t)0x00)
#define LIS3DSH_CR6_WTM_ENABLED ((uint8_t)0x01)
#define LIS3DSH_CR6_ADDINC_DISABLED ((uint8_t)0x00)
#define LIS3DSH_CR6_ADDINC_ENABLED ((uint8_t)0x01)
#define LIS3DSH_CR6_FIFO_EMPTY_TO_INT1_DISABLED ((uint8_t)0x00)
#define LIS3DSH_CR6_FIFO_EMPTY_TO_INT1_ENABLED ((uint8_t)0x01)
#define LIS3DSH_CR6_FIFO_WTM_TO_INT1_DISABLED ((uint8_t)0x00)
#define LIS3DSH_CR6_FIFO_WTM_TO_INT1_ENABLED ((uint8_t)0x01)
#define LIS3DSH_CR6_FIFO_OVERRUN_TO_INT1_DISABLED ((uint8_t)0x00)
#define LIS3DSH_CR6_FIFO_OVERRUN_TO_INT1_ENABLED ((uint8_t)0x01)
#define LIS3DSH_CR6_BOOT_TO_INT2_DISABLED ((uint8_t)0x00)
#define LIS3DSH_CR6_BOOT_TO_INT2_ENABLED ((uint8_t)0x01)
#define LIS3DSH_SPI SPI1
#define LIS3DSH_SPI_CLK RCC_APB2Periph_SPI1
#define LIS3DSH_SPI_SCK_PIN GPIO_Pin_5
#define LIS3DSH_SPI_SCK_GPIO_PORT GPIOA
#define LIS3DSH_SPI_SCK_GPIO_CLK RCC_AHB1Periph_GPIOA
#define LIS3DSH_SPI_SCK_SOURCE GPIO_PinSource5
#define LIS3DSH_SPI_SCK_AF GPIO_AF_SPI1
#define LIS3DSH_SPI_MISO_PIN GPIO_Pin_6
#define LIS3DSH_SPI_MISO_GPIO_PORT GPIOA
#define LIS3DSH_SPI_MISO_GPIO_CLK RCC_AHB1Periph_GPIOA
#define LIS3DSH_SPI_MISO_SOURCE GPIO_PinSource6
#define LIS3DSH_SPI_MISO_AF GPIO_AF_SPI1
#define LIS3DSH_SPI_MOSI_PIN GPIO_Pin_7
#define LIS3DSH_SPI_MOSI_GPIO_PORT GPIOA
#define LIS3DSH_SPI_MOSI_GPIO_CLK RCC_AHB1Periph_GPIOA
#define LIS3DSH_SPI_MOSI_SOURCE GPIO_PinSource7
#define LIS3DSH_SPI_MOSI_AF GPIO_AF_SPI1
#define LIS3DSH_SPI_CS_PIN GPIO_Pin_3
#define LIS3DSH_SPI_CS_GPIO_PORT GPIOE
#define LIS3DSH_SPI_CS_GPIO_CLK RCC_AHB1Periph_GPIOE
#define LIS3DSH_SPI_INT1_PIN GPIO_Pin_0
#define LIS3DSH_SPI_INT1_GPIO_PORT GPIOE
#define LIS3DSH_SPI_INT1_GPIO_CLK RCC_AHB1Periph_GPIOE
#define LIS3DSH_SPI_INT1_EXTI_LINE EXTI_Line0
#define LIS3DSH_SPI_INT1_EXTI_PORT_SOURCE EXTI_PortSourceGPIOE
#define LIS3DSH_SPI_INT1_EXTI_PIN_SOURCE EXTI_PinSource0
#define LIS3DSH_SPI_INT1_EXTI_IRQn EXTI0_IRQn
#define LIS3DSH_SPI_INT2_PIN GPIO_Pin_1
#define LIS3DSH_SPI_INT2_GPIO_PORT GPIOE
#define LIS3DSH_SPI_INT2_GPIO_CLK RCC_AHB1Periph_GPIOE
#define LIS3DSH_SPI_INT2_EXTI_LINE EXTI_Line1
#define LIS3DSH_SPI_INT2_EXTI_PORT_SOURCE EXTI_PortSourceGPIOE
#define LIS3DSH_SPI_INT2_EXTI_PIN_SOURCE EXTI_PinSource1
#define LIS3DSH_SPI_INT2_EXTI_IRQn EXTI1_IRQn
#define LIS3DSH_CS_LOW() GPIO_ResetBits(LIS3DSH_SPI_CS_GPIO_PORT, LIS3DSH_SPI_CS_PIN)
#define LIS3DSH_CS_HIGH() GPIO_SetBits(LIS3DSH_SPI_CS_GPIO_PORT, LIS3DSH_SPI_CS_PIN)
#define LIS3DSH_FLAG_TIMEOUT ((uint32_t)0x1000)
typedef struct
{
// **** Control Register 1 ****
uint8_t SM1_Hysteresis;
uint8_t SM1_Pin;
uint8_t SM1_Enable;
// **** END OF Control Register 1 ****
// **** Control Register 2 ****
uint8_t SM2_Hysteresis;
uint8_t SM2_Pin;
uint8_t SM2_Enable;
// **** END OF Control Register 2 ****
// **** Control Register 3 ****
uint8_t CR3_Dren;
uint8_t CR3_Iea;
uint8_t CR3_Iel;
uint8_t CR3_Int2En;
uint8_t CR3_Int1En;
uint8_t CR3_Vfilt;
uint8_t CR3_Strt;
// **** END OF Control Register 3
// **** Control Register 4 ****
uint8_t CR4_Odr;
uint8_t CR4_Bdu;
uint8_t CR4_Zen;
uint8_t CR4_Yen;
uint8_t CR4_Xen;
// **** END OF Control Register 4
// **** Control Register 5 ****
uint8_t CR5_Bw;
uint8_t CR5_Fscale;
uint8_t CR5_St;
uint8_t CR5_Sim;
// **** END OF Control Register 5
// **** Control Register 6 ****
uint8_t CR6_Boot;
uint8_t CR6_FifoEn;
uint8_t CR6_WtmEn;
uint8_t CR6_AddInc;
uint8_t CR6_P1Empty;
uint8_t CR6_P1Wtm;
uint8_t CR6_P1OverRun;
uint8_t CR6_P2Boot;
// **** END OF Control Register 6
} LIS3DSH_InitTypeDef;
typedef struct
{
uint16_t x;
uint16_t y;
uint16_t z;
} accel_vector;
extern LIS3DSH_InitTypeDef deviceLIS3DSH;
extern GPIO_InitTypeDef portLIS3DSH;
extern SPI_InitTypeDef busLIS3DSH;
extern accel_vector accelData;
void LIS3DSH_Init(LIS3DSH_InitTypeDef* LIS3DSH_InitStruct);
uint32_t LIS3DSH_TIMEOUT_UserCallback(void);
void LIS3DSH_AccelInit(void);
void LIS3DSH_Read(uint8_t* pBuffer,
uint8_t ReadAddr,
uint16_t NumByteToRead);
void LIS3DSH_Write(uint8_t* pBuffer,
uint8_t WriteAddr,
uint16_t NumByteToWrite);
void LIS3DSH_FailureHandler(void);
accel_vector LIS3DSH_ReadData(void);
void LIS3DSH_SoftReset(void);
#endif
ctrl is type uin8_t and I am using IAR Embedded Workbench with C and STM32F4Discovery board. Here is a code that inits part of LIS3DSH_IniStruct:
deviceLIS3DSH.CR4_Odr=LIS3DSH_CR4_ODR_1600HZ;
deviceLIS3DSH.CR4_Bdu=LIS3DSH_CR4_BDU_ENABLED;
deviceLIS3DSH.CR4_Zen=LIS3DSH_CR4_Z_AXIS_ENABLED;
deviceLIS3DSH.CR4_Yen=LIS3DSH_CR4_Y_AXIS_ENABLED;
deviceLIS3DSH.CR4_Xen=LIS3DSH_CR4_X_AXIS_ENABLED;
and deviceLIS3DSH is declared as:
LIS3DSH_InitTypeDef deviceLIS3DSH;
The same code but with the if-statements replaced with pure bit manipulation:
// **** CONTROL REGISTER 4 SETUP ****
ctrl |= (LIS3DSH_InitStruct->CR4_Odr);
ctrl |= (LIS3DSH_InitStruct->CR4_Bdu << LIS3DSH_CR4_BDU_POSITION);
ctrl |= (LIS3DSH_InitStruct->CR4_Zen << LIS3DSH_CR4_Z_AXIS_POSITION);
ctrl |= (LIS3DSH_InitStruct->CR4_Yen << LIS3DSH_CR4_Y_AXIS_POSITION);
ctrl |= (LIS3DSH_InitStruct->CR4_Xen << LIS3DSH_CR4_X_AXIS_POSITION);
LIS3DSH_Write(&ctrl,
LIS3DSH_CTRL_REG4_ADDR,
sizeof(ctrl));
delay(1000000);
// **** END OF CONTROL REGISTER 4 SETUP ****
These are already bit manipulation.
if(LIS3DSH_InitStruct->CR4_Bdu)
This tests if the integer inside is 0 or not. The test is a logical operator, so it checks all the bits. Internally, it might be a tst assembly instruction.
ctrl|=(1<<LIS3DSH_CR4_BDU_POSITION);
Here is some actual bit manipulation. ctrl has 8 bits, and we want to make one of these a 1, even it is already is 1.
So we take 1 which is 00000001 and shift the bits left to get the 1 into the position we are concerned with. Which position is this? It is given by the macro LIS3DSH_CR4_BDU_POSITION which is defined to be a number from 0 to 7 in the header file.
So the right hand side becomes 1<<4 or 00010000 or 0x10 or 16.
The we or this number with ctrl via ctrl = ctrl | 0x10; Which has the effect of making sure the 5th bit of the ctrl integer is a 1. It is shorter to write ctrl |= (1<<4);

Resources