cancel
Showing results for 
Search instead for 
Did you mean: 

Currently I am working on M95128 EEPROM ic which is interface with MSP432P401M controller through SPI communication. I am trying to read data which i write but everytime I receive 0xFF from memory. I have attached the code for your reference.

Spath.1674
Associate II
 
10 REPLIES 10
mckenney
Senior

Per the data sheet (DocID5798 Rev 19) p.1, the M95128 is a 16KB device.

> int i=0x025698;

This device address is much larger than 16K (0x4000). Even reduced to 16 bits it's too large. Try address 500 or something.

>  uac_wrBuf[j++] = M95128_CMD_WREN;

Per data sheet Fig 8, WREN should be sent as a separate transaction.

>  uac_wrBuf[j++] = M95128_CMD_WRITE; /* Write Instruction */

>  uac_wrBuf[j++] = (uint8_t)((ui_addr >> 16) & 0xFF); /* First 8-bit MSB of 24-bit address */

>  uac_wrBuf[j++] = (uint8_t)((ui_addr >> 8) & 0xFF); /* Second 8-bit MSB of 24-bit address */

>  uac_wrBuf[j++] = (uint8_t)((ui_addr) & 0xFF);    /* Third 8-bit MSB of 24-bit address */

Per data sheet Fig 13, the M95128 uses 16-bit, not 24-bit, addressing.

>   P3->SEL0 |= BIT4 | BIT5 | BIT6 | BIT7;     // set 4-SPI pin as second function

With UCMODE=0 (which is indeed what you want) you shouldn't give STE (P3.4) to the USCI. Remove "BIT4" from this line.

>  // data out on first rising edge

As a general rule when using the USCI, if the device wants CPHA=0 you should set UCCKPH=1 and vice versa. (I periodically slog through the words to figure out why, then I promptly forget.)

JNguyen
Senior

Some EEPROM requires a block erase before write. Adesto AT25SF041 does. The equivalent MicroChip EEPROM doesn't. This might not be your problem, but you can easily check it out if the data sheet doesn't clearly state the requirement.

Spath.1674
Associate II

Hello,

as per your suggestion I have made the changes in code. first, I am trying to only read status register in order to just ensure communication between memory and msp432 . thereafter I will try to write data in memory.

Steps to read status register:-

1) spi intialise :- spi is operate in 3 bit mode(no cs pin) with mode 0. ckpl bit set to 0 and ckph bit set to 1.

2) cs pin low

3) send 0x05

4) send dummy byte 0x00

5) read data of ststus register

6) cs pin high

but i got 0x00 in receive buffer.

I have attached code for your reference also i have attached screenshot of circuit diagram

0690X00000As0wcQAB.png

mckenney
Senior

As I read Data Sheet Sec 7.2, 0x00 is a not-incorrect SR value (albeit not a very distinctive one). Maybe try sending a WREN sequence first, then see if WEL=1?

In the just-to-make-sure department:

1) Add this line just before the "P3->DIR = BIT4" line, to make sure the device sees a falling edge [Ref DS Sec 7.1]:

> P3->OUT |= BIT4; // Initially high to ensure /CS falling edge

2) Check (one more time) to assure SDO is connected to SOMI and SDI to SIMO.

Spath.1674
Associate II

Hello,

Thanks.. I can successfully read status register (0x02) after write WREN in memory​.Now, I want to write the data in memory and read. Please find the attachment of my code

mckenney
Senior

You appear to have switched to an AVR. It's been a long time since I've done SPI on an AVR, so I'll suppose your treatment is correct.

1) WriteDummy (still) isn't sending the WREN in a separate transaction. You need to raise then lower /CS between the WREN and the WRITE.

2) ReadDummy isn't quite finished:

a) it's reading from an address different from where you wrote

