• AVR Freaks

Helpful ReplyHot!SST26VF032 reading problem

Page: 12 > Showing page 1 of 2
Author
ainhi
New Member
  • Total Posts : 21
  • Reward points : 0
  • Joined: 2016/11/16 08:51:47
  • Location: 0
  • Status: offline
2016/11/17 03:00:22 (permalink)
0

SST26VF032 reading problem

Hi!
I'm new to this forum, hope someone can help me ^^
I am using a PIC24fj128ga310 connected to a Explorer 16 board, and I am trying to access to SST26VF032 memory through the SPI2.
The problem is that the memory's ID (JEDEC) is read correctly (when I send the command 0x9F it returns 3 Bytes: 0xbf, 0x26 and 0x02, which are the ones that correspond to SST26VF032), but when sending any other instruction it always returns 0000.
 
I've been reading a lot of posts about this, but nothing worked for me. I also tried the driver provided by Microchip but it doesn't work either (or I can't make it work, as I don't understand it fully).
 
Here I add some (hopefully) relevant information about my connections and my code:
 
pragma configurations:
// CONFIG 1
    #pragma config JTAGEN = OFF // JTAG Port Enable (Disabled)
    #pragma config GCP = OFF // General Segment Code Protect (Code protection is disabled)
    #pragma config GWRP = OFF // General Segment Write Protect (Disabled)
    #pragma config FWDTEN = WDT_DIS // Watchdog Timer Enable (WDT disabled in hardware; SWDTEN bit disabled)
    #pragma config ICS = PGx2 // ICD Pin Placement Select(EMUC/EMUD share PGC2/PGD2)
    #pragma config WINDIS = OFF // Windowed WDT Disable (Standard Watchdog Timer)

    // CONFIG 2
    #pragma config POSCMD = XT // Primary Oscillator Select (XT Crystal Oscillator)
    #pragma config FNOSC = PRIPLL // Initial Oscillator Source Selection (Primary Oscillator (XT, HS, EC) with PLL)
    #pragma config IOL1WAY = OFF // Peripheral pin select configuration (Allow multiple reconfigurations)
    #pragma config LPCFG = OFF

 
Pin connections (done through PPS configuration):
* CE - RD10
* Vcc - +3.3V
* Vss - GND
* SI - RG7
* S0 - RG8
* SCK - RG6
 
/* SPI2 */
    /* INPUT SPI2 */
    RPINR22bits.SDI2R = 26; // RP26 = RG7
    /* OUTPUT SPI2 */
    RPOR9bits.RP19R = 10; // 10 equivale a SDO2 / RP19R = RG8
    RPOR10bits.RP21R = 11; // 11 equivale a SCK2OUT / RP21 = RG6
    

 
SPI2's Initialization:
// Init the PIC24 SPI peripheral
void InitSPI(void )
{
    SPI2STATbits.SPIEN = 0; // Disable SPI
    
    SPI2STAT = 0x0000;
    SPI2CON1 = 0x0120;
    SPI2CON2 = 0;
    SPI2STAT = 0x8000;
        
    SPI2STATbits.SPIEN = 1;
    
    IFS2bits.SPI2IF = 0; // clear interrupt flag
 IEC2bits.SPI2IE = 0; // enable interrupt
}

 
Some interesting functions / code:
// Send one byte of data and receive one back at the same time
unsigned char writeSPI2(unsigned char data)
{
    SPI2BUF = data; // write to buffer for TX
    while(!SPI2STATbits.SPIRBF);
    return SPI2BUF; // read the received value
}

(this works)
/* JEDEC READ */
    SST26_CS = 0;
    writeSPI2(SST26_CMD_RJDC);
    x = writeSPI2();
    printf("x: %#04x\n", x);
    y = writeSPI2();
    printf("y: %#04x\n", y);
    z = writeSPI2();
    printf("z: %#04x\n", z);
    SST26_CS = 1;

 
And the image attached is the output through UART to CoolTerm.
 
Hope someone can help, I am trying to solve this problem since last week and I'm stressed out.
 
PS: The UART2 is also configured through PPS and it works so I conclude that the remapping isn't a problem.
 

