Setting up MCU headers - c

I've been having some trouble setting up my libraries.
I'm looking forward to get a macro like PINSEL(P,N) with P as the number of the GPIO port and also N as the number of the pin in the port.
#ifndef uint32_t
typedef unsigned int uint32_t;
#endif
#ifndef __RW
#define __RW volatile
#endif
#ifndef __R
#define __R volatile const
#endif
typedef union{
struct {
uint32_t PINSELP4:2;
} PINSELP4[16];
struct{
__RW uint32_t PINSEL9_;
};
struct{
__RW uint32_t RES1_:24;
__RW uint32_t PINSELP4_28_:2;
__RW uint32_t PINSELP4_29_:2;
__RW uint32_t RES2_:4;
};
}PINSELP4_t;
#define PINSELP4_ ((PINSELP4_t *)(0x4002C024))
#define PINSELP4(N) PINSELP4_->PINSELP4_[N]->PINSELP4
#define PINSEL9 PINSELP4_->PINSEL9_
#define PINSELP4_28 PINSELP4_->PINSELP4_28_
#define PINSELP4_29 PINSELP4_->PINSELP4_29_
The example above shows the shorter struct of the 5 I've defined.
so then I've defined this two macros
#define PINSEL__(N)[] {PINSELP0(N),PINSELP1(N),PINSELP2(N),PINSELP3(N),PINSELP4(N)}
#define PINSEL(P,N) PINSEL__(N)[P]
I'm trying to make an "array of macros" for this to work. I'ts the only way I've figured it out. It still doesn't work. When I call the macro, I get
../src/../Includes/PINSEL_LPC1769.h:246:20: error: expected expression before '[' token
#define PINSEL__(N)[]={PINSELP0(N),PINSELP1(N),PINSELP2(N),PINSELP3(N),PINSELP4(N)}
^
as error.
I'm trying to make a really complete down layer so I can get a much clearer app layer. So if there's another way of doing this, I'll be listening.
Thank you all!

Related

Is there a way to define macro for pins in AVR gcc so i can access those as variables?

I'm trying to write definitions for AVR C code so that i can access pins by simmple macro like
STATUS_LED_OUT =1;
in GENET_HW_DEF.h file, included to main C file. You can reproduce this bug by including this file into any C project.
I'm using avr studio 6.2 and 7 - both give the same result. I cannot compile getting werid macro unfold message like below. (CPU ATMega1284p)
D:\_SVN\Compass\AVR\Compass_IO_proto\Compass IO_proto\GENET_HW_DEF.h(19,49): error: expected ')' before '&' token
#define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->bit##bt
^
D:\_SVN\Compass\AVR\Compass_IO_proto\Compass IO_proto\GENET_HW_DEF.h(42,25): info: in expansion of macro 'REGISTER_BIT'
#define STATUS_LED_OUT REGISTER_BIT(PORTB,7)
^
D:\_SVN\Compass\AVR\Compass_IO_proto\Compass IO_proto\GENET_HW_DEF.h(46,2): info: in expansion of macro 'STATUS_LED_OUT'
STATUS_LED_OUT=1;
^
Interesting enough, copied to fresh project with just only one or two declarations compiles fine, until one makes any changes in the declarations - like adding another macro reference. Then it becomes stuck again.
Also - if i comment all macro usages like
STATUS_LED_DIR=1;
STATUS_LED_OUT=1;
then I'm able to compile project and then after uncommenting usage lines it still compiles fine.. untill clean is executed. I'm probably messing with macro quirks but I have no idea where.
typedef struct
{
unsigned int bit0:1;
unsigned int bit1:1;
unsigned int bit2:1;
unsigned int bit3:1;
unsigned int bit4:1;
unsigned int bit5:1;
unsigned int bit6:1;
unsigned int bit7:1;
} _io_reg;
#define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->bit##bt
#ifndef GENET_HW_DEF
#define GENET_HW_DEF
// define functionalities and flags - comment/uncomment apropriate lines
#define GENET_USART_0 256
#define GENET_USART_1 256
#define F_CPU 20000000UL
#define STATUS_LED 7
#define ERROR_LED 4
#define ADC_GLOBAL_ENABLE A
#define ADC_CHANNEL_0 0
#define ADC_CHANNEL_1 4
#define ADC_CHANNEL_2 2
#define ADC_CHANNEL_3 3
#define ADC_CHANNEL_4 1
#define ADC_CHANNEL_5 5
#define ADC_CHANNEL_6 6
#define ADC_CHANNEL_7 7
// actual definitions and initialization
#ifdef STATUS_LED
#define STATUS_LED_OUT REGISTER_BIT(PORTB,STATUS_LED)
#define STATUS_LED_DIR REGISTER_BIT(DDRB,STATUS_LED)
#define STATUS_LED_PIN REGISTER_BIT(PINB,STATUS_LED)
STATUS_LED_DIR=1;
STATUS_LED_OUT=1;
#endif
#ifdef ERROR_LED
#define ERROR_LED_OUT REGISTER_BIT(PORTC,ERROR_LED)
#define ERROR_LED_DIR REGISTER_BIT(DDRC,ERROR_LED)
ERROR_LED_DIR=1;
ERROR_LED_OUT=1;
#endif
#ifdef GENET_USART_0
#define USART0_ENABLED
#define UART_RX0_BUFFER_SIZE GENET_USART_0
#define UART_TX0_BUFFER_SIZE GENET_USART_0
#endif
#ifdef GENET_USART_1
#define USART1_ENABLED
#define UART_RX1_BUFFER_SIZE GENET_USART_1
#define UART_TX1_BUFFER_SIZE GENET_USART_1
#endif
#endif
I reproduced your problem.
You cannot call STATUS_LED_DIR=1; outside code execution flow. This must be inside a function (for example main()).
Now you will end with other compilation errors but this was the main mistake.
Second correction, you need 2 level for concatenation
#define CONCAT(bt) bit##bt
#define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->CONCAT(bt)

