Forum: Mikrocontroller und Digitale Elektronik LPC1758 und PN532 über SPI


von Jay B. (cellardoor)


Lesenswert?

Hallo,

ich versuche vergeblich die Komunikation zwischen meinem LPC1758 und 
einem PN532 NFC Modul zum Laufen zu bringen. Mit Hilfe des SSP 
Interfaces und der NXP Library habe ich bereits die SPI-MOSI Verbindung 
zum Laufen gebracht.

Leider bekommen ich vom NP532 bis jetzt keine Reaktion auf der MISO 
Leitung.

Meine Initialisierung sieht in etwa so aus:
1
     
2
  SSP_INIT_STRUC.CPHA = SSP_CPHA_FIRST;
3
  SSP_INIT_STRUC.CPOL = SSP_CPOL_HI;
4
  SSP_INIT_STRUC.ClockRate = 5000000;
5
  SSP_INIT_STRUC.Databit = SSP_DATABIT_8;
6
  SSP_INIT_STRUC.Mode = SSP_MASTER_MODE;
7
  SSP_INIT_STRUC.FrameFormat = SSP_FRAME_SPI;
8
9
  PINSEL_InitStruct.Funcnum=PINSEL_FUNC_2;    //2      SLK
10
  PINSEL_InitStruct.OpenDrain=PINSEL_PINMODE_OPENDRAIN;  //OPendrain
11
  PINSEL_InitStruct.Pinmode=PINSEL_PINMODE_TRISTATE;    //tristate
12
  PINSEL_InitStruct.Pinnum=PINSEL_PIN_7;
13
  PINSEL_InitStruct.Portnum=PINSEL_PORT_0;
14
  PINSEL_ConfigPin(&PINSEL_InitStruct);
15
16
  PINSEL_InitStruct.Funcnum=PINSEL_FUNC_2;        //2  MISO
17
  PINSEL_InitStruct.OpenDrain=PINSEL_PINMODE_NORMAL;  //normal
18
  PINSEL_InitStruct.Pinmode=PINSEL_PINMODE_TRISTATE;
19
  PINSEL_InitStruct.Pinnum=PINSEL_PIN_8;
20
  PINSEL_InitStruct.Portnum=PINSEL_PORT_0;
21
  PINSEL_ConfigPin(&PINSEL_InitStruct);
22
23
  PINSEL_InitStruct.Funcnum=PINSEL_FUNC_2;        //2  MOSI
24
  PINSEL_InitStruct.OpenDrain=PINSEL_PINMODE_NORMAL;   //normal
25
  PINSEL_InitStruct.Pinmode=PINSEL_PINMODE_PULLUP;
26
  PINSEL_InitStruct.Pinnum=PINSEL_PIN_9;
27
  PINSEL_InitStruct.Portnum=PINSEL_PORT_0;
28
  PINSEL_ConfigPin(&PINSEL_InitStruct);
29
30
  PINSEL_InitStruct.Funcnum=PINSEL_FUNC_2;        //2  SSEL
31
  PINSEL_InitStruct.OpenDrain=PINSEL_PINMODE_NORMAL;   //normal
32
  PINSEL_InitStruct.Pinmode=PINSEL_PINMODE_PULLUP ;
33
  PINSEL_InitStruct.Pinnum=PINSEL_PIN_6;
34
  PINSEL_InitStruct.Portnum=PINSEL_PORT_0;
35
  PINSEL_ConfigPin(&PINSEL_InitStruct);


Und meine Sendeversuche so:
1
   spi_data[0] = (0x00); //preambule
2
    spi_data[1] = (0x00); //start
3
    spi_data[2] = (0xFF); //start
4
    spi_data[3] = (0x06); //packet length
5
    spi_data[4] = (0xFA); //checksum
6
    spi_data[5] = (0xD4); //tfi
7
    spi_data[6] = (0x14); //data
8
    spi_data[7] = (0x01); //data
9
    spi_data[8] = (0x00); //data
10
    spi_data[9] = (0x01); //data
11
    spi_data[10] = (0xE9); //dcs
12
    spi_data[11] = (0x00); //post
13
14
for(i = 0; i<12; i++) {
15
  SSP_SendData(LPC_SSP1,spi_data[i]);
16
                      }

