예제 #1
0
void pumpRx(COM_Port_t port)
{
  if (checkValidPort(port) == false)
  {
    return;
  }
  // UART
  if ( (port == COM_USART0) || (port == COM_USART1) || (port == COM_USART2) )
  {
    uint8_t *buf;
    UARTDRV_Count_t xferred, remaining;
    INT_Disable();
    UARTDRV_GetReceiveStatus(comhandle[port]->uarthandle, &buf, &xferred, &remaining);
    updateBuffer(comhandle[port]->rxQueue, xferred, comhandle[port]->rxsize);
    INT_Enable();
  }
#ifdef COM_VCP_ENABLE
  if (port == COM_VCP)
  {
    //VCP functionality (VUART) on EFRs do not yet support Rx.
    return;
    //x uint8_t rxbyte;
    //x uint16_t xferred;
    //x BSP_vcpRead( &rxbyte, 1, 1, &xferred, false );
    //x if (xferred>0)
    //x {
    //x   INT_Disable();
    //x   FIFO_ENQUEUE(comhandle[port]->rxQueue, rxbyte, comhandle[port]->rxsize);
    //x   INT_Enable();
    //x }
  }
#endif
}
예제 #2
0
Ecode_t COM_WriteByte(COM_Port_t port, uint8_t dataByte)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
  return COM_WriteData(port, &dataByte, 1);
}
예제 #3
0
Ecode_t COM_PrintCarriageReturn(COM_Port_t port)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
  return COM_Printf(port, "\r\n");
}
예제 #4
0
Ecode_t COM_Init(COM_Port_t port, COM_Init_t *init)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }

  comhandle[port]->rxQueue = (COM_FifoQueue_t *) comRxQueues[port];
  comhandle[port]->txQueue = (COM_FifoQueue_t *) comTxQueues[port];
  comhandle[port]->rxsize = comRxQueueSize[port];
  comhandle[port]->txsize = comTxQueueSize[port];
  // VCP

#if (COM_VCP_PORTS > 0) && defined(COM_VCP_ENABLE)
  if (port == COM_VCP)
  {
    //emDebugInit() should have already been called. 
  }
#endif


  // UART
#if (COM_UART_PORTS > 0)
  if ( (port == COM_USART0) || (port == COM_USART1) || (port == COM_USART2) )
  {
    Ecode_t status;

    comhandle[port]->uarthandle = uarthandle[port-COM_VCP_PORTS];

    // add rx/tx buffer queue to initdata
    init->uartdrvinit.rxQueue = comRxBufferQueues[port];
    init->uartdrvinit.txQueue = comTxBufferQueues[port];

    // iniitalize hardware
    status = UARTDRV_Init(uarthandle[port-COM_VCP_PORTS], &init->uartdrvinit);
    if (status != EMBER_SUCCESS)
    {
      return status;
    }
    // start ping pong buffers for FIFO
    UARTDRV_Receive(uarthandle[port-COM_VCP_PORTS], 
                    comhandle[port]->rxQueue->fifo, 
                    comhandle[port]->rxsize/2, 
                    reloadUartBuffer);
    UARTDRV_Receive(uarthandle[port-COM_VCP_PORTS],
                    &comhandle[port]->rxQueue->fifo[comhandle[port]->rxsize/2],
                    comhandle[port]->rxsize/2, 
                    reloadUartBuffer);

    #ifndef ENABLE_EXP_UART
      halEnableVCOM();
    #endif
  }
