Reading Mass Flow Sensor EEPROM

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Reading Mass Flow Sensor EEPROM

1,017 Views
adegonge
Contributor II

Hello,

I'm having a bit of trouble working out exactly how to read an Atmel EEPROM with an SPI interface that contains some calibration numbers. I only have to read the first 80 bytes, but I'm just having a bit of trouble as to how I would go about doing this using a Freescale FRDM K64F Board. I understand the basics of the board and have written programs on it for controlling stepper motors, taking analog inputs, etc. I also understand EEPROM to an extent but not exactly how it works. Is there any guide I can be directed to to help me understand EEPROM better or better yet, how I would write a code for this purpose? Again, I only have to read the EEPROM so that simplifies things a bit, but its still a bit out of my grasp.

Tags (4)
0 Kudos
3 Replies

834 Views
larryc
Contributor II

So the EEPROM has a spi interface, is that correct? 

On an EEPROM, generally, you write a short op code for READ, then an 8 bit address, then the EEPROM provides the data back.  You have to chip select the EEPROM if there are multiple devices on the SPI bus.  You also have to keep the PSI clock running to get the part to shift back the data one bit at a time into the SPI input register.

You can use a Kinetis BSP SPI function, or write your own if you understand the Kinetis registers.

If you need an register level SPI example, there are a few around.  Post and I can put one up as well.

Larry

834 Views
adegonge
Contributor II

Larry,

So I found the SPI functions in Kinetis and that appears to be exactly what I'm looking for. I'm having a bit of trouble with the syntax but I do see all the desired I/O pins defined in the function and I've found them all on the board so once I figure out how to issue the ReceiveBlock command I should be good to go, thanks!

0 Kudos

834 Views
larryc
Contributor II

Here's some direct register access SPI code.  Sends a command to an encoder to read position and reads back 8 bytes of data.  Long but tested working..

NOTE:  Best to remove extra CR's in this paste in - not sure why they occur

static void
prvSetupHardware( void )

