/** Main program entry point. This routine contains the overall program flow, including initial
 *  setup of all components and the main program loop.
 */
int main(void)
{
	SetupHardware();

	RingBuffer_InitBuffer(&USBtoUSART_Buffer, USBtoUSART_Buffer_Data, sizeof(USBtoUSART_Buffer_Data));
	RingBuffer_InitBuffer(&USARTtoUSB_Buffer, USARTtoUSB_Buffer_Data, sizeof(USARTtoUSB_Buffer_Data));

	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
	GlobalInterruptEnable();

	for (;;)
	{
		/* Only try to read in bytes from the CDC interface if the transmit buffer is not full */
		if (!(RingBuffer_IsFull(&USBtoUSART_Buffer)))
		{
			int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);

			/* Read bytes from the USB OUT endpoint into the USART transmit buffer */
			if (!(ReceivedByte < 0))
			  RingBuffer_Insert(&USBtoUSART_Buffer, ReceivedByte);
		}

		/* Check if the UART receive buffer flush timer has expired or the buffer is nearly full */
		uint16_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);
		if (BufferCount)
		{
			Endpoint_SelectEndpoint(VirtualSerial_CDC_Interface.Config.DataINEndpoint.Address);

			/* Check if a packet is already enqueued to the host - if so, we shouldn't try to send more data
			 * until it completes as there is a chance nothing is listening and a lengthy timeout could occur */
			if (Endpoint_IsINReady())
			{
				/* Never send more than one bank size less one byte to the host at a time, so that we don't block
				 * while a Zero Length Packet (ZLP) to terminate the transfer is sent if the host isn't listening */
				uint8_t BytesToSend = MIN(BufferCount, (CDC_TXRX_EPSIZE - 1));

				/* Read bytes from the USART receive buffer into the USB IN endpoint */
				while (BytesToSend--)
				{
					/* Try to send the next byte of data to the host, abort if there is an error without dequeuing */
					if (CDC_Device_SendByte(&VirtualSerial_CDC_Interface,
											RingBuffer_Peek(&USARTtoUSB_Buffer)) != ENDPOINT_READYWAIT_NoError)
					{
						break;
					}

					/* Dequeue the already sent byte from the buffer now we have confirmed that no transmission error occurred */
					RingBuffer_Remove(&USARTtoUSB_Buffer);
				}
			}
		}

		/* Load the next byte from the USART transmit buffer into the USART */
		if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer)))
		  Serial_SendByte(RingBuffer_Remove(&USBtoUSART_Buffer));

		CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
		USB_USBTask();
	}
}
Beispiel #2
0
/* Insert multiple items into Ring Buffer */
int RingBuffer_InsertMult(RINGBUFF_T *RingBuff, const void *data, int num)
{
	uint8_t *ptr = RingBuff->data;
	int cnt1, cnt2;

	/* We cannot insert when queue is full */
	if (RingBuffer_IsFull(RingBuff))
		return 0;

	/* Calculate the segment lengths */
	cnt1 = cnt2 = RingBuffer_GetFree(RingBuff);
	if (RB_INDH(RingBuff) + cnt1 >= RingBuff->count)
		cnt1 = RingBuff->count - RB_INDH(RingBuff);
	cnt2 -= cnt1;

	cnt1 = MIN(cnt1, num);
	num -= cnt1;

	cnt2 = MIN(cnt2, num);
	num -= cnt2;

	/* Write segment 1 */
	ptr += RB_INDH(RingBuff) * RingBuff->itemSz;
	memcpy(ptr, data, cnt1 * RingBuff->itemSz);
	RingBuff->head += cnt1;

	/* Write segment 2 */
	ptr = (uint8_t *) RingBuff->data + RB_INDH(RingBuff) * RingBuff->itemSz;
	data = (const uint8_t *) data + cnt1 * RingBuff->itemSz;
	memcpy(ptr, data, cnt2 * RingBuff->itemSz);
	RingBuff->head += cnt2;

	return cnt1 + cnt2;
}
int RingBuffer_Put(RingBuffer *rb, void *element)
{
	int end, retval;

#ifdef RING_BUFFER_THREAD_SAFE
	VOS_SmP(rb->sem, 50);
#endif
	end = (rb->start + rb->count) % rb->size;
	memcpy(rb->buffer + end * rb->element_size, element, rb->element_size);
	if (RingBuffer_IsFull(rb))
	{
		rb->start = (rb->start + 1) % rb->size; /* full, overwrite */
		retval = RING_BUFFER_OVERWRITE;
	}
	else
	{
		++rb->count;
		retval = RING_BUFFER_NORMAL;
	}
#ifdef RING_BUFFER_THREAD_SAFE
	VOS_SmV(rb->sem);
#endif

	return retval;
}
Beispiel #4
0
/** Main program entry point. This routine contains the overall program flow, including initial
 *  setup of all components and the main program loop.
 */
