Forum: Mikrocontroller und Digitale Elektronik Probleme beim RFid lesen mit EM4095


von Ich S. (random_user789)


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
}

von Marc V. (Firma: Vescomp) (logarithmus)


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.

von Ich S. (random_user789)


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!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.