Attached Image(s)

#1
NKurzman
A Guy on the Net
  • Total Posts : 18141
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: online
Re: SST26VF032 reading problem 2016/11/17 07:30:54 (permalink)
3 (1)
If you have the JEDEC code then your SPI link is working.
What commands are not working?
#2
ainhi
New Member
  • Total Posts : 21
  • Reward points : 0
  • Joined: 2016/11/16 08:51:47
  • Location: 0
  • Status: offline
Re: SST26VF032 reading problem 2016/11/18 01:26:31 (permalink)
3 (1)
I guess all of them.
 
I erase the memory, I read the status register, I read an address of the memory, I write to two different addresses but nothing seems works, all the responses are 0000.
I also tried reading the block protection register, not sure if I did correctly:
 
SST26_CS = 0;
writeSPI2(0x72);
for(g = 0; g < 10; g++)
    arr[g] = writeSPI2();
SST26_CS = 1;
for(g = 0; g < 10; g++)
    printf("array %d: %#04", g, arr[g]);

  
PD: I also tried another memory, the SST25VF016, with this one I can read JEDEC and the Status Register, but reading and writing don't work either. Not sure what conclusion to get from this.
post edited by ainhi - 2016/11/18 03:41:43
#3
NKurzman
A Guy on the Net
  • Total Posts : 18141
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: online
Re: SST26VF032 reading problem 2016/11/18 07:39:23 (permalink)
3 (1)
Do you clear the write protect bits first?
And send a write enable before each write?
Did you look at the microchip sample code?
#4
ainhi
New Member
  • Total Posts : 21
  • Reward points : 0
  • Joined: 2016/11/16 08:51:47
  • Location: 0
  • Status: offline
Re: SST26VF032 reading problem 2016/11/18 08:35:23 (permalink)
0
mmm, not sure if I understood the first question. I tried setting to 0 the Write Block Protection.
 
void WBPR()
{
int g;
SST25_CS = 0;
writeSPI2(0x06); // Write Enable
SST25_CS = 1;

SST25_CS = 0;
writeSPI2(0x42); // Write Block Protection
for(g = 0; g < 10; g++)
{
writeSPI2(0x00);
}
SST25_CS = 1;
}

 
Write enable is done everytime I try writing: I mean, when I erase the memory or when I write in it.
 
If you mean the sample code that is available here http://www.microchip.com/wwwproducts/en/SST26VF032 in the "Documentation" section, yes, I tried that driver or sample code. With that one I get all 0xFF-s instead of 0000s, I changed the driver's code so that the pins correspond to my configuration (as I use SPI2, I am using pins RG6, RG7 and RG8, but the driver provided by Microchip uses RF6, RF7 and RF8)
 
 
#5
NKurzman
A Guy on the Net
  • Total Posts : 18141
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: online
Re: SST26VF032 reading problem 2016/11/18 11:12:37 (permalink)
3 (1)
Yes you must do that First.
for every write there must be a read that is how SPI works.
 
SST25_CS = 0;
writeSPI2(0x06); // Send Write Enable
(void)readSPI2();         // clear returned byte from the SPI Buffer, or it will fill up and cause and overflow error.
SST25_CS = 1;
 
 
 
 
#6
ainhi
New Member
  • Total Posts : 21
  • Reward points : 0
  • Joined: 2016/11/16 08:51:47
  • Location: 0
  • Status: offline
Re: SST26VF032 reading problem 2016/11/21 04:13:07 (permalink)
1 (1)
not sure what I am doing wrong.
 
I changed some parts of my code to do the "for every write a read" and now the JEDEC doesn't work the way it should:
 

/* JEDEC ID */
SST25_CS = 0;
vSPIPut(SST26_CMD_RJDC); // Read JEDEC ID
x = uiSPIGet();
y = uiSPIGet();
z = uiSPIGet();
SST25_CS = 1;
printf("Manufacturer ID: %#04x, Device Type: %#04x, Device ID: %#04x\n", x, y, z);

 
and the answer is the following:
Manufacturer ID: 0000, Device Type: 0xbf, Device ID: 0x26

 
it seems that it costs one cycle to get the data, even if in the data-sheet says it's "instantaneous".
Should I use an auxiliar variable to read the first answer and then read the other ones? Something like this for all the instructions:

