This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP430FR4133: SPI read alaways zero when connect MSP430FR4133 with rc520

Part Number: MSP430FR4133

Tool/software: Code Composer Studio

i am trying to communicate with rc520 SPI peripheral with below code but i am always get zeros when read spi here my code(i am using library but i give you only what i use):-

#include <msp430fr4133.h>


#define RC522EN BIT3 //pin 8.3 is the enable pin
#define RC522CS BIT0 //pin 4.0 is the reset pin

#define RC522READ 0x80 //bit 7 set for read operation
#define RC522WRITE 0x7E //bit 7 unset for write operation

//Page 1:Command
#define Reserved10 0x10
#define ModeReg 0x11
#define TxModeReg 0x12
#define RxModeReg 0x13
#define TxControlReg 0x14
#define TxAutoReg 0x15
#define TxSelReg 0x16
#define RxSelReg 0x17
#define RxThresholdReg 0x18
#define DemodReg 0x19
#define Reserved11 0x1A
#define Reserved12 0x1B
#define MifareReg 0x1C
#define Reserved13 0x1D
#define Reserved14 0x1E
#define SerialSpeedReg 0x1F


inline void readRC522(unsigned char addr, unsigned char *value){
//read a register's value
 spitxrx(RC522CS, ((addr << 1) & RC522WRITE) | RC522READ, value, 1, 0);
return;
}


unsigned char verifyRC522(unsigned char addr, unsigned char data, unsigned char mask){


unsigned char regval=0;
readRC522(addr, &regval);//always regval is zero?????
if((data&mask)==(regval&mask)) return 1; //data matches

//error
return 0;
}

inline void writeRC522(unsigned char addr, unsigned char value){
//set a particular register to a value
spitxx(RC522CS, (addr<<1)&RC522WRITE, value);
return;
}

void spitxx(int enpin, unsigned char addr, unsigned char data){

P4OUT &= ~enpin; //set CS low to select chip
__delay_cycles(1000); //wait 1 milliseconds for startup

while(UCB0STATW & UCBUSY);//make sure the bus is not in use
UCB0TXBUF=addr;
while(!(UCB0IFG & UCTXIFG));//wait for room in tx bufer
UCB0TXBUF=data;
while(UCB0STATW & UCBUSY);//wait for communication to complete
P4OUT |= enpin; //set CS high to deselect chip
__delay_cycles(1000); //wait 1 milliseconds for startup
return;
}

void NSSHigh_Low(void)
{
P8OUT &= ~RC522EN;
__delay_cycles(50000); //wait 50 milliseconds for full-on shutdown
P8OUT |= RC522EN;
__delay_cycles(500000); //wait 50 milliseconds for startup // Exit power down mode. This triggers a hard reset.
//Section 8.8.2 in the datasheet says the oscillator start-up time is the start up time of the crystal
}

void initClockTo16MHz()
{
// Configure one FRAM waitstate as required by the device datasheet for MCLK
// operation beyond 8MHz _before_ configuring the clock system.
FRCTL0 = FRCTLPW | NWAITS_1;

__bis_SR_register(SCG0); // disable FLL
CSCTL3 |= SELREF__REFOCLK; // Set REFO as FLL reference source
CSCTL0 = 0; // clear DCO and MOD registers
CSCTL1 &= ~(DCORSEL_7); // Clear DCO frequency select bits first
CSCTL1 |= DCORSEL_5; // Set DCO = 16MHz
CSCTL2 = FLLD_0 + 487; // set to fDCOCLKDIV = (FLLN + 1)*(fFLLREFCLK/n)
// = (487 + 1)*(32.768 kHz/1)
// = 16 MHz

__delay_cycles(3);
__bic_SR_register(SCG0); // enable FLL
while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // FLL locked
}

