Probleme beim RFid lesen mit EM4095

OP #4105739
Lesenswert?
• ▲
▼
Hallo zusammen,
ich moechte an meinem AtMega1280 in einem Mikroelektronika BigAVR6 board 
einen RFid Reader anschliessen. Dafuer habe ich mir das passende 
Erweiterungsboard mit einem EM4095 gekauft und mich ans programmieren 
gesetzt, das dauert jetzt leider schon mehrere Wochen. Ich schaffs 
einfach nicht das Teil ordentlich zum laufen zu bringen.

Mein Ansatz:

RFid board an PORTK.
Interrupt auf out-pin.
Wenn fallende Flanke erkannt, interrupt auf clk-pin.
ab da zaehle ich im interrupt die clk zyklen. Jeden 64. Interrupt lese 
ich ein Datenbit, und zwar einmal das untere und das naechste mal das 
obere. Sind die beiden Bits unterschiedlich, steht die Information im 
unteren Bit (invertierte Manchaster codierung).
Dann warte ich auf weitere acht einsen, das waere dann das startpaket. 
Liegt eine null dazwischen, lege ich den Interrupt wieder auf den 
out-pin und versuche mich neu zu synchronisieren.
Konnten 9 Einsen gelesen werden, starte ich die Daten zu lesen und in 
einem Array abzulegen. Dabei ueberpruefe ich mit jedem 5. Bit die 
paritaet der vorherigen 4 bits und zum schluss das Stop-bit.
Wenn bis zum Ende keine Paritaet verletzt wurde und das Stop-bit 0 ist, 
uebergebe ich die Daten einem Handler der damit machen kann was er 
moechte, ansonsten wird der Handler mit einem Fehlerstatus aufgerufen.

Das ganze scheint aber nicht zu funktionieren (der Handler wird nur sehr 
selten mit SUCCESS aufgerufen und wenn dann mit falschen Daten). Ich 
sitz jetzt schon 2 Wochen lang am debuggen und kann den Fehler einfach 
nicht finden.
Wenn mir vielleicht jemand Helfen koennte? Vielleicht ist mein Ansatz ja 
auch komplett falsch?

Header:
1
#ifndef RFID_H
2
#define RFID_H
3

4
#define RFID_PORT (PORTK)
5
#define RFID_PIN (PINK)
6
#define RFID_DDR (DDRK)
7
#define RFID_INT_CR (PCICR)
8
#define RFID_INT_MSK (PCMSK2)
9
#define RFID_INT_VECT (PCINT2_vect)
10

11
#include "util.h"
12
#include <avr/io.h>
13
#include <stdlib.h>
14
#include <stdbool.h>
15
#include <avr/interrupt.h>
16
#include <avr/sleep.h>
17

18
typedef enum {
19
  VALID,
20
  INVALID,
21
} status_t;
22

23
//configuration and Handler registration
24
error_t rfid_init(void (*decodeEvent)(status_t, uint8_t*));
25

26
//interrupt enable and wake up RFid reader
27
error_t rfid_enable(void);
28

29
//put RFid reader to sleep and disable interrupts
30
void rfid_disable(void);
31

32
#endif

Code:
1
#include "rfid.h"
2

3
static void (*handler)(status_t, uint8_t*);
4

5
static volatile uint8_t one_cnt = 0;
6
static volatile uint8_t clk_cnt = 0;
7
static volatile uint8_t data_cnt = 0;
8
static volatile uint8_t row_cnt = 0;
9
static volatile uint8_t lower_level = 0;
10
static volatile uint8_t *data;
11
static volatile uint8_t prev = 0;
12
static volatile uint8_t checked = 1;
13

14
error_t rfid_init(void (*_handler)(status_t, uint8_t*))
15
{
16
  RFID_DDR = 0xFC;
17
  RFID_PORT = 0x07;
18
  RFID_INT_MSK = 0x01;
19
  handler = _handler;
20
  return SUCCESS;
21
}
22

23
error_t rfid_enable(void)
24
{
25
  if(((RFID_INT_CR & 0x04) != 0) || ((RFID_PIN & 0x04) == 0))
26
  {
27
    return ERROR;
28
  }
29
  one_cnt = 0;
30
  clk_cnt = 0;
31
  data_cnt = 0;
32
  row_cnt = 0;
33
  lower_level = 0;
34
  prev = 0;
35
  checked = 1;
36
  RFID_INT_MSK = 0x01;
37
  RFID_INT_CR |= 0x04;
38
  RFID_PORT &= 0xFB;
39
  return SUCCESS;
40
}
41