/* JEDEC ID */
SST25_CS = 0;
vSPIPut(SST26_CMD_RJDC); // Read JEDEC ID
aux = uiSPIGet();
x = uiSPIGet();
y = uiSPIGet();
z = uiSPIGet();
SST25_CS = 1;
printf("Manufacturer ID: %#04x, Device Type: %#04x, Device ID: %#04x\n", x, y, z);

 
 
BTW, these are the functions to read and write SPI:

inline void __attribute__((always_inline)) vSPIPut(uint8_t data){
uint8_t clear;

putcSPI2((uint8_t)data);
clear = getcSPI2();
return;
}

inline uint8_t __attribute__((always_inline)) uiSPIGet(void){

putcSPI2((uint8_t)0xFF);
return((uint8_t)getcSPI2());
}

#7
NKurzman
A Guy on the Net
  • Total Posts : 18141
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: online
Re: SST26VF032 reading problem 2016/11/21 07:44:34 (permalink)
3 (1)
After a putcSPI2 you need to wait for the bits to leave you PIC. That simultaneously clocks in the data from the external flash chip.
You need to check the tx buffer empty flag to in sure the write has ended.
Then you need to check the read buffer flag to insure the data is in the read buffer.

This will be as fast or slow as the baud rate is.

Are you referencing the data sheet and the section data sheet?
#8
ainhi
New Member
  • Total Posts : 21
  • Reward points : 0
  • Joined: 2016/11/16 08:51:47
  • Location: 0
  • Status: offline
Re: SST26VF032 reading problem 2016/11/22 07:13:21 (permalink)
3 (1)
Not sure if I understood completely.
 
I changed the SPIput and SPIget like this:
 
// *------------------------------------------------------*
inline void __attribute__((always_inline)) vSPIPut(uint8_t data)
{
uint8_t clear;

putcSPI2((uint8_t)data);
while(SPI2STATbits.SPITBF); // read Transfer Buffer Full

clear = getcSPI2();
while(!SPI2STATbits.SPIRBF); // read Receive Buffer Full

return;
}
// *------------------------------------------------------*
inline uint8_t __attribute__((always_inline)) uiSPIGet(void)
{

putcSPI2((uint8_t)0xFF);
while(SPI2STATbits.SPITBF); // read Transfer Buffer Full

return((uint8_t)getcSPI2());
while(!SPI2STATbits.SPIRBF); // read Receive Buffer Full
}
}

 
so that it reads the Transmision buffer and reception buffer. Is that what you meant?
 
I am looking at both datasheets (PIC24F and SST26) but not sure what I am doing wrong.
 
 
I tried reading the Status Register after setting Write-Enable (it should return 0x02), but it keeps returning 0000:
 
SST25_CS = 0;
vSPIPut(EEPROM_CMD_WREN); // Read Status Register
aux = uiSPIGet();
SST25_CS = 1;
SST25_CS = 0;
vSPIPut(SST26_CMD_RDSR); // Read Status Register
aux = uiSPIGet();
status = uiSPIGet();
SST25_CS = 1;
printf("Status Register: %#04x\n", status);

 
 
About the baud-rate, I noticed that in other PICs there is an option to set SPIxBRG, but in PIC24F I can't find that option.
#9
ainhi
New Member
  • Total Posts : 21
  • Reward points : 0
  • Joined: 2016/11/16 08:51:47
  • Location: 0
  • Status: offline
Re: SST26VF032 reading problem 2016/11/22 08:29:46 (permalink)
0
I did another test:
 
I changed the Initialization of the SPI, and I found out that, depending on the Primary and Secondary Prescaler values, the output is 0000 or 0xFF. Not sure which result is better, as it isn't the correct one in either way...
 
PS: JEDEC continues neing correct (bf, 26, 02), not changes for this.
#10
Aussie Susan
Super Member
  • Total Posts : 3646
  • Reward points : 0
  • Joined: 2008/08/18 22:20:40
  • Location: Melbourne, Australia
  • Status: offline