int main(void)
{
	SetupHardware();

	RingBuffer_InitBuffer(&USBtoUSART_Buffer, USBtoUSART_Buffer_Data, sizeof(USBtoUSART_Buffer_Data));
    RingBuffer_InitBuffer(&ToUSB_Buffer, ToUSB_Buffer_Data, sizeof(ToUSB_Buffer_Data));

	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
	sei();

	for (;;)
	{
		/* Only try to read in bytes from the CDC interface if the transmit buffer is not full */
		if (!(RingBuffer_IsFull(&USBtoUSART_Buffer)))
		{
			int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);

			/* Read bytes from the USB OUT endpoint into the USART transmit buffer */
			if (!(ReceivedByte < 0))
			  RingBuffer_Insert(&USBtoUSART_Buffer, ReceivedByte);
		}
		
		/* Load the next byte from the USART transmit buffer into the USART */
		if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer)))
		  Serial_SendByte(RingBuffer_Remove(&USBtoUSART_Buffer));

		cdc_send_USB_data(&VirtualSerial_CDC_Interface);
		USB_USBTask();
	}
}
/** ISR to manage the reception of data from the serial port, placing received bytes into a circular buffer
 *  for later transmission to the host.
 */
ISR(USART1_RX_vect, ISR_BLOCK)
{
	uint8_t ReceivedByte = UDR1;

	if ((USB_DeviceState == DEVICE_STATE_Configured) && !(RingBuffer_IsFull(&USARTtoUSB_Buffer)))
	  RingBuffer_Insert(&USARTtoUSB_Buffer, ReceivedByte);
}
void HandleSerial(void)
{
	// Only try to read in bytes from the CDC interface if the transmit buffer is not full 
	if (!(RingBuffer_IsFull(&FromHost_Buffer)))
	{
		int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
		// Read bytes from the USB OUT endpoint into the USART transmit buffer 
		if (!(ReceivedByte < 0)){
		  	RingBuffer_Insert(&FromHost_Buffer, ReceivedByte);
			CDC_Device_SendByte(&VirtualSerial_CDC_Interface, ReceivedByte);
		}
	}

	while (RingBuffer_GetCount(&FromHost_Buffer) > 0)
	{
		int16_t c = RingBuffer_Remove(&FromHost_Buffer);

		if(c == '\n' || c == '\r'){
			if(cmd_cnt > 0 && (cmd[cmd_cnt-1] == '\n' || cmd[cmd_cnt-1] == '\r'))
				cmd_cnt--;
			cmd[cmd_cnt] = 0;			
			execute_command();
			cmd_cnt = 0;			
		}
		else{
			cmd[cmd_cnt++] = c;			
		}
	}
}
int main(void)
{
	SetupHardware();

	RingBuffer_InitBuffer(&USBtoUSART_Buffer, USBtoUSART_Buffer_Data, sizeof(USBtoUSART_Buffer_Data));
	RingBuffer_InitBuffer(&USARTtoUSB_Buffer, USARTtoUSB_Buffer_Data, sizeof(USARTtoUSB_Buffer_Data));

	LEDs_SetAllLEDs(0);

	sei();

	for (;;)
	{
		if ((PINF & 0x01) == 0x01)
			LEDs_SetAllLEDs(2);
		else
			LEDs_SetAllLEDs(0);
		/* Only try to read in bytes from the CDC interface if the (outbound) transmit buffer is not full */
		if (!(RingBuffer_IsFull(&USBtoUSART_Buffer)))
		{
			int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);

			/* Read bytes from the USB OUT endpoint into the USART transmit buffer */
			if (!(ReceivedByte < 0))
			  RingBuffer_Insert(&USBtoUSART_Buffer, ReceivedByte);
		}

		/* Check if the UART receive buffer flush timer has expired or the buffer is nearly full */
		uint16_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);
		if ((TIFR0 & (1 << TOV0)) || (BufferCount > (uint8_t)(sizeof(USARTtoUSB_Buffer_Data) * .75)))
		{
			/* Clear flush timer expiry flag */
			TIFR0 |= (1 << TOV0);

			/* Read bytes from the USART receive buffer into the USB IN endpoint */
			while (BufferCount--)
			{
				/* Try to send the next byte of data to the host, abort if there is an error without dequeuing */
				if (CDC_Device_SendByte(&VirtualSerial_CDC_Interface,
				                        RingBuffer_Peek(&USARTtoUSB_Buffer)) != ENDPOINT_READYWAIT_NoError)
				{
					break;
				}

				/* Dequeue the already sent byte from the buffer now we have confirmed that no transmission error occurred */
				RingBuffer_Remove(&USARTtoUSB_Buffer);
			}
		}

		/* Load the next byte from the USART transmit buffer into the USART */
		if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer)))
		  Serial_SendByte(RingBuffer_Remove(&USBtoUSART_Buffer));

		CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
		USB_USBTask();
	}
}
/** Main program entry point. This routine contains the overall program flow, including initial
 *  setup of all components and the main program loop.
 */
