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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  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. int 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. return retval;
  67. }
  68. static enum dfu_status setup_read( size_t off, size_t *len, void **buf )
  69. {
  70. // Calculate starting address from offset
  71. *buf = (void*)&_app_rom + (USB_DFU_TRANSFER_SIZE / 4) * off;
  72. // Calculate length of transfer
  73. /*
  74. *len = *buf > (void*)(&_app_rom_end) - USB_DFU_TRANSFER_SIZE
  75. ? 0 : USB_DFU_TRANSFER_SIZE;
  76. */
  77. // Check for error
  78. /*
  79. if ( *buf > (void*)&_app_rom_end )
  80. return (DFU_STATUS_errADDRESS);
  81. */
  82. return (DFU_STATUS_OK);
  83. }
  84. static enum dfu_status setup_write( size_t off, size_t len, void **buf )
  85. {
  86. static int last = 0;
  87. if ( len > sizeof(staging) )
  88. return (DFU_STATUS_errADDRESS);
  89. // We only allow the last write to be less than one sector size.
  90. if ( off == 0 )
  91. last = 0;
  92. if ( last && len != 0 )
  93. return (DFU_STATUS_errADDRESS);
  94. if ( len != FLASH_SECTOR_SIZE )
  95. {
  96. last = 1;
  97. memset( staging, 0xff, sizeof(staging) );
  98. }
  99. *buf = staging;
  100. return (DFU_STATUS_OK);
  101. }
  102. static enum dfu_status finish_write( void *buf, size_t off, size_t len )
  103. {
  104. void *target;
  105. if ( len == 0 )
  106. return (DFU_STATUS_OK);
  107. target = flash_get_staging_area(off + (uintptr_t)&_app_rom, FLASH_SECTOR_SIZE);
  108. if ( !target )
  109. return (DFU_STATUS_errADDRESS);
  110. memcpy( target, buf, len );
  111. // Depending on the error return a different status
  112. switch ( flash_program_sector(off + (uintptr_t)&_app_rom, FLASH_SECTOR_SIZE) )
  113. {
  114. /*
  115. case FTFL_FSTAT_RDCOLERR: // Flash Read Collision Error
  116. case FTFL_FSTAT_ACCERR: // Flash Access Error
  117. case FTFL_FSTAT_FPVIOL: // Flash Protection Violation Error
  118. return (DFU_STATUS_errADDRESS);
  119. case FTFL_FSTAT_MGSTAT0: // Memory Controller Command Completion Error
  120. return (DFU_STATUS_errADDRESS);
  121. */
  122. case 0:
  123. default: // No error
  124. return (DFU_STATUS_OK);
  125. }
  126. }
  127. static struct dfu_ctx dfu_ctx;
  128. void init_usb_bootloader( int config )
  129. {
  130. dfu_init( setup_read, setup_write, finish_write, &dfu_ctx );
  131. }
  132. void main()
  133. {
  134. #if defined(_mk20dx128vlf5_) // Kiibohd-dfu / Infinity
  135. // XXX McHCK uses B16 instead of A19
  136. // Enabling LED to indicate we are in the bootloader
  137. GPIOA_PDDR |= (1<<19);
  138. // Setup pin - A19 - See Lib/pin_map.mchck for more details on pins
  139. PORTA_PCR19 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  140. GPIOA_PSOR |= (1<<19);
  141. #elif defined(_mk20dx256vlh7_) // Kiibohd-dfu
  142. // Enabling LED to indicate we are in the bootloader
  143. GPIOA_PDDR |= (1<<5);
  144. // Setup pin - A5 - See Lib/pin_map.mchck for more details on pins
  145. PORTA_PCR5 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  146. GPIOA_PSOR |= (1<<5);
  147. #else
  148. #error "Incompatible chip for bootloader"
  149. #endif
  150. uart_serial_setup();
  151. printNL( NL "Bootloader DFU-Mode" );
  152. // XXX REMOVEME
  153. /*
  154. GPIOB_PDDR |= (1<<16);
  155. PORTB_PCR16 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  156. GPIOB_PSOR |= (1<<16);
  157. // RST
  158. GPIOC_PDDR |= (1<<8);
  159. PORTC_PCR8 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  160. GPIOC_PSOR |= (1<<8);
  161. // CS1B
  162. GPIOC_PDDR |= (1<<4);
  163. PORTC_PCR4 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  164. GPIOC_PCOR |= (1<<4);
  165. */
  166. // Backlight
  167. /*
  168. GPIOC_PDDR |= (1<<1);
  169. PORTC_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  170. GPIOC_PCOR |= (1<<1);
  171. GPIOC_PDDR |= (1<<2);
  172. PORTC_PCR2 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  173. GPIOC_PCOR |= (1<<2);
  174. GPIOC_PDDR |= (1<<3);
  175. PORTC_PCR3 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  176. GPIOC_PCOR |= (1<<3);
  177. */
  178. /*
  179. // Read Firmware 1 Status
  180. FTFL.fccob.read_1s_block.fcmd = FTFL_FCMD_READ_1s_BLOCK;
  181. FTFL.fccob.read_1s_block.addr = (uintptr_t)&_app_rom;
  182. FTFL.fccob.read_1s_block.margin = FTFL_MARGIN_NORMAL;
  183. int retval = ftfl_submit_cmd();
  184. print("Firmware Erase Status: ");
  185. printHex( retval );
  186. print( NL );
  187. // Read Bootloader 1 Status
  188. FTFL.fccob.read_1s_block.fcmd = FTFL_FCMD_READ_1s_BLOCK;
  189. FTFL.fccob.read_1s_block.addr = (uintptr_t)&_bootloader;
  190. FTFL.fccob.read_1s_block.margin = FTFL_MARGIN_NORMAL;
  191. retval = ftfl_submit_cmd();
  192. print("Bootloader Erase Status: ");
  193. printHex( retval );
  194. print( NL );
  195. */
  196. /*
  197. // Program First Longword of firmware
  198. FTFL.fccob.program_longword.fcmd = FTFL_FCMD_PROGRAM_LONGWORD;
  199. FTFL.fccob.program_longword.addr = (uintptr_t)&_app_rom;
  200. FTFL.fccob.program_longword.data_be[0] = 0x1;
  201. FTFL.fccob.program_longword.data_be[1] = 0x2;
  202. FTFL.fccob.program_longword.data_be[2] = 0x4;
  203. FTFL.fccob.program_longword.data_be[3] = 0x8;
  204. int retval = ftfl_submit_cmd();
  205. print("Write Longword Status: ");
  206. printHex( retval );
  207. print( NL );
  208. */
  209. /*
  210. // Erase Sector
  211. FTFL.fccob.erase.fcmd = FTFL_FCMD_ERASE_SECTOR;
  212. FTFL.fccob.erase.addr = (uintptr_t)&_app_rom;
  213. int retval = ftfl_submit_cmd();
  214. print("Erase Status: ");
  215. printHex( retval );
  216. print( NL );
  217. // Prepare FlexRAM
  218. FTFL.fccob.set_flexram.fcmd = FTFL_FCMD_SET_FLEXRAM;
  219. FTFL.fccob.set_flexram.flexram_function = FTFL_FLEXRAM_RAM;
  220. retval = ftfl_submit_cmd();
  221. print("Set FlexRAM Status: ");
  222. printHex( retval );
  223. print( NL );
  224. // Write to FlexRAM
  225. memset( FlexRAM, 0xB4, 1000 );
  226. memset( &FlexRAM[1000], 0xE3, 1000 );
  227. // Program Sector
  228. FTFL.fccob.program_section.fcmd = FTFL_FCMD_PROGRAM_SECTION;
  229. FTFL.fccob.program_section.addr = (uintptr_t)&_app_rom;
  230. FTFL.fccob.program_section.num_words = 128;
  231. //FTFL.fccob.program_section.num_words = 250; // 2000 kb / 64 bits
  232. retval = ftfl_submit_cmd();
  233. print("Program Sector1 Status: ");
  234. printHex( retval );
  235. print( NL );
  236. FTFL.fccob.program_section.fcmd = FTFL_FCMD_PROGRAM_SECTION;
  237. FTFL.fccob.program_section.addr = (uintptr_t)&_app_rom + 0x400;
  238. FTFL.fccob.program_section.num_words = 128;
  239. //FTFL.fccob.program_section.num_words = 250; // 2000 kb / 64 bits
  240. retval = ftfl_submit_cmd();
  241. print("Program Sector2 Status: ");
  242. printHex( retval );
  243. print( NL );
  244. for ( uint8_t sector = 0; sector < 1; sector++ )
  245. //sector_print( &_bootloader, sector, 16 );
  246. sector_print( &_app_rom, sector, 16 );
  247. print( NL );
  248. */
  249. flash_prepare_flashing();
  250. //uint32_t *position = &_app_rom;
  251. usb_init( &dfu_device );
  252. for (;;)
  253. {
  254. usb_poll();
  255. }
  256. }