xflash_dump.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include <stddef.h>
  2. #include <avr/wdt.h>
  3. #include <avr/interrupt.h>
  4. #include "xflash_dump.h"
  5. #include "xflash.h"
  6. bool xfdump_check_state()
  7. {
  8. uint32_t magic;
  9. XFLASH_SPI_ENTER();
  10. xflash_rd_data(DUMP_OFFSET + offsetof(dump_t, header.magic),
  11. (uint8_t*)&magic, sizeof(magic));
  12. return magic == DUMP_MAGIC;
  13. }
  14. bool xfdump_check_crash()
  15. {
  16. // check_state will call SPI_ENTER for us
  17. if(!xfdump_check_state())
  18. return false;
  19. uint8_t crash;
  20. xflash_rd_data(DUMP_OFFSET + offsetof(dump_t, header.crash),
  21. (uint8_t*)&crash, sizeof(crash));
  22. return crash;
  23. }
  24. void xfdump_reset()
  25. {
  26. XFLASH_SPI_ENTER();
  27. xflash_enable_wr();
  28. xflash_sector_erase(DUMP_OFFSET + offsetof(dump_t, header.magic));
  29. xflash_wait_busy();
  30. }
  31. static void xfdump_erase()
  32. {
  33. XFLASH_SPI_ENTER();
  34. for(uint32_t addr = DUMP_OFFSET;
  35. addr < DUMP_OFFSET + DUMP_SIZE;
  36. addr += 4096)
  37. {
  38. xflash_enable_wr();
  39. xflash_sector_erase(DUMP_OFFSET);
  40. xflash_wait_busy();
  41. }
  42. }
  43. static void xfdump_dump_core(dump_header_t& hdr, uint32_t addr, uint8_t* buf, uint16_t cnt)
  44. {
  45. XFLASH_SPI_ENTER();
  46. // start by clearing all sectors (we need all of them in any case)
  47. xfdump_erase();
  48. // write header
  49. static_assert(sizeof(hdr) < 256, "header is larger than a single page write");
  50. xflash_enable_wr();
  51. xflash_page_program(DUMP_OFFSET, (uint8_t*)&hdr, sizeof(hdr));
  52. xflash_wait_busy();
  53. // write data
  54. xflash_multipage_program(addr, buf, cnt);
  55. }
  56. void xfdump_dump()
  57. {
  58. dump_header_t buf;
  59. buf.magic = DUMP_MAGIC;
  60. buf.regs_present = false;
  61. buf.crash = false;
  62. // write sram only
  63. xfdump_dump_core(buf, DUMP_OFFSET + offsetof(dump_t, data.sram),
  64. (uint8_t*)SRAM_START, SRAM_SIZE);
  65. }
  66. void xfdump_full_dump_and_reset(bool crash)
  67. {
  68. dump_header_t buf;
  69. buf.magic = DUMP_MAGIC;
  70. buf.regs_present = true;
  71. buf.crash = crash;
  72. // disable interrupts for a cleaner register dump
  73. cli();
  74. // write all addressable ranges (this will trash bidirectional registers)
  75. xfdump_dump_core(buf, DUMP_OFFSET + offsetof(dump_t, data),
  76. 0, SRAM_START + SRAM_SIZE);
  77. // force a reset soon
  78. wdt_enable(0);
  79. while(true);
  80. }