#endif //(COM_UART_PORTS > 0)

  return EMBER_SUCCESS;
}
예제 #5
0
Ecode_t COM_WriteHex(COM_Port_t port, uint8_t dataByte)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
  uint8_t hex[2];
  emWriteHexInternal(hex, dataByte, 2);
  return COM_WriteData(port, hex, 2);
}
예제 #6
0
co::IService* System_Base::getServiceAt( co::IPort* port )
{
	checkValidPort( port );
	co::IService* res = NULL;
	switch( port->getIndex() )
	{
	case 0:		res = static_cast<co::ISystem*>( this ); break;
	default:	raiseUnexpectedPortIndex();
	}
	return res;
}
예제 #7
0
Ecode_t COM_WriteString(COM_Port_t port, PGM_P string)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
  uint8_t *fifohead= &comhandle[port]->txQueue->fifo[comhandle[port]->txQueue->head];
  uint8_t length = 0;
  uint8_t wraplength = 0;
  while(*string != '\0') {
    while (! getOutputFifoSpace(port, 0)) {};
    INT_Disable();
    FIFO_ENQUEUE(comhandle[port]->txQueue,*string,comhandle[port]->txsize);
    INT_Enable();
    string++;
    length++;
    // queue just wrapped
    if (comhandle[port]->txQueue->head == 0)
    {
      // store first transmit length
      wraplength = length;
      // transmit chunk      
      if ( (port == COM_USART0) || (port == COM_USART1) || (port == COM_USART2) )
      {
        while(UARTDRV_Transmit(comhandle[port]->uarthandle, fifohead, wraplength, unloadTxBuffer) != EMBER_SUCCESS);
      }
#ifdef COM_VCP_ENABLE
      if (port == COM_VCP)
      {
          emDebugSendVuartMessage(comhandle[port]->txQueue->fifo, comhandle[port]->txsize);
          dequeueFifoBuffer(port, comhandle[port]->txsize);
      }
#endif //COM_VCP_ENABLE
      // move fifohead back to start
      fifohead = comhandle[port]->txQueue->fifo;
    }
  }  

  if ( length > wraplength)
  {
    if ( (port == COM_USART0) || (port == COM_USART1) || (port == COM_USART2) )
    {
      while(UARTDRV_Transmit(comhandle[port]->uarthandle, fifohead, length - wraplength, unloadTxBuffer) != EMBER_SUCCESS);
    }
  #ifdef COM_VCP_ENABLE
    if (port == COM_VCP)
    {
          emDebugSendVuartMessage(comhandle[port]->txQueue->fifo, comhandle[port]->txsize);
          dequeueFifoBuffer(port, comhandle[port]->txsize);
    }
  #endif //COM_VCP_ENABLE
  }
  return EMBER_SUCCESS;
}
예제 #8
0
Ecode_t COM_PrintfVarArg(COM_Port_t port, PGM_P formatString, va_list ap)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
  Ecode_t stat = EMBER_SUCCESS; 
  if(!emPrintfInternal(COM_WriteData, port, formatString, ap))
    stat = EMBER_ERR_FATAL;
  return stat;
}
예제 #9
0
co::IService* Component_Base::getServiceAt( co::IPort* port )
{
	checkValidPort( port );
	co::IService* res = NULL;
	switch( port->getIndex() )
	{
	case 0:		res = static_cast<co::IDynamicServiceProvider*>( this ); break;
	case 1:		res = static_cast<co::IReflector*>( this ); break;
	default:	raiseUnexpectedPortIndex();
	}
	return res;
}
예제 #10
0
Ecode_t COM_ReadLine(COM_Port_t port, char *data, uint8_t max)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
  uint8_t index=0;

  while(COM_ReadPartialLine(port, data, max, &index) != EMBER_SUCCESS) {
    halResetWatchdog();
  }
  return EMBER_SUCCESS;
}
예제 #11
0
Ecode_t COM_Printf(COM_Port_t port, PGM_P formatString, ...)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
  Ecode_t stat;
  va_list ap;
  va_start (ap, formatString);
  stat = COM_PrintfVarArg(port, formatString, ap);
  va_end (ap);
  return stat;
}
예제 #12
0
IService* ReflectorBase::getServiceAt( IPort* port )
{
	checkValidPort( port );

	IService* res = NULL;
	switch( port->getIndex() )
	{
	case 0: res = static_cast<IReflector*>( this ); break;
	default:
		raiseUnexpectedPortIndex();
	}

	return res;
}
예제 #13
0
Ecode_t COM_GuaranteedPrintf(COM_Port_t port, PGM_P formatString, ...)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
  Ecode_t stat;
  va_list ap;
  va_start (ap, formatString);
  if(!emPrintfInternal(COM_ForceWriteData, port, formatString, ap))
    stat = EMBER_ERR_FATAL;
  va_end (ap);
  return stat;
}
예제 #14
0
Ecode_t COM_ReadDataTimeout(COM_Port_t port,
                                       uint8_t *data,
                                       uint16_t length,
                                       uint16_t *bytesRead,
                                       uint16_t firstByteTimeout,
                                       uint16_t subsequentByteTimeout)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
  uint16_t bytesReadInternal = 0;
  Ecode_t status;
  uint16_t timeout = firstByteTimeout;
  uint16_t startTime = halCommonGetInt16uMillisecondTick();
  
  // loop until we read the max number of bytes or the timeout elapses
  while (bytesReadInternal < length
         && elapsedTimeInt16u(startTime,halCommonGetInt16uMillisecondTick()) < timeout) {
    status = COM_ReadByte(port, data);

    switch (status) {
      case EMBER_SUCCESS:
        ++data;
        ++bytesReadInternal;
        // reset timer and timeout for next character
        startTime = halCommonGetInt16uMillisecondTick();
        timeout = subsequentByteTimeout;
        break;

      case EMBER_SERIAL_RX_EMPTY:
        // empty queue is not an error for us, we just want to keep waiting
        break;

      default:
        // only store number of bytes read if the caller provided a non-NULL pointer
        if (bytesRead) {
          *bytesRead = bytesReadInternal;
        }
        return status;
    }
  }

  // only store number of bytes read if the caller provided a non-NULL pointer
  if (bytesRead) {
    *bytesRead = bytesReadInternal;
  }

  return bytesReadInternal == length ? EMBER_SUCCESS : EMBER_SERIAL_RX_EMPTY;
}
예제 #15
0
Ecode_t COM_ReadByte(COM_Port_t port, uint8_t *dataByte)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
  // make sure rx buffer is updated
  pumpRx(port);
  if (comhandle[port]->rxQueue->used > 0) {
    INT_Disable();
      *dataByte = FIFO_DEQUEUE(comhandle[port]->rxQueue, comhandle[port]->rxsize);
    INT_Enable();
    return EMBER_SUCCESS;
  }
  return EMBER_SERIAL_RX_EMPTY;
}
예제 #16
0
Ecode_t COM_ForceWriteData(COM_Port_t port, uint8_t *data, uint8_t length)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
#ifdef COM_VCP_ENABLE
  if ( port == COM_VCP )
  {
    emDebugSendVuartMessage(data, length);
    return EMBER_SUCCESS;
  }
