|
|
View previous topic :: View next topic |
Author |
Message |
Jerry I
Joined: 14 Sep 2003 Posts: 96 Location: Toronto, Ontario, Canada
|
SPI Slave problem |
Posted: Thu Aug 15, 2013 7:05 pm |
|
|
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
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
|
|
Posted: Thu Aug 15, 2013 10:40 pm |
|
|
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
|
|
Posted: Fri Aug 16, 2013 7:57 pm |
|
|
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 |
|
|
|
|
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
|