This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

interface AT93C46 using SPI with F28069

Hi,

  I m trying to interface AT93C46 using SPI with F28069.I am using Polling method for interfacing.As per datasheet of AT93C46 in write operation need to check MISO for SET. How to do Write operation?

Which clocking scheme is required?

Regards,

SSY

  • Sagar,

    It looks like you will have to get creative to allow the F2806x SPI to work with this AT93C46.

    the EEPROM requires CS active high which the F2806x does not support in master mode, so you will have to use a GPIO for it. (set GPIO high --> write command --> set GPIO low) 

    According to the EEPROM datasheet, the BUSY/READY signal will be present on SOMI after a write cycle has been initiated. I would use the following sequence for the Write command:

    1. Set CS high, 
    2. Write command + data
    3. Set CS low
    4. Wait at least 250ns
    5. Set CS high
    6. Wait twp (Write Cycle Time) ms for the Ready status to be present on SOMI line
    7. Set CS low again to end the Write sequence.

    The Data from the EEPROM is synchronized to the rising edge of the CLK so you might want to try setting the F2806x cock scheme to be Polarity = 0, Phase = 1.

    Please let me know if this has helped and good luck!

    Thanks,
    Mark

  • Hi Mark,

    Thanks for the reply.

    I am also using GPIO pin for CS.I followed the following sequence for Write command.I am using 16 bit data format.

    Uint8 AT93C46_WR(Uint16 EE_address,Uint16 EE_data)
    {
    CS_CLEAR = 1;
    delay_loop(1);              //delay of 50us
    CS_SET = 1;

    AT93C46_EW(); //EWEN func call

    CS_CLEAR = 1;
    delay_loop(1);
    CS_SET = 1;

    delay_loop(50);

    // Write opcode & Address send
    spi_xmit((WRITE) | (EE_address));

    spi_xmit(EE_data);

    //data send
    CS_CLEAR = 1;
    delay_loop(1);
    CS_SET = 1;

    EALLOW;
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0; // Configure GPIO17 as GPIO
    GpioCtrlRegs.GPADIR.bit.GPIO17 = 0; // MISO PIN as GPIO as INPUT
    EDIS;

    while(MISO_STATUS == 0);

    CS_CLEAR = 1;

    delay_loop(50);

    return(1);
    }

    To read the MISO staus I am initialize MISO pin as gpio in Read configuration. In Read operation this Miso pin initialize  as MISO.

    But MISO pin is always kept high for write and read operation.

    After write  the data in Write operation MOSI pin giving a Pulse.

    Please find attached copy of code.

    Regards,

    Sagar

    8400.Example_2806xSpi_FFDLB.c
    // TI File $Revision: /main/3 $ 
    // Checkin $Date: March 3, 2011   15:59:09 $ 
    //###########################################################################
    //
    // FILE:   Example_2806xSpi_FFDLB.c
    //
    // TITLE:  F2806x Device Spi Digital Loop Back program. 
    //
    // ASSUMPTIONS:
    //
    //    This program requires the F2806x header files. 
    // 
    //    This program uses the internal loop back test mode of the peripheral. 
    //    Other then boot mode pin configuration, no other hardware configuration
    //    is required. 
    //
    //    As supplied, this project is configured for "boot to SARAM" 
    //    operation.  The F2806x Boot Mode table is shown below.  
    //    $Boot_Table:
    //
    //    While an emulator is connected to your device, the TRSTn pin = 1,
    //    which sets the device into EMU_BOOT boot mode. In this mode, the
    //    peripheral boot modes are as follows:
    //
    //      Boot Mode:       EMU_KEY        EMU_BMODE
    //                       (0xD00)	     (0xD01)
    //      ---------------------------------------
    //      Wait             !=0x55AA        X
    //      I/O              0x55AA	         0x0000
    //      SCI              0x55AA	         0x0001
    //      Wait             0x55AA	         0x0002
    //      Get_Mode         0x55AA	         0x0003
    //      SPI              0x55AA	         0x0004
    //      I2C              0x55AA	         0x0005
    //      OTP              0x55AA	         0x0006
    //      ECANA            0x55AA	         0x0007 
    //      SARAM            0x55AA	         0x000A	  <-- "Boot to SARAM"
    //      Flash            0x55AA	         0x000B
    //      Wait             0x55AA          Other
    //
    //   Write EMU_KEY to 0xD00 and EMU_BMODE to 0xD01 via the debugger
    //   according to the Boot Mode Table above. Build/Load project,
    //   Reset the device, and Run example
    //
    //   $End_Boot_Table
    //
    //
    // Description:
    //
    //    This program is a SPI example that uses the internal loopback of
    //    the peripheral.  Interrupts are not used.
    //
    //    A stream of data is sent and then compared to the received stream.
    //  
    //    The sent data looks like this:
    //    0000 0001 0002 0003 0004 0005 0006 0007 .... FFFE FFFF
    //
    //    This pattern is repeated forever.  
    //
    //          Watch Variables:         
    //                sdata - sent data
    //                rdata - received data
    //		          ok
    
    
    ////###########################################################################		
    // $TI Release: 2806x C/C++ Header Files V1.10 $ 
    // $Release Date: April 7, 2011 $ 
    //###########################################################################
    
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    // Prototype statements for functions found within this file.
    //void delay_loop(void);
    void delay_loop(Uint16 );
    void spi_xmit(Uint16);
    Uint16 spi_xmit_rx(Uint16 data);
    void spi_fifo_init(void);
    void spi_init(void);
    void Init_Spi_E2Prom();
    
    void AT93C46_EW();
    Uint8 AT93C46_WR(Uint16 EE_address,Uint16 EE_data);
    Uint16 AT93C46_RD(Uint16 EE_address);
    
    #define CS_CLEAR	(GpioDataRegs.GPACLEAR.bit.GPIO19)
    #define CS_SET		(GpioDataRegs.GPASET.bit.GPIO19)
    #define MISO_STATUS (GpioDataRegs.GPADAT.bit.GPIO17)
    
    #define READ 		(0x0300)
    #define EWEN   		(0x0260)
    #define WRITE		(0x0280)
    #define DUMMY_BYTE  (0x0000)
    
    /*
    #define EWENOPCODE   (0x02)
    #define EWENADD	   	 (0x60)
    #define WROPCODE	 (0x02)
    #define RDOPCODE 	 (0x03)
    */
    
    Uint8 sdata;  // send data
    Uint16 rdata,ddata;  // received data
    Uint8 read1,read2,read3;
    
    void main(void)
    {
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2806x_SysCtrl.c file.
    
       InitSysCtrl();
    
    // Step 2. Initialize GPIO:
    // This example function is found in the F2806x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example  
    // Setup only the GP I/O only for SPI-A functionality
    // This function is found in F2806x_Spi.c
    
       InitSpiaGpio();
    
       EALLOW;
       GpioCtrlRegs.GPADIR.bit.GPIO19 = 1;         // CS pin as GPIO   as OUTPUT
       GpioCtrlRegs.GPADIR.bit.GPIO17 = 0;         // MISO PIN as GPIO as INPUT
       CS_CLEAR 					  = 1;
       EDIS;
    
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts 
       DINT;
    
    // Initialize PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.  
    // This function is found in the F2806x_PieCtrl.c file.
    
       InitPieCtrl();
    
    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
       
    // Initialize the PIE vector table with pointers to the shell Interrupt 
    // Service Routines (ISR).  
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2806x_DefaultIsr.c.
    // This function is found in F2806x_PieVect.c.
    
       InitPieVectTable();
    	
    // Step 4. Initialize all the Device Peripherals:
    // This function is found in F2806x_InitPeripherals.c
    // InitPeripherals(); // Not required for this example
    // spi_fifo_init();	  // Initialize the Spi FIFO
    // spi_init();		  // init SPI
    
       Init_Spi_E2Prom();
    
    // Step 5. User specific code:
    // Interrupts are not used in this example. 
    
       sdata = 0x02;
       read1 = 0x0000;
    
    // AT93C46_EW();
    
       AT93C46_WR(0x0001,0x0000);
       read1 = AT93C46_RD(0x0001);
    
       for(;;)
       {  }
    } 	
    
    // Step 7. Insert all local Interrupt Service Routines (ISRs) and functions here:	
    
    void delay_loop(Uint16 delay)
    {
        long i,j;
        
        for(j = 0;j < delay;j++)
        {
        	for (i = 0; i < 10; i++) {}
        }
    }
    /*
    void spi_init()
    {    
    	SpiaRegs.SPICCR.all = 0x4F;		   // Reset on, rising edge, 8-bit char bits
    	SpiaRegs.SPICTL.all = 0x06;    	   // Enable master mode, normal phase, // enable talk, and SPI int disabled.
    	SpiaRegs.SPIBRR     = 0x007F;
        SpiaRegs.SPICCR.all = 0x8F;		   // Relinquish SPI from Reset
        SpiaRegs.SPIPRI.bit.FREE = 1;      // Set so breakpoints don't disturb xmission
    }
    */
    
    void Init_Spi_E2Prom()
    {
    	SpiaRegs.SPICCR.all 			  = 0x0F;   	  // 16-bit char bits
    	SpiaRegs.SPISTS.all 	  		 |= 0x80;
    //	SpiaRegs.SPIBRR 			  	  = (0x10*5);
    	SpiaRegs.SPIBRR   				  = 0x007F;
    //	SpiaRegs.SPICTL.all 			  = 0x06;
    	SpiaRegs.SPICTL.bit.MASTER_SLAVE  = 1;  //Master
    	SpiaRegs.SPICTL.bit.TALK          = 1;
    	SpiaRegs.SPICTL.bit.CLK_PHASE     = 1;                //
    	SpiaRegs.SPICCR.bit.CLKPOLARITY   = 0;                //Data is output on falling edge and input on rising edge.
    	read2							  = SpiaRegs.SPIRXBUF;
    	SpiaRegs.SPICCR.all    	  		 |= 0x80;
    //    SpiaRegs.SPIPRI.bit.FREE 	  	  = 1;                // Set so breakpoints don't disturb xmission
    }
    
    void spi_fifo_init()
    {
    // Initialize SPI FIFO registers
        SpiaRegs.SPIFFTX.all	=	0xE040;
        SpiaRegs.SPIFFRX.all	=	0x2040;
        SpiaRegs.SPIFFCT.all	=	0x0;
    }
    
    void spi_xmit(Uint16 data)
    {
    	SpiaRegs.SPITXBUF = data;
    	ddata             = data;
    
    //   	while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG  != 1) {}
    	while(!(SpiaRegs.SPISTS.all & 0x40));
    		rdata = SpiaRegs.SPIRXBUF;
    
    //	SpiaRegs.SPICCR.bit.CLKPOLARITY = 1;
    }
    
    Uint16 spi_xmit_rx(Uint16 data)
    {
    	Uint16 rxdata;
    
        SpiaRegs.SPITXBUF = data;
    //    	while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG  != 1) {}
    	while(!(SpiaRegs.SPISTS.all & 0x40));
    		rxdata = SpiaRegs.SPIRXBUF;
    
    //    SpiaRegs.SPICCR.bit.CLKPOLARITY = 1;
    
        return(rxdata);
    }
    //===========================================================================
    // No more.
    //===========================================================================
    
    void AT93C46_EW()
    {
    	CS_CLEAR = 1;
    	delay_loop(2);
    	CS_SET	 = 1;
    
    	spi_xmit(EWEN);
    
    	CS_CLEAR = 1;
    
    	delay_loop(2);
    }
    
    Uint8 AT93C46_WR(Uint16 EE_address,Uint16 EE_data)
    {
    	CS_CLEAR = 1;
    	delay_loop(1);
    	CS_SET	 = 1;
    
    	AT93C46_EW();                 //EWEN func call
    
    	CS_CLEAR = 1;
    	delay_loop(1);
    	CS_SET	 = 1;
    
    	delay_loop(50);
    
    	// Write opcode & Address send
    	spi_xmit((WRITE) | (EE_address));
    
    	spi_xmit(EE_data);
    
        //data send
    	CS_CLEAR = 1;
    	delay_loop(1);
    	CS_SET	 = 1;
    
    	EALLOW;
    		GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0; 		// Configure GPIO17 as GPIO
    		GpioCtrlRegs.GPADIR.bit.GPIO17  = 0;        // MISO PIN as GPIO as INPUT
        EDIS;
    
    	while(MISO_STATUS == 0);
    
    	CS_CLEAR = 1;
    
    	delay_loop(50);
    
        return(1);
    }
    
    Uint16 AT93C46_RD(Uint16 EE_address)
    {
    	Uint16 EE_data;
    
    	CS_CLEAR = 1;
    	delay_loop(1);
    	CS_SET	 = 1;
    
    	spi_xmit((READ) | EE_address);
    
    	EALLOW;
        GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1;	 // Configure GPIO17 as MISO
        EDIS;
    
    //    SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
    
        EE_data = spi_xmit_rx(DUMMY_BYTE);       // dummy byte send & Read Data
    
        CS_CLEAR = 1;
    //	delay_loop(10);
    
    	return(EE_data);
    }
    
    
    
    

    Please find attached waveform of MOSI and CLK pins.

    1st waveform is of write sequence.

    2nd waveform is the data i.e. 0x1234 which is  I want to write . At the end of  data write u can see the pulse on MOSI pin.i.e. unknown for me . after that I am doing read sequence.

    Thanks & regards,

    Sagar

  • Hi Mark,

    Waiting for reply from you.

    My SPI initialize is following way


    void Init_Spi_E2Prom()
    {
    SpiaRegs.SPICCR.all = 0x0F; // 16-bit char bits
    SpiaRegs.SPISTS.all |= 0x80;
    SpiaRegs.SPIBRR = 0x007F;
    SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1; //Master
    SpiaRegs.SPICTL.bit.TALK = 1;
    SpiaRegs.SPICTL.bit.CLK_PHASE = 1; //
    SpiaRegs.SPICCR.bit.CLKPOLARITY = 0; //Data is output on falling edge and input on rising edge.
    SpiaRegs.SPICCR.all |= 0x80;
    // SpiaRegs.SPIPRI.bit.FREE = 1; // Set so breakpoints don't disturb xmission
    }

    How I will find my transmission is completed and ready to receive.

    I am using following instruction for transmission & receiving data

    transmission :

     while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG != 1) {}

    Receiving 

    while(!(SpiaRegs.SPISTS.all & 0x40)){}

         rdata = SpiaRegs.SPIRXBUF;

    Regards,

    Sagar