jackknife.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * Copyright (c) 2009 Openmoko Inc.
  3. *
  4. * Authors Christopher Hall <hsw@openmoko.com>
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <inttypes.h>
  20. #include "regs.h"
  21. // override the default console bps for faster programming
  22. #define CONSOLE_BPS 115200
  23. // default is to program the on-board flash
  24. #if !defined(PROGRAM_TEST_JIG)
  25. #define PROGRAM_TEST_JIG 0
  26. #endif
  27. #define SAMO_RESTRICTIONS 1
  28. #include "samo.h"
  29. // do not add any static variables
  30. // this program is restricted to 512 bytes .text
  31. // and stack/register variables only
  32. enum {
  33. COMMAND_BOARD_REVISION = 'A',
  34. COMMAND_SPI_WRITE = 'W',
  35. COMMAND_SPI_READ = 'R',
  36. COMMAND_SPI_DESELECT = 'H',
  37. COMMAND_SPI_SELECT = 'L',
  38. };
  39. static void serial_put(uint8_t c);
  40. static uint8_t serial_get(void);
  41. static uint32_t serial_get16(void);
  42. static uint8_t spi_transfer(uint8_t c);
  43. int main(void)
  44. {
  45. init_pins();
  46. init_rs232_ch0();
  47. SDCARD_CS_HI();
  48. EEPROM_CS_HI();
  49. EEPROM_WP_HI();
  50. REG_SPI_CTL1 =
  51. //BPT_32_BITS |
  52. //BPT_16_BITS |
  53. BPT_8_BITS |
  54. //BPT_1_BITS |
  55. //CPHA |
  56. //CPOL |
  57. //MCBR_MCLK_DIV_512 |
  58. //MCBR_MCLK_DIV_256 |
  59. //MCBR_MCLK_DIV_128 |
  60. //MCBR_MCLK_DIV_64 |
  61. //MCBR_MCLK_DIV_32 |
  62. //MCBR_MCLK_DIV_16 |
  63. //MCBR_MCLK_DIV_8 |
  64. MCBR_MCLK_DIV_4 |
  65. //TXDE |
  66. //RXDE |
  67. MODE_MASTER |
  68. //MODE_SLAVE |
  69. ENA |
  70. 0;
  71. #if PROGRAM_TEST_JIG
  72. // set P05 high to enable external boot FLASH ROM
  73. REG_P5_P5D |= 0x20;
  74. REG_P5_IOC5 |= 0x20;
  75. #else
  76. // set P05 low to disable external boot FLASH ROM
  77. REG_P5_P5D &= ~0x20;
  78. REG_P5_IOC5 |= 0x20;
  79. #endif
  80. // flush spi buffer
  81. (void)REG_SPI_RXD;
  82. for (;;) {
  83. uint8_t command = serial_get();
  84. // switch will create jump table and overflow our 512 bytes
  85. if (COMMAND_BOARD_REVISION == command) {
  86. serial_put('A');
  87. serial_put(board_revision());
  88. } else if (COMMAND_SPI_DESELECT == command) {
  89. EEPROM_CS_HI();
  90. } else if (COMMAND_SPI_SELECT == command) {
  91. EEPROM_CS_LO();
  92. } else if (COMMAND_SPI_WRITE == command) {
  93. uint32_t len = serial_get16();
  94. while (len--) {
  95. (void)spi_transfer(serial_get());
  96. }
  97. } else if (COMMAND_SPI_READ == command) {
  98. uint32_t len = serial_get16();
  99. while (len--) {
  100. serial_put(spi_transfer(0x00));
  101. }
  102. } else {
  103. serial_put('?');
  104. }
  105. }
  106. }
  107. static void serial_put(uint8_t c)
  108. {
  109. while (0 == (REG_EFSIF0_STATUS & TDBEx)) {
  110. }
  111. REG_EFSIF0_TXD = c;
  112. }
  113. static uint8_t serial_get(void)
  114. {
  115. while (0 == (REG_EFSIF0_STATUS & RDBFx)) {
  116. }
  117. return REG_EFSIF0_RXD;
  118. }
  119. static uint32_t serial_get16(void)
  120. {
  121. uint32_t value = serial_get();
  122. return value | serial_get() << 8;
  123. }
  124. static uint8_t spi_transfer(uint8_t out)
  125. {
  126. REG_SPI_TXD = out;
  127. do {} while (~REG_SPI_STAT & RDFF);
  128. return REG_SPI_RXD;
  129. }