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 support@ccsinfo.com

SPI Setup and Problems

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



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

SPI Setup and Problems
PostPosted: Sun Jan 16, 2005 12:55 pm     Reply with quote

Hello All,

First attempt with SPI and not having much good luck. Any help would be greatly appreciated. I have read as many of the relevent posts as I could find.

Compiler: 3.18
Part: 18F452
Standard Run Mode
Target Voltage: 5v
Osc Speed: 4MHz

PIC is master, slave is a magnetometer module.

http://www.pnicorp.com/supportProduct?nodeId=c4b10&tab=datasheets

Basic operation is described on page 9 and is included here:

MicroMag Host Processor Interface

Basic operation will follow these steps.
1 SSNOT is brought low.

2 Pulse RESET high (return to low state). You must RESET the MicroMag before every measurement.

3 Data is clocked in on the MOSI line. Once eight bits are read in, the MicroMag will execute the command.

4 The MicroMag will make the measurement. A measurement consists of forward biasing the sensor and making a period count; then reverse biasing the sensor and counting again; and finally, taking the difference between the two bias directions.

5 At the end of the measurement, the DRDY line is set to high indicating that the data is ready. In response to the next 16 SCLK pulses, data is shifted out on the MISO line. If you need to make another measurement, go to Step 2. You can send another command after the reset. In this case, keep SSNOT low. If you will not be using the MicroMag, set SSNOT to high
to disable the SPI port.


Here is my relevent code:

Code:
/*******************************
    Part Specific Settings
*******************************/
#include <18F452.H>

#device ADC=8 // place A/D in 8 bit mode

#fuses  HS,NOPROTECT,NOWDT,PUT,BROWNOUT,NOLVP

#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,BRGH1oK,errors)

#byte portb = 0x0f81
#byte portd = 0x0f83

/*******************************
      I/O Definitions
*******************************/
//       port A not_used

//       port B not_used


#define  mm_reset       PIN_C0
#define  mm_drdy        PIN_C1
#define  mm_ssnot       PIN_C2
//       SCL            PIN_C3
//       SDA            PIN_C4
//       SDO            PIN_C5
//       RS232 TX       PIN_C6
//       RS232 RX       PIN_C7

//       port D not_used

#define  debug_1_LED    PIN_E0
#define  debug_2_LED    PIN_E1
//       not_used       PIN_E2

/*************************
    MicroMag Support
*************************/

int1 mm_read_stat = 1;

signed int16   reading_hi = 0;
signed int16   reading_lo = 0;
signed int16   reading    = 0;


/*************************
       Prototypes
*************************/




/*************************
       Includes
*************************/
#include <INPUT.C>
#include <STDLIB.H>
#include <STRING.H>

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

                     MAIN

*********************************************/
void main() {

   setup_wdt(wdt_off);

   setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16 );

   output_high(mm_ssnot);
   output_low(mm_ssnot);
   output_low(mm_reset);
   
   output_float(mm_drdy);

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

                  MAIN DO LOOP

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

   do {


   //Regular events here

   if (mm_read_stat) {
      output_high(mm_reset);
      delay_us(5);
      output_low(mm_reset);
     
      printf("\n\rReset MM\n\r");

      spi_write(0b00000001);
      mm_read_stat = 0;
   }

   if (input(mm_drdy)) {
      reading_hi = spi_read(0x00);
      reading_lo = spi_read(0x00);

      printf("\n\r High Byte");
      printf("\n\r %u", reading_hi);
      printf("\n\r Low Byte");
      printf("\n\r %u", reading_lo);


      reading = ((reading_hi << 8) & reading_lo);

      printf("\n\r Reading");
      printf("\n\r %u", reading);

      mm_read_stat = 1;
   }
   )
   /*************** END MAIN LOOP **************/
   while(TRUE);
}



MicroMag Peculiarities:
1MHz max clock
1Byte command (obviously, with SPI)
2Byte data return


Some of the specific questions I have are:
There isn't a "USE#" for SPI, am I missing some required code to get the SPI configured?

I believe I've got the clock polarity set correctly but can't be sure.

Am I handling the 2Bytes of returned data correctly? (Just SPI_READ() twice and put the bytes together?)

Thanks again for any help,

John
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jan 16, 2005 3:58 pm     Reply with quote

1. In your setup_spi() statement, you are specifying the rising edge.
But this function parameter is defined as the edge at which data
changes, not the edge that it's sampled on. If you look at the
MicroMag data sheet, you'll see that data changes on the falling edge.
So you need to change the parameter to be: SPI_H_TO_L

2. Your printf statement is only setup to display an 8-bit value.
You need to use "lu" or "lx" to display a value greater than
8-bits with CCS.
Change this it to this:
Code:
printf("\n\r %lu", reading);


3. I'm not sure what you're doing with "mm_rdstat". After sending
the command, I would have put in a while() statement to wait for
DRDY to go high, before proceeding any farther. Something like this:
Code:
while(!input(mm_drdy));

In in a real program, I would also put in a timeout loop. After a
suitable period had passed, I would give up waiting for DRDY to
go high, and exit the routine with a "return" value of "FAILED",
or "FAILURE_TIMED_OUT".

4. Also, if I was writing a driver for this chip, I would make it with
functions. I'd make a driver file called "micromag.c" with all the
functions in it. I'd also have "micromag.h" file with the function
prototypes and #define statements for constants, etc.
Then you can #include these files in any future project.

I didn't examine everything in your program, so there may be other
problems that I didn't see.
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Mon Jan 17, 2005 10:04 am     Reply with quote

PCM,

Thanks for the help. It's up and running.

Quote:
3. I'm not sure what you're doing with "mm_rdstat".


That was a status marker so that the main loop could continue while the MicroMag was taking the measurement. No need to hold up progress waiting for the reading?

I also canned the reassembly of the two bytes into a long. I'm only really interested in the delta of the last digit.

Thanks for the tips on modularization. Right now just slapping stuff together on a test board. My coding probably shows how new I am. Hopefully, I'll work up to elegant optimized code.

Thanks Again,

John
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