CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

SPI Slave problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Jerry I



Joined: 14 Sep 2003
Posts: 96
Location: Toronto, Ontario, Canada

View user's profile Send private message

SPI Slave problem
PostPosted: Thu Aug 15, 2013 7:05 pm     Reply with quote

Hi

Thanks in advance for any help on identifying my problem.

I trying to use this compass module from unagi.net

http://unagi.net/wp-content/uploads/2011/09/cm1015datasheet091.pdf

It is a SPI Master device, in which case I have configured the PIC 18F13K22 as a SPI slave device.

From the data sheet the compass module shifts out 32 data bytes. I in turn place the data in a buffer compass_data[32]
The first 2 bytes of data is refered as header bytes are
0xA0, 0x01.

I have confirmed this with my logic analyser.
https://dl.dropboxusercontent.com/u/61484629/Waveform.jpg

The 4 traces shown are.
Top #1

Test pin is -> at every change in state edge is the point where data is captured to buffer.

#2
SPI Clock from Compass Module

#3
SPI Data from Compass Module

#4
SDONE Signal from Compass Module, Data will start shifting out.


The data from the capture buffer
compass_data[0] = 0x50 compass_data[1] 0x00

It appears that the first byte 0x50 -> is bit reversed to the 1st header byte 0xA0

0x50 = 0b00000101 <-> 0xA0 = 0b10100000

Now the next byte, not captured at all correct. The rest of the bytes also do not appear to be correct.

Am I droping bytes/bits, Is it not saving it fast enough??.

Do I need to find a PIC with double buffer SPI interface.

Any ideas?.

Thanks

Jerry Question

I am using compiler version PCH 4.140

Code:

#case

#define PIC_18FXXX

#IFDEF PIC_18FXXX
  #include <18F13K22.h>

  #fuses intrc_io, nowdt, noprotect, mclr, nolvp, put, nofcmen, noieso
  #fuses borv27, nodebug, nopllen
  #device *=16
#ENDIF

#device adc=16

// #use delay(clock=64000000, internal)    //2 instruction=0.2us
// #use delay(clock=32000000, internal)    //2 instruction=0.2us
#use delay(clock=16000000, internal)    //2 instruction=0.2us
// #use delay(clock=8000000, internal)    //2 instruction=0.2us
// #use delay(int=8000000)

#use rs232(baud=9600, parity=N, xmit=PIN_B7, rcv=PIN_B5, bits=8, errors)

#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)

// ------- PORTS -----------------------------------

#byte PORTB      = 0xF81
#byte PORTA      = 0xF80

#byte TRISC      = 0xF94
#byte TRISB      = 0xF93
#byte TRISA      = 0xF92

// ------- PORTB Bits -----------------------------------

#bit portb7     = PORTB.7
#bit portb6     = PORTB.6
#bit portb5     = PORTB.5
#bit portb4     = PORTB.4
#bit portb3     = PORTB.3
#bit portb2     = PORTB.2
#bit portb1     = PORTB.1
#bit portb0     = PORTB.0

#bit rb7        = PORTB.7
#bit rb6        = PORTB.6
#bit rb5        = PORTB.5
#bit rb4        = PORTB.4
#bit rb3        = PORTB.3
#bit rb2        = PORTB.2
#bit rb1        = PORTB.1
#bit rb0        = PORTB.0

// ------- PORTA Bits -----------------------------------

#bit porta6     = PORTA.6
#bit porta5     = PORTA.5
#bit porta4     = PORTA.4
#bit porta3     = PORTA.3
#bit porta2     = PORTA.2
#bit porta1     = PORTA.1
#bit porta0     = PORTA.0

#bit ra6        = PORTA.6
#bit ra5        = PORTA.5
#bit ra4        = PORTA.4
#bit ra3        = PORTA.3
#bit ra2        = PORTA.2
#bit ra1        = PORTA.1
#bit ra0        = PORTA.0

// ------ TRISC Bits -----------------------------------

#bit trisc7     = TRISC.7
#bit trisc6     = TRISC.6
#bit trisc5     = TRISC.5
#bit trisc4     = TRISC.4
#bit trisc3     = TRISC.3
#bit trisc2     = TRISC.2
#bit trisc1     = TRISC.1
#bit trisc0     = TRISC.0

// ------ TRISB Bits ----------------------------------

#bit trisb7     = TRISB.7
#bit trisb6     = TRISB.6
#bit trisb5     = TRISB.5
#bit trisb4     = TRISB.4
#bit trisb3     = TRISB.3
#bit trisb2     = TRISB.2
#bit trisb1     = TRISB.1
#bit trisb0     = TRISB.0

// ------- TRISA Bits -----------------------------------

