Sunday, June 25th 2017, 9:09am UTC+2

You are not logged in.

  • Login
  • Register

leonarff

Beginner

Date of registration: Oct 2nd 2013

Posts: 6

1

Thursday, October 8th 2015, 5:46pm

emFile with NOR Flash Crash

I'm using emFILE v3.28 library for evaluating for EA1788 evaluation board with Keil IDE.
I tried to run the physical layer FS_NOR_PHY_CFI_1x16 and could not.
The flash is connected as follows:



So I had to implement my own:

C/C++ Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#include <stdio.h>
#include "norflash_sst39vf3201.h"
#include "FS.h"
#include "RTOS.h"

static int WriteOff(U8 Unit, U32 Off, const void * pSrc, U32 Len);
static int ReadOff(U8 Unit, void * pDest, U32 Off, U32 Len);
static int EraseSector(U8 Unit, unsigned int SectorIndex);
static void GetSectorInfo(U8 Unit, unsigned int SectorIndex, U32 * pOff, U32 * pLen);
static int GetNumSectors(U8 Unit);
static void Configure(U8 Unit, U32 BaseAddr, U32 StartAddr, U32 NumBytes);
static void OnSelectPhy(U8 Unit);
static void DeInit(U8 Unit);

const FS_NOR_PHY_TYPE FS_NOR_PHY_CFI_39FV3201 __attribute__ ((section("EXT_FLASH"))) = {
	WriteOff,
	ReadOff,
	EraseSector,
	GetSectorInfo,
	GetNumSectors,
	Configure,
	OnSelectPhy,
	DeInit
};

typedef struct
{
	U32 BaseAddr;
	U32 StartAddr;
	U32 NumBytes;
} DRIVER_INSTANCE;

DRIVER_INSTANCE iDriver[10];

static int WriteOff(U8 Unit, U32 Off, const void * pSrc, U32 Len)
{
	U32 flash_addr;
	U16 *pSource16;
	U8 *pSource8;

//	printf("WriteOff - Off: %lX, pSrc: %lX, Len: %lu\n", Off, (U32)pSrc, Len);
//	fflush(stdout);

  pSource16 = (U16 *)pSrc;
	flash_addr = iDriver[Unit].StartAddr + ((Off >> 1) << 1);

	// Se offset ímpar
	if (Off % 2)
	{
		pSource8 = (U8 *)pSrc;
		OS_EnterRegion();
		if (NORFLASHWriteWord(flash_addr, ((*pSource8++) << 8) | *((U8 *)flash_addr)) != 0)
		{
			OS_LeaveRegion();
			return 1;
		}
		OS_LeaveRegion();

		pSource16 = (U16 *)pSource8;
		Len--;
		flash_addr += 2;
	}
	
	while (Len >= 2)
	{
		OS_EnterRegion();
		if (NORFLASHWriteWord(flash_addr, *pSource16++) != 0)
		{
			OS_LeaveRegion();
			return 1;
		}
		OS_LeaveRegion();

		Len -= 2;
		flash_addr += 2;
	}
	
	if (Len == 1)
	{
		pSource8 = (U8 *)pSource16;
		OS_EnterRegion();
		if (NORFLASHWriteWord(flash_addr, ((*((U8 *)(flash_addr + 1))) << 8) | *pSource8) != 0)
		{
			OS_LeaveRegion();
			return 1;
		}
		OS_LeaveRegion();
	}
	
	return 0;
}

static int ReadOff(U8 Unit, void * pDest, U32 Off, U32 Len)
{
	U32 *pSource32, *pDestin32;
	U16 *pSource16, *pDestin16;
	U8 *pSource8, *pDestin8;

//	printf("ReadOff - pDest: %lX, Off: %lX, Len: %lu\n", (U32)pDest, Off, Len);
//	fflush(stdout);
	
	pSource32 = (U32 *) (iDriver[Unit].StartAddr + Off);
	pDestin32 = (U32 *) pDest;
	if (Len >= 4)
	{
		while (Len >= 4)
		{
			*pDestin32++ = *pSource32++;
			Len -= 4;
		}
		
		if (Len == 0) return 0;
	}
	
	if (Len >= 2)
	{
		pSource16 = (U16 *) pSource32;
		pDestin16 = (U16 *) pDestin32;

		while (Len >= 2)
		{
			*pDestin16++ = *pSource16++;
			Len -= 2;
		}

		if (Len == 0) return 0;
		
		pSource32 = (U32 *) pSource16;
		pDestin32 = (U32 *) pDestin16;
	}
	
	if (Len >= 1)
	{
		pSource8 = (U8 *) pSource32;
		pDestin8 = (U8 *) pDestin32;

		while (Len--) *pDestin8++ = *pSource8++;
	}
	
	return 0;
}

static int EraseSector(U8 Unit, unsigned int SectorIndex)
{
//	printf("EraseSector - SectorIndex: %u\n", SectorIndex);
//	fflush(stdout);

	OS_EnterRegion();
	NORFLASHSectorErase(SectorIndex);
	OS_LeaveRegion();
	
	return 0;
}

static void GetSectorInfo(U8 Unit, unsigned int SectorIndex, U32 * pOff, U32 * pLen)
{
//	volatile int x, y, z ,w;
//	
//	if ((SectorIndex >= 512) || (pOff == NULL) || (pLen == NULL))
//	{
//		x = SectorIndex;
//		y = (int)pOff;
//		z = (int)pLen;
//		w = SectorIndex;
//		return;
//	}
	
//	printf("GetSectorInfo - SectorIndex: %u, pOff: %lX, pLen: %lX\n", SectorIndex, (U32)pOff, (U32)pLen);
//	fflush(stdout);
	
	*pOff = SectorIndex * 4096;
	*pLen = 4096;
}

static int GetNumSectors(U8 Unit)
{
//	printf("GetNumSectors\n");
//	fflush(stdout);

	return (iDriver[Unit].NumBytes / 4096);
}

static void Configure(U8 Unit, U32 BaseAddr, U32 StartAddr, U32 NumBytes)
{
//	printf("Configure\n");
//	fflush(stdout);

	iDriver[Unit].BaseAddr = BaseAddr;
	iDriver[Unit].StartAddr = StartAddr;
	iDriver[Unit].NumBytes = NumBytes;
}

static void OnSelectPhy(U8 Unit)
{
//	printf("OnSelectPhy\n");
//	fflush(stdout);
}

static void DeInit(U8 Unit)
{
//	printf("DeInit\n");
//	fflush(stdout);
}


When I write a file with the size of the drive it is saved normally.
But if I delete the file and write again, there is a Hardware Fault.
This hardware fault is caused by pLen parameter of GetSectorInfo routine that is 0.



Could anyone help me?

This post has been edited 2 times, last edit by "leonarff" (Oct 14th 2015, 6:49pm)


SEGGER - Marius

Super Moderator

Date of registration: Aug 10th 2011

Posts: 23

2

Friday, January 15th 2016, 3:58pm

Hello leonarff,

In some cases, the NOR driver needs to know only the address of a physical sector
and it calls GetSectorInfo() with the pLen parameter set to NULL.
You can avoid the Hardware Fault error by validating the pLen parameter before dereferencing it.

C/C++ Source code

1
2
3
if (pLen) {
  *pLen = 4096;
}


Best regards,
Marius