/firmware/src/Motherboard/DebugPacketProcessor.cc

http://github.com/makerbot/G3Firmware · C++ · 149 lines · 112 code · 10 blank · 27 comment · 37 complexity · 2065dbfc3e0668628253c62375d77720 MD5 · raw file

  1. /*
  2. * Copyright 2010 by Adam Mayer <adam@makerbot.com>
  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. #include "DebugPacketProcessor.hh"
  18. #include "UART.hh"
  19. #include "Timeout.hh"
  20. #include "Configuration.hh"
  21. #include "Motherboard.hh"
  22. #include "Errors.hh"
  23. #include "Tool.hh"
  24. #include "Command.hh"
  25. namespace CommandCode {
  26. enum {
  27. DEBUG_ECHO = 0x70,
  28. DEBUG_GENERATE_BAD_PACKET = 0x71,
  29. DEBUG_SIMULATE_BAD_PACKET = 0x72,
  30. DEBUG_SLAVE_PASSTHRU = 0x73,
  31. DEBUG_CLEAR_COMMAND_QUEUE = 0x74,
  32. DEBUG_NO_SUCH_COMMAND = 0x75,
  33. DEBUG_SET_DEBUG_CODE = 0x76,
  34. DEBUG_GET_DEBUG_CODE = 0x77,
  35. DEBUG_COMMAND_QUEUE_FILLER = 0xF0
  36. };
  37. }
  38. namespace BadReceptionCode {
  39. enum {
  40. RECEIVED_NOISE = 1,
  41. BAD_PACKET_LENGTH = 2,
  42. BAD_CRC = 3,
  43. TIMEOUT = 4
  44. };
  45. }
  46. namespace BadResponseCode {
  47. enum {
  48. NO_RESPONSE = 1,
  49. SKIP_START_BYTE = 2,
  50. BAD_PACKET_LENGTH = 3,
  51. BAD_CRC = 4,
  52. TIMEOUT = 5
  53. };
  54. }
  55. OutPacket debugSlaveOut;
  56. /// Identify a debug packet, and process it. If the packet is a debug
  57. /// packet, return true, indicating that no further processing should
  58. /// be done. Otherwise, processing of this packet should drop through
  59. /// to the next processing level.
  60. bool processDebugPacket(const InPacket& from_host, OutPacket& to_host) {
  61. if (from_host.getLength() == 0) {
  62. return false;
  63. } // drop through on a nop packet
  64. uint8_t command = from_host.read8(0);
  65. if ((command & 0x70) == 0x70) {
  66. // This is a debug packet
  67. if (command == CommandCode::DEBUG_ECHO) {
  68. // We start from 1 so we can skip the debug command byte.
  69. to_host.reset();
  70. for (int i = 1; i < from_host.getLength(); i++) {
  71. to_host.append8(from_host.read8(i));
  72. }
  73. return true;
  74. } else if (command == CommandCode::DEBUG_GENERATE_BAD_PACKET) {
  75. // TODO
  76. } else if (command == CommandCode::DEBUG_SIMULATE_BAD_PACKET) {
  77. // TODO
  78. } else if (command == CommandCode::DEBUG_SLAVE_PASSTHRU) {
  79. // BLOCK: wait until sent
  80. {
  81. OutPacket& out = tool::getOutPacket();
  82. InPacket& in = tool::getInPacket();
  83. out.reset();
  84. for (int i = 1; i < from_host.getLength(); i++) {
  85. out.append8(from_host.read8(i));
  86. }
  87. Timeout acquire_lock_timeout;
  88. acquire_lock_timeout.start(50000); // 50 ms timeout
  89. while (!tool::getLock()) {
  90. if (acquire_lock_timeout.hasElapsed()) {
  91. to_host.append8(RC_TOOL_LOCK_TIMEOUT);
  92. Motherboard::getBoard().indicateError(ERR_SLAVE_LOCK_TIMEOUT);
  93. return true;
  94. }
  95. }
  96. Timeout t;
  97. t.start(50000); // 50 ms timeout
  98. tool::startTransaction();
  99. tool::releaseLock();
  100. while (!tool::isTransactionDone()) {
  101. if (t.hasElapsed()) {
  102. to_host.append8(RC_DOWNSTREAM_TIMEOUT);
  103. Motherboard::getBoard().indicateError(ERR_SLAVE_PACKET_TIMEOUT);
  104. return true;
  105. }
  106. tool::runToolSlice();
  107. }
  108. // Copy payload back. Start from 0-- we need the response code.
  109. for (int i = 0; i < in.getLength(); i++) {
  110. to_host.append8(in.read8(i));
  111. }
  112. }
  113. return true;
  114. } else if (command == CommandCode::DEBUG_CLEAR_COMMAND_QUEUE) {
  115. command::reset();
  116. to_host.append8(RC_OK);
  117. return true;
  118. } else if (command == CommandCode::DEBUG_SET_DEBUG_CODE ) {
  119. uint8_t debug_register = from_host.read8(1);
  120. uint8_t value = from_host.read8(2);
  121. if (debug_register == 0) {
  122. Motherboard::getBoard().indicateError(value);
  123. }
  124. to_host.append8(RC_OK);
  125. } else if (command == CommandCode::DEBUG_GET_DEBUG_CODE ) {
  126. uint8_t debug_register = from_host.read8(1);
  127. to_host.append8(RC_OK);
  128. if (debug_register == 0) {
  129. to_host.append8(Motherboard::getBoard().getCurrentError());
  130. } else {
  131. to_host.append8(0);
  132. }
  133. }
  134. return false;
  135. } else {
  136. // This is not a debug packet
  137. return false;
  138. }
  139. }