0

This is my program:

#include <stdio.h>

#define uart0 0x860
#define uart1 0x880

void send_char( int output )
{
    int nothing;
    //while write on uart1 is not ready, wait
    while(!((*(uart1+8) & 0x0040) && 0x0040)) //+8 eller +2? 2 byte (8 bitar)
    {
        nothing = 0;

    }
    *(uart1+4) = output; // +4 eller +1? en byte (4 bitar)
}

int rec_charx(void)
{
    if(!((*(uart1+8) & 0x0040) && 0x0040)) //+8 eller +2? 2 byte (8 bitar)
    {
        return *(uart1) & 0x000f;
    }
    else
    {
        return -1;
    }
}

The compiler complains:

expected ')' before 'output'

Why? How can I fix it? I don't understand the complaint.

Update

We've rewritten to program but we still get compilation errors:

#include <stdio.h>

static int* const uart1 = (int*) 0x880;

void send_char( int output )
{
    int nothing;
    //while write on uart1 is not ready, wait
    while(!((uart1[2] & 0x0040) && 0x0040)) //+8 eller +2? 2 byte (8 bitar)
    {
        //do nothing
        nothing = 0;

    }
    uart1[1] = output; // skriv till uart1
}

int rec_charx(void)
{
    if(!((*(uart1+8) & 0x0040) && 0x0040)) //+8 eller +2? 2 byte (8 bitar)
    {
        return *(uart1) & 0x000f;
    }
    else
    {
        return -1;
    }
}
Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424
  • 1
    Which line generates the error? Also, unrelated to the question, but `foo && 0x0040` is a logical (as opposed to bitwise) operation, so it always evaluates to `foo`. – Adam Liss Nov 11 '12 at 16:02
  • 1
    Also unrelated to the question: `*(uart1+8)` - you are accessing content of an address w/o telling the compiler what type of value are you trying to get. You really should use explicit casting in this and all the other cases. – kliteyn Nov 11 '12 at 16:06
  • BTW, I tried compiling it, and I get lots of following erros: `test.c: In function 'send_char': test.c:10: error: invalid type argument of 'unary *' (have 'int')` – kliteyn Nov 11 '12 at 16:09
  • Unrelated : `&&` does not seem to be right. – SwiftMango Nov 11 '12 at 16:24
  • You might like to tell us the line error occurs in. – alk Nov 11 '12 at 16:45

3 Answers3

3

You need to use constants instead of those defines:

#define uart0 0x860
#define uart1 0x880

like so:

const int * uart0 = 0x860;    
const int * uart1 = 0x868;

Also noted that incrementing a pointer of type int * by 1, moves it pointing to and address +sizeof(int*). So assuming an int being 4 bytes long, uart1 + 1 would point to address 0x884.

alk
  • 69,737
  • 10
  • 105
  • 255
  • Those seem to be `int*`, but how would that help? – Michael Krelin - hacker Nov 11 '12 at 16:00
  • @MichaelKrelin-hacker: the OP's code tries to dereference a pointer, for example: *(uart1+8). but since uart1 is simply an integer, the dereference fail (at least in the decent modern C compiler, older C compiler might allow). – LeleDumbo Nov 11 '12 at 16:07
  • @LeleDumbo, I wasn't overly precise. I meant how would that help with this `expected ')'` problem. (which I'm not sure would be produced by exact this code, honestly). – Michael Krelin - hacker Nov 11 '12 at 16:35
  • @MichaelKrelin-hacker: I don't know what compiler the OP use, esp. if it's MSVC or very old (<3.4) GCC such misleading parse error message could appear (actually, I'm even quite sure that this is not the only error line that the compiler emits). This would help at least to correct the pointer semantic problem. – LeleDumbo Nov 13 '12 at 16:32
  • @LeleDumbo, I *assumed* (not necessarily correctly) that it is the first error message. Although yes, I'm not sure how this code could go that far without error messages. – Michael Krelin - hacker Nov 13 '12 at 18:08
0

#define uart0 (int*)0x860
#define uart1 (int*)0x880

Also have to change

while(!((*(uart1+2) & 0x0040) == 0x0040)) 
                 ^            ^^

But this definitely isn't the most beautiful way to access memory. The macro stuff works now, but embedded it to another expression may produce unexpected results or fail to compile.

(int*) xxx + y calculates the expression in the size of (int) i.e. 4.

Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57
0

Best way to fix your issue: read the documentation of your compiler. Your compiler probably comes with an header file that already defines a set of macros to access the UART hardware.

Otherwise here is how to declare your macros:

#include <stdint.h>

#define UART0 (*(volatile uint8_t *) 0x860)
#define UART1 (*(volatile uint8_t *) 0x880)

This assumes your UART registers are 8-bit. If they are 16 or 32-bit, change the uint8_t type in the macro definitions with the appropriate type.

You will need to adapt your code to use these macros.

ouah
  • 142,963
  • 15
  • 272
  • 331