int main(void)
{
	SetupHardware();

	RingBuffer_InitBuffer(&USBtoUSART_Buffer);
	RingBuffer_InitBuffer(&USARTtoUSB_Buffer);

	sei();

	for (;;)
	{
		/* Only try to read in bytes from the CDC interface if the transmit buffer is not full */
		if (!(RingBuffer_IsFull(&USBtoUSART_Buffer)))
		{
			int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);

			/* Read bytes from the USB OUT endpoint into the USART transmit buffer */
			if (!(ReceivedByte < 0))
			  RingBuffer_Insert(&USBtoUSART_Buffer, ReceivedByte);
		}

		/* Check if the UART receive buffer flush timer has expired or the buffer is nearly full */
		RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);
		if ((TIFR0 & (1 << TOV0)) || (BufferCount > BUFFER_NEARLY_FULL))
		{
			TIFR0 |= (1 << TOV0);

			if (USARTtoUSB_Buffer.Count) {
				LEDs_TurnOnLEDs(LEDMASK_TX);
				PulseMSRemaining.TxLEDPulse = TX_RX_LED_PULSE_MS;
			}

			/* Read bytes from the USART receive buffer into the USB IN endpoint */
			while (BufferCount--)
			  CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&USARTtoUSB_Buffer));

			/* Turn off TX LED(s) once the TX pulse period has elapsed */
			if (PulseMSRemaining.TxLEDPulse && !(--PulseMSRemaining.TxLEDPulse))
			  LEDs_TurnOffLEDs(LEDMASK_TX);

			/* Turn off RX LED(s) once the RX pulse period has elapsed */
			if (PulseMSRemaining.RxLEDPulse && !(--PulseMSRemaining.RxLEDPulse))
			  LEDs_TurnOffLEDs(LEDMASK_RX);
		}

		/* Load the next byte from the USART transmit buffer into the USART */
		if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer))) {
		  Serial_TxByte(RingBuffer_Remove(&USBtoUSART_Buffer));

		  	LEDs_TurnOnLEDs(LEDMASK_RX);
			PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS;
		}

		CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
		USB_USBTask();
	}
}
Beispiel #9
0
/** Main program entry point. This routine contains the overall program flow, including initial
 *  setup of all components and the main program loop.
 */