Re: SST26VF032 reading problem 2016/11/22 18:38:22 (permalink)
3 (1)
We really need to understand what the 'vSPIPut' and 'uiSPIGet' functions are really trying to do and exactly what the 'putcSPI2' and 'getSPI2' functions actually do. (This is one of the reasons I avoid library functions for straight-forward peripherals such as SPI.)
For example, is 'vSPIPut' simply trying to send a value to the slave? If so, is 'putcSPI2' only writing its parameter to the SPIxBUF and returning? If not (i.e. it is waiting for the exchange to complete) then the following 'while' is a waste of time.
Also, if 'putcSPI2' waits AND also reads the returned value, then the 'getSPI2' function should not be writing to the SSPxBUF as that would initiate another exchange. The other alternative is that it simply reads the SSPxBUF (in which case you have all of the overhead of a function call and return to perform a simple assignment).
Whatever the case, the tests in the 'while' loops are probably wrong. Normally you check the SPITBF to be clear before you initiate an exchange and use the SPIRBF to determine when it has completed. This means the check for SPITBF comes before the assignment to SSPxBUF and the check for SPIRBF comes BEFORE reading the value from the peripheral.
In the 'uiSPIGet' function, you actually return before you get to the last 'while' loop.
As for the "baud-rate" for the SPI peripheral, how you set it depends on the device in question. Some give you a few options (division factors) based on the system clock, and others have a separate and more flexible arrangement (although generally still based on the system clock). You need to look at the data sheet for your device. Also 'baud rate' for the SPI peripherla is generally referred to as the clocking rate or clock speed.
Susan
#11
ainhi
New Member
  • Total Posts : 21
  • Reward points : 0
  • Joined: 2016/11/16 08:51:47
  • Location: 0
  • Status: offline
Re: SST26VF032 reading problem 2016/11/23 02:01:07 (permalink)
3 (1)
Hi!
 
Thanks for the answer.
I also prefer writing my own code instead of using the given libraries, but for this project I tried so many things that I have everything mixed.
 
The code I wrote (for writing and reading SPI) is the following:

// Send one byte of data and receive one back at the same time
unsigned char write_SPI2(unsigned char data)
{
unsigned char result;

SPI2BUF = data; // write to buffer for TX
while(!SPI2STATbits.SPIRBF);
result = SPI2BUF; // read the received value

return result;
}

 
When I use writeSPI2, the results obtained are always 0xFF, besides JEDEC, which works fine too.
 
Codes for vSPIPut and uiSPIGet:
void WriteSPI2(unsigned int data_out)
{
if (SPI2CON1bits.MODE16) /* word write */
SPI2BUF = data_out;
else
SPI2BUF = data_out & 0xff; /* byte write */
}
 
unsigned int ReadSPI2()
{

SPI2STATbits.SPIROV = 0;

if (SPI2CON1bits.MODE16)
return ( SPI2BUF ); /* return word read */
else
return (SPI2BUF & 0xff); /* return byte read */

}

 
There are two defines for the functions:
#define  putcSPI2  WriteSPI2
#define  getcSPI2   ReadSPI2

 
I read in the SST26 datasheet the following line:
 
- Single-bit, SPI backwards compatible:
 -   Read, High-Speed Read and JEDEC ID Read

 
and in the Device Operation section it also says the following:
 
To provide backward compatibility to traditional Serial Flash devices, the device's inital state after a power-on is SPI bus protocol supporting only Read, High-Speed Read and JEDEC-ID Read instructions

 
Until now I didn't pay attention as I didn't understand it, but maybe it means that, when using SPI with this Flash, the ONLY operations allowed are those three. If someone can explain this line I would be really glad, because if it means that I can't do anything else when connected through SPI, maybe I should change the Flash, as my PIC doesn't have SQI.
 
If that's the case, can anyone recomend me a Flash that is fully compatible with SPI protocol?
#12
NKurzman
A Guy on the Net
  • Total Posts : 18141
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: online
Re: SST26VF032 reading problem 2016/11/23 07:24:50 (permalink)
3 (1)
I am using the same flash with a PIC 32
It works fine.
The warning is about those that want to us the chip in SQI mode.

