Atmel website | ARM Community | AVR freaks | Technical Support
Banner
 FAQ •  Search •  Register •  Login 

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 11 posts ] 
Author Message
 Post subject: SPI read - shifted bits
PostPosted: Fri Aug 20, 2010 5:25 pm 
Offline

Joined: Fri Aug 20, 2010 5:12 pm
Posts: 6
We are running uTasker + RUM on an AT91SAM7X256-EK board with REB board version 2.1.

We try to communicate thru SPI with the RF230, but communication seems to be erroneous. The hal_register_read function below seems to be reading values shifted to the left with one bit (e.g. expected: address = 0x11, actual result: address = 0x22).

Any ideas?

Thanks,
Alex

Code:
/** @brief  This function reads data from one of the radio transceiver's registers.
*          This function is relocated to SRAM.
*
*  @param  address Register address to read from. See datasheet for register
*          map.
*
*  @see    Look at the at86rf23x_registermap.h file for register address
*          definitions.
*
*  @returns The actual value of the read register.
*
*/
u8 hal_register_read(u8 address)
{
    u8 dummy = 0;

    //Add the register read command to the register address.
    address &= HAL_TRX_CMD_RADDRM;
    address |= HAL_TRX_CMD_RR;

    // Send the address to read.
    fnInUserInterrupt(1); // entering;
    uDisable_Interrupt() ;

    // Pull SEL line.
    //PIO_CODR_A = _BV(SPI_RF_NPCS);
    PIO_CODR_A = SPI_CS0_1B;

    // Transmission is started by writing the transmit data.
    SPI_TDR_1 = address;

    // Wait for receiver data register full.
    while((SPI_SR_1 & SPI_RDRF) == 0);

    // Dummy read.
    dummy = SPI_RDR_1;

    // Read the data by sending a dummy byte.

    // Transmission is started by writing the transmit data.
    SPI_TDR_1 = HAL_DUMMY_READ;

    // Wait for receiver data register full.
    while((SPI_SR_1 & SPI_RDRF) == 0);

    // Release SEL line.
    PIO_SODR_A = SPI_CS0_1B;

    // Read data.
    address = SPI_RDR_1;

    uEnable_Interrupt();
    fnInUserInterrupt(0); // leaving

    return address;
}


Top
 Profile  
 
 Post subject: Re: SPI read - shifted bits
PostPosted: Fri Aug 20, 2010 6:06 pm 
Offline

Joined: Thu Feb 25, 2010 5:02 pm
Posts: 88
Hello,

Code looks ok to me.

If you are passing in 0x11 to this function it is returning the contents of register 0x11 (BATMON) as 0x22.

According to the data sheet this decodes to:
BATMON_OK=1 (above the threshold)
BATMON_HR=0
BATMON_VTH=0x2 (1.8V threshold with BATMON_HR=0)

Regards,

_________________
Duane P. Fridley, IEEE CSDP
Viable Bytes, Inc.


Top
 Profile  
 
 Post subject: Re: SPI read - shifted bits
PostPosted: Fri Aug 20, 2010 6:27 pm 
Offline

Joined: Fri Aug 20, 2010 5:12 pm
Posts: 6
Hi Duane,

Thank you for your reply.

I meant to say that data in the reply comes shifted with one bit. For example, if I try to read MAN_ID_0:

hal_register_read(0x1E) returns 0x3E instead of 0x1F as it should.

We have tried to correct this by manually shifting to the right, like this [1], but I'm not sure this is fixing the actual problem.

Thank you,
Alex

[1]
Code:
u8 hal_register_read(u8 address)
{
u32 dummy = 0;

//Add the register read command to the register address.
address &= HAL_TRX_CMD_RADDRM;
address |= HAL_TRX_CMD_RR;

// Send the address to read.
fnInUserInterrupt(1); // entering;
uDisable_Interrupt() ;

// Pull SEL line.
//PIO_CODR_A = _BV(SPI_RF_NPCS);
PIO_CODR_A = SPI_CS0_1B;

// Transmission is started by writing the transmit data.
SPI_TDR_1 = address;

// Wait for receiver data register full.
while((SPI_SR_1 & SPI_RDRF) == 0);

// Dummy read.
dummy = SPI_RDR_1;

// Read the data by sending a dummy byte.

// Transmission is started by writing the transmit data.
SPI_TDR_1 = (u8)dummy; //HAL_DUMMY_READ;

dummy = dummy << 8;
// Wait for receiver data register full.
while((SPI_SR_1 & SPI_RDRF) == 0);



// Read data.
dummy |= SPI_RDR_1;

dummy = dummy >> 1;

// Release SEL line.
PIO_SODR_A = SPI_CS0_1B;

uEnable_Interrupt();

fnInUserInterrupt(0); // leaving

return (u8)dummy;
}


Top
 Profile  
 
 Post subject: Re: SPI read - shifted bits
PostPosted: Fri Aug 20, 2010 6:56 pm 
Offline

Joined: Thu Feb 25, 2010 5:02 pm
Posts: 88
Ok.

Check your spi configuration.

I've seen this happen if the CPOL and NCPHA are incorrectly configured in the "SPI Chip Select Register".

Regards,

_________________
Duane P. Fridley, IEEE CSDP
Viable Bytes, Inc.


Top
 Profile  
 
 Post subject: Re: SPI read - shifted bits
PostPosted: Fri Aug 20, 2010 7:16 pm 
Offline

Joined: Fri Aug 20, 2010 5:12 pm
Posts: 6
I think the SPI configuration is ok. CPOL is 0. We have made a minor adjustment to the SPI init [2], to lower the baud from 6MHz to about 500kHz:

