-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnand_m79a.c
113 lines (80 loc) · 3.4 KB
/
nand_m79a.c
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
/************************** Flash Memory Driver ***********************************
Filename: nand_m79a.c
Description: Top NAND controller layer that manages storage and maps logical addresses
to physical locations using low level drivers.
Version: 0.1
Author: Tharun Suresh
********************************************************************************
Version History.
Ver. Date Comments
0.1 Jan 2022 In Development
********************************************************************************
The following functions are available in this library:
********************************************************************************/
#include "nand_m79a.h"
/******************************************************************************
* Initialization
*****************************************************************************/
/**
@brief Initializes the NAND. Steps: Reset device and check for correct device IDs.
@note This function must be called first when powered on.
@return NAND_ReturnType
@retval Ret_ResetFailed
@retval Ret_WrongID
@retval Ret_Success
*/
NAND_ReturnType NAND_Init(SPI_HandleTypeDef *hspi) {
NAND_ID dev_ID;
/* Wait for T_POR = 1.25ms after power on */
NAND_Wait(T_POR);
/* Reset NAND flash during initialization. May not be necessary though (page 50) */
if (NAND_Reset(hspi) != Ret_Success) {
return Ret_ResetFailed;
} else {
/* check if device ID is same as expected */
NAND_Read_ID(hspi, &dev_ID);
if (dev_ID.manufacturer_ID != NAND_ID_MANUFACTURER || dev_ID.device_ID != NAND_ID_DEVICE) {
return Ret_WrongID;
} else {
return Ret_Success;
}
}
}
/******************************************************************************
* Reads and Writes
*****************************************************************************/
/**
@brief
@note
@return NAND_ReturnType
@retval
*/
// NAND_ReturnType func(SPI_HandleTypeDef *hspi) {
// }
NAND_ReturnType NAND_Read(SPI_HandleTypeDef *hspi, NAND_Addr *address, uint16_t length) {
PhysicalAddrs addr_i;
uint8_t data[PAGE_SIZE];
// TODO: can't just be any address. start address has to be page start. and max len must be page end.
// handle writing between pages.
/* Convert logical address to physical internal addresses to send to NAND */
__map_logical_addr(address, &addr_i);
NAND_Page_Read(hspi, &addr_i, data, length);
return Ret_Success;
}
/******************************************************************************
* Internal Functions
*****************************************************************************/
/**
@brief
@note
@return NAND_ReturnType
@retval
*/
NAND_ReturnType __map_logical_addr(NAND_Addr *address, PhysicalAddrs *addr_struct) {
addr_struct -> plane = ADDRESS_2_PLANE(*address);
addr_struct -> block = ADDRESS_2_BLOCK(*address);
addr_struct -> page = ADDRESS_2_PAGE(*address);
addr_struct -> rowAddr = 0 || ((ADDRESS_2_BLOCK(*address) << ROW_ADDRESS_PAGE_BITS) | ADDRESS_2_PAGE(*address));
addr_struct -> colAddr = 0 || ((ADDRESS_2_PLANE(*address) << COL_ADDRESS_BITS) | ADDRESS_2_COL(*address));
return Ret_Success;
}