#endif //COM_VCP_ENABLE
  Ecode_t status;
  status = UARTDRV_ForceTransmit(comhandle[port]->uarthandle, data, length);
  return status;
}
예제 #17
0
Ecode_t COM_WriteData(COM_Port_t port, uint8_t *data, uint8_t length)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
#ifdef COM_VCP_ENABLE
  if ( port == COM_VCP )
  {
    emDebugSendVuartMessage(data, length);
    return EMBER_SUCCESS;
  }
#endif //COM_VCP_ENABLE

  uint8_t *fifohead= &comhandle[port]->txQueue->fifo[comhandle[port]->txQueue->head];
  uint8_t wraplength = 0;
  for (uint8_t i =0; i<length; i++) {
    while (! getOutputFifoSpace(port, 0)) {};
    INT_Disable();
    FIFO_ENQUEUE(comhandle[port]->txQueue,*data,comhandle[port]->txsize);
    INT_Enable();
    data++;
    // queue just wrapped
    if (comhandle[port]->txQueue->head == 0)
    {
      // store first transmit length
      wraplength = i + 1;
      // transmit chunk
      if ( (port == COM_USART0) || (port == COM_USART1) || (port == COM_USART2) )
      {
        while (UARTDRV_Transmit(comhandle[port]->uarthandle,fifohead, wraplength, unloadTxBuffer) != EMBER_SUCCESS);
      }
      // move fifohead back to start
      fifohead = comhandle[port]->txQueue->fifo;
    }
  }  
  if (length>wraplength)
  {
    if ( (port == COM_USART0) || (port == COM_USART1) || (port == COM_USART2) )
    {
      while(UARTDRV_Transmit(comhandle[port]->uarthandle, fifohead, length - wraplength, unloadTxBuffer) != EMBER_SUCCESS);
    }
  }
  return EMBER_SUCCESS;
}
예제 #18
0
Ecode_t COM_ReadData(COM_Port_t port,
                                uint8_t *data,
                                uint16_t length,
                                uint16_t *bytesRead)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
  uint16_t bytesReadInternal = 0;
  Ecode_t status;

  while (bytesReadInternal < length) {
    status = COM_ReadByte(port, data);

    switch (status) {
      case EMBER_SUCCESS:
        ++data;
        ++bytesReadInternal;
        break;

      case EMBER_SERIAL_RX_EMPTY:
        // empty queue is not an error for us, we just want to keep waiting
        break;

      default:
        // only store number of bytes read if the caller provided a non-NULL pointer
        if (bytesRead) {
          *bytesRead = bytesReadInternal;
        }
        return status;
    }
  }

  // only store number of bytes read if the caller provided a non-NULL pointer
  if (bytesRead) {
    *bytesRead = bytesReadInternal;
  }

  return EMBER_SUCCESS;

}
예제 #19
0
Ecode_t COM_WaitSend(COM_Port_t port)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
  if (port == COM_VCP)
  {
    while (comhandle[port]->txQueue->used>0);
  }
  if ( (port==COM_USART0) || (port==COM_USART1) || (port==COM_USART2) )
  {
    while ( (comhandle[port]->txQueue->used > 0)
            || (UARTDRV_GetTransmitDepth(comhandle[port]->uarthandle) > 0)
            || !( (USART_StatusGet(comhandle[port]->uarthandle->initData.port) & _USART_STATUS_TXC_MASK) 
                  #ifdef _USART_STATUS_TXIDLE_MASK
                  && (USART_StatusGet(comhandle[port]->uarthandle->initData.port) & _USART_STATUS_TXIDLE_MASK)
                  #endif
                ) );
  }

  return EMBER_SUCCESS;
}
 /// Write-only accessor to _destPort.
 /// @param newVal The TCP port between 0 and 65535.
 /// @throw InvalidPort If the port is out of range.
 virtual void setDestPort(const int& newVal) {
     if ( checkValidPort(newVal) ) _destPort = newVal;
     else throw InvalidPort("Bad port number given to devUdp4::setPort");
     _dest_addr.sin_port = htons(newVal);
 }