Code:
SPwe_CSR0_1 = ((0x08 << SPwe_SCBR_LSB) | SPwe_8_BweTS | SPwe_NCPHA);

with:
Code:
SPwe_CSR0_1 = ((0xC8 << SPwe_SCBR_LSB) | (0x08 << 24) | (0x08 << 16) | SPwe_8_BweTS | SPwe_NCPHA);


because the original one was producing random values for the register dump from the tranceiver, but I don't think this change has any negative impact.

What do you think?

Thank you,
Alex

[2]
Code:
int spiInit(void)
{
// Before anything else, reset the SPI.
SPI_CR_1 = SPI_SWRST;

// Enable either A or B peripheral of PIOA.
PIO_BSR_A = SPI_RF_PINS;

// Disable PIO control and Enable manual control for sel pin and peripheral
// control for miso, mosi and sck.
PIO_PDR_A = SPI_RF_PINS;

// Enable manual control of the sel pin.
PIO_PER_A = SPI_CS0_1B;

// Set SEL line as an output pin.
PIO_OER_A = SPI_CS0_1B;

// Set the line drive to high for CS.
PIO_SODR_A = SPI_CS0_1B;

// Enable SPI clock.
PMC_PCER = (PMC_PCSR | SPI1);

// SPI reset - AGAIN! Then enable!
SPI_CR_1 = SPI_SWRST;
SPI_CR_1 = SPIEN;

// Set SPI to fixed peripheral at SPI0_CS2 or SPI1_CS0, fault detection
// disabled, master mode.
SPI_MR_1 = ((SPI_RF_CS_MR << SPI_PCS_LSB) | MODFDIS | SPI_MSTR);

// Data is sampled on the falling edge of the SPCK.
// SPI baud is empirically set to 6.5MHz.
SPI_CSR0_1 = ((0xC8 << SPI_SCBR_LSB) | (0x08 << 24) | (0x08 << 16) | SPI_8_BITS | SPI_NCPHA);
//SPI_CSR0_1 = ((0xC8 << SPI_SCBR_LSB) | SPI_8_BITS | SPI_NCPHA);
//SPI_CSR0_1 = ((0x08 << SPI_SCBR_LSB) | SPI_8_BITS | SPI_NCPHA);
return 0;
}


Top
 Profile  
 
 Post subject: Re: SPI read - shifted bits
PostPosted: Fri Aug 20, 2010 7:32 pm 
Offline

Joined: Thu Feb 25, 2010 5:02 pm
Posts: 88
Quote:
Code:
SPwe_CSR0_1 = ((0xC8 << SPwe_SCBR_LSB) | (0x08 << 24) | (0x08 << 16) | SPwe_8_BweTS | SPwe_NCPHA);


The clock polarity is ok I believe you need to remove the SPWe_NCPHA from the bitwise OR for proper communication with the RF230.

Edit
The Atmel data sheet is a little confusing :? the NCPHA is Not CPHA so by not setting it you are setting the proper mode (mode 1).

Regards,

_________________
Duane P. Fridley, IEEE CSDP
Viable Bytes, Inc.


Top
 Profile  
 
 Post subject: Re: SPI read - shifted bits
PostPosted: Fri Aug 20, 2010 7:57 pm 
Offline

Joined: Fri Aug 20, 2010 5:12 pm
Posts: 6
Hmmm... it makes sense... however, we've just tried without SPI_NCPHA with both the original and the modified versions of the hal_register_read function and it did not work, we could not initialize the chip (although with SPI_NCPHA it initializes).

Thanks,
Alex


Top
 Profile  
 
 Post subject: Re: SPI read - shifted bits
PostPosted: Fri Aug 20, 2010 8:15 pm 
Offline

Joined: Thu Feb 25, 2010 5:02 pm
Posts: 88
You might try adding a delay before the first SPCK transistion by setting the DLYBS field in the CSR register.

Edit
Oops, sorry I see you already have the DLYBS set (got side tracked with paying work)... Just for a test you could set this to max 0xFF. If I get a chance tomorrow I'll take a closer look at your code and see if anything jumps out.

Regards,

_________________
Duane P. Fridley, IEEE CSDP
Viable Bytes, Inc.


Top
 Profile  
 
 Post subject: Re: SPI read - shifted bits
PostPosted: Sat Aug 21, 2010 10:26 am 
Offline

Joined: Fri Aug 20, 2010 5:12 pm
Posts: 6
Hi,

Just tried with 0xFF for DLYBS and there is no change :(

Thanks... it was worth the shot...

Alex


Top
 Profile  
 
 Post subject: Re: SPI read - shifted bits
PostPosted: Sat Aug 21, 2010 2:20 pm 
Offline

Joined: Thu Feb 25, 2010 5:02 pm
Posts: 88
Hmm. You might scope the CS and SCLK lines (trigger on the falling edge of CS) and see if there is a delay from CS to the first SCLK rising edge. My experience with the DLYBS works with variable CS, I can't remember if it also works with Fixed CS.

If there is no delay try adding a short delay after asserting the CS line before you send the data.

_________________
Duane P. Fridley, IEEE CSDP
Viable Bytes, Inc.


Top
 Profile  
 
 Post subject: Re: SPI read - shifted bits
PostPosted: Thu Aug 26, 2010 5:01 pm 
Offline

Joined: Fri Aug 20, 2010 5:12 pm
Posts: 6
Hi Duane,

Thanks for all the help. It worked after all. The weird behavior was caused by the chips on the REB board being quite old. We replaced them and now it's working wonderfully.

Thanks,
Alex


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: Google [Bot] and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: