/**
  ******************************************************************************
  * @file    TADebug.c
  * @author  C. Otten
  * @version V0.0.0
  * @date    03/10/2011
  * @brief   Thermistor Array debug
  ******************************************************************************
  *
  * COPYRIGHT 2011 Liquid Robotics, Inc.
  **/

#include "includes.h"
#include "uart.h"
#include "pib_apps.h"
#include "User_app_init.h"
#include "fltPyldComms.h"
#include "TADebug.h"

#ifdef  _DEBUG_PORT

typedef struct _TADEBUG_TASK_
{
  uint8_t taskID;
  uint8_t portNum;
}TADEBUG_TASK, *PTADEBUG_TASK;

extern char fileIn[NUM_TASK_FILES][MAX_FILE_SIZE_IN] __attribute__((section(".xdata")));
extern char fileOut[NUM_TASK_FILES][MAX_FILE_SIZE_OUT] __attribute__((section(".xdata")));
extern uint16_t fileOutSize[NUM_TASK_FILES];
extern BOOL fileAvailable[NUM_TASK_FILES];
extern uint32_t fileAvailableID[NUM_TASK_FILES];

extern FLOAT_TX_BUFFER txFloatData[MAX_FLOAT_BUFFERS] __attribute__((section(".xdata")));
extern uint8_t  headFloatTx;
extern uint8_t tailFloatTx;

extern uint8_t  DotToPad(char* pad, char* dot);
extern uint16_t mainTaskAddress;

void TADebug_CharOut(PTADEBUG_TASK pTaskInfo, uint8_t *pp, uint8_t *count);

uint8_t TADebug_Init(PTADEBUG_TASK pTaskInfo)
{
  uint8_t retval = SUCCESS;

  OSuartInitPort(pTaskInfo->portNum, 115200, UART_MODE_EIGHT_DATA_BITS, UART_MODE_ONE_STOP_BIT, UART_MODE_NO_PARITY);

  OSTimeDlyHMSM(0,0,1,0);

  return retval;
}


extern uint8_t os_busy;
void TADebug(void* pParam)                    // Task.
{
  TADEBUG_TASK taskInfo;
  PTADEBUG_TASK pTaskInit = (PTADEBUG_TASK)pParam;
  uint8_t retval = FAIL;
  uint8_t prev_port = 0;
  uint8_t pp_count;

  taskInfo.taskID = pTaskInit->taskID;
  taskInfo.portNum = pTaskInit->portNum;

  retval = TADebug_Init(&taskInfo);

  uint8_t err;
  uint8_t achar;
  // Debug. Send string to a PCOM in the debug slot.
  //  If there's no PCOM, no harm done. If there is one, make sure it is not attached to any instrument.
  OSuartPutStrWait(taskInfo.portNum, "tadebug start\r", 100, &err);

  if(retval == SUCCESS)
  {
    for(;;)
    {
      while (os_busy == 1)
      // When Ocean Server controller is busy with Float C&C, let it focus on that task only.
      // Capture debug commands for as long as the receive buffer allows.
      OSTimeDly(10);

      achar = OSuartGetCharWait(taskInfo.portNum, 1, &err);
      if (err == OS_ERR_NONE)
      {
        if (os_busy == 0)
          OSuartPutCharWait(USER_PORT_2, achar, 10);
        else
          OSuartPutStrWait(taskInfo.portNum, "Ocean Server in use.\r", 100, &err);
      }

      if (os_busy == 0)
      {
        // OK to check for "stray" characters from either Ocean Server ports.
        // Normally there will not be much of anything, since the Ocean Server controller is turned
        //  off between samples. That also means that one will not be able to control it manually.
        if ((prev_port == USER_PORT_2) || (prev_port == USER_PORT_3))
          TADebug_CharOut(&taskInfo, &prev_port, &pp_count);
        else
        {
          // Neither port has been active so far.
          if (OSuartGetCharAvail(USER_PORT_2, &err))
          {
            // Start with Port 2.
            OSuartPutStrWait(taskInfo.portNum, "@2{", 100, &err);
            achar = OSuartGetCharWait(USER_PORT_2, 1, &err);
            if (err == OS_ERR_NONE)
              OSuartPutCharWait(taskInfo.portNum, achar, 10);
            prev_port = USER_PORT_2;
            pp_count = 1;
          }
          if (OSuartGetCharAvail(USER_PORT_3, &err))
          {
            // Start with Port 3.
            OSuartPutStrWait(taskInfo.portNum, "@3{", 100, &err);
            achar = OSuartGetCharWait(USER_PORT_2, 1, &err);
            if (err == OS_ERR_NONE)
              OSuartPutCharWait(taskInfo.portNum, achar, 10);
            prev_port = USER_PORT_3;
            pp_count = 1;
          }
          // If neither port has anything, that's fine too.
        }
      }
    } // for (ever)
  }
  return;
} // TADebug (task)


void TADebug_CharOut(PTADEBUG_TASK pTaskInfo, uint8_t *pp, uint8_t *count)
{
  uint8_t other;
  BOOL    change = FALSE;
  uint8_t err;
  uint8_t achar;

  other = (*pp == USER_PORT_2) ? USER_PORT_3 : USER_PORT_2;
  if (OSuartGetCharAvail(*pp, &err) == 0)
  {
    if (OSuartGetCharAvail(other, &err) == 0)
      // Neither port has anything to say. Just exit without any changes.
      return;
    else
      change = TRUE;
  }
  else
    if ((*count > 50) && OSuartGetCharAvail(other, &err))
      change = TRUE;

  if (change)
  {
    // Don't let one port hog the output to the exclusion of the other.
    // Or, need to switch anyway.
    *count = 0;
    *pp = other;
    if (*pp == USER_PORT_2)                     // Frame the output.
      OSuartPutStrWait(pTaskInfo->portNum, "}\n@2{", 100, &err);
    else
      OSuartPutStrWait(pTaskInfo->portNum, "}\n@3{", 100, &err);
  }
  // Output the next character.
  achar = OSuartGetCharWait(*pp, 1, &err);
  if (err == OS_ERR_NONE)
  {
/*
    if (achar < 0x20 || achar > 0x7E)
    {
      OSuartPutCharWait(pTaskInfo->portNum, '~', 10);
      err = (achar >> 4) & 0xF;
      OSuartPutCharWait(pTaskInfo->portNum, (err > 9) ? err - 10 + 'A' : err + '0', 10);
      err = achar & 0xF;
      OSuartPutCharWait(pTaskInfo->portNum, (err > 9) ? err - 10 + 'A' : err + '0', 10);
    }
    else
*/
      OSuartPutCharWait(pTaskInfo->portNum, achar, 10);
    if (!(++*count))
      (*count)--;                                 // Don't roll over.
  }
} // TADebug_CharOut


#endif // _DEBUG_PORT