int main(void)
{
	SetupHardware();

	RingBuffer_InitBuffer(&FromHost_Buffer, FromHost_Buffer_Data, sizeof(FromHost_Buffer_Data));

	GlobalInterruptEnable();

	for (;;)
	{
		/* Only try to read in bytes from the CDC interface if the transmit buffer is not full */
		if (!(RingBuffer_IsFull(&FromHost_Buffer)))
		{
			int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);

			/* Read bytes from the USB OUT endpoint into the USART transmit buffer */
			if (!(ReceivedByte < 0))
			  RingBuffer_Insert(&FromHost_Buffer, ReceivedByte);
		}

		while (RingBuffer_GetCount(&FromHost_Buffer) > 0)
		{
			static uint8_t EscapePending = 0;
			int16_t HD44780Byte = RingBuffer_Remove(&FromHost_Buffer);

			if (HD44780Byte == COMMAND_ESCAPE)
			{
				if (EscapePending)
				{
					HD44780_WriteData(HD44780Byte);
					EscapePending = 0;
				}
				else
				{
					/* Next received character is the command byte */
					EscapePending = 1;
				}
			}
			else
			{
				if (EscapePending)
				{
					HD44780_WriteCommand(HD44780Byte);
					EscapePending = 0;
				}
				else
				{
					HD44780_WriteData(HD44780Byte);
				}
			}
		}

		CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
		USB_USBTask();
	}
}
Beispiel #10
0
/**
 * @remarks: behavior changed to block only when txring buffer is full (prior to return)
 * Guarantees that everything is written (thus retries whenever necessary)
 */
static void uart0_write_internal(const uint8_t* data, size_t size, bool in_rtos) {
	uint32_t written;
	while (size > 0) {
		written = Chip_UART0_SendRB(LPC_USART0, &txring, data, size);
		data += written;
		size -= written;

		if (in_rtos && RingBuffer_IsFull(&txring) && xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
			xSemaphoreTake(sem_uart_ready, portMAX_DELAY);
		}
	}
}
Beispiel #11
0
/* Insert a single item into Ring Buffer */
int RingBuffer_Insert(RINGBUFF_T *RingBuff, const void *data) {
	uint8_t *ptr = RingBuff->data;

	/* We cannot insert when queue is full */
	if (RingBuffer_IsFull(RingBuff))
		return 0;

	ptr += RB_INDH(RingBuff) * RingBuff->itemSz;
	memcpy(ptr, data, RingBuff->itemSz);
	RingBuff->head++;

	return 1;
}
Beispiel #12
0
/* Return empty status of ring buffer */
bool RingBuffer_Insert8(RINGBUFF_T *RingBuff, uint8_t data8)
{
	bool full = RingBuffer_IsFull(RingBuff);

	if (!full) {
		*RingBuff->bufferIn = data8;
		RingBuff->used++;
		RingBuff->bufferIn++;
		if (RingBuff->bufferIn >= RingBuff->bufferLast) {
			RingBuff->bufferIn = RingBuff->bufferBase;
		}
	}

	return (bool) !full;
}
Beispiel #13
0
/** ISR to manage the reception of data from the serial port, placing received bytes into a circular buffer
 *  for later transmission to the host.
 */