undeclared here (not in a function) in C

im new with c language, but i try to unerstand this quark hashing algorithm that was written in c language, and i found an error while im compiling the source code, from what i understand the WIDTH it already declared, but why is it still error ?
this is the source code
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
/* uncomment to printf execution traces */
// #define DEBUG
#if defined(UQUARK)
#define CAPACITY 16
#define RATE 1
#define WIDTH 17
#elif defined(DQUARK)
#define CAPACITY 20
#define RATE 2
#define WIDTH 22
#endif
#define DIGEST WIDTH
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint8_t u8;
typedef struct {
int pos; /* number of bytes read into x from current block */
// u32 x[ WIDTH*8 ]; /* one bit stored in each word */
u32 x[ WIDTH*8 ]; /* one bit stored in each word */
} hashState;
#if defined(UQUARK)
/* 17 bytes */
u8 iv[] = {0xd8,0xda,0xca,0x44,0x41,0x4a,0x09,0x97,
0x19,0xc8,0x0a,0xa3,0xaf,0x06,0x56,0x44,0xdb};
and its showing this error
quark.c:36:10: error : 'WIDTH' undeclared here (not in a function)
u32 x[WIDTH*8];
I guess for some reason neither UQUARK nor DQUARK are defined.
Add this:
#if defined(UQUARK) && defined(DQUARK)
#error both UQUARK and DQUARK are defined
#endif
#if !defined(UQUARK) && !defined(dQUARK)
#error Neither UQUARK nor DQUARK are defined
#endif
just before following line:
#if defined(UQUARK)
Then the compilation will abort if either both UQUARK and DQUARK are defined (which probably makes no sense) or if neither UQUARK nor DQUARK are defined (which probably happens in your case).
Now the question is: who defines UQUARK and/or DQUARK? Only you can tell.

IAR Pragma data_alignment not working

