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.

MSP430FR6877: Communication with W25Q16JV

Part Number: MSP430FR6877

I am using MSP430FR6877 with external flash W25Q16JV,

I am using UCA0 SPI for communication, the communication is up and running, and I can read/write status registers and read manufacturer id for example,

But reading/writing data/code to the memory is still not working,

I am trying to test it by writing 5 bytes to address 0 in the flash, however when I read them, I find the reset values "0xFF",

The code is as following:

1- initialization:

void flashInit(void)
{  
  // initialize spi comm with flash
  spiInit();
  
  // hard reset
  GPIO_setOutputLowOnPin(PORT_FLASH_RST, PIN_FLASH_RST);
//  configResetPin();
  __delay_cycles(100000);
  GPIO_setOutputHighOnPin(PORT_FLASH_RST, PIN_FLASH_RST);
  __delay_cycles(100000);
  GPIO_setOutputHighOnPin(PORT_FLASH_WP, PIN_FLASH_WP);
  GPIO_setOutputHighOnPin(PORT_FLASH_CS, PIN_FLASH_CS);
  
  // soft reset: command 0x66 then 0x99
  Reset();
  
//  /* test: read manufacturer id */
  uint8_t command[4] = {0};
  uint8_t data[2] = {0};
  command[0] = 0x90;
  command[1] = 0;
  command[2] = 0;
  command[3] = 0;

  spiTxRx(command, 4, data, 2, 1);
  
  WriteEnable();
  WriteUnprotect();
  
  /* chip erase */
  command[0] = 0x60;                                                      //write command 
  spiTxRx(command, 1, data, 0, 1);  

  __delay_cycles(160000);
  
  command[0] = 0x01;
  command[1] = 0x00;
  spiTxRx(command, 2, data, 0, 1);
  
  command[0] = 0x31;
  command[1] = 0x00;
  spiTxRx(command, 2, data, 0, 1);
  
  command[0] = 0x11;
  command[1] = 0x00;
  spiTxRx(command, 2, data, 0, 1);
  
//  command[0] = 0x05;
//  spiTxRx(command, 1, data, 2, 1);
  
  // 10 ms delay until the flash is power up
  __delay_cycles(160000);
}

2- Write:

void flashWrite(uint32_t address, uint8_t* data, uint16_t size)
{
  // clear write protect
  uint8_t command[4];
  uint8_t dummy = 0;
  
  WriteEnable();
  WriteUnprotect();
  
  /*  This section writes data.  The first character is the write command */ 
  command[0] = 0x02;                                                      //write command 
  command[1] = (unsigned char)(address >> 16);
  command[2] = (unsigned char)(address >>  8);
  command[3] = (unsigned char)(address >>  0);

  GPIO_setOutputLowOnPin(PORT_FLASH_CS, PIN_FLASH_CS);
  __delay_cycles(8800);
    
  spiTxRx(command, 4, &dummy, 0, 0);                              //send write command 
  spiTxRx(data, size, &dummy, 0, 0);                                 //write data
  
  __delay_cycles(8800);
  GPIO_setOutputHighOnPin(PORT_FLASH_CS, PIN_FLASH_CS);

  while(FlashReadStatus() == 0x03);                              //this ensure read operation are completed

  __delay_cycles(3200); 
}

3- Read:

void flashRead(uint32_t address, uint8_t* data, uint16_t size)
{
  uint8_t command[4];

  /*This section reads back data.  The first character is the read command */
  command[0] = 0x03;                                                  //send read command 
  command[1] = (uint8_t)(address >> 16);
  command[2] = (uint8_t)(address >>  8);
  command[3] = (uint8_t)(address >>  0);

  spiTxRx(command, 4, data, size, 1);                                  //send read command and read data
}

4- Other used functions:

static void spiInit(void)
{  
  UCA0CTLW0 = UCSWRST;                     // **Put state machine in reset**
  UCA0CTLW0 |= UCMST + UCSYNC + UCCKPL + UCMSB; // 3-pin, 8-bit SPI master MSB

  UCA0CTLW0 |= UCSSEL_2;                    // SMCLK Device specific

  UCA0BR0 = 4;                          // CLK / 1
  UCA0BR1 = 0;
  UCA0CTL1 &= ~UCSWRST;

  return;
}

static void spiTxRx(uint8_t *addr, uint32_t addlen, uint8_t *data, uint32_t datalen, uint8_t csEn)
{
  unsigned int i=0, j=0;
  unsigned char dummy = 0;
  
  if (csEn == 1)
  {
    GPIO_setOutputLowOnPin(PORT_FLASH_CS, PIN_FLASH_CS);
    __delay_cycles(8800);
  }
  
  while(addlen-i){
    while   ( !(UCA0IFG & UCTXIFG) );
    UCA0IFG &= ~UCRXIFG;
    UCA0TXBUF=addr[i++];
    while   ( !(UCA0IFG & UCRXIFG) );
    dummy=UCA0RXBUF;
  }
  
  dummy = 0;
  
  while(datalen-j){
    while   ( !(UCA0IFG & UCTXIFG) );
          UCA0TXBUF=dummy;
          while(!(UCA0IFG & UCRXIFG));//wait for byte to be received
          data[j++]=UCA0RXBUF;
  }
  
  if (csEn == 1)
  {
    __delay_cycles(8800);
    GPIO_setOutputHighOnPin(PORT_FLASH_CS, PIN_FLASH_CS);
  }
  
  return;
}

static void GlobalBlockProtectionUnlock (void)
{
  /* send gloal block unlock command */
  uint8_t command = 0x98;
  uint8_t dummy = 0;

  spiTxRx(&command, 1, &dummy, 0, 1);
}

static void Reset(void)
{
  /* send gloal block unlock command */
  uint8_t command = 0x66;
  uint8_t dummy = 0;

  spiTxRx(&command, 1, &dummy, 0, 1);
  
  command = 0x99;
  spiTxRx(&command, 1, &dummy, 0, 1);
}

static void WriteUnprotect (void)
{
  GlobalBlockProtectionUnlock();

  __delay_cycles(160000);
}

static void WriteEnable (void)
{
  /* send write enable command */
  uint8_t command = 0x06;
  uint8_t dummy = 0;

  spiTxRx(&command, 1, &dummy, 0, 1);
}

static uint8_t FlashReadStatus(void)
{
  /* read status reg-1 */
  uint8_t command = 0x05;
  uint8_t data = 0;

  spiTxRx(&command, 1, &data, 1, 1);
  
  return (uint8_t)data;
}

static void configResetPin(void)
{
  /* send write enable command */
  uint8_t command[2];
  uint8_t dummy = 0;
    
  command[0] = 0x11;
  command[1] = 0x80;

  spiTxRx(command, 2, &dummy, 0, 1);
}

**Attention** This is a public forum