emFile with NOR Flash Crash

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • 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 Source Code

    1. #include <stdio.h>
    2. #include "norflash_sst39vf3201.h"
    3. #include "FS.h"
    4. #include "RTOS.h"
    5. static int WriteOff(U8 Unit, U32 Off, const void * pSrc, U32 Len);
    6. static int ReadOff(U8 Unit, void * pDest, U32 Off, U32 Len);
    7. static int EraseSector(U8 Unit, unsigned int SectorIndex);
    8. static void GetSectorInfo(U8 Unit, unsigned int SectorIndex, U32 * pOff, U32 * pLen);
    9. static int GetNumSectors(U8 Unit);
    10. static void Configure(U8 Unit, U32 BaseAddr, U32 StartAddr, U32 NumBytes);
    11. static void OnSelectPhy(U8 Unit);
    12. static void DeInit(U8 Unit);
    13. const FS_NOR_PHY_TYPE FS_NOR_PHY_CFI_39FV3201 __attribute__ ((section("EXT_FLASH"))) = {
    14. WriteOff,
    15. ReadOff,
    16. EraseSector,
    17. GetSectorInfo,
    18. GetNumSectors,
    19. Configure,
    20. OnSelectPhy,
    21. DeInit
    22. };
    23. typedef struct
    24. {
    25. U32 BaseAddr;
    26. U32 StartAddr;
    27. U32 NumBytes;
    28. } DRIVER_INSTANCE;
    29. DRIVER_INSTANCE iDriver[10];
    30. static int WriteOff(U8 Unit, U32 Off, const void * pSrc, U32 Len)
    31. {
    32. U32 flash_addr;
    33. U16 *pSource16;
    34. U8 *pSource8;
    35. // printf("WriteOff - Off: %lX, pSrc: %lX, Len: %lu\n", Off, (U32)pSrc, Len);
    36. // fflush(stdout);
    37. pSource16 = (U16 *)pSrc;
    38. flash_addr = iDriver[Unit].StartAddr + ((Off >> 1) << 1);
    39. // Se offset ímpar
    40. if (Off % 2)
    41. {
    42. pSource8 = (U8 *)pSrc;
    43. OS_EnterRegion();
    44. if (NORFLASHWriteWord(flash_addr, ((*pSource8++) << 8) | *((U8 *)flash_addr)) != 0)
    45. {
    46. OS_LeaveRegion();
    47. return 1;
    48. }
    49. OS_LeaveRegion();
    50. pSource16 = (U16 *)pSource8;
    51. Len--;
    52. flash_addr += 2;
    53. }
    54. while (Len >= 2)
    55. {
    56. OS_EnterRegion();
    57. if (NORFLASHWriteWord(flash_addr, *pSource16++) != 0)
    58. {
    59. OS_LeaveRegion();
    60. return 1;
    61. }
    62. OS_LeaveRegion();
    63. Len -= 2;
    64. flash_addr += 2;
    65. }
    66. if (Len == 1)
    67. {
    68. pSource8 = (U8 *)pSource16;
    69. OS_EnterRegion();
    70. if (NORFLASHWriteWord(flash_addr, ((*((U8 *)(flash_addr + 1))) << 8) | *pSource8) != 0)
    71. {
    72. OS_LeaveRegion();
    73. return 1;
    74. }
    75. OS_LeaveRegion();
    76. }
    77. return 0;
    78. }
    79. static int ReadOff(U8 Unit, void * pDest, U32 Off, U32 Len)
    80. {
    81. U32 *pSource32, *pDestin32;
    82. U16 *pSource16, *pDestin16;
    83. U8 *pSource8, *pDestin8;
    84. // printf("ReadOff - pDest: %lX, Off: %lX, Len: %lu\n", (U32)pDest, Off, Len);
    85. // fflush(stdout);
    86. pSource32 = (U32 *) (iDriver[Unit].StartAddr + Off);
    87. pDestin32 = (U32 *) pDest;
    88. if (Len >= 4)
    89. {
    90. while (Len >= 4)
    91. {
    92. *pDestin32++ = *pSource32++;
    93. Len -= 4;
    94. }
    95. if (Len == 0) return 0;
    96. }
    97. if (Len >= 2)
    98. {
    99. pSource16 = (U16 *) pSource32;
    100. pDestin16 = (U16 *) pDestin32;
    101. while (Len >= 2)
    102. {
    103. *pDestin16++ = *pSource16++;
    104. Len -= 2;
    105. }
    106. if (Len == 0) return 0;
    107. pSource32 = (U32 *) pSource16;
    108. pDestin32 = (U32 *) pDestin16;
    109. }
    110. if (Len >= 1)
    111. {
    112. pSource8 = (U8 *) pSource32;
    113. pDestin8 = (U8 *) pDestin32;
    114. while (Len--) *pDestin8++ = *pSource8++;
    115. }
    116. return 0;
    117. }
    118. static int EraseSector(U8 Unit, unsigned int SectorIndex)
    119. {
    120. // printf("EraseSector - SectorIndex: %u\n", SectorIndex);
    121. // fflush(stdout);
    122. OS_EnterRegion();
    123. NORFLASHSectorErase(SectorIndex);
    124. OS_LeaveRegion();
    125. return 0;
    126. }
    127. static void GetSectorInfo(U8 Unit, unsigned int SectorIndex, U32 * pOff, U32 * pLen)
    128. {
    129. // volatile int x, y, z ,w;
    130. //
    131. // if ((SectorIndex >= 512) || (pOff == NULL) || (pLen == NULL))
    132. // {
    133. // x = SectorIndex;
    134. // y = (int)pOff;
    135. // z = (int)pLen;
    136. // w = SectorIndex;
    137. // return;
    138. // }
    139. // printf("GetSectorInfo - SectorIndex: %u, pOff: %lX, pLen: %lX\n", SectorIndex, (U32)pOff, (U32)pLen);
    140. // fflush(stdout);
    141. *pOff = SectorIndex * 4096;
    142. *pLen = 4096;
    143. }
    144. static int GetNumSectors(U8 Unit)
    145. {
    146. // printf("GetNumSectors\n");
    147. // fflush(stdout);
    148. return (iDriver[Unit].NumBytes / 4096);
    149. }
    150. static void Configure(U8 Unit, U32 BaseAddr, U32 StartAddr, U32 NumBytes)
    151. {
    152. // printf("Configure\n");
    153. // fflush(stdout);
    154. iDriver[Unit].BaseAddr = BaseAddr;
    155. iDriver[Unit].StartAddr = StartAddr;
    156. iDriver[Unit].NumBytes = NumBytes;
    157. }
    158. static void OnSelectPhy(U8 Unit)
    159. {
    160. // printf("OnSelectPhy\n");
    161. // fflush(stdout);
    162. }
    163. static void DeInit(U8 Unit)
    164. {
    165. // printf("DeInit\n");
    166. // fflush(stdout);
    167. }
    Display All


    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?

    The post was edited 2 times, last by leonarff ().

  • 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 Source Code

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


    Best regards,
    Marius
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.