-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprocess.c
292 lines (254 loc) · 13 KB
/
process.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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
// Process.c is the application layer. All function calls are hardware ambivalent.
//
#include <stdint.h> // Find integer types like "uint8_t"
#include "Eve2_81x.h" // Matrix Orbital EVE Driver
#include "Arduino_AL.h" // include the hardware specific abstraction layer header for the specific hardware in use.
#include "MatrixEve2Conf.h" // Header for EVE Display configuration settings
#include "process.h" // Every c file has it's header and this is the one for this file
// The size of the buffer we use for data transfers. It is a tiny buffer in Arduino Uno
#define COPYBUFSIZE WorkBuffSz
#define NUM_IMAGES 8
#define LINE_LIMIT 35 // should never exceed 33
uint32_t Time2CheckTouch = 0; // "Private" variable holding time of next check for user input
uint32_t PressTimeout = 0; // "Private" variable counting down time you can spend pressing the screen
FileParms FoundFiles[NUM_IMAGES]; // "Private" array of filenames and parameters found in Eve attached flash
void MakeScreen_Bitmap(uint8_t FileIndex)
{
uint32_t tmp = FoundFiles[FileIndex].FlashAddress;
Log("Bitmap at %lu\n", tmp);
Send_CMD(CMD_DLSTART);
Send_CMD(CLEAR(1,1,1));
Send_CMD(CMD_FLASHSOURCE); // Tell the next command where to get it's data from in flash
Send_CMD(RAM_FLASH | tmp); // This is the address in Eve attached flash
Cmd_SetBitmap(RAM_FLASH | tmp/32, COMPRESSED_RGBA_ASTC_8x8_KHR, 800, 480);
Send_CMD(BEGIN(BITMAPS));
Send_CMD(VERTEX2II(0, 0, 0, 0));
Send_CMD(END());
Send_CMD(DISPLAY());
Send_CMD(CMD_SWAP);
UpdateFIFO();
}
bool FlashGetFileParms(void)
{
// Transfer the first 1024 bytes of flash into RAM_G or you could just transfer enough to get the actual size of the map and then do it again
// Log("FlashGetFileParms Reading Flash\n");
Send_CMD(CMD_FLASHREAD);
Send_CMD(RAM_G); // Address we are writing to
Send_CMD(RAM_FLASH_POSTBLOB); // Address we are reading from
Send_CMD(0x00000400); // It will be 1K bytes - enough for quite a large list but check this
UpdateFIFO(); // Trigger the CoProcessor to start processing commands out of the FIFO
Wait4CoProFIFOEmpty(); // wait here until the coprocessor has read and executed every pending command.
// File format for the .map is:
// Filename = 12 characters padded with spaces
// a space and a colon and a space
// beginning address field of 6 characters padded with spaces
// a space and a colon and a space
// file size field of variable length - no padding
// end of line and carriage return (0D 0A)
// More of the same if needed
// One or more zeros to pad to 0x10 boundary. I have no proof that this zero will be provided if the previous data happens to fall on the boundary.
uint32_t WorkingAddress = RAM_G;
for(uint8_t i = 0; i < NUM_IMAGES; i++) // One must assume that things are as planned and there are NUM_IMAGES images
{
uint8_t CharCount = 0;
uint8_t tmpBuf[LINE_LIMIT];
while (CharCount < LINE_LIMIT)
{
// get bytes and place in buffer.
tmpBuf[CharCount] = rd8(WorkingAddress++);
// Before going any further check for a zero. There are no zeros anywhere until we have run out of map file
// Since we are done when we read enough lines, the zero should never be seen by us, so any zero encountered is an error
if (tmpBuf[CharCount] == 0x00) // if we got a zero
return false;
if (tmpBuf[CharCount] == 0x0D) // if we got the line end
{
if (rd8(WorkingAddress++) == 0x0A) // then see if we get the carriage return
{
// We found an entry and we know where we are so let's monopolize on that and store the rest of the parameters now
// If Bridgetek also save media parameters in the map file, we could parse and store things like bitmap dimensions
// or number of frames of an animation and many other such useful information that we are now forced to hardcode.
// We could make our own map file in a text editor
CharCount = 0;
while (tmpBuf[CharCount++] != 0x20); // run through the tmpbuf again looking for the first space
tmpBuf[CharCount-1] = 0x00; // null terminate the filename string
memcpy(FoundFiles[i].FileName, tmpBuf, strlen(tmpBuf)+1); // Copy the file name
// the rest of the buffer is still valid - go to start of the start address (index = 15)
// look for the next occurance of a space and replace that with a zero to make a string of it
CharCount = 15;
while (tmpBuf[CharCount++] != 0x20);
tmpBuf[CharCount-1] = 0x00; // null terminate the start address string
// I intended to use something like atol() or strtoul(), but could get neither to work properly
uint32_t tmp = 0;
for (uint8_t i = 15; i < CharCount-1; i++)
{
tmp *= 10;
tmp += (tmpBuf[i] - '0');
}
FoundFiles[i].FlashAddress = tmp;
Log("%s: %s = %lu\n",FoundFiles[i].FileName, &tmpBuf[15], FoundFiles[i].FlashAddress);
break; // Entry complete, leave while loop
}
}
CharCount++;
}
}
return true;
}
bool FlashAttach(void)
{
Send_CMD(CMD_FLASHATTACH);
UpdateFIFO(); // Trigger the CoProcessor to start processing commands out of the FIFO
Wait4CoProFIFOEmpty(); // Wait here until the coprocessor has read and executed every pending command.
uint8_t FlashStatus = rd8(REG_FLASH_STATUS + RAM_REG);
if (FlashStatus != FLASH_STATUS_BASIC)
{
// Log("FlashAttach: NOT attached\n");
return false;
}
return true;
}
bool FlashDetach(void)
{
Send_CMD(CMD_FLASHDETACH);
UpdateFIFO(); // Trigger the CoProcessor to start processing commands out of the FIFO
Wait4CoProFIFOEmpty(); // Wait here until the coprocessor has read and executed every pending command.
uint8_t FlashStatus = rd8(REG_FLASH_STATUS + RAM_REG);
if (FlashStatus != FLASH_STATUS_DETACHED)
{
// Log("FlashDetach: NOT detached\n");
return false;
}
return true;
}
bool FlashFast(void)
{
Cmd_Flash_Fast();
UpdateFIFO(); // Trigger the CoProcessor to start processing commands out of the FIFO
Wait4CoProFIFOEmpty(); // Wait here until the coprocessor has read and executed every pending command.
uint8_t FlashStatus = rd8(REG_FLASH_STATUS + RAM_REG);
if (FlashStatus != FLASH_STATUS_FULL)
{
// Log("FlashFast: NOT full mode\n");
return false;
}
return true;
}
bool FlashErase(void)
{
// Log("FlashErase: Erasing Flash\n");
Send_CMD(CMD_FLASHERASE);
UpdateFIFO(); // Trigger the CoProcessor to start processing commands out of the FIFO
Wait4CoProFIFOEmpty(); // Wait here until the coprocessor has read and executed every pending command.
// Log("FlashErase: Finished Erase\n");
}
// Load the output.bin file into flash if it exists
// Return indicates whether it was done or not
bool FlashLoad(void)
{
// Check for the existence of the packed flash file (output.bin)
if(!FileExists("output.bin"))
return false; // File does not exist, so we do not need to load it into flash
// Check for the existence of the completion flag file (transfer.fin)
if(FileExists("transfer.fin"))
return false; // File exists indicating that the transfer has already occurred in the past
// upload file to flash
if( !FileTransfer2Flash("output.bin", RAM_FLASH) )
{
// Log("FlashLoad: File Operation Failed\n");
return false;
}
// Rename the file to "output.fin" <-- This is what you want, but Arduino has no
// rename function. The rename was essentially a "flag" to tell this system
// whether the file transfer had already taken place or not. I am going to
// make a file with a specific name ("transfer.fin") to indicate that it's done.
FileOpen("transfer.fin", FILEWRITE);
if(!myFileIsOpen())
{
// Log("FlashLoad: No create file\n");
FileClose();
return false;
}
FileClose();
// Log("output.bin automatically transferred to flash\n");
return true;
}
// FileTransfer2Flash
// Transfer a file from SD card to Eve attached flash
// FlashAddress should be on a 4K boundary (multiple of 0x1000) - this is really important
bool FileTransfer2Flash(char *filename, uint32_t FlashAddress)
{
uint8_t FlashStatus;
uint32_t FlashSize;
// check for file open - we can only have one file open - fail if already open
if (myFileIsOpen())
{
// Log("FT2F: File already open\n");
return false;
}
// Open file
FileOpen(filename, FILEREAD);
if(!myFileIsOpen())
{
// Log("FT2F: Open File Failed\n");
FileClose();
return false;
}
FlashAttach();
FlashFast();
// Read file size
uint32_t Remaining = FileSize();
uint32_t FileSectors = Remaining / 0x1000; // Number of 4K sectors required to store file
if(Remaining % 0x1000) // If the file is not on 4K boundary (and when is it?)
FileSectors++; // Add a 4K sector for the partial
// Calculate file fitting and number of 4K blocks
FlashSize = rd32(REG_FLASH_SIZE + RAM_REG) * 0x100000; // A flash of 8M bytes which will report size = 8
uint32_t SectorsAvailable = (FlashSize - (FlashAddress - RAM_FLASH)) / 0x1000; // Number of 4K sectors available in the flash chip from the requested base address
if ( FileSectors > SectorsAvailable )
{
// Log("FT2F: File does not fit\n");
return false; // We can not continue without flash space to store file
}
uint32_t BufPerSector = 0x1000 / COPYBUFSIZE;
// Write file in sectors to RAM_G at the working RAM space (RAM_G_WORKING)
for (uint16_t h = 0; h < FileSectors; h++ ) // Loop through file data in 4K chunks until all 4K chunks have been processed
{
// Read file data COPYBUFSIZE at a time and write to RAM_G_WORKING space until 4K is reached
// Each execution of this loop will stuff a 4K block into RAM_G
for (uint16_t i = 0; i < BufPerSector; i++)
{
// Check each buffer load to see whether there is still more file than buffer
// If there is enough data, then get the data into the buffer and subtract that amount from Remaining
if(Remaining > COPYBUFSIZE)
{
FileReadBuf(LogBuf, COPYBUFSIZE);
Remaining -= COPYBUFSIZE;
}
else
{
// There is not enough file data to fill buffer. Get what there is (if any) and fill the rest with ones
// this should result in some number of manually padded buffer-loads being placed into RAM_G
for ( uint8_t j = 0; j < COPYBUFSIZE; j++ )
{
if(Remaining)
{
LogBuf[j] = FileReadByte();
Remaining--;
}
else
LogBuf[j] = 0xFF;
}
}
// Write the buffer to RAM_G
WriteBlockRAM(RAM_G_WORKING + (i * COPYBUFSIZE), LogBuf, COPYBUFSIZE);
}
// Send the 4K buffer of data to flash via FIFO command
Send_CMD(CMD_FLASHUPDATE); // Transfer data from RAM_G into flash automatically erasing 4K sectors as required
Send_CMD(FlashAddress + ((uint32_t)h * 0x1000)); // Destination address in Flash
Send_CMD(RAM_G_WORKING); // Source address in RAM_G
Send_CMD(0x1000); // Number of bytes to transfer (4096)
UpdateFIFO(); // Trigger the CoProcessor to start processing commands out of the FIFO
Wait4CoProFIFOEmpty(); // wait here until the coprocessor has read and executed every pending command.
}
FileClose(); // We are done with that file so close it
return true;
}