This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

SPI SST25VF016B

Hi, i'm writing a library to handle the SST25VF016B data flash unit for the land tiger LPC1768. Datasheet for the chip

So far I've written this code:

SPI.h:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef __SPI_H
#define __SPI_H
#include "LPC17xx.h"
#include "../types.h"
#include "../power.h"
typedef enum{
ABRT = 1<<3,
MODF = 1<<4,
ROVR = 1<<5,
WCOL = 1<<6,
SPIF = 1<<7
}SPIStatus;
void SPI_Init(const unsigned long frequency);
void enableChipSelect(void);
void disableChipSelect(void);
uint8_t SPI_Transfer(uint8_t data);
#endif /* end __SPI_H */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

SPI.c:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "lpc17xx.h"
#include "SPI.h"
uint8_t dummy;
void SPI_Init(const unsigned long frequency) {
//P0.15 (SCK)
LPC_PINCON->PINSEL0 &= ~(3UL<<30);
LPC_PINCON->PINSEL0 |= (3UL<<30);
//P0.17 (MISO), P0.18 (MOSI)
LPC_PINCON->PINSEL1 &= ~((3<<2) | (3<<4));
LPC_PINCON->PINSEL1 |= (3<<2) | (3<<4);
//P0.16 (GPIO)
LPC_PINCON->PINSEL1 &= ~(3<<0);
//SCK, SSEL, MOSI as OUTPUT
LPC_GPIO0->FIODIR |= (1<<15) | (1<<16) | (1<<18);
//MISO as INPUT
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

DataFlash.h:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef __DataFlash_H
#define __DataFlash_H
#include "LPC17xx.h"
#include "../types.h"
#include "../SPI/SPI.h"
typedef enum{
DF_READ_ID = 0x0,
DF_JEDEC_READ_ID = 0x9F,
DF_GET_STATUS_REGISTER = 0x05,
DF_READ_LO_FREQ = 0x03,
DF_READ_HI_FREQ = 0x0B,
DF_ERASE_4KB = 0x20,
DF_ERASE_32KB = 0x52,
DF_ERASE_64KB = 0xD8,
DF_ERASE_CHIP_1 = 0x60,
DF_ERASE_CHIP_2 = 0xC7,
DF_BYTE_PROGRAM = 0x02,
DF_AUTO_ADDRESS_INCREMENT_PROGRAM = 0xAD,
DF_ENABLE_WRITE_STATUS_REGISTER = 0x50,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

DataFlash.c:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "DataFlash.h"
void DF_Init(bool read_only) {
SPI_Init(1000000);
disableChipSelect();
if (read_only == false) {
while (true) {
uint8_t s = DF_ReadStatusRegister();
if (s != 0xFF & (s & (DF_BLOCK_PROTECTION_LV_0 | DF_BLOCK_PROTECTION_LV_1 | DF_BLOCK_PROTECTION_LV_2 | DF_BLOCK_PROTECTION_LV_3)) != 0x0) break;
}
DF_UnlockChip();
}
}
uint8_t DF_WaitForStatusRegisterWithValues(uint8_t statusON, uint8_t statusOFF) {
enableChipSelect();
SPI_Transfer(DF_GET_STATUS_REGISTER);
uint8_t status;
while (true) {
status = SPI_Transfer(0xFF);
if ((((status & statusON) == statusON) && ((status & statusOFF) == 0x0))) {
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Then in order to test it i wrote a function to read the memory (0x80 bytes) and display those to the LCD and mapped erase and write a byte to the land tiger keys... Nothing special I just call the library functions.

My porblem is that this code work only sometimes. Like for example if it manages to write data to the LCD if I write a byte sometimes it works and sometimes if just freeze on the status register busy check as the SPI_Transfer(0xFF) to read the status register returns 0xFF (this happens also with other functions).

Now after trying to write a byte the device won't pass DF_ChipUnlock() as on DF_Init(false) it passes the first loop to check for 0x1C (block protection on startup) but after that when it enter the method DF_ChipUnlock() it freezes there, as DF_EnableWriteStatusRegister(); DF_WriteStatusRegister(0x0); won't work (the status register always reads 0x1C (all sectors protected)).

Am I missing something?

Thanks for your time.

0