Kiibohd Controller
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

main.c 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /* Copyright (c) 2011,2012 Simon Schubert <[email protected]>.
  2. * Modifications by Jacob Alexander 2014-2015 <[email protected]>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. // ----- Includes -----
  18. // Local Includes
  19. #include "mchck.h"
  20. #include "dfu.desc.h"
  21. #include "debug.h"
  22. // ----- Variables -----
  23. /**
  24. * Unfortunately we can't DMA directly to FlexRAM, so we'll have to stage here.
  25. */
  26. static char staging[ USB_DFU_TRANSFER_SIZE ];
  27. // ----- Functions -----
  28. void sector_print( void* buf, size_t sector, size_t chunks )
  29. {
  30. uint8_t* start = (uint8_t*)buf + sector * USB_DFU_TRANSFER_SIZE;
  31. uint8_t* end = (uint8_t*)buf + (sector + 1) * USB_DFU_TRANSFER_SIZE;
  32. uint8_t* pos = start;
  33. // Verify if sector erased
  34. FTFL.fccob.read_1s_section.fcmd = FTFL_FCMD_READ_1s_SECTION;
  35. FTFL.fccob.read_1s_section.addr = (uintptr_t)start;
  36. FTFL.fccob.read_1s_section.margin = FTFL_MARGIN_NORMAL;
  37. FTFL.fccob.read_1s_section.num_words = 250; // 2000 kB / 64 bits
  38. int retval = ftfl_submit_cmd();
  39. print( NL );
  40. print("Block ");
  41. printHex( sector );
  42. print(" ");
  43. printHex( (size_t)start );
  44. print(" -> ");
  45. printHex( (size_t)end );
  46. print(" Erased: ");
  47. printHex( retval );
  48. print( NL );
  49. // Display sector
  50. for ( size_t line = 0; pos < end - 24; line++ )
  51. {
  52. // Each Line
  53. printHex_op( (size_t)pos, 4 );
  54. print(": ");
  55. // Each 2 byte chunk
  56. for ( size_t chunk = 0; chunk < chunks; chunk++ )
  57. {
  58. // Print out the two bytes (second one first)
  59. printHex_op( *(pos + 1), 2 );
  60. printHex_op( *pos, 2 );
  61. print(" ");
  62. pos += 2;
  63. }
  64. print( NL );
  65. }
  66. }
  67. static enum dfu_status setup_read( size_t off, size_t *len, void **buf )
  68. {
  69. // Calculate starting address from offset
  70. *buf = (void*)&_app_rom + (USB_DFU_TRANSFER_SIZE / 4) * off;
  71. // Calculate length of transfer
  72. /*
  73. *len = *buf > (void*)(&_app_rom_end) - USB_DFU_TRANSFER_SIZE
  74. ? 0 : USB_DFU_TRANSFER_SIZE;
  75. */
  76. // Check for error
  77. /*
  78. if ( *buf > (void*)&_app_rom_end )
  79. return (DFU_STATUS_errADDRESS);
  80. */
  81. return (DFU_STATUS_OK);
  82. }
  83. static enum dfu_status setup_write( size_t off, size_t len, void **buf )
  84. {
  85. static int last = 0;
  86. if ( len > sizeof(staging) )
  87. return (DFU_STATUS_errADDRESS);
  88. // We only allow the last write to be less than one sector size.
  89. if ( off == 0 )
  90. last = 0;
  91. if ( last && len != 0 )
  92. return (DFU_STATUS_errADDRESS);
  93. if ( len != FLASH_SECTOR_SIZE )
  94. {
  95. last = 1;
  96. memset( staging, 0xff, sizeof(staging) );
  97. }
  98. *buf = staging;
  99. return (DFU_STATUS_OK);
  100. }
  101. static enum dfu_status finish_write( void *buf, size_t off, size_t len )
  102. {
  103. void *target;
  104. if ( len == 0 )
  105. return (DFU_STATUS_OK);
  106. target = flash_get_staging_area(off + (uintptr_t)&_app_rom, FLASH_SECTOR_SIZE);
  107. if ( !target )
  108. return (DFU_STATUS_errADDRESS);
  109. memcpy( target, buf, len );
  110. print("BUF: ");
  111. printHex( off );
  112. sector_print( target, 0, 16 );
  113. // Depending on the error return a different status
  114. switch ( flash_program_sector(off + (uintptr_t)&_app_rom, FLASH_SECTOR_SIZE) )
  115. {
  116. /*
  117. case FTFL_FSTAT_RDCOLERR: // Flash Read Collision Error
  118. case FTFL_FSTAT_ACCERR: // Flash Access Error
  119. case FTFL_FSTAT_FPVIOL: // Flash Protection Violation Error
  120. return (DFU_STATUS_errADDRESS);
  121. case FTFL_FSTAT_MGSTAT0: // Memory Controller Command Completion Error
  122. return (DFU_STATUS_errADDRESS);
  123. */
  124. case 0:
  125. default: // No error
  126. return (DFU_STATUS_OK);
  127. }
  128. }
  129. static struct dfu_ctx dfu_ctx;
  130. void init_usb_bootloader( int config )
  131. {
  132. dfu_init( setup_read, setup_write, finish_write, &dfu_ctx );
  133. }
  134. void main()
  135. {
  136. #if defined(_mk20dx128vlf5_) // Kiibohd-dfu / Infinity
  137. // XXX McHCK uses B16 instead of A19
  138. // Enabling LED to indicate we are in the bootloader
  139. GPIOA_PDDR |= (1<<19);
  140. // Setup pin - A19 - See Lib/pin_map.mchck for more details on pins
  141. PORTA_PCR19 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  142. GPIOA_PSOR |= (1<<19);
  143. #elif defined(_mk20dx256vlh7_) // Kiibohd-dfu
  144. // Enabling LED to indicate we are in the bootloader
  145. GPIOA_PDDR |= (1<<5);
  146. // Setup pin - A5 - See Lib/pin_map.mchck for more details on pins
  147. PORTA_PCR5 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  148. GPIOA_PSOR |= (1<<5);
  149. #else
  150. #error "Incompatible chip for bootloader"
  151. #endif
  152. uart_serial_setup();
  153. printNL( NL "Bootloader DFU-Mode" );
  154. // XXX REMOVEME
  155. /*
  156. GPIOB_PDDR |= (1<<16);
  157. PORTB_PCR16 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  158. GPIOB_PSOR |= (1<<16);
  159. // RST
  160. GPIOC_PDDR |= (1<<8);
  161. PORTC_PCR8 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  162. GPIOC_PSOR |= (1<<8);
  163. // CS1B
  164. GPIOC_PDDR |= (1<<4);
  165. PORTC_PCR4 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  166. GPIOC_PCOR |= (1<<4);
  167. */
  168. // Backlight
  169. /*
  170. GPIOC_PDDR |= (1<<1);
  171. PORTC_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  172. GPIOC_PCOR |= (1<<1);
  173. GPIOC_PDDR |= (1<<2);
  174. PORTC_PCR2 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  175. GPIOC_PCOR |= (1<<2);
  176. GPIOC_PDDR |= (1<<3);
  177. PORTC_PCR3 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  178. GPIOC_PCOR |= (1<<3);
  179. */
  180. /*
  181. // Read Firmware 1 Status
  182. FTFL.fccob.read_1s_block.fcmd = FTFL_FCMD_READ_1s_BLOCK;
  183. FTFL.fccob.read_1s_block.addr = (uintptr_t)&_app_rom;
  184. FTFL.fccob.read_1s_block.margin = FTFL_MARGIN_NORMAL;
  185. int retval = ftfl_submit_cmd();
  186. print("Firmware Erase Status: ");
  187. printHex( retval );
  188. print( NL );
  189. // Read Bootloader 1 Status
  190. FTFL.fccob.read_1s_block.fcmd = FTFL_FCMD_READ_1s_BLOCK;
  191. FTFL.fccob.read_1s_block.addr = (uintptr_t)&_bootloader;
  192. FTFL.fccob.read_1s_block.margin = FTFL_MARGIN_NORMAL;
  193. retval = ftfl_submit_cmd();
  194. print("Bootloader Erase Status: ");
  195. printHex( retval );
  196. print( NL );
  197. */
  198. /*
  199. // Program First Longword of firmware
  200. FTFL.fccob.program_longword.fcmd = FTFL_FCMD_PROGRAM_LONGWORD;
  201. FTFL.fccob.program_longword.addr = (uintptr_t)&_app_rom;
  202. FTFL.fccob.program_longword.data_be[0] = 0x1;
  203. FTFL.fccob.program_longword.data_be[1] = 0x2;
  204. FTFL.fccob.program_longword.data_be[2] = 0x4;
  205. FTFL.fccob.program_longword.data_be[3] = 0x8;
  206. int retval = ftfl_submit_cmd();
  207. print("Write Longword Status: ");
  208. printHex( retval );
  209. print( NL );
  210. */
  211. /*
  212. // Erase Sector
  213. FTFL.fccob.erase.fcmd = FTFL_FCMD_ERASE_SECTOR;
  214. FTFL.fccob.erase.addr = (uintptr_t)&_app_rom;
  215. int retval = ftfl_submit_cmd();
  216. print("Erase Status: ");
  217. printHex( retval );
  218. print( NL );
  219. // Prepare FlexRAM
  220. FTFL.fccob.set_flexram.fcmd = FTFL_FCMD_SET_FLEXRAM;
  221. FTFL.fccob.set_flexram.flexram_function = FTFL_FLEXRAM_RAM;
  222. retval = ftfl_submit_cmd();
  223. print("Set FlexRAM Status: ");
  224. printHex( retval );
  225. print( NL );
  226. // Write to FlexRAM
  227. memset( FlexRAM, 0xB4, 1000 );
  228. memset( &FlexRAM[1000], 0xE3, 1000 );
  229. // Program Sector
  230. FTFL.fccob.program_section.fcmd = FTFL_FCMD_PROGRAM_SECTION;
  231. FTFL.fccob.program_section.addr = (uintptr_t)&_app_rom;
  232. FTFL.fccob.program_section.num_words = 128;
  233. //FTFL.fccob.program_section.num_words = 250; // 2000 kb / 64 bits
  234. retval = ftfl_submit_cmd();
  235. print("Program Sector1 Status: ");
  236. printHex( retval );
  237. print( NL );
  238. FTFL.fccob.program_section.fcmd = FTFL_FCMD_PROGRAM_SECTION;
  239. FTFL.fccob.program_section.addr = (uintptr_t)&_app_rom + 0x400;
  240. FTFL.fccob.program_section.num_words = 128;
  241. //FTFL.fccob.program_section.num_words = 250; // 2000 kb / 64 bits
  242. retval = ftfl_submit_cmd();
  243. print("Program Sector2 Status: ");
  244. printHex( retval );
  245. print( NL );
  246. for ( uint8_t sector = 0; sector < 1; sector++ )
  247. //sector_print( &_bootloader, sector, 16 );
  248. sector_print( &_app_rom, sector, 16 );
  249. print( NL );
  250. */
  251. flash_prepare_flashing();
  252. //uint32_t *position = &_app_rom;
  253. usb_init( &dfu_device );
  254. for (;;)
  255. {
  256. usb_poll();
  257. }
  258. }