1- #include < SPI.h>
2- #include " RC522.h"
3- #include < Arduino.h>
1+ #include < avr/io.h>
42#include < avr/boot.h>
3+ #include " RC522.h"
4+
5+ /* Moving to Atmel Studio? */
56
6- void __attribute__ ((noinline)) watchdogConfig(uint8_t x);
7+ void boot_program_page (uint32_t , uint8_t *);
8+ void __attribute__ ((noinline)) watchdogConfig(uint8_t );
9+ void initSPI ();
710
8- /* 3760 bytes free after removing serial */
9- /* Compared with 5624 bytes it's a huge difference */
11+ /* 3820 bytes free after removing serial */
12+ /* Compared with 5714 bytes it's a huge difference */
1013// #define S_DEBUG
1114
1215void setup () {
1316 cli ();
14- pinMode (A1, OUTPUT) ;
15- digitalWrite (A1, HIGH) ;
17+ DDRC |= 0b00000010 ;
18+ PORTC |= 0b00000010 ;
1619#ifdef S_DEBUG
1720 Serial.begin (115200 );
1821 Serial.println (F (" MostUseless Bootloader Reader" ));
@@ -31,7 +34,7 @@ void setup() {
3134#endif
3235
3336 watchdogConfig (0 );
34- digitalWrite (A1, LOW) ;
37+ PORTC &= ! 0b00000010 ;
3538 asm (" jmp 0" );
3639 }
3740 }
@@ -40,150 +43,184 @@ void setup() {
4043 Serial.flush ();
4144#endif
4245
43- SPI. begin ();
44- RC522 rfid ( 10 ) ;
46+ initSPI ();
47+ RC522 rfid;
4548 rfid.PCD_Init ();
4649
50+ /* Generic key */
51+ RC522::MIFARE_Key key;
52+ memset (key.keyuint8_t , 0xFF , 6 );
53+
4754 /* You have 2 seconds to scan first tag */
48- watchdogConfig (( _BV (WDP2) | _BV (WDP1) | _BV (WDP0) | _BV (WDE) ));
55+ watchdogConfig (_BV (WDP2) | _BV (WDP1) | _BV (WDP0) | _BV (WDE));
4956
50- /* Jump to code after timeout */
51- /* Timeout doesn't work but lol, the rest of stuff works */
57+ /* If the tag is not scanned, it will triger watchdog */
5258 while (!rfid.PICC_IsNewCardPresent ());
5359 while (!rfid.PICC_ReadCardSerial ());
5460
55- digitalWrite (A1, LOW);
61+ /* Now you have 8 seconds between tags */
62+ watchdogConfig (_BV (WDP3) | _BV (WDP0) | _BV (WDE));
63+
64+ PORTC &= !0b00000010 ;
5665
5766 /* Sketch metadata */
5867 uint16_t siz = 0 ;
68+ uint16_t blocks = 0 ;
5969 uint8_t parts = 0 ;
60- uint8_t pages = 0 ;
61- uint8_t blocks = 2 ;
6270
63- /* Buffer and SPM stuff */
64- uint8_t pageoffset = 0 ;
65- uint8_t memptr = 0 ;
71+ /* Programming */
72+ bool metaRead = false ;
73+ uint8_t currentPart = 0 ;
74+ uint16_t blocksWritten = 0 ;
75+ volatile static uint8_t buffer[18 ];
76+ uint8_t len = 18 ;
6677
67- /*
68- We don't need to worry about extra data in last
69- page if we already set buffer as empty :)
70- */
71- volatile static uint8_t pageBuffer[256 ];
72- memset (pageBuffer, 0xFF , 256 );
78+ /* Buffer and SPM stuff */
79+ volatile static uint8_t writeBuffer[16 ];
80+ uint16_t memptr = 0 ;
81+
82+ /* Token capacity (blocks) may vary */
83+ uint16_t tokencap = 0 ;
84+ do {
85+ PORTC |= 0b00000010 ;
86+ asm (" wdr" );
87+ #ifdef S_DEBUG
88+ Serial.println (" Scan tag" );
89+ Serial.flush ();
90+ #endif
91+ /* Check new card */
92+ while (!rfid.PICC_IsNewCardPresent ());
93+ while (!rfid.PICC_ReadCardSerial ());
94+ RC522::PICC_Type piccType = rfid.PICC_GetType (rfid.uid .sak );
95+ PORTC &= !0b00000010 ;
96+
97+ switch (piccType) {
98+ case RC522::PICC_TYPE_MIFARE_UL:
99+ case RC522::PICC_TYPE_MIFARE_PLUS:
100+ case RC522::PICC_TYPE_MIFARE_DESFIRE:
101+ case RC522::PICC_TYPE_MIFARE_4K:
102+ case RC522::PICC_TYPE_MIFARE_MINI: // I dare you to use this one
103+ tokencap = 0 ;
104+ default : continue ;
105+ case RC522::PICC_TYPE_MIFARE_1K:
106+ tokencap = 64 ; break ;
107+ }
73108
74- /* Generic key */
75- RC522::MIFARE_Key key;
76- memset (key.keyByte , 0xFF , 6 );
109+ if (tokencap == 0 ) {
110+ #ifdef S_DEBUG
111+ Serial.println (" Not supported" );
112+ #endif
113+ return ;
114+ }
77115
78- /*
79- Reading every block and using page offset
80- to save progress if more parts are needed
81- */
116+ rfid.PCD_Authenticate (RC522::PICC_CMD_MF_AUTH_KEY_A, 1 , &key, &(rfid.uid ));
117+ rfid.MIFARE_Read (1 , buffer, &len);
82118
83- for (uint8_t block = 1 ; block < blocks; block++) {
84- if ((block + 1 ) % 4 == 0 ) {
85- blocks++;
119+ if (buffer[0 ] - 1 != currentPart) {
120+ #ifdef S_DEBUG
121+ Serial.print (" Wrong part: " );
122+ Serial.print (buffer[0 ]);
123+ Serial.print (" != " );
124+ Serial.println (currentPart + 1 );
125+ #endif
126+ rfid.PICC_HaltA ();
127+ rfid.PCD_StopCrypto1 ();
86128 continue ;
87129 }
88130
89- uint8_t buffer[18 ];
90- byte len = 18 ;
91-
92- rfid.PCD_Authenticate (RC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(rfid.uid ));
93- rfid.MIFARE_Read (block, buffer, &len);
94-
95- /*
96- 2 bytes - code size
97- 1 byte - parts [token]
98- 1 byte - full pages (including not full)
99- 1 byte - amount of data in last page
100- 1 byte - full blocks
101- 1 byte - amount of data in last block
102- */
103- if (block == 1 ) {
131+ if (!metaRead && currentPart == 0 ) {
132+ /*
133+ 2 bytes - code size
134+ 2 bytes - full blocks
135+ 1 byte - pages (unused)
136+ 1 byte - parts [tokens]
137+ */
104138 siz = word (buffer[1 ], buffer[2 ]);
105- blocks = word (buffer[3 ], buffer[4 ]) + 2 ;
106- pages = buffer[5 ];
139+ blocks = word (buffer[3 ], buffer[4 ]);
107140 parts = buffer[6 ];
108141#ifdef S_DEBUG
109142 Serial.print (F (" Sketch size:\t " ));
110143 Serial.print (siz);
111144 Serial.print (F (" bytes\r\n Parts [tokens]:\t " ));
112145 Serial.println (parts);
113- Serial.print (F (" Pages total:\t " ));
114- Serial.println (pages);
115146 Serial.print (F (" Blocks total:\t " ));
116- Serial.println (blocks - 2 );
147+ Serial.println (blocks);
117148 Serial.flush ();
118149#endif
119- continue ;
150+ metaRead = true ;
120151 }
121152
122- for (uint8_t a = 0 ; a < 16 ; a++) {
123- pageBuffer[(pageoffset * 16 ) + a] = buffer[a];
153+ for (uint8_t a = 2 ;
154+ a < tokencap && blocksWritten != blocks;
155+ a++) {
156+ asm (" wdr" );
157+ if ((a + 1 ) % 4 == 0 ) continue ;
158+ #ifdef S_DEBUG
159+ Serial.print (a);
160+ Serial.print (' \t ' );
161+ #endif
162+ rfid.PCD_Authenticate (RC522::PICC_CMD_MF_AUTH_KEY_A, a, &key, &(rfid.uid ));
163+ rfid.MIFARE_Read (a, buffer, &len);
164+ for (uint16_t x = 0 ; x < 16 ; x++)
165+ writeBuffer[x] = buffer[x];
166+
167+ PORTC |= 0b00000010 ;
168+ boot_program_page (memptr, writeBuffer);
169+ blocksWritten += 1 ;
170+ memptr += 16 ;
124171 }
125- pageoffset++;
126172
127- /* Check if page is full */
128- if (pageoffset < 16 && block != blocks - 1 ) continue ;
129- pageoffset = 0 ;
173+ rfid.PICC_HaltA ();
174+ rfid.PCD_StopCrypto1 ();
130175
176+ currentPart += 1 ;
177+ } while (currentPart <= parts && blocksWritten != blocks);
178+ PORTC |= 0b00000010 ;
131179#ifdef S_DEBUG
132- Serial.print (F (" \r\n ---- Page " ));
133- Serial.print (memptr + 1 );
134- Serial.println (F (" ----" ));
135- for (uint16_t x = 1 ; x <= 256 ; x++) {
136- Serial.print (pageBuffer[x - 1 ] < 0x10 ? " 0" : " " );
137- Serial.print (pageBuffer[x - 1 ], HEX);
138- if (x % 16 == 0 )
139- Serial.println ();
140- }
141- Serial.flush ();
180+ Serial.println (" Done!" );
181+ Serial.flush ();
142182#endif
143183
144- /* Write each page to flash */
145- digitalWrite (A1, HIGH);
146- boot_program_page (memptr, pageBuffer);
147-
148- /* Finished writing to flash */
149- memptr += 256 ;
150- memset (pageBuffer, 0xFF , 256 );
151- }
152- rfid.PICC_HaltA ();
153- rfid.PCD_StopCrypto1 (); // Stop encryption on PCD
184+ /* We're done here */
154185 rfid.PCD_AntennaOff ();
155-
156- digitalWrite (A1, LOW);
157186 watchdogConfig (_BV (WDE)); // 16ms
187+ PORTC &= !0b00000010 ;
158188 while (1 ); // Trigger watchdog to jump to code
159189}
160190
161- void boot_program_page (uint32_t page, uint8_t *buf) {
162- uint16_t i;
191+ void boot_program_page (uint16_t addr, uint8_t *buf) {
192+ #ifdef S_DEBUG
193+ Serial.print (" Writing at: " );
194+ Serial.println (addr);
195+ Serial.print (' \t ' );
196+ for (uint16_t x = 0 ; x < 16 ; x++) {
197+ Serial.print (buf[x] < 0x10 ? " 0" : " " );
198+ Serial.print (buf[x], HEX);
199+ }
200+ Serial.println ();
201+ Serial.flush ();
202+ #endif
163203 uint8_t sreg;
164204
165205 sreg = SREG;
166206 cli ();
167207
168208 eeprom_busy_wait ();
169209
170- boot_page_erase (page);
210+ if (addr == 0 || addr % SPM_PAGESIZE == 0 )
211+ boot_page_erase (addr);
171212 boot_spm_busy_wait ();
172- for (i = 0 ; i < SPM_PAGESIZE ; i += 2 )
213+ for (uint8_t i = 0 ; i < 16 ; i += 2 )
173214 {
174215 uint16_t w = *buf++;
175216 w += (*buf++) << 8 ;
176- boot_page_fill (page + i, w);
217+ boot_page_fill (addr + i, w);
177218 }
178219
179- boot_page_write (page); // Store buffer in flash page.
180- boot_spm_busy_wait (); // Wait until the memory is written.
181-
182- // Reenable RWW-section again. We need this if we want to jump back
183- // to the application after bootloading.
220+ boot_page_write (addr);
221+ boot_spm_busy_wait ();
184222 boot_rww_enable ();
185223
186- // Re-enable interrupts (if they were ever enabled).
187224 SREG = sreg;
188225}
189226
@@ -192,5 +229,18 @@ void watchdogConfig(uint8_t x) {
192229 WDTCSR = x;
193230}
194231
232+ void initSPI () {
233+ uint8_t sreg = SREG;
234+ cli ();
235+
236+ /* Set up SPI outs */
237+ DDRB |= 0b101100 ;
238+ /* SPI in */
239+ DDRB &= 0b101111 ;
240+
241+ SPCR |= _BV (MSTR) | _BV (SPE);
242+ SREG = sreg;
243+ }
244+
195245void loop () {
196246}
0 commit comments