Außerdem verstehe ich nicht wie man die Checksum berechnet. Im 
Usermanualauf Seite 28 heßt es hierzu " 1 Packet Length Checksum LCS 
byte that satisfies the relation: Lower byte of [LEN + LCS] = 0x00 "

Vielleicht gibt es ja jemanden, der so etwas ähnliches schon gemacht hat 
und mir helfen kann? Ich probier schon den ganzen Tag herum und komme 
nicht drauf. Hier noch das Usermanual für den NP532 
http://www.nxp.com/documents/user_manual/141520.pdf

danke schon mal für eure Hilfe und mit freundlichen Grüßen

von grundschüler (Gast)


Lesenswert?

spi wird dann schwierig, wenn ein fifo vorhanden ist. Bist du sicher, 
dass deine Senderoutine den fifo berücksichtigt?

Senderoutine von Elm Chan:
1
/* Send multiple byte */
2
static
3
void xmit_spi_multi (
4
  const BYTE *buff,  /* Pointer to the data */
5
  UINT btx      /* Number of bytes to send (512) */
6
)
7
{
8
  UINT n = 512;
9
  WORD d;
10
11
12
  SSPxCR0 = 0x000F;      /* Select 16-bit mode */
13
14
  for (n = 0; n < 8; n++) {  /* Push 8 frames into pipeline  */
15
    d = *buff++;
16
    d = (d << 8) | *buff++;
17
    SSPxDR = d;
18
  }
19
  btx -= 16;
20
  do {            /* Transmit data block */
21
    d = *buff++;
22
    d = (d << 8) | *buff++;
23
    while (!(SSPxSR & _BV(2))) ;
24
    SSPxDR; SSPxDR = d;
25
  } while (btx -= 2);
26
  for (n = 0; n < 8; n++) {
27
    while (!(SSPxSR & _BV(2))) ;
28
    SSPxDR;
29
  }
30
31
  SSPxCR0 = 0x0007;      /* Select 8-bit mode */
32
}

von Jim M. (turboj)


Lesenswert?

Stelle mal den P0.6 (SSEL0) auf GPIO zurück und setzte den Output 
manuell.
Beim automatischen CS kann der Pin zwischen 2 Bytes kurz high werden, 
das will man meistens nicht so haben.

von Jay B. (cellardoor)


Lesenswert?

Danke für eure Tipps,

stimmt ich hab hab den fifo nicht berücksichtigt. Bedeutet das, dass ein 
Circular Buffer für die Kommunikation benötigt wird ?

Ich habe SSEL jetzt manuell gesteuert, da man auf dem Oszi wirklich 
gesehn hat, dass P0.6 zwischen den einzelnen Bytes immer wieder auf High 
gezogen wurde.

von grundschüler (Gast)


Angehängte Dateien:

Lesenswert?

Jay Bee schrieb:
> Circular Buffer?

du musst nur sehen, dass vor dem Lesen im Fifo keine alten Werte mehr 
stehen.

Zum Austesten von spi-Problemen empfiehlt sich bitbang-code/Dateianhang. 
Du brauchst nur noch die defines für pinDIR etc. Beim lpc1768 sehen die 
so aus:
1
#define pinSET(portn,pinn) (*(volatile uint32_t*)(0x2009C018UL+(portn*0x20UL)))|=(1UL<<pinn)
2
#define pinCLR(portn,pinn) (*(volatile uint32_t*)(0x2009C01CUL+(portn*0x20UL)))|=(1UL<<pinn)
3
#define pinDIRin(portn,pinn)  (*(volatile uint32_t*)(0x2009C000UL+(portn*0x20UL)))&=~(1UL<<pinn)
4
#define pinDIRout(portn,pinn) (*(volatile uint32_t*)(0x2009C000UL+(portn*0x20UL)))|=(1UL<<pinn)
5
#define pinSEL(p,b,v)    PINSEL[(p) * 2 + (b) / 16] = (PINSEL[(p) * 2 + (b) / 16] & ~(3 << ((b) * 2 % 32))) | (v << ((b) * 2 % 32))
6
#define pinVAL(portn,pinn) ((*(volatile uint32_t*)(0x2009C014UL+(portn*0x20UL))& (1<<pinn))>>pinn)
7
#define pinTOG(portn,pinn) ((*(volatile uint32_t*)(0x2009C014UL+(portn*0x20UL))^= (1<<pinn)))
 (aus LPC176x.h)

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.