text: /* This source file is part of the ATMEL QTouch Library 5.0.8 */
  
  /*****************************************************************************
   *
   * \file
   *
   * \brief  This file contains the QDebug transport layer API that can be used to
   * transfer data from a Touch Device to QTouch Studio using the QT600
   * USB Bridge.
   *
   *
   * - Userguide:          QTouch Library Peripheral Touch Controller User Guide.
   * - Support email:      www.atmel.com/design-support/
   *
   *
   * Copyright (c) 2013-2015 Atmel Corporation. All rights reserved.
   *
   * \asf_license_start
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   *
   * 1. Redistributions of source code must retain the above copyright notice,
   *    this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright notice,
   *    this list of conditions and the following disclaimer in the documentation
   *    and/or other materials provided with the distribution.
   *
   * 3. The name of Atmel may not be used to endorse or promote products derived
   *    from this software without specific prior written permission.
   *
   * 4. This software may only be redistributed and used in connection with an
   *    Atmel microcontroller product.
   *
   * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
   * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   * POSSIBILITY OF SUCH DAMAGE.
   *
   * \asf_license_stop
   *
   ******************************************************************************/
  
  /*============================ INCLUDES ======================================*/
  #include <parts.h>
  
  #include "touch.h"
  #include "touch_api_ptc.h"
  
  /*! compile qdebug files only when QDebug is enabled. */
  #if DEF_TOUCH_QDEBUG_ENABLE == 1
  
  #include "QDebug_samd.h"
  #include "QDebugTransport.h"
  #include "QDebugSettings.h"
  
  #if (defined QDEBUG_SPI)
  #include "SPI_Master.h"
  #elif (defined QDEBUG_SERIAL)
  #include "SERIAL.h"
  #elif defined(QDEBUG_BITBANG_SPI)
  #include "BitBangSPI_Master.h"
  #else
  #warning "No Debug Interface is selected in QDebugSettings.h"
  #endif
  
  /*============================ GLOBAL VARIABLES ==============================*/
  
  uint8_t TX_Buffer[TX_BUFFER_SIZE];
  uint16_t TX_index = 4;
  
  uint8_t RX_Buffer[RX_BUFFER_SIZE];
  uint16_t RX_index;
  
  uint8_t SequenceL = 0;
  uint8_t SequenceH = 0;
  
  /*============================ IMPLEMENTATION ================================*/
  
  /*! \brief Initialize the send and receive buffers.
   * \note Called from QDebug_Init.
   */
  void Init_Buffers(void)
  {
  #ifdef __DEBUG__
  	for (int i = 0; i < sizeof(TX_Buffer); i++) {
  		RX_Buffer[i] = 0;
  		RX_Buffer[i] = 0;
  	}
  #endif
  
  	TX_Buffer[0] = MESSAGE_START;
  	TX_index = 4;           /* Start to add data after MSG_START, MSG_SIZEH,
  	                         * MSG_SIZEL, and Sequence number */
  	RX_index = 0;
  }
  
  /*! \brief Puts one byte in the Transmit Buffer.
   * \param data: byte to be sent.
   * \note Called from QDebug_Init.
   */
  void PutChar(uint8_t data)
  {
  	TX_Buffer[TX_index++] = data;
  }
  
  /*! \brief Puts two bytes in the Transmit Buffer.
   * \param data: 16bit data to be sent.
   * \note Big Endian. TX_index is post incremented.
   */
  void PutInt(uint16_t data)
  {
  	TX_Buffer[TX_index++] = data >> 8;
  	TX_Buffer[TX_index++] = data;
  }
  
  /*! \brief Get one byte from the Receive Buffer.
   * \return uint8_t: byte received.
   * \note RX_index is post incremented.
   */
  uint8_t GetChar(void)
  {
  	return RX_Buffer[RX_index++];
  }
  
  /*! \brief Send the content of the TX_Buffer to the USB Bridge using the
   * interface selected in QDebugSettings.h
   * \note Called from the transmit functions in QDebug.c.
   */
  void Send_Message(void)
  {
  	uint8_t checksum = 0;
  	uint16_t i;
  
  	SequenceL = (SequenceL + 1) & 0x0F; /* inc and wrap */
  
  	/* Store length field */
  	TX_Buffer[1] = (uint8_t)(TX_index >> 8);
  	TX_Buffer[2] = (uint8_t)(TX_index & 0xFF);
  
  	/* Store Sequence Number */
  	TX_Buffer[3] = (SequenceH << 4) + SequenceL;
  
  	/* Calculate checksum */
  	for (i = 1; i < TX_index; i++) {
  		checksum ^= TX_Buffer[i];
  	}
  	TX_Buffer[TX_index] = checksum;
  
  	/* Send data using selected interface */
  #if (defined QDEBUG_SPI)
  	SPI_Send_Message();
  #elif (defined QDEBUG_SERIAL)
  	SERIAL_Send_Message();
  #elif defined(QDEBUG_BITBANG_SPI)
  	BitBangSPI_Send_Message();
  #endif
  
  	/* Ready for next message */
  	TX_index = 4;
  }
  
  /*! \brief Executes a master read transmission if TWI is selected as interface.
   * Checks if RX_Buffer has a valid frame
   * \return uint8_t: returns a true or false Dependant on whether a valid frame
   * is
   * available or not
   * \note Called from QDebug_ProcessCommands in QDebug.c.
   */
  uint8_t Receive_Message(void)
  {
  #if (defined QDEBUG_SERIAL)
  	SERIAL_Retrieve_Message();
  #endif
  	/* Check for token */
  	if (RX_Buffer[0] != 0x1B) {
  		return 0;
  	}
  
  	/* Yes, we have received a valid frame! */
  	RX_index = 4;           /* Next GetChar() will get the command id */
  	return 1;
  }
  
  /*! \brief Handles the incoming bytes from the interface selected in
   * QDebugSettings.h and puts the bytes in the RX_Buffer data read by
   * the selected interface
   * \return uint8_t: returns a true if more data must be read,
   * returns a false if the frame is complete
   * \note Used by SPI and TWI receive handlers.
   */
  uint8_t RxHandler(uint8_t c)
  {
  	static uint16_t length = 0;
  	static uint16_t received = 0;
  	static uint8_t state = STATE_IDLE;
  	uint8_t nextstate;
  	uint8_t checksum;
  	uint16_t i;
  
  	switch (state) {
  	case STATE_IDLE:
  		if (c == 0x1B) {
  			nextstate = STATE_LENGTH1;
  		} else {
  			nextstate = STATE_IDLE;
  		}
  
  		break;
  
  	case STATE_LENGTH1:
  		RX_Buffer[1] = c;
  		length = c << 8;
  		nextstate = STATE_LENGTH2;
  		break;
  
  	case STATE_LENGTH2:
  		RX_Buffer[2] = c;
  		length |= c;
  		if ((length < 4) || (length > 270)) {
  			/* Illegal length, discard it */
  			nextstate = STATE_IDLE;
  		} else {
  			received = 3;
  			nextstate = STATE_DATA;
  		}
  
  		break;
  
  	case STATE_DATA:
  		RX_Buffer[received] = c;
  
  		if (received == length) {
  			/* This is the CRC byte */
  			checksum = 0;
  			for (i = 1; i <= length; i++) {
  				checksum ^= RX_Buffer[i];
  			}
  
  			if (checksum == 0) {
  				/* Valid frame */
  				RX_Buffer[0] = 0x1B;
  			}
  
  			nextstate = STATE_IDLE;
  			break;
  		}
  
  		nextstate = STATE_DATA;
  		received++;
  		break;
  
  	default:
  		nextstate = STATE_IDLE;
  	}
  
  	state = nextstate;
  
  	return state;
  }
  
  #endif  /* #if DEF_TOUCH_QDEBUG_ENABLE == 1 */
  