-
Notifications
You must be signed in to change notification settings - Fork 3
/
xbox-teensy-flasher.ino
156 lines (127 loc) · 3.68 KB
/
xbox-teensy-flasher.ino
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
#include "XSPI.h"
#include "XNAND.h"
#include "defs.h"
#define USBSERIAL Serial
#define DBGSERIAL Serial2
#define dbg(MSG) DBGSERIAL.print(F(MSG))
#define dbgf(MSG, ...) DBGSERIAL.printf(F(MSG), __VA_ARGS__)
uint32_t read_param_le(void);
void StartFlashRead(uint32_t, uint32_t);
void StartFlashWrite(uint32_t, uint32_t);
void FlashInit(void);
void FlashDeinit(void);
void FlashStatus(void);
uint16_t STATUS = 0;
uint8_t PAGE_BUFFER[0x210] = {};
void setup() {
// put your setup code here, to run once:
USBSERIAL.begin(115200);
DBGSERIAL.begin(9600);
dbg("Init SPI\n");
XSPI_Init();
}
void loop() {
if (USBSERIAL.available()) {
int16_t command = USBSERIAL.read(); // serial.read is 0-255 or -1 :(
if (command > 0) {
uint32_t paramA = read_param_le();
uint32_t paramB = read_param_le();
switch(command)
{
case REQ_DATAREAD: StartFlashRead(paramA << 5, paramB); break;
case REQ_DATAWRITE: StartFlashWrite(paramA << 5, paramB); break;
case REQ_DATAINIT: FlashInit(); break;
case REQ_DATADEINIT: FlashDeinit(); break;
case REQ_DATASTATUS: FlashStatus(); break;
// case REQ_DATAERASE: FlashErase(paramA << 5); break;
// case REQ_POWERUP: PowerUp(); break;
// case REQ_SHUTDOWN: Shutdown(); break;
// case REQ_UPDATE: Update(); break;
}
}
}
}
uint32_t read_param_le() {
uint32_t buffer = 0;
int16_t read = -1;
for(int i = 0; i < 4; ) {
if (USBSERIAL.available()) {
read = USBSERIAL.read();
buffer = (buffer >> 8) | (read << 24);
i++;
}
}
return buffer;
}
void StartFlashRead(uint32_t startPage, uint32_t len) {
uint8_t* buff_ptr = PAGE_BUFFER;
STATUS = 0;
uint32_t wordsLeft = 0;
uint32_t nextPage = startPage;
len /= 4;
while(len) {
uint8_t readNow;
if(!wordsLeft)
{
STATUS = XNAND_StartRead(nextPage);
nextPage++;
wordsLeft = 0x210 / 4;
buff_ptr = PAGE_BUFFER;
}
readNow = (len < wordsLeft) ? len : wordsLeft;
XNAND_ReadFillBuffer(buff_ptr, readNow);
buff_ptr += (readNow*4);
wordsLeft -= readNow;
len -= readNow;
if(!wordsLeft) {
USBSERIAL.write(PAGE_BUFFER, 0x210);
}
}
}
void StartFlashWrite(uint32_t startPage, uint32_t len) {
STATUS = XNAND_Erase(startPage);
XNAND_StartWrite();
uint8_t* buff_ptr = PAGE_BUFFER;
uint32_t wordsLeft = 0;
uint32_t nextPage = startPage;
len /= 4;
while(len)
{
uint8_t writeNow;
if(!wordsLeft)
{
while (USBSERIAL.available() < 0x210) {}
USBSERIAL.readBytes((char*)PAGE_BUFFER, 0x210);
buff_ptr = PAGE_BUFFER;
wordsLeft = 0x210 / 4;
}
writeNow = (len < wordsLeft) ? len : wordsLeft;
XNAND_WriteProcess(buff_ptr, writeNow);
buff_ptr += (writeNow*4);
wordsLeft -= writeNow;
len -= writeNow;
//execute write if buffer in NAND controller is filled
if(!wordsLeft)
{
STATUS = XNAND_WriteExecute(nextPage++);
XNAND_StartWrite();
}
}
}
void FlashInit(void) {
dbg("Entering flashmode\n");
XSPI_EnterFlashmode();
dbg("Reading flashconfig\n");
uint8_t FlashConfig[4];
XSPI_Read(0, FlashConfig); //2 times?
XSPI_Read(0, FlashConfig);
USBSERIAL.write(FlashConfig, 4);
}
void FlashDeinit() {
dbg("Leaving flashmode\n");
XSPI_LeaveFlashmode();
}
void FlashStatus() {
uint8_t FlashStatus[2] = {(uint8_t)(STATUS & 0xFF), (uint8_t)(STATUS >> 8)};
USBSERIAL.write(FlashStatus, 2);
}