b) It needs to send a "dummy" byte after the address in order to fetch the data (it looks like that's commented out?). I suggest you change SPI_Write() to always return SPDR; the caller can ignore it or not.

Hi,

Sorry,I have attached wrong file.I made changes as per your suggestions now I am able to read status register. Now,I just want to read data which I have write.I have attached code for reference

Hi, I am able to read status register 0x02 after writing WREN instruction.Now, I am writing single byte of data in memory and I am able to read that data as well, but I am facing a problem at this point such that after writing certain bytes I am not able to read them. Please refer the image, in which I have mentioned the bytes I have written in the memory and their respective results.also,I have attached code for your reference

/**********LED indication**********/
// Buzzer           = Red
// Warning          = Yellow
// Normal operation = Green
 
 
#include "msp.h"
#include "common.h"
#include "math.h"
#include "stdio.h"
#include "string.h"
#include "M95128.h"
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
 
int j=0x0000;     /*******/
int i;
uint8_t status,status1;
int sayali,sayali1;
uint8_t Data,xlow,xhigh;
 
void main(void)
{
	 WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD;		// stop watchdog timer
 
	 pin_init();
	 dev_init_48M();                                // Microcontroller set on 48MHz
 
	 SPI_INT();
 
	 P3->DIR = (BIT4);             // CS as output
	 P3->OUT |= (BIT4);            // CS pin high initially
 
	 P3->OUT &=~(BIT4);            // CS pin low
	 __delay_cycles (500);         //delay
	 while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG));
	 EUSCI_B2->TXBUF =M95128_CMD_WREN;   //wren(0x06) transmit
	 __delay_cycles (500);         //delay
	 P3->OUT |= (BIT4);            // CS pin high
 
	 __delay_cycles (500000);         //delay
 
	 P3->OUT &=~(BIT4);            // CS pin low
	 __delay_cycles (500);         //delay
	 while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG));
	 EUSCI_B2->TXBUF =M95128_CMD_WRITE;     //send write 0x02
	 while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG));
	 EUSCI_B2->TXBUF =0x00;      //send adress high
	 while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG));
	 EUSCI_B2->TXBUF =0x05;       //send adress low
	 while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG));
	 EUSCI_B2->TXBUF =0x0B;      // trying to send data 0xAA
	 __delay_cycles (500);         //delay
	 P3->OUT |= (BIT4);            // CS pin high
 
	 __delay_cycles (500000);         //delay
 
	 P3->OUT &=~(BIT4);            // CS pin low
	 __delay_cycles (500);         //delay
	 while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG));
	 EUSCI_B2->TXBUF =M95128_CMD_WRDIS;   //wren(0x06) transmit
	 __delay_cycles (500);         //delay
	 P3->OUT |= (BIT4);            // CS pin high
 
	 __delay_cycles (500000);         //delay
 
	 P3->OUT &=~(BIT4);            // CS pin low
	 __delay_cycles (500);         //delay
	 while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG));
	 EUSCI_B2->TXBUF =M95128_CMD_READ;  //send read 0x03
	 while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG));
	 EUSCI_B2->TXBUF =0x00;   //send adress high
	 while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG));
	 EUSCI_B2->TXBUF =0x05;    //send adress low
	 status1 = spi_rx();       //read data which we write expected ans is 0x12
	 __delay_cycles (500);         //delay
	 P3->OUT |= (BIT4);            // CS pin high
 
	 while(1)
	 {
 
	 }
}
 
/*************SPI Receive****************/
int spi_rx()
{
     while(!(EUSCI_B2->IFG & EUSCI_B_IFG_TXIFG));
     EUSCI_B2->TXBUF = 0x00;
     __delay_cycles (200);
     // Wait till a character is received
     // while (!(EUSCI_B0->IFG & EUSCI_B_IFG_RXIFG));
     Data = EUSCI_B2->RXBUF;  // Move data to a temporary buffer
     // Clear the receive interrupt flag
     // EUSCI_B0->IFG &= ~EUSCI_B_IFG_RXIFG;
     return Data;
}
 
//**************SPI Initialization*******************//
void SPI_INT()
{
   P3->SEL0 |= BIT5 | BIT6 | BIT7;            // set 4-SPI pin as second function
 
   EUSCI_B2->CTLW0 |= EUSCI_B_CTLW0_SWRST;           // Put eUSCI state machine in reset
   EUSCI_B2->CTLW0 =  EUSCI_B_CTLW0_SWRST |          // Remain eUSCI state machine in reset
                      EUSCI_B_CTLW0_MST |            // Set as SPI master
                      EUSCI_B_CTLW0_SYNC |           // Set as synchronous mode
                      EUSCI_B_CTLW0_MSB |            // MSB first
                      EUSCI_B_CTLW0_MODE_0 |         // 4-pin mode with slave enable when STE low
                      EUSCI_B_CTLW0_CKPH |
                      EUSCI_B_CTLW0_SSEL__SMCLK;     // SMCLK
   // Clock polarity initially low
   // data out on first rising edge
   // data out on first falling edge
   // this setting are according to AD7730 CLK_POL tie to ground or Zero
   EUSCI_B2->BRW = 0x03;                             // /2,fBitClock = fBRCLK/(UCBRx+1).       //change   (48MHz/3+1)= 12Mhz   /****/
   EUSCI_B2->CTLW0 &= ~EUSCI_B_CTLW0_SWRST;          // Initialize USCI state machine
}

The code you've posted is quite a bit different from the code you've attached. More generally, your code is enough of a "moving target" that I can't match code with symptom.

> dev_init_48M(); // Microcontroller set on 48MHz

Are you really running SMCLK at 48MHz? This violates the USCI input clock spec of 24MHz [Ref DS (SLAS826G) Table 5-36]. (This isn't an idle specification -- someone once documented the effects, which are that the signal edges get rounded to the point that even a human can't define them any more.)

Try removing this line and see what you get. 3MHz should be plenty for now.