42
void rfid_disable(void)
43
{
44
  RFID_PORT |= 0x04;
45
  RFID_INT_CR &= 0xFB;
46
}
47

48
void inline __attribute__((always_inline)) use_data(void)
49
{
50
  //parity
51
  if(checked != 1 && ((data_cnt & 0x03) == 0x00))
52
  {
53
    uint8_t val = data[row_cnt];
54
    if(((((val)^(val >> 1))^((val >> 2)^(val >>3)))&0x01) == lower_level)
55
    {
56
      data[row_cnt] &= 0x0F;
57
      row_cnt++;
58
      data[row_cnt] = 0;
59
    }
60
    else
61
    {
62
      handler(INVALID, (uint8_t*)data);
63
      one_cnt = 0;
64
      RFID_INT_MSK = 0x01;
65
    }
66
    //last parity
67
    if(data_cnt > 42)
68
    {
69
      val = 0;
70
      for(row_cnt = 0; row_cnt < 10; row_cnt++)
71
        val ^= data[row_cnt];
72
      if((lower_level == 0x00) && (((val ^ (data[10])) & 0x0F) == 0x00))
73
      {
74
        handler(VALID, (uint8_t*)(&data[2]));
75
      }
76
      else
77
      {
78
        handler(INVALID, (uint8_t*)data);
79
      }
80
      one_cnt = 0;
81
      RFID_INT_MSK = 0x01;
82
    }
83
    checked = 1;
84
  }
85
  else
86
  {
87
    data[row_cnt] = (data[row_cnt] << 1) | lower_level;
88
    //save data
89
    data_cnt++;
90
    checked = 0;
91
  }
92
}
93

94

95
ISR(RFID_INT_VECT, ISR_BLOCK){
96
  clk_cnt++;
97
  //Already had a one
98
  if(one_cnt != 0){
99
    //every 64th clk
100
    if((clk_cnt & 0x3F) == 0)
101
    {
102
      //second manchester bit
103
      if((clk_cnt & 0x40) == 0)
104
      {
105
        //toggle
106
        if(lower_level != (RFID_PIN & 0x01))
107
        {
108
          //need more ones
109
          if(one_cnt != 9)
110
          {
111
            //found another one
112
            if((RFID_PIN & 0x01) == 0x00)
113
            {
114
              one_cnt++;
115
              //last sync one?
116
              if(one_cnt == 9)
117
              {
118
                PORTL++;
119
                data_cnt = 0;
120
                data = malloc(11*sizeof(uint8_t));
121
                data[0] = 0;
122
                row_cnt = 0;
123
                data[0] = 0;
124
                checked = 1;
125
              }
126
            }
127
            //synchronisation lost
128
            else
129
            {
130
              one_cnt = 0;
131
              RFID_INT_MSK = 0x01;
132
              free((void*)data);
133
            }
134
          }
135
          else
136
          {
137
            use_data();
138
          }
139
        }
140
      }
141
      //first manchester bit
142
      else
143
      {
144
        lower_level = (RFID_PIN & 0x01);
145
      }
146
    }
147
  }
148
  else if((RFID_PIN & 0x01) == 0)
149
  {
150
    //first one. Needed to synchronize
151
    clk_cnt = 0x40;
152
    one_cnt = 1;
153
    lower_level = 0x01;
154
    //disable interrupt on out pin, synchronisation is done via clk
155
    RFID_INT_MSK = 0x02;
156
  }
157
}
(Firma: Vescomp) #4105859
Lesenswert?
• ▲
▼
Ich Selbst schrieb:
> Wenn mir vielleicht jemand Helfen koennte? Vielleicht ist mein Ansatz ja
> auch komplett falsch?

 Ich kann mich jetzt nicht mehr genau erinnern, aber ich habe das mit
 OCR0A gemacht, wenn der gefeuert hat war es Timeout, ansonsten
 war es zwischen 20 und 45 Shortbit, zwischen 50 und 80 Longbit, alles
 andere war Fehler.
 Statemachine aufbauen mit PrevState, FlankenArt und PrevBit.
OP #4106399
Lesenswert?
• ▲
▼
Hi,
also du hast den interrupt am out-pin und machst die synchronisation 
ueber einen Timer? Ich habe gesehen die frequenz am clk kann start 
variieren, deshalb wollte ich mich nicht auf einen Timer verlassen.
Mein naechster Ansatz waere gewesen clk an einen Counter zu haengen, 
dann spar ich mir die lange ISR beim interrupt den ich beim clk hatte 
und hab die selbe information wie du von wegen timeout.
Werds mal sauber implementieren, mit state machine und so, und meld mich 
wieder zurueck obs geklappt hat!

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

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.