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);
}