-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSmall_NAND_Test.c
202 lines (162 loc) · 7.58 KB
/
Small_NAND_Test.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
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
/*
* NAND_Test.c
*
* Created: 10-Mar-18 12:20:56 AM
* Author: Krystine
*/
#include "Small_NAND_Test.h"
static uint32_t dataIdx;
char WELCOME[31] = "About to initialize device...\n";
char GOODBYE[10] = "Goodbye!\n";
char START_WRITE[22] = "Device writing begin!\n";
char DONE_WRITE[25] = "Device writing complete.\n";
char START_READ[22] = "Begin device reading.\n";
char DONE_READ[25] = "Device reading complete!\n";
char NEW_LINE = '\n';
static char charBuffer[5];
static char statBuffer[100];
/*************************************************************
* FUNCTION: nand_test_driver()
* -----------------------------------------------------------
* This function
*
* Parameters: none
*
* Returns:
* status : Current value of the status register.
*************************************************************/
uint8_t small_nand_test_driver()
{
volatile uint8_t status; /* Value of the flash status register. */
int retVal; /* Return value of functions that don't return a status. */
int tempRetVal;
static uint8_t pageCount; /* Loop control variable for writes and reads. Iterate over pages. */
static uint32_t blockAddress; /* The micro stores values little endian but is configured to send SPI data big endian */
uint32_t nextBlockOffset; /* Offset to get to the next block in the main memory array. */
uint32_t colAddress; /* Column address for in-page offset */
static uint32_t address; /* The OR'd bits of block and page addresses to create a single 3 byte address. */
uint8_t page[PAGE_SIZE_EXTRA]; /* Holds a page worth (PAGE_SIZE bytes) of data. */
uint8_t dataByteLast;
int i; /* Loop control variable for printing. */
int blockCount; /* Loop control variable for looping through blocks. */
/* INITIALIZATIONS */
blockAddress = 0x000040;
nextBlockOffset = 0x000040;
colAddress = 0x0000;
dataIdx = 0;
/**************
* INITIALIZE *
**************/
/* Set up USB connection */
/* Wait for USB connection to be made with computer. */
do { /* NOTHING */ } while (!usb_dtr());
/* Write welcome message to PC console. */
retVal = usb_write((uint8_t *) WELCOME, sizeof(WELCOME));
/* Initialize the flash interface. */
flash_init();
/* Start by erasing the entire device (except the superblock). */
status = flash_erase_device();
/* Wait until device is done erasing. */
flash_wait_until_not_busy();
/*********
* WRITE *
*********/
for(blockCount = 0; blockCount < NUM_TEST_BLOCKS; blockCount++) {
do {
retVal = usb_write((uint8_t *) START_WRITE, sizeof(START_WRITE));
} while(retVal != USB_OK );
/* Iterate through a page worth of data to fill up all 64 pages
* of the block. */
for(pageCount = 0; pageCount < PAGES_PER_BLOCK; pageCount++)
{
/* Get next page data to write. */
small_nand_test_load_data(page, PAGE_SIZE_LESS);
/* Bitwise OR block count a page count to get 3-byte data address. */
address = (blockAddress | pageCount);
/* Write test data. */
status = flash_write(address, colAddress, page, PAGE_SIZE_LESS);
/* Wait until device is done erasing. */
flash_wait_until_not_busy();
}
blockAddress += nextBlockOffset;
}
/********
* READ *
********/
for(blockCount = 0; blockCount < NUM_TEST_BLOCKS; blockCount++) {
do {
retVal = usb_write((uint8_t *) DONE_WRITE, sizeof(DONE_WRITE));
} while(retVal != USB_OK);
/* Reinitialize variables for reading. */
blockAddress = 0x000040;
/* Read data back and print over USB. Data integrity will
* be checked on the PC end. */
do {
retVal = usb_write((uint8_t *) START_READ, sizeof(START_READ));
} while(retVal != USB_OK);
/* Iterate through every page in the block and print the data to the PC. */
for(pageCount = 0; pageCount < PAGES_PER_BLOCK; pageCount++) {
/* Bitwise OR block count a page count to get 3-byte data address. */
address = (blockAddress | pageCount);
/* Read test data. */
status = flash_read(address, colAddress, page, PAGE_SIZE_LESS);
/* Wait until device is done reading. */
flash_wait_until_not_busy();
/* Initialize the data byte last variable for debugging purposes. */
dataByteLast = page[0];
/* Loop through each item in a page to print it one byte at a time separated by a newline. */
for(i = 0; i < PAGE_SIZE_LESS; i++) {
/* Wait for USB to not be busy. This prevents charBuffer from being overwritten. */
while(usb_isInBusy() == true) {/* WAIT */}
/* Place new data in the buffer. */
snprintf(charBuffer, 5,"%3d\n", page[i]);
/* Try to write the data. If an error occurs, the error value will be printed as well. */
do {
retVal = usb_write(charBuffer, sizeof(charBuffer));
/* If there was an error, print the error value. */
if(retVal != USB_OK) {
sprintf(statBuffer, "ERROR: %d LAST DATA: %d CURRENT DATA:", retVal, dataByteLast);
do {
tempRetVal = usb_write(statBuffer, sizeof(statBuffer));
} while(tempRetVal != USB_OK);
/* Wait until USB is not busy since the string that was just sent is large. */
while(usb_isInBusy() == true) {/* WAIT */}
}
} while(retVal != USB_OK);
/* Store the previous iteration value for debugging. */
dataByteLast = page[i];
}
} /* End pages per block loop. */
/* Go to next block's address. */
blockAddress += nextBlockOffset;
} /* End blocks per run loop. */
/* Print done message. */
do {
retVal = usb_write((uint8_t *) DONE_READ, sizeof(DONE_READ));
} while(retVal != USB_OK);
return 0;
}
/*************************************************************
* FUNCTION: nand_test_load_data()
* -----------------------------------------------------------
* This function loads a page of data based on the PAGE_SIZE.
* Data is taken from a static TEST_DATA array containing
* TEST_DATA_SIZE elements. The value of TEST_DATA_SIZE must
* be greater than PAGE_SIZE.
*
* Parameters:
* page[] : Array to hold new page data.
* PAGE_SIZE : Amount of data to load into page[].
*
* Returns:
* page[] : New data returned by reference.
*************************************************************/
void small_nand_test_load_data(uint8_t page[], const int PAGE_SIZE)
{
int i; /* Loop control variable. */
/* Load data from page data array. */
for(i = 0; i < PAGE_SIZE; i++)
{
page[i] = TEST_DATA[i];
}
}