I am trying to compile the libvpx library (webm decoder by google) with IAR embedded workbench for an ARM-A7 (bare metal application).
I managed to pull in all the necessary files, and it compiles, but there is a problem with the data alignment of some variables.
In the library, there is a macro DATA_ALIGNMENT() that expands to the GNUC __attribute__(aligned(n)) preprocessor directive. I think I managed to get this macro to work with the IAR version of data alignment (pragma data alignment), but I get the following warning
"Warning [Pe609]: this kind of pragma may not be used here"
and when I run the code, my variables are not aligned!
When searching for the warning on the internet, they say you cannot use pragma with definitions of the variables, but only when creating a variable of some kind! However, for data alignment you need to do it when defining the struct (and GCC does allow it, so why wouldnt IAR?)
Any help would be appreciated!
CODE
Macro Definitions:
#if (defined(__GNUC__) && __GNUC__) || defined(__SUNPRO_C)
#define DECLARE_ALIGNED(n, typ, val) typ val __attribute__((aligned(n)))
#elif defined(__ICCARM__)
#define CONCAT(a,b) a##b
#define DECLARE_ALIGNED(n, typ, val) CONCAT(DECLARE_ALIGNED_,n) (typ,val)
#define DECLARE_ALIGNED_1(typ, val) _Pragma("data_alignment=1") typ val
#define DECLARE_ALIGNED_8(typ, val) _Pragma("data_alignment=8") typ val
#define DECLARE_ALIGNED_16(typ, val) _Pragma("data_alignment=16") typ val
#define DECLARE_ALIGNED_32(typ, val) _Pragma("data_alignment=32") typ val
#define DECLARE_ALIGNED_256(typ, val) _Pragma("data_alignment=256") typ val
#else
#warning No alignment directives known for this compiler.
#define DECLARE_ALIGNED(n, typ, val) typ val
#endif
Example where used:
typedef struct VP9Decoder {
DECLARE_ALIGNED(16, MACROBLOCKD, mb);
DECLARE_ALIGNED(16, VP9_COMMON, common);
int ready_for_new_data;
int refresh_frame_flags;
...
} VP9Decoder;
I have tried this directly in my IAR compiler (7.40.6) and it works fine:
#define CONCAT(a,b) a##b
#define DECLARE_ALIGNED(n, typ, val) CONCAT(DECLARE_ALIGNED_,n) (typ,val)
#define DECLARE_ALIGNED_8(typ, val) _Pragma("data_alignment=8") typ val
typedef struct
{
int a;
char b;
char pad1;
char pad3;
char pad4;
int c;
char d;
} myType;
void main( void)
{
DELCARE_ALIGNED_4( myType, data);
// So data.a will be aligned to a 4 byte boundary
// data.b will be aligned to four bytes
// data.pad, pad1, pad2 are wasted space.
// data.c will be aligned to four bytes
// data.d will be aligned to four bytes
}
Unless you need to your struct to be in a specific order, for example mapping onto something, then ordering your struct carefully can reduce its size. For example, the padding I inserted in this case would quite likey be inserted by the compiler anyway. The order would be better as int a, int c, char b, char d. as the original struct is probably 16 bytes long due to padding and alignment. Whereas it could to be made to be only 12.

Warning: "extra ; ignored" by using C macros with ARMCC

My compiler raises the warning #381-D: extra ";" ignored in such a situation:
I have a struct defined, like the following
struct example_s
{
u8_t foo;
SOME_MACRO(bar);
};
The macro SOME_MACRO(x) does the following:
#if defined(SYSTEM_A)
#define SOME_MACRO(x) u16_t x##something
#else
#define SOME_MACRO(x) /* nothing */
#endif
Of course, the warning is correct, when SYSTEM_A is not defined. Simply because I have now a ; within the struct. But does someone know a way to avoid it correctly? I don't want to break the typical C-style by moving the ; into the macro.
One way that is a bit of a kludge but it seems to work with gcc:
#if defined(SYSTEM_A)
#define SOME_MACRO(x) u16_t x##something
#else
#define SOME_MACRO(x) int x[0] /* nothing */
#endif
With this method you end up with a struct like this:
struct example_s
{
u8_t foo;
int bar[0];
};
which has the correct size (i.e. as size as if bar had not been defined at all).
You can add an unnamed 0-width bitfield instead:
#if defined(SYSTEM_A)
#define SOME_MACRO(x) u16_t x##something
#else
#define SOME_MACRO(x) unsigned :0
#endif
you can also insert an empty anonymous struct :
#if defined(SYSTEM_A)
#define SOME_MACRO(x) u16_t x##something
#else
#define SOME_MACRO(x) struct {}
#endif

Documenting macros (with doxygen) for a member of a struct

I prefer to define certain macros inside of my struct definitions, so it's easy to see possible values for a given member. For example:
typedef struct foo_t {
uint16_t flags;
#define FOO_FLAG_BELL 0x0001
#define FOO_FLAG_BOOK 0x0002
#define FOO_FLAG_CANDLE 0x0004
#define FOO_FLAG_LANTERN 0x0008
}
Doxygen wants to list those macros at the top, with all of the other macros. I've make use of the grouping tags (//#{ and //#}) to group these macros together, and named the group with foo_t.flags, but I'd like to find a way to more-closely associate the values with the structure. Should I use \link and \endlink to somehow link to that group name?
Use enums.
typedef struct foo_t {
enum flag_define {
FOO_FLAG_BELL = 0x0001, /**< The flag for the bell or whatever. */
FOO_FLAG_BOOK = 0x0002,
FOO_FLAG_CANDLE = 0x0004,
FOO_FLAG_LANTERN = 0x0008,
} flags:16; /**< My flag thing */
} foo_t;

Resources