Why are you coding 16 bit operation when 8 bit does not work yet?
Of the three write functions the first is correct.
The second two may be right or wrong depending on how the rest of the code is.
To read is exactly the same as writing
Write ssbuf
Check BF
Read ssbuf
#13
ainhi
New Member
  • Total Posts : 21
  • Reward points : 0
  • Joined: 2016/11/16 08:51:47
  • Location: 0
  • Status: offline
Re: SST26VF032 reading problem 2016/11/23 10:11:23 (permalink)
0
Could it be a configuration problem, then?
 
My pragmas are the following:
// CONFIG 1
#pragma config JTAGEN = OFF // JTAG Port Enable (Disabled)
#pragma config GCP = OFF // General Segment Code Protect (Code protection is disabled)
#pragma config GWRP = OFF // General Segment Write Protect (Disabled)
#pragma config FWDTEN = WDT_DIS // Watchdog Timer Enable (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config ICS = PGx2 // ICD Pin Placement Select(EMUC/EMUD share PGC2/PGD2)
#pragma config WINDIS = OFF // Windowed WDT Disable (Standard Watchdog Timer)
// CONFIG 2
#pragma config POSCMD = XT // Primary Oscillator Select (XT Crystal Oscillator)
#pragma config FNOSC = PRIPLL // Initial Oscillator Source Selection (Primary Oscillator (XT, HS, EC) with PLL)
#pragma config IOL1WAY = OFF // Peripheral pin select configuration (Allow multiple reconfigurations)
#pragma config LPCFG = OFF

RCONbits.SWDTEN = 0;

 
And the Initialization of the SPI the following:
void InitSPI(void )
{
TRISGbits.TRISG6 = 0;
TRISGbits.TRISG7 = 1;
TRISGbits.TRISG8 = 0;

SPI2STATbits.SPIEN = 0; // Disable SPI

SPI2STAT = 0x0000;
//SPI2CON1 = 0x013B;

SPI2CON1bits.DISSCK = 0;
SPI2CON1bits.DISSDO = 0;
SPI2CON1bits.MODE16 = 0;
SPI2CON1bits.SMP = 1;
SPI2CON1bits.CKE = 0;
SPI2CON1bits.SSEN = 0;
SPI2CON1bits.CKP = 1;
SPI2CON1bits.MSTEN = 1;
SPI2CON1bits.SPRE = 0;
SPI2CON1bits.PPRE = 2;

SPI2CON2 = 0;
SPI2STAT = 0x8000;

SPI2STATbits.SPIEN = 1;

IFS2bits.SPI2IF = 0; // clear interrupt flag
IEC2bits.SPI2IE = 0; // enable interrupt
}

#14
Aussie Susan
Super Member
  • Total Posts : 3646
  • Reward points : 0
  • Joined: 2008/08/18 22:20:40
  • Location: Melbourne, Australia
  • Status: offline
Re: SST26VF032 reading problem 2016/11/23 18:51:48 (permalink)
0
One thing you have not mentioned so far: are you setting RG6, RG7 and RG8 to 'digital' mode? They have AN17, AN18 and AN19 on them.
Looking at the last code example, I get the feeling that you are copying code from all over the place without understanding what it does. For example, you set SPI2STATbits.SPIEN to 0 and then set SPI2STAT to zero - one or the other but both suggests you don't know why you have the code lines there. Similarly setting SPI2STAT to 0x8000 and then setting SPI2STATbits.SPIEN to 1!!!
However, the CKP, CKE and SMP bit settings woud seem to be appropriate for the slave chip (as per its data sheet, Figure 4).
Susan
#15
ainhi
New Member
  • Total Posts : 21
  • Reward points : 0
  • Joined: 2016/11/16 08:51:47
  • Location: 0
  • Status: offline
Re: SST26VF032 reading problem 2016/11/24 01:52:12 (permalink)
0
I know the code is quite confusing, sorry about that. I've been testing a lot of different things and maybe I forgot to remove the previous code, so there are mixed parts.
I have to admit that I haven't noticed that SPI2STATbits.SPIEN = 1 and SPI2STAT = 0x8000 are the same. I fixed that.
 
