PageRenderTime 50ms CodeModel.GetById 11ms app.highlight 33ms RepoModel.GetById 1ms app.codeStats 1ms

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