ISR(USART1_RX_vect, ISR_BLOCK)
{
    uint8_t ReceivedByte = UDR1;

    if (USB_DeviceState == DEVICE_STATE_Configured && !RingBuffer_IsFull(&USARTtoUSB_Buffer))
        RingBuffer_Insert(&USARTtoUSB_Buffer, ReceivedByte);

    RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);
    if (BufferCount >= (sizeof(joyReport) + 1)) {
          joyReport.X = (int8_t) RingBuffer_Remove(&USARTtoUSB_Buffer);
          joyReport.Y = (int8_t) RingBuffer_Remove(&USARTtoUSB_Buffer);
          joyReport.Button = (uint8_t) RingBuffer_Remove(&USARTtoUSB_Buffer);
          /* Remove spacer at the end of the struct*/
          RingBuffer_Remove(&USARTtoUSB_Buffer);
    }
}
Beispiel #14
0
/* Insert 32-bit value in ring buffer */
bool RingBuffer_Insert32(RINGBUFF_T *RingBuff, uint32_t data32)
{
	bool full = RingBuffer_IsFull(RingBuff);

	if (!full) {
		uint32_t *buff32 = (uint32_t *) RingBuff->bufferIn;
		*buff32 = data32;
		RingBuff->used++;
		buff32++;
		RingBuff->bufferIn = (uint8_t *) buff32;
		if (RingBuff->bufferIn >= RingBuff->bufferLast) {
			RingBuff->bufferIn = RingBuff->bufferBase;
		}
	}

	return (bool) !full;
}
Beispiel #15
0
/* Insert 16-bit value in ring buffer */
bool RingBuffer_Insert16(RINGBUFF_T *RingBuff, uint16_t data16)
{
	bool full = RingBuffer_IsFull(RingBuff);

	if (!full) {
		uint16_t *buff16 = (uint16_t *) RingBuff->bufferIn;
		*buff16 = data16;
		RingBuff->used++;
		buff16++;
		RingBuff->bufferIn = (uint8_t *) buff16;
		if (RingBuff->bufferIn >= RingBuff->bufferLast) {
			RingBuff->bufferIn = RingBuff->bufferBase;
		}
	}

	return (bool) !full;
}
Beispiel #16
0
void UARTBridge_Task(void)
{
	/* Must be in the configured state for the USART Bridge code to process data */
	if (USB_DeviceState != DEVICE_STATE_Configured)
	  return;

	/* Only try to read in bytes from the CDC interface if the transmit buffer is not full */
	if (!(RingBuffer_IsFull(&USBtoUART_Buffer)))
	{
		int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);

		/* Read bytes from the USB OUT endpoint into the UART transmit buffer */
		if (!(ReceivedByte < 0))
		  RingBuffer_Insert(&USBtoUART_Buffer, ReceivedByte);
	}

	/* Check if the UART receive buffer flush timer has expired or buffer is nearly full */
	uint16_t BufferCount = RingBuffer_GetCount(&UARTtoUSB_Buffer);
	if ((TIFR0 & (1 << TOV0)) || (BufferCount > 200))
	{
		/* Clear flush timer expiry flag */
		TIFR0 |= (1 << TOV0);

		/* Read bytes from the USART receive buffer into the USB IN endpoint */
		while (BufferCount--)
		{
			/* Try to send the next byte of data to the host, abort if there is an error without dequeuing */
			if (CDC_Device_SendByte(&VirtualSerial_CDC_Interface,
									RingBuffer_Peek(&UARTtoUSB_Buffer)) != ENDPOINT_READYWAIT_NoError)
			{
				break;
			}

			/* Dequeue the already sent byte from the buffer now we have confirmed that no transmission error occurred */
			RingBuffer_Remove(&UARTtoUSB_Buffer);
		}
	}

	CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
}
/*---------------------------------------------------------------------------*/
int transport_getdata(uint8_t* buf, int count)
{
  int i;
  int t16;
  int8_t res;
  uint8_t sockId;

  while(count > RingBuffer_GetCount(&tcpBuffer))
  {
    res = esp8266_getTCPData(ESP8266_1SecTimeout,commonBuffer,sizeof(commonBuffer),&rv,&sockId);       

    if(res == ESP8266_TIMEOUT)
    {
      return 0;
    }

    if(sockId != 0)
    {
      esp8266_hal_rebootSystem();
    }
    
    for(i=0;i<rv;i++)
    {
      if(!RingBuffer_IsFull(&tcpBuffer))
      {
        RingBuffer_Insert(&tcpBuffer,commonBuffer[i]);        
      }
    }

  }

  for(i=0;i<count;i++)
  {
    buf[i] = RingBuffer_Remove(&tcpBuffer);
  }  

  return count;
}
Beispiel #18
0
void UARTBridge_Task(void)
{
	/* Must be in the configured state for the USART Bridge code to process data */
	if (USB_DeviceState != DEVICE_STATE_Configured)
	  return;

	/* Read bytes from the USB OUT endpoint into the UART transmit buffer */
	int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
	if (!(ReceivedByte < 0) && !(RingBuffer_IsFull(&USBtoUART_Buffer)))
	  RingBuffer_Insert(&USBtoUART_Buffer, ReceivedByte);
	
	/* Check if the UART receive buffer flush timer has expired or buffer is nearly full */
	RingBuff_Count_t BufferCount = RingBuffer_GetCount(&UARTtoUSB_Buffer);
	if ((TIFR0 & (1 << TOV0)) || (BufferCount > 200))
	{
		TIFR0 |= (1 << TOV0);

		/* Read bytes from the UART receive buffer into the USB IN endpoint */
		while (BufferCount--)
		  CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&UARTtoUSB_Buffer));
	}

	CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
}
Beispiel #19
0
int main(void)
{
    SetupHardware();

    RingBuffer_InitBuffer(&RF12toUSB_Buffer, RF12toUSB_Buffer_Data, sizeof(RF12toUSB_Buffer_Data));
    RingBuffer_InitBuffer(&USBtoRF12_Buffer, USBtoRF12_Buffer_Data, sizeof(USBtoRF12_Buffer_Data));
    RingBuffer_InitBuffer(&Transmit_Buffer,  Transmit_Buffer_Data,  sizeof(Transmit_Buffer_Data));

    sei();

    for (;;)
    {
        uint16_t RFM12B_status = RFM12B_SPI_Transfer(0);
        
        if (( RFM12B_status & RFM12B_STATUS_RSSI )
           && !RFM12B_Transmit_Active )
        {
            PORTD &= ~0x40;
        }
        else
        {
            PORTD |= 0x40;
        }
        
        /* Only try to read in bytes from the CDC interface if the transmit buffer is not full */
        if (  !RingBuffer_IsFull( &USBtoRF12_Buffer )
           && !RFM12B_Transmit_Active )
        {
            int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);

            /* Read bytes from the USB OUT endpoint into the USART transmit buffer */
            if (!(ReceivedByte < 0)) 
            {  
               if ( ReceivedByte != END_OF_PACKET )
               {
                   RingBuffer_Insert( &USBtoRF12_Buffer, ReceivedByte );
               }
               else
               {
                   /* TODO : Need to implement LBT */
                   RFM12B_Start_Transmit();
               }
            }
        }

        /* Check to see if there's an RGIT or an FFIT bit set in the status
           register indicating that we need to send or receive a byte */
        if ( RFM12B_status & RFM12B_STATUS_RGIT )
        {
            if ( RFM12B_Transmit_Active )
            {
                RFM12B_Transmit();
            }
            else
            {
                RFM12B_Receive();
            }
        }
        
        /* Check the flush timer.  This is used to timeout incoming packets
           that don't arrive in time or to flush the data to the USB host.
           First, check to see if we are in the middle of receiving a packet */
        if ( RxLength )
        {
            /* A packet is being received. Check the flush timer
               and timeout the packet if it takes too long */
            if ( TIFR0 & _BV(TOV0))
            {
                /* Clear flush timer expiry flag */
                TIFR0 |= _BV(TOV0);

                /* Flush timer overflows every 4ms.  256 bytes at ~50k
                   should take approximately 42ms so we allow 12 counts
                   for overflow.  This should probably be calculated
                   based on the bit rate and max message length */
                if ( ++RxTimeout > 12 )
                {
                    RingBuffer_Insert( &RF12toUSB_Buffer, END_OF_PACKET );
                    RFM12B_SPI_Transfer( 0xCA81 );
                    RFM12B_SPI_Transfer( 0xCA83 );
                    RxLength = 0;
                }
            }
        }
        else
        {
            /* No packet is being received.  Check if the UART receive 
               buffer flush timer has expired or the buffer is nearly full */
            uint16_t BufferCount = RingBuffer_GetCount(&RF12toUSB_Buffer);
            if ((TIFR0 & (1 << TOV0)) || (BufferCount > (uint8_t)(sizeof(RF12toUSB_Buffer_Data) * .75)))
            {
                /* Clear flush timer expiry flag */
                TIFR0 |= _BV(TOV0);
    
                /* Read bytes from the USART receive buffer into the USB IN endpoint */
                while (BufferCount--)
                {
                    /* Try to send the next byte of data to the host, abort if there is an error without dequeuing */
                    if (CDC_Device_SendByte(&VirtualSerial_CDC_Interface,
                                            RingBuffer_Peek(&RF12toUSB_Buffer)) != ENDPOINT_READYWAIT_NoError)
                    {
                        break;
                    }
    
                    /* Dequeue the already sent byte from the buffer now we have confirmed that no transmission error occurred */
                    RingBuffer_Remove(&RF12toUSB_Buffer);
                }
            }
        }
        
        CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
        USB_USBTask();
    }
}
Beispiel #20
0
/** Main program entry point. This routine contains the overall program flow, including initial
 *  setup of all components and the main program loop.
 */