{

        static unsigned char encoder[1000];

    /* Enable the interrupt on SW1. */

    taskDISABLE_INTERRUPTS();

#define
WANT_SPI_MUX_SETUP

#ifdef
WANT_SPI_MUX_SETUP

#define
BYTES_TO_READ 8

    // Turn on the SPI0 clock

    SIM_SCGC6 |= SIM_SCGC6_DSPI0_MASK;

    // PTE26 A0 - encode mux selection

    // PTE27 A1

    // PTE28 A2

    // PTE12 A3

    PORTE_PCR26 = PORT_PCR_MUX( 1 ) |
PORT_PCR_IRQC(0) | PORT_PCR_SRE_MASK   |
PORT_PCR_DSE_MASK;

    PORTE_PCR27 = PORT_PCR_MUX( 1 ) |
PORT_PCR_IRQC(0) | PORT_PCR_SRE_MASK   |
PORT_PCR_DSE_MASK;

    PORTE_PCR28 = PORT_PCR_MUX( 1 ) |
PORT_PCR_IRQC(0) | PORT_PCR_SRE_MASK   |
PORT_PCR_DSE_MASK;

    PORTE_PCR12 = PORT_PCR_MUX( 1 ) |
PORT_PCR_IRQC(0) | PORT_PCR_SRE_MASK   |
PORT_PCR_DSE_MASK;

    GPIOE_PDDR |= (1<<26);

    GPIOE_PDDR |= (1<<27);

    GPIOE_PDDR |= (1<<28);

    GPIOE_PDDR |= (1<<12);

        // Set mult out A0-A2 to 0 ENDAT mux

    GPIOE_PDOR &= ~((1<<26)  |
(1<<27)  |  (1<<27) | (1<<12) );

    // Set up needed pins for SPI0

    // PTD0 - CS0

    // PTD1 - Clock

    // PTD2 - DOut

    // PTD3 - DIn

    // All pins - ALT2 config for SPI0, nor
IRQ/DMA, high drive strength and fast slew (0 for fast slew)

    PORTD_PCR0 = PORT_PCR_MUX( 2 ) |
PORT_PCR_IRQC(0) | PORT_PCR_SRE_MASK   |
PORT_PCR_DSE_MASK;

    PORTD_PCR1 = PORT_PCR_MUX( 2 ) |
PORT_PCR_IRQC(0) | PORT_PCR_SRE_MASK   |
PORT_PCR_DSE_MASK;

    PORTD_PCR2 = PORT_PCR_MUX( 2 ) |
PORT_PCR_IRQC(0) | PORT_PCR_SRE_MASK   |
PORT_PCR_DSE_MASK;

    PORTD_PCR3 = PORT_PCR_MUX( 2 ) |
PORT_PCR_IRQC(0) | PORT_PCR_PE_MASK /* |  
PORT_PCR_PS_MASK */ ;  //pull down

    // PTE26, 27, 28, 12  output for encoder mux selection.  pull down.

    // Set up the SPI0 MCR register for what we
need

    // Looks like we need:

    // 
Use Master mode - the encoder is the slave

    // 
Continuous clock?

    // 
?? Use CS5 as peripheral CS ?? - Need to enable it in PCR

    // 
PCS lines - set active low or high - use high for now (1 = inactive
high)

    // 
Clear TX Fifo (1)

    // 
Clear RX Fif0 (1)

    // 
Run SCLK Continuous (1)

   

    SPI0_MCR = SPI_MCR_HALT_MASK |   // stop the SPI;

                   SPI_MCR_MSTR_MASK |       // master mode

               SPI_MCR_CONT_SCKE_MASK |  // sclk cont

           SPI_MCR_DCONF(0) |        // SPI mode

        // SPI_MCR_PCSSE_MASK |      //cs5 continuous

           SPI_MCR_PCSIS(1) |        // cs0 inactive hi

           SPI_MCR_CLR_RXF_MASK |

           SPI_MCR_CLR_TXF_MASK ; // Last

     //for (int z=0; z<13; z++)
printf(".");

       // CTOR configuration

       // We want:

       //  
Double baud rate?

       //  
Frame size is 8 (size is fmsz+1)

       //  
Delay

       //  
Close phase - output fulling receive falling

       SPI0_CTAR0 = (/*
SPI_CTAR_DBR_MASK*/  SPI_CTAR_FMSZ(7)

       // BR 5 and PBR 0 is 1Mhz

       // BR 4 and PBR 0 is 2Mhz - this doesnt
work

       | SPI_CTAR_PDT(7) | SPI_CTAR_BR(5) |

       SPI_CTAR_PBR(0) |
SPI_CTAR_CPHA_MASK  |

       SPI_CTAR_LSBFE_MASK |

       SPI_CTAR_PCSSCK(0) |

       SPI_CTAR_CSSCK(3)  );

       // SPI_CTAR_CPOL_MASK );

#ifdef
ENCODER_STARTUP

   while ( 1 ) {

       // Do a read and wait

       SPI0_MCR = ~SPI_MCR_HALT_MASK &
SPI0_MCR;  // clear the halt bit

       unsigned char command = 0x70;   // read

       //unsigned char command = 0x5a;   // read w/ reset

       // Clear tranfer count register

       // SPI0_TCR = 0;

       int spi_cnt;

       for (spi_cnt=0;
spi_cnt<BYTES_TO_READ; spi_cnt++ )

       {

           SPI0_PUSHR = (command  | SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(1) |
SPI_PUSHR_CTAS(0));

           //while (!(SPI0_SR &
SPI_SR_TFFF_MASK)  );

           command = spi_cnt+1;

           while (!(SPI0_SR &
SPI_SR_RFDF_MASK)  );

           unsigned char byte;

           encoder[spi_cnt] = SPI0_POPR;

           SPI0_SR = SPI_SR_RFDF_MASK;   // clear the reception flag (not
self-clearing)

           //printf("byte read
%0x\n",SPI0_POPR );

     }

       // Last byte transfer/receiver

       command = 0xff;

       SPI0_PUSHR = (command  | /* SPI_PUSHR_CONT_MASK | */
SPI_PUSHR_PCS(1) | SPI_PUSHR_CTAS(0));

       while (!(SPI0_SR &
SPI_SR_TFFF_MASK)  );  // wait for transmit

       while (!(SPI0_SR &
SPI_SR_RFDF_MASK)  );

      

       unsigned char junk = SPI0_POPR;

       SPI0_SR = SPI_SR_RFDF_MASK;   // clear the reception flag (not
self-clearing)

}

0 Kudos