int main(void) {


WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

P4DIR = BIT0;
P4OUT = BIT0;
P4SEL0 = 0;
P4REN = 0;

P5DIR = 0;
P5OUT = 0;
P5SEL0 = BIT0 + BIT1 + BIT2 + BIT3;
P5REN = 0;

P6DIR = 0;
P6OUT = 0;
P6SEL0 = 0;
P6REN = 0;

P7DIR = BIT4 | BIT5;
P7OUT = 0;
P7SEL0 = 0;
P7REN = 0;

P8DIR = BIT3;
P8OUT = BIT0;
P8SEL0 = 0;
P8REN = 0;

// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;

 

//////////////SPI init
UCB0CTLW0 = UCSWRST; // **Put state machine in reset**
UCB0CTLW0 |= UCMST + UCSYNC + UCCKPL + UCMSB; // 3-pin, 8-bit SPI master MSB
UCB0CTLW0 |= UCSSEL_2; // SMCLK
UCB0BR0 |= 4; // CLK / 1
UCB0BR1 = 0;
UCB0CTL1 &= ~UCSWRST;

//bring reset high and wait for chip to wake up:
NSSHigh_Low();

writeRC522(TModeReg, 0x8D); //Tauto=1, f(timer)=6.78 MHz/TPreScaler was 8D
writeRC522(TPrescalerReg, 0x3E); //was 3E
writeRC522(TReloadRegL, 1); //was dec30
writeRC522(TReloadRegH, 30); //was 0
writeRC522(TxAutoReg, 0x40);
writeRC522(ModeReg, 0x3D);
writeRC522(RFCfgReg, regvar[RFCfgReg][0]); //max power
writeRC522(CommandReg, PCD_IDLE);
writeRC522(FIFOLevelReg, BIT7); //flush FIFO

if(!verifyRC522(TModeReg, TModeReg,0x8D){

//errrrrrrrrrrrrrror

}

}

any support will be apperiated

  • 1) spitxrx() is kind of central to your question, but I don't see it defined anywhere

    2) This

    > if(!verifyRC522(TModeReg, TModeReg,0x8D)

    doesn't look right. You set TModeReg to 0x8D above, so I don't think it will look much like 0x2A now. Maybe(?) you want something like:

    > if(!verifyRC522(TModeReg, 0x8D, 0xFF)

  • Thank you for your response about point:

    1-

    void spitxrx(int enpin, unsigned char addr, unsigned char *data, unsigned int len, unsigned char inc){

    unsigned int i=0;

    unsigned char workingaddr=addr, dummy;

    P4OUT &= ~enpin; //set CS low to select chip

    __delay_cycles(1000);  //wait 50 milliseconds for startup

    while(UCB0STATW & UCBUSY);//make sure the bus is not in use

    //dummy=UCB0RXBUF; //clear the rxready flag

    UCB0TXBUF=addr;

    while(!(UCB0IFG & UCRXIFG));//wait for byte to be received

    data[0]=UCB0RXBUF;

    while(len-i){

    workingaddr += inc;

    UCB0TXBUF=workingaddr;

    while(!(UCB0IFG & UCRXIFG));//wait for byte to be received

    data[i]=UCB0RXBUF;

    i++;

    }

    P4OUT |= enpin; //set CS high to deselect chip

    __delay_cycles(1000);  //wait 50 milliseconds for startup

    dummy++;

    return;

    }

    2- I think that error here that when I read from SPI I always read zeros, even this  I will try and feed you back with results.

  • Are you fairly certain the RC522 is in SPI mode? How are the I2C and EA pins wired? [Ref MFRC522 data sheet R3.9, Table 5]

  • Hmmmm, I wonder why you said that. I have rc520 and I believe that it didn't has i2c, but from your point of view do you think that the above code will work and has no logical errors? Also I have question is there any tool to know that SPI working fine? (Note: I don't have logic analyser or oscilscope)

    Thanks for your trying to help, appreciate that.

  • I've been looking at this device. I didn't find any obvious hits with "rc520", and there seemed to be some overlap in function.

    https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf

    Could you post a complete part number? (Or better yet, a data sheet link?)

    I didn't see anything obviously wrong with your code, so I'm looking outside.

  • here is it's data sheet i think it's same 522 except 522 has I2C

    chinaidcard.com/.../20170728182043_7212.pdf

  • Based on CV520 data sheet Sec 8.1.1 and Fig 13, I think you want UCCKPL=0 and UCCKPH=1.

    Also, when I ran the code through a formatter [Hint: Use Code Tags -- the button with the "</>" in it] I noticed this:

    > //dummy=UCB0RXBUF; //clear the rxready flag

    In context, I think this line is pretty important to avoid reading stale data. I would actually suggest you put this line at the end of spitxx, so you always exit with the IFGs in sync. Was there a reason you removed this line?

    --------------

    Debugging SPI without a scope can be tricky. Some general suggestions:

    1) Try reading some register that has a non-zero value at reset. This will help distinguish whether it's the read or the write failing.. It looks like (e.g.) ModGsPReg (0x29) is 0x20 after reset.

    2) Try reading a few registers at once. This will help show an off-by-1 error.

    3) Try slowing the SPI clock way down. Maybe start at 10kHz and work up. A slower SPI clock is more forgiving of slave quirks, loose connections, long wires, and questionable solder joints.

  • First this issue not resolved, I click the resolved button by mistake.

    About UCCKPH=1 I tried but no difference.

    For suggestions about dummy flag and SPI I will try your recommendation and feed you back with results.

    Thank you for your efforts ❤️.

  • I tried what we agreed but also with zero values in the reading SPI register.

  • What did you get from ModGsPReg?

  • Unfortunately, always Zeros

  • i have another things i want to ask you when i am out on NSS pin "P8OUT |= RC522EN;" i found the voltage 1.25 volt. Does rc520 will know that and enable functionality of rc520?

    i read on the data sheet that NSS must be one to work and to enable the rc520 ic, and NRSTPD must be low when send data by SPI and after sending data it will be high again like chip select. right ?

  • >P8DIR = BIT3;
    >P8OUT = BIT0;

    This looks a bit unusual. If one of these is NSS and the other NRSTPD you probably want to set both high and both output. I think this may be where your 1.25V is coming from.

    As I read the data sheet, the pin usage is just the opposite -- NRSTPD ("Not-RST") is used to reset the device and NSS ("Not-Slave-Select") is the SPI Chip Select. 

  • thank you the issue now is resolved, i made them opposite than other.

    now it works fine thank you

**Attention** This is a public forum