shell.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /*
  2. * =====================================================================================
  3. *
  4. * ________ .__ __ ________ ____ ________
  5. * \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
  6. * / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
  7. * / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
  8. * \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
  9. * \__> \/ \/ \/ \/ \/
  10. *
  11. * www.optixx.org
  12. *
  13. *
  14. * Version: 1.0
  15. * Created: 07/21/2009 03:32:16 PM
  16. * Author: david@optixx.org
  17. *
  18. * =====================================================================================
  19. */
  20. #include <stdint.h>
  21. #include <string.h>
  22. #include <avr/io.h>
  23. #include <stdlib.h>
  24. #include <avr/interrupt.h>
  25. #include <util/delay.h>
  26. #include <avr/pgmspace.h>
  27. #include <avr/eeprom.h>
  28. #include "pwm.h"
  29. #include "debug.h"
  30. #include "info.h"
  31. #include "sram.h"
  32. #include "util.h"
  33. #include "uart.h"
  34. #include "dump.h"
  35. #include "irq.h"
  36. #include "config.h"
  37. #include "crc.h"
  38. #include "command.h"
  39. #include "shared_memory.h"
  40. uint8_t command_buf[RECEIVE_BUF_LEN];
  41. uint8_t recv_buf[RECEIVE_BUF_LEN];
  42. volatile uint8_t recv_counter = 0;
  43. volatile uint8_t cr = 0;
  44. uint8_t *token_ptr;
  45. uint8_t *get_token(void)
  46. {
  47. uint8_t *p = token_ptr;
  48. while (*p == ' ')
  49. p++;
  50. if (*p == '\0')
  51. return NULL;
  52. token_ptr = p;
  53. do {
  54. token_ptr++;
  55. if (*token_ptr == ' ' || *token_ptr == '\n' || *token_ptr == '\r') {
  56. *token_ptr++ = '\0';
  57. break;
  58. }
  59. } while (*token_ptr != ' ' && *token_ptr != '\n' && *token_ptr != '\r');
  60. return p;
  61. }
  62. uint8_t get_dec(uint32_t *decval)
  63. {
  64. const uint8_t *t;
  65. t = get_token();
  66. if (t != NULL) {
  67. int x = util_sscandec(t);
  68. if (x < 0)
  69. return 0;
  70. *decval = x;
  71. return 1;
  72. }
  73. return 0;
  74. }
  75. uint8_t parse_hex(const uint8_t *s, uint32_t *hexval)
  76. {
  77. uint32_t x = util_sscanhex(s);
  78. *hexval = (uint32_t) x;
  79. return 1;
  80. }
  81. uint8_t get_hex(uint32_t *hexval)
  82. {
  83. const uint8_t *t;
  84. t = get_token();
  85. if (t != NULL)
  86. return parse_hex(t, hexval);
  87. return 0;
  88. }
  89. uint8_t get_hex_arg2(uint32_t *hexval1, uint32_t *hexval2)
  90. {
  91. return get_hex(hexval1) && get_hex(hexval2);
  92. }
  93. uint8_t get_hex_arg3(uint32_t *hexval1, uint32_t *hexval2, uint32_t *hexval3)
  94. {
  95. return get_hex(hexval1) && get_hex(hexval2) && get_hex(hexval3);
  96. }
  97. static uint8_t get_int32(uint32_t *val)
  98. {
  99. if (!get_hex(val)){
  100. info_P(PSTR("Invalid argument!\n"));
  101. return 0;
  102. } else {
  103. return 1;
  104. }
  105. }
  106. static uint8_t get_int8(uint8_t *val)
  107. {
  108. uint32_t ret;
  109. if (!get_hex(&ret) ||ret > 0xff){
  110. info_P(PSTR("Invalid argument!\n"));
  111. return 0;
  112. }else{
  113. *val = (uint8_t)ret;
  114. return 1;
  115. }
  116. }
  117. static int get_bool(void)
  118. {
  119. const uint8_t *t;
  120. t = get_token();
  121. if (t != NULL) {
  122. int result = util_sscanbool(t);
  123. if (result >= 0)
  124. return result;
  125. }
  126. info_P(PSTR("Invalid argument (should be 0 or 1)!\n"));
  127. return -1;
  128. }
  129. void prompt(void){
  130. uart_putc('\r');
  131. uart_putc('\n');
  132. uart_putc('>');
  133. }
  134. ISR(USART0_RX_vect) // Interrupt for UART Byte received
  135. {
  136. UCSR0B &= (255 - (1<<RXCIE0));// Interrupts disable for RxD
  137. sei();
  138. if(recv_counter == (sizeof(recv_buf)-1)) {
  139. cr=1;
  140. recv_buf[recv_counter]='\0';
  141. recv_counter=0;
  142. prompt();
  143. }
  144. recv_buf[recv_counter] = UDR0;
  145. uart_putc(recv_buf[recv_counter]); /* do a echo, maybe should reside not in interrupt */
  146. if (recv_buf[recv_counter] == 0x0d) {
  147. /* recv_buf[recv_counter] = 0; */
  148. cr = 1; // found a CR, so the application should do something
  149. recv_buf[++recv_counter]='\0'; // terminate string
  150. recv_counter = 0;
  151. prompt();
  152. } else {
  153. // we accept backspace or delete
  154. if ((recv_buf[recv_counter] == 0x08 || recv_buf[recv_counter] == 0x7f) && recv_counter > 0) {
  155. recv_counter--;
  156. } else {
  157. recv_counter++;
  158. }
  159. }
  160. UCSR0B |= (1<<RXCIE0);// Interrupts enable for RxD
  161. }
  162. enum cmds { CMD_DUMP,
  163. CMD_CRC,
  164. CMD_EXIT,
  165. CMD_RESET,
  166. CMD_IRQ,
  167. CMD_AVR,
  168. CMD_SNES,
  169. CMD_LOROM,
  170. CMD_HIROM,
  171. CMD_WR,
  172. CMD_SHMWR,
  173. CMD_SHMSAVE,
  174. CMD_SHMRESTORE,
  175. CMD_LOADER,
  176. CMD_RECONNECT,
  177. CMD_STATUS,
  178. CMD_HELP
  179. };
  180. uint8_t cmdlist[][CMD_HELP] PROGMEM = {
  181. {"DUMP"},
  182. {"CRC"},
  183. {"EXIT"},
  184. {"RESET"},
  185. {"IRQ"},
  186. {"AVR"},
  187. {"SNES"},
  188. {"LOROM"},
  189. {"HIROM"},
  190. {"WR"},
  191. {"SHMWR"},
  192. {"SHMSAVE"},
  193. {"SHMRESTORE"},
  194. {"LOADER"},
  195. {"RECONNECT"},
  196. {"STATUS"},
  197. {"HELP"},
  198. };
  199. void shell_help(void){
  200. uint8_t i;
  201. info_P(PSTR("\n"));
  202. for (i=CMD_DUMP; i<CMD_HELP; i++){
  203. info_P((PGM_P)cmdlist[i]);
  204. info_P(PSTR("\n"));
  205. }
  206. }
  207. void shell_run(void)
  208. {
  209. uint8_t *t;
  210. uint32_t arg1;
  211. uint32_t arg2;
  212. uint32_t arg3;
  213. uint16_t crc;
  214. if (!cr)
  215. return;
  216. cr=0;
  217. strcpy((char*)command_buf, (char*)recv_buf);
  218. token_ptr = command_buf;
  219. t = get_token();
  220. if (t == NULL)
  221. shell_help();
  222. util_strupper(t);
  223. if (strcmp_P((const char*)t,(PGM_P)cmdlist[CMD_DUMP]) == 0) {
  224. if (get_hex_arg2(&arg1,&arg2))
  225. dump_memory(arg1,arg2);
  226. else
  227. info_P(PSTR("DUMP <start addr> <end addr>\n"));
  228. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_CRC]) == 0) {
  229. if (get_hex_arg2(&arg1,&arg2)){
  230. crc = crc_check_bulk_memory(arg1,arg2,0x8000);
  231. info_P(PSTR("0x%06lx - 0x%06lx crc=0x%04x\n"),arg1,arg2,crc);
  232. } else
  233. info_P(PSTR("CRC <start addr> <end addr>\n"));
  234. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_EXIT]) == 0) {
  235. leave_application();
  236. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_RESET]) == 0) {
  237. send_reset();
  238. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_IRQ]) == 0) {
  239. info_P(PSTR("Send IRQ\n"));
  240. snes_irq_on();
  241. snes_irq_lo();
  242. _delay_us(20);
  243. snes_irq_hi();
  244. snes_irq_off();
  245. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_AVR]) == 0) {
  246. info_P(PSTR("Activate AVR bus\n"));
  247. avr_bus_active();
  248. snes_irq_lo();
  249. snes_irq_off();
  250. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_SNES]) == 0) {
  251. info_P(PSTR("Activate SNES bus\n"));
  252. snes_irq_lo();
  253. snes_irq_off();
  254. snes_wr_disable();
  255. snes_bus_active();
  256. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_LOROM]) == 0) {
  257. info_P(PSTR("Set LOROM\n"));
  258. snes_lorom();
  259. snes_wr_disable();
  260. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_HIROM]) == 0) {
  261. info_P(PSTR("Set HIROM\n"));
  262. snes_hirom();
  263. snes_wr_disable();
  264. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_WR]) == 0) {
  265. arg1 = get_bool();
  266. if(arg1==1){
  267. info_P(PSTR("Set WR enable"));
  268. snes_wr_enable();
  269. }else if (arg1==0){
  270. info_P(PSTR("Set WR disable"));
  271. snes_wr_disable();
  272. }
  273. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_SHMWR]) == 0) {
  274. if (get_hex_arg2(&arg1,&arg2))
  275. shared_memory_write((uint8_t)arg1, (uint8_t)arg1);
  276. else
  277. info_P(PSTR("SHMWR <command> <value>\n"));
  278. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_SHMSAVE]) == 0) {
  279. shared_memory_scratchpad_region_tx_save();
  280. shared_memory_scratchpad_region_rx_save();
  281. info_P(PSTR("Save scratchpad\n"));
  282. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_SHMRESTORE]) == 0) {
  283. shared_memory_scratchpad_region_tx_restore();
  284. shared_memory_scratchpad_region_rx_restore();
  285. info_P(PSTR("Restore scratchpad\n"));
  286. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_LOADER]) == 0) {
  287. boot_startup_rom(500);
  288. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_RECONNECT]) == 0) {
  289. usb_connect();
  290. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_STATUS]) == 0) {
  291. transaction_status();
  292. }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_HELP]) == 0) {
  293. shell_help();
  294. }
  295. prompt();
  296. /*
  297. dias
  298. set irq vector
  299. set reset vector
  300. dump cart header
  301. */
  302. }