#bit trisa6     = TRISA.6
#bit trisa5     = TRISA.5
#bit trisa4     = TRISA.4
#bit trisa3     = TRISA.3
#bit trisa2     = TRISA.2
#bit trisa1     = TRISA.1
#bit trisa0     = TRISA.0


#define SCLK    rb6
#define SDAT    rb4
#define SDONE   ra2
#define SREQ    ra1
#define TESTPIN ra0

#define COMPASS_DATA    0x0e
#define INCLINOMETER_DATA   0x10

#define COMPASS_PACKET_LEN  32


typedef unsigned int8 uint8;

uint8 compass_data[32];
uint8 compass_back[32];
int8 read_cnt;

char rx_char;
int1 new_rx;

/************************************************************************
*  SPI IRQ
*/
/*******************************************************************************
 *  SPI  detector
 */
// #int_SSP
// void  SPI_isr(void)
// {
//         compass_data[read_cnt] = spi_read();
//         read_cnt++;
//
//         SREQ = 0;
// }

/************************************************************************
*  RX IRQ
*/
/*******************************************************************************
 *  RDA  detector
 */
#int_RDA
void  RDA_isr(void)
{
    rx_char = getc();

    if (rx_char == '{')
        reset_cpu(); //asci 123 for bootboader.

    if (rx_char == '?')
    {
        printf("Unagi Compass Module CM1015\r\n");
    }

    if (rx_char == 'r')
    {
        read_cnt = 0;
        SREQ = 1;
    }

    rx_char = '\0';
}
/*******************************************************************************

/*******************************************************************************

*  Main
*/
void main()
{
    int8 i;
    unsigned int16 heading, inclination;

    setup_wdt(WDT_OFF);
    setup_adc(ADC_OFF);

    setup_spi(SPI_SLAVE| SPI_MODE_0 |SPI_SS_DISABLED); //4

    clear_interrupt(INT_RDA);
    enable_interrupts(INT_RDA);

//     clear_interrupt(INT_SSP);
//     enable_interrupts(INT_SSP);

    enable_interrupts(GLOBAL);

//    setup_oscillator(OSC_16MHZ | OSC_PLL_OFF);
//    setup_oscillator(OSC_16MHZ | OSC_PLL_ON);
//    setup_oscillator(OSC_8MHZ | OSC_PLL_ON);
//    setup_oscillator(OSC_8MHZ | OSC_PLL_OFF);
//    setup_oscillator(OSC_8MHZ|OSC_TIMER1|OSC_31250|OSC_PLL_OFF);

    TRISB = 0b11111111;   // All Inputs Lower nibble Interrupt on change
    port_b_pullups(TRUE);

    TRISC = 0b00000000;

    TRISA = 0b00001100;

    port_a_pullups(0x04);

    port_b_pullups(0x50);

    SREQ = 0;
    TESTPIN = 0;

    printf("Unagi Compass Module CM1015 Interface\r\n");

    while(TRUE)
    {
        while (spi_data_is_in())
        {
            TESTPIN = !TESTPIN;
            compass_data[read_cnt++] = spi_read();

            SREQ = 0;
        }

        if (read_cnt == COMPASS_PACKET_LEN)
        {
            heading = 0;
            inclination = 0;

            for (i = 0; i < COMPASS_PACKET_LEN; i++)
            {
                printf("%02x ", compass_data[i]);
            }
            printf("\r\n");

            printf ("Header = %02x %02x Heading = %02x%02x,%02x%02x\r\n", compass_data[0x00], compass_data[0x01], compass_data[0x0f], compass_data[0x0e], compass_data[0x11], compass_data[0x10]);

            heading = make16(compass_data[0x0f], compass_data[0x0e]);
            inclination = make16(compass_data[0x11], compass_data[0x10]);

            printf("Heading = %5.2w    Inclination = %5.2w\r\n", heading, inclination);

            read_cnt = 0;
        }
    }
}
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Aug 15, 2013 10:40 pm     Reply with quote

The serial interfaces are not in sync because you have disabled the SPI CS on the PIC. Instead you should enable the PIC's slave SOI CS line and connect the CS input of the PIC to SDONE output of the compass.

I have no idea whether or not this is a good compass module however it is clear from the datasheet that this is a half baked implementation. It appears the design was originally foreseen to have I2C and SPI slave implementations but instead they took the easy approach of a half baked serial interface.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Jerry I



Joined: 14 Sep 2003
Posts: 96
Location: Toronto, Ontario, Canada

View user's profile Send private message

PostPosted: Fri Aug 16, 2013 7:57 pm     Reply with quote

Thanks for the reply.

That was it, I added and enable the SS (slave select line) and it appears to be working fine. Now to test how good the compass module really is.

Thanks Andrew.

Anyone know of a compass module with tilt compensation, and can be used as an inclinometer. It can be a completely housed finished product.

Thanks again.

Jerry Very Happy
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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 vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group