int main(void)
{
	SetupHardware();
	
	RingBuffer_InitBuffer(&USBtoUSART_Buffer);
	RingBuffer_InitBuffer(&USARTtoUSB_Buffer);

    setupEeprom();

	sei();


	for (;;)
	{

		// Only try to read in bytes from the CDC interface if the transmit buffer is not full
		if (!(RingBuffer_IsFull(&USBtoUSART_Buffer)))
		{
			int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);

			// Read bytes from the USB OUT endpoint into the USART transmit buffer
			if (!(ReceivedByte < 0))
			  RingBuffer_Insert(&USBtoUSART_Buffer, ReceivedByte);
		}
		
		// Check if the UART receive buffer flush timer has expired or the buffer is nearly full
		RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);
		if ((TIFR0 & (1 << TOV0)) || (BufferCount > BUFFER_NEARLY_FULL))
		{
			TIFR0 |= (1 << TOV0);

			if (USARTtoUSB_Buffer.Count) {
				LEDs_TurnOnLEDs(LEDMASK_TX);
				PulseMSRemaining.TxLEDPulse = TX_RX_LED_PULSE_MS;
			}

			// Read bytes from the USART receive buffer into the USB IN endpoint
			while (BufferCount--)
			  CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&USARTtoUSB_Buffer));
			  
			// Turn off TX LED(s) once the TX pulse period has elapsed
			if (PulseMSRemaining.TxLEDPulse && !(--PulseMSRemaining.TxLEDPulse))
			  LEDs_TurnOffLEDs(LEDMASK_TX);

			// Turn off RX LED(s) once the RX pulse period has elapsed
			if (PulseMSRemaining.RxLEDPulse && !(--PulseMSRemaining.RxLEDPulse))
			  LEDs_TurnOffLEDs(LEDMASK_RX);

			if (ResetTimer > 0)
			{
				// SAM3X RESET/ERASE Sequence
				// --------------------------
				if (ResetTimer == 95) {
                    eepromInterruptDisable();
					setErasePin(true);
					setResetPin(false);
				}
				if (ResetTimer == 35) {
                    eepromInterruptDisable();
					setErasePin(false);
					setResetPin(false);
				}
				if (ResetTimer == 25) {
                    eepromInterruptDisable();
					setErasePin(false);
					setResetPin(true);
				}
				if (ResetTimer == 1) {
                    eepromInterruptDisable();
					setErasePin(false);
					setResetPin(false);
				}
				ResetTimer--;
			} else {
				setErasePin(false);
				setResetPin(false);
                eepromInterruptEnable();
			}
		}
		
		// Load the next byte from the USART transmit buffer into the USART
		if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer))) {
			Serial_TxByte(RingBuffer_Remove(&USBtoUSART_Buffer));
			LEDs_TurnOnLEDs(LEDMASK_RX);
			PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS;
		}

        // CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
        // USB_USBTask();
        serviceEepromRequest();
		CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
		USB_USBTask();
	}

}