예제 #21
0
bool COM_Unused(uint8_t port)
{
  return !checkValidPort((COM_Port_t) port);
}
예제 #22
0
void ComponentBase::checkValidReceptacle( IPort* receptacle )
{
	checkValidPort( receptacle );
	if( receptacle->getIsFacet() )
		throw NoSuchPortException( "receptacle expected, got facet" );
}
예제 #23
0
Ecode_t COM_ReadPartialLine(COM_Port_t port, char *data, uint8_t max, uint8_t * index)
{
  if (checkValidPort(port)==false)
  {
    return EMBER_ERR_FATAL;
  }
  Ecode_t err;
  uint8_t ch;

  if (((*index) == 0) || ((*index) >= max))
    data[0] = '\0';

  for (;;) {   
    err = COM_ReadByte(port, &ch);

    // no new serial port char?, keep looping
    if (err) return err;

    // handle bogus characters
    if ( ch > 0x7F ) continue;

    // handle leading newline - fogBUGZ # 584
    if (((*index) == 0) &&
        ((ch == '\n') || (ch == 0))) continue;

    // Drop the CR, or NULL that is part of EOL sequence.
    if ((*index) >= max) {
      *index = 0;
      if ((ch == '\r') || (ch == 0)) continue;
    }

    // handle backspace
    if ( ch == 0x8 || ch == 0x7F ) {
      if ( (*index) > 0 ) {
        // delete the last character from our string
        (*index)--;
        data[*index] = '\0';
        // echo backspace
        COM_WriteString(port, "\b \b");
      }
      // don't add or process this character
      continue;
    }

    //if the string is about to overflow, fake in a CR
    if ( (*index) + 2 > max ) {
      ch = '\r';
    }

    COM_WriteByte(port, ch); // term char echo

    //upcase that char
    if ( ch>='a' && ch<='z') ch = ch - ('a'-'A');

    // build a string until we press enter
    if ( ( ch == '\r' ) || ( ch == '\n' ) ) {
      data[*index] = '\0';

      if (ch == '\r') {
        COM_WriteByte(port, '\n'); // "append" LF
        *index = 0;                       // Reset for next line; \n next
      } else {
        COM_WriteByte(port, '\r'); // "append" CR
        *index = max;                     // Reset for next line; \r,\0 next
      }

      return EMBER_SUCCESS;
    } 
      
    data[(*index)++] = ch;
  }
}