In my PPS_Configuration function, where I set the RG6, RG7 and RG8 to be SPI pins, I am setting ANSG to 0.
 
I made a lot of different projects for the SPI - Flash. I tried the code provided by Microchip in the product's site (SST26VF032), I tried code from other people, I looked at the code examples from Microchip, I tried writing my own code, but all the results are the same: JEDEC works but everything else doesn't. sad: sad
 
 
Thank you so much for answering, I'm getting frustrated with this, I have no idea why it doesn't work. It's already more than two weeks and I didn't make any progress.
 
PS: I found a document from Microchip explaining how SPI works, so I will read it thoroughly to understand the module better.
#16
ainhi
New Member
  • Total Posts : 21
  • Reward points : 0
  • Joined: 2016/11/16 08:51:47
  • Location: 0
  • Status: offline
Re: SST26VF032 reading problem 2016/11/24 09:25:44 (permalink)
0
I did another test using SST25VF016B instead of using SST26.
 
In this case, I can Read Status Register, Write Status Register (I disabled the BPs or Block Protections), Write Enable works (as I checked if after setting it the Status Register was changed)... but Read and Write don't work... Read always returns 0xff even if I tried writing something else.
 
// *------------------------------------------------------*
void vSST25WriteByte(uint8_t data, unsigned long address){

unsigned char aux;
vSST25WriteEnable();

SST26_CS = 0;
aux = write_SPI2(SST26_CMD_WRITE);
aux = write_SPI2(((address & 0xFFFFFF) >> 16));
aux = write_SPI2(((address & 0xFFFF) >> 8));
aux = write_SPI2(address & 0xFF);
aux = write_SPI2(data);
SST26_CS = 1;

// Wait for write end
while(uiSST25IsWriteBusy())
{
LATAbits.LATA7 =! LATAbits.LATA7;
Delayms(100);
}
}
// *------------------------------------------------------*
uint8_t uiSST25ReadByte(unsigned long address){
uint8_t temp, aux;

SST26_CS = 0;
aux = write_SPI2(SST26_CMD_READ);
aux = write_SPI2(((address & 0xFFFFFF) >> 16));
aux = write_SPI2(((address & 0xFFFF) >> 8));
aux = write_SPI2(address & 0xFF);
temp = write_SPI2(0);
SST26_CS = 1;

return (temp);
}

#17
NKurzman
A Guy on the Net
  • Total Posts : 18141
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: online
Re: SST26VF032 reading problem 2016/11/24 10:04:26 (permalink)
3 (1)
Read will return 0xFF until you have a successful write. That is the erased value on the flash memory.
#18
ainhi
New Member
  • Total Posts : 21
  • Reward points : 0
  • Joined: 2016/11/16 08:51:47
  • Location: 0
  • Status: offline
Re: SST26VF032 reading problem 2016/11/24 10:35:59 (permalink)
3 (1)
Finally, I made it work with SST25, I can read and write Byte per Byte grin: grin
 
Not sure what's going on with SST26, maybe I am doing wrong the Block Protection part, or something else that in SST25 isn't needed.
 
I noticed that in SST25VF016B there is a pin which is WP, which is used to Enable and Disable Write-Protect. In SST26VF032 there isn't any pin which works like that. I guess the equivalent instruction to WP pin would be the Write Block Protection Register. 
#19
ainhi
New Member
  • Total Posts : 21
  • Reward points : 0
  • Joined: 2016/11/16 08:51:47
  • Location: 0
  • Status: offline
Re: SST26VF032 reading problem 2016/11/30 09:46:51 (permalink) ☄ Helpfulby mayk888 2017/02/02 03:22:14
4.67 (3)
Thank you everyone for your help.
 
At the end I couldn't make the SST26VF032 Flash work, so I bought SST26VF032B (which is quite different) and I managed it to work with the code of the SST25VF032B one (changing some minimal aspects).
 
Now, everything works with SST26VF032B!!!!
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2020 APG vNext Commercial Version 4.5