Doppelbelegung SBIT bei IAR

OP #6312671
Ich versuche im Moment meinen UDisk Code auch nach IAR ew8051 zu 
portieren, allerdings möglichst auf der gleichen Code Basis. Es sind 
sowieso schon zu viele ifdefs drin...
Beitrag "Re: uC für 0,20€ CH552 / CH554 von WCH Billig Micro mit USB Funktion, Chip vorstellung"
Ein entsprechendes Header File hab ich geschrieben und ist im Anhang. 
Das passt auch soweit.
Neben der union Deklaration habe ich zusätzlich auch die SBIT Identifier 
per define drin. Der Hintergrund ist einfach dass mein Quellcode so 
nicht verändert werden muss. Das funktioniert solange die SBITs nicht 
doppelt belegt sind.
1
...
2
If (UIF_DETECT) //same bitpos as UIF_BUS_RESET
3
{
4
   ....
5
}
Wenn ich das UIF_DETECT durch UIF_BUS_RESET ersetze läuft der Compiler 
durch. Das will ich aber nicht da die Bedeutung des Bits an der Stelle 
eben nicht USB Reset ist sondern im Hostmode das Connect Bit. Ein Blick 
ins outputfile des Precompiler zeigt dann auch das Problem:
1
if ((USB_INT_FG_bit . (USB_INT_FG_bit . UIF_BUS_RESET  )))
Klar dass der compiler da Fehler meldet. Kennt jemand eine Lösung für 
das Problem.
Thomas
Angehängte Dateien:
Moderator
UIF_BUS_RESET ist im Header-File gar nicht definiert. Meinst du
UIF_BUS_RST?

Die Zeile

1
    #define UIF_DETECT   (USB_INT_FG_bit.UIF_BUS_RST)

ersetzt du einfach durch

1
    #define UIF_DETECT   UIF_BUS_RST

Dann funktioniert auch

1
If (UIF_DETECT) ...

Du könntest aber auch den Bitfeldern (die du ja sowieso nicht direkt,
sondern nur über die Makros benutzt) andere Namen geben, bspw. so:

1
typedef struct {
2
    unsigned char b0 : 1;
3
    unsigned char b1 : 1;
4
    unsigned char b2 : 1;
5
    unsigned char b3 : 1;
6
    unsigned char b4 : 1;
7
    unsigned char b5 : 1;
8
    unsigned char b6 : 1;
9
    unsigned char b7 : 1;
10
} bits;
11

12
// ...
13

14
SFR union
15
{
16
  unsigned char USB_INT_FG;            // USB interrupt flag
17
  bits USB_INT_FG_bit;
18
}@ 0xD8;
19
    #define UIF_BUS_RST  (USB_INT_FG_bit.b0)  
20
    #define UIF_DETECT   (USB_INT_FG_bit.b0)
21
    #define UIF_TRANSFER (USB_INT_FG_bit.b1)
22
    #define UIF_SUSPEND  (USB_INT_FG_bit.b2)
23
    #define UIF_HST_SOF  (USB_INT_FG_bit.b3)
24
    #define UIF_FIFO_OV  (USB_INT_FG_bit.b4)
25
    #define U_SIE_FREE   (USB_INT_FG_bit.b5)
26
    #define U_TOG_OK     (USB_INT_FG_bit.b6)
27
    #define U_IS_NAK     (USB_INT_FG_bit.b7)

Die Struktur bits muss nur einmal für alle Register definiert werden,
was die Länge des Header-Files deutlich verkürzt.


Oder so:

1
typedef struct {
2
    unsigned char b0 : 1;
3
    unsigned char b1 : 1;
4
    unsigned char b2 : 1;
5
    unsigned char b3 : 1;
6
    unsigned char b4 : 1;
7
    unsigned char b5 : 1;
8
    unsigned char b6 : 1;
9
    unsigned char b7 : 1;
10
} bits;
11

12
#define SBIT(reg, bit) (((volatile bits *)&reg)->b##bit)
13

14
// ...
15

16
SFR unsigned char USB_INT_FG @ 0xD8;
17

18
#define UIF_BUS_RST  SBIT(USB_INT_FG, 0)  
19
#define UIF_DETECT   SBIT(USB_INT_FG, 0)
20
#define UIF_TRANSFER SBIT(USB_INT_FG, 1)
21
#define UIF_SUSPEND  SBIT(USB_INT_FG, 2)
22
#define UIF_HST_SOF  SBIT(USB_INT_FG, 3)
23
#define UIF_FIFO_OV  SBIT(USB_INT_FG, 4)
24
#define U_SIE_FREE   SBIT(USB_INT_FG, 5)
25
#define U_TOG_OK     SBIT(USB_INT_FG, 6)
26
#define U_IS_NAK     SBIT(USB_INT_FG, 7)


PS: In dieser Zeile ist dir übrigens ein Underscore verrutscht:

1
    #define U_IS_NAK     (USB_INT__FGbit.U_IS_NAK)

Es sollte wohl so heißen:

1
    #define U_IS_NAK     (USB_INT_FG_bit.U_IS_NAK)
OP
Yalu X. schrieb:
> #define SBIT(reg, bit) (((volatile bits *)&reg)->b##bit)

Vielen Dank Yalu, das Makro gefällt mir noch am besten. Passt auch gut 
zu den anderen Compileren, das werde ich einbauen und testen.
Es sind auch noch ein paar wenige andere Fehler im h File zb SBUF. Ist 
halt mein erster Kontakt mit IAR.

Thomas
OP
Es wäre so elegant gewesen... geht aber nicht da Pointer im sfr Bereich 
vom Compiler nicht erlaubt sind. Das gilt übrigens genauso für SDCC und 
Keil. Ist ein Architektur Ding. Bleibt also nur die lange Variante.
Dein SBIT Makro arbeitet korrekt wie es soll.

Der Code compiliert nun mit minimalen Änderungen. Jetzt muss ich nur 
noch herausbekommen wie ich die Startadresse auf etwas anderes als 0 
gesetzt bekomme.
Keil und SDCC sind irgendwie übersichtlicher.

Thomas
OP
Insgesamt muss ich sagen dass man schon etwas Zeit investieren muss bis 
man den Dreh mit den Optionen und Einstellungen raus hat. Ich hab auch 
das Gefühl dass die IDE manchmal seltsame Dinge tut wenn man an den 
Optionen dreht.
Fakt ist dass die IDE abstürzt wenn man ein Clean macht und im Editor 
noch ein File offen hat was durch Clean gelöscht wird.
Zum linken an eine andere Addresse als 0 muss man den startup Code 
ändern. Dort wird mit einem Makro überprüft ob der ResetVector bei 0 
liegt. Dieses Makro muss man deaktivieren, den Rest kann man dann im 
Linker Controlfile einstellen.
Zur Code Größe kann ich keine genauen Angaben machen, da ich das Demo 
Limit erreiche. Vom Gefühl her würde ich aber sagen, dass IAR etwas 
schlechter als Keil ist aber besser als SDCC.

Thomas

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.