Beispiel #1
0
/**
 * @brief Run in slave mode accepting and processing commands.
 */
void Transfer_Slave(void) {
  uint8_t checksum;
  TRANSFER_OPCODE opcode;
  
  while (1) {
    opcode = (TRANSFER_OPCODE)USB_Receive();
    checksum = USB_Receive();
    if ((checksum+opcode) != 0xFF) {
      USB_Send(TRANSFER_NAK);
      continue;
    }
    USB_Send(TRANSFER_ACK);

    switch(opcode) {
    case RCV_APP:
      Cmd_RCV_APP();
      break;
	  case DEL_APP:
      Cmd_DEL_APP();
      break;
	  case LST_APPS:
      Cmd_LST_APPS();
      break;
	  case RUN_APP:
      Cmd_RUN_APP();
      break;
    }
  }
}
Beispiel #2
0
void UartSendData(uint8_t port) {
  #if defined(PROMINI)
    UCSR0B |= (1<<UDRIE0);
  #endif
  #if defined(PROMICRO)
    switch (port) {
      case 0:
        while(serialHeadTX[0] != serialTailTX[0]) {
           if (++serialTailTX[0] >= TX_BUFFER_SIZE) serialTailTX[0] = 0;
           #if !defined(TEENSY20)
             USB_Send(USB_CDC_TX,serialBufferTX[serialTailTX[0]],1);
           #else
             Serial.write(serialBufferTX[serialTailTX[0]],1);
           #endif
         }
        break;
      case 1: UCSR1B |= (1<<UDRIE1); break;
    }
  #endif
  #if defined(MEGA)
    switch (port) {
      case 0: UCSR0B |= (1<<UDRIE0); break;
      case 1: UCSR1B |= (1<<UDRIE1); break;
      case 2: UCSR2B |= (1<<UDRIE2); break;
      case 3: UCSR3B |= (1<<UDRIE3); break;
    }
  #endif
}
Beispiel #3
0
/**
 * @brief Receives an app. id from a sender and removes it from the fs.
 * @retval TRANSFER_OK if the receive and delete succeed.
 *         -TRANSFER_CMD_FAIL if the receive or delete fail.
 */
TRANSFER_STATUS Cmd_DEL_APP(void) {
uint8_t checksum, id;
  /*** Receive file id ***/
  id = USB_Receive();
  checksum = id;
  checksum += USB_Receive();
  if(checksum != 0xFF 
     || id >= FS_GetNumFiles()
     || FS_DeleteFile(id) != FS_OK) {
    USB_Send(TRANSFER_NAK);
    return TRANSFER_CMD_FAIL;
  }
  USB_Send(TRANSFER_ACK);  

  return TRANSFER_OK;
}
Beispiel #4
0
int USBLink::send(const uint8_t *data, uint32_t len, uint16_t timeoutMs)
{
	uint32_t time, start, timeout = timeoutMs * CLKFREQ_MS;

 	if (!USB_handleState())
	{
		g_sendComplete = 0;
		return -1;
	}

	USB_Send(data, len);
	while(1)
	{
		start = g_sendTimerStart; // avoid race condition with usb interrupt routine-- sample here 
		time = LPC_TIMER1->TC; // time is guaranteed to be more recent than start
		if ((uint32_t)(time-start) > timeout || g_sendComplete)
			break;
	}
  	if (g_sendComplete)
		return len;
	else
	{
		USB_SendReset();
		return LINK_RESULT_ERROR_SEND_TIMEOUT;
	}
}
Beispiel #5
0
/**
	* @brief Send back data received over USB
	*/
void usbCommLoopBack(void)
{ 		
		if(USB_GetTxSize() > 0)
		{
			USB_Send( USB_Receive() );
		}
}
Beispiel #6
0
// After each rule is processed, send network packets for each changed rule and reset changeflag
void sendChangedRules(void)
{
	for(ruleNum_t rule = 0; rule < ARRAY_SIZE(ruleData); rule++)
	{
		if(ruleState[rule].ok >= ruleChanged)
		{
UDP_Port_t port = ruleData[rule].networkPort ? : rule;
			if(ruleData[rule].type >= 0 /*&& ruleData[rule].networkPort*/)
			{
				Packet_t sendPacket;
				if(USB_isReady() && USB_prepareTS(&sendPacket))
				{
					sendPacket.len = UDP_GenerateBroadcast(sendPacket.data, /*ruleData[rule].networkPort*/ port, sizeof(ruleValue_t));
					ruleValue_t *packetValue = (ruleValue_t *)(sendPacket.data + sendPacket.len);
					*packetValue = ruleState[rule].value;

					sendPacket.len += sizeof(ruleValue_t);
					USB_Send(sendPacket);

					ruleState[rule].ok = ruleOK;
				}
				// else: could not send packet, try again next round
			} else {
				ruleState[rule].ok = ruleSendLater;
			}
		}
	}
Beispiel #7
0
int
CDC::write(const void* buf, size_t size)
{
  if ((_usbLineInfo.lineState & 0x01) &&
      (USB_Send(CDC_TX, buf, size) != (int) size))
    return (IOStream::EOF);

  return (size);
}
Beispiel #8
0
void Joystick_::ReportState()
{
	uint8_t data[joyBytes];
	
	memcpy(data, &buttons, 2);	
	memcpy(data+2, axes, 5);	

	USB_Send(HID_TX | TRANSFER_RELEASE,data,joyBytes);
}
Beispiel #9
0
size_t UsbMidiModule::_write(uint8_t c)
{
	midi_event_t midiEvent;
	if (m_midiToUsb.process(c, midiEvent))
	{
		USB_Send(getInEndpointId(), &midiEvent, sizeof(midiEvent));
	}

	return 1;
}
Beispiel #10
0
void UsbMidiModule::_sendUSB(u8 midiUsbEvent, u8 data1, u8 data2, u8 data3)
{
	u8 packet[4];
	packet[0] = midiUsbEvent;
	packet[1] = data1;
	packet[2] = data2;
	packet[3] = data3;

	USB_Send(getInEndpointId(), packet, sizeof(packet));
}
Beispiel #11
0
//force a write without bothering to check if the serial port is open
size_t Serial_::WRITE(uint8_t c)
{
    int r = USB_Send(CDC_TX,&c,1);
    if (r > 0) {
        return r;
    } else {
        setWriteError(2);
        return 0;
    }
}
Beispiel #12
0
/**
 * @brief Receives an app. id, retrieves it from the fs, and runs the app.
 * @retval Doesn't return on success. -TRANSFER_CMD_FAIL on failure.
 */
TRANSFER_STATUS Cmd_RUN_APP(void) {
  uint8_t checksum, id;
  
  /*** Receive file id ***/
  id = USB_Receive();
  checksum = id;
  checksum += USB_Receive();
  if(checksum != 0xFF 
     || id >= FS_GetNumFiles()) {
    USB_Send(TRANSFER_NAK);
    return TRANSFER_CMD_FAIL;
  }
  USB_Send(TRANSFER_ACK);  
  
  //Run the application in the file
  FS_RunFile(id);
  
  return TRANSFER_CMD_FAIL; //Shouldn't ever get here.
}
Beispiel #13
0
/**
 * @brief Sends a command with headers for all the applications in the fs.
 * @retval TRANSFER_OK if the send succeeds.
 *         -TRANSFER_CMD_FAIL if the send fails.
 */
TRANSFER_STATUS Cmd_LST_APPS(void) {
  uint8_t checksum, numFiles, i, j;
  FS_File *file;
  /*** Send number of files in FS ***/
  numFiles = FS_GetNumFiles();
  checksum = 0xFF - numFiles;
  USB_Send(numFiles);
  USB_Send(checksum);
  if (USB_Receive() == TRANSFER_NAK)
    return TRANSFER_CMD_FAIL;
  /*** Send files 1 at a time ***/
  for (i = 0; i < numFiles; i++) {
    file = FS_GetFile(i);
    checksum = 0;
    USB_Send(file->id);
    checksum += file->id;
    for (j = 0; j < FS_FILE_MAX_NAME_LEN; j++) {
      USB_Send(file->name[j]);
      checksum += file->name[j];      
    }
    checksum += file->numPages;    
    USB_Send(file->numPages);
    USB_Send(0xFF-checksum);
    
    if (USB_Receive() != TRANSFER_ACK)
      return TRANSFER_CMD_FAIL;
  }
  
  return TRANSFER_OK;
}
Beispiel #14
0
size_t MIDIUSB_::write(MIDIEvent c)
{
    // TODO: only try to send bytes if the connection is open
    if(USB_Ready(MIDI_TX)) {
        int r = USB_Send(MIDI_TX,&c,4);
        if (r > 0) {
            return r;
        } else {
            return 0;
        }
    } else {
        return 0;
    }
}
size_t Serial_::write(const uint8_t *buffer, size_t size)
{
  /* only try to send bytes if the high-level CDC connection itself
   is open (not just the pipe) - the OS should set _cdcLineState when the port
   is opened and clear _cdcLineState when the port is closed.
   bytes sent before the user opens the connection or after
   the connection is closed are lost - just like with a UART. */

  // NOTE:  if my outgoing buffer is too full, stop sending

  // TODO - ZE - check behavior on different OSes and test what happens if an
  // open connection isn't broken cleanly (cable is yanked out, host dies
  // or locks up, or host virtual serial port hangs)

  if(USBDevice.configured() && // make sure I'm running
//     !USB_IsStalled(CDC_TX) && // make sure I'm not stalled
     !USB_IsSendQFull(CDC_TX)) // make sure I'm not flooding the queue
  {  
    if(_cdcLineState & CONTROL_LINE_STATE_DTR) // make sure DTR is set
    {
      if(size > 128)
      {
        size = 128; // adjust size DOWN to limit output buffer size
      }

      int r = USB_Send(CDC_TX, buffer, size, 1);

      // TODO:  check for partial sends and retry??

      if(r > 0)
      {
        CDC_FrameReceived(); // inform the host of my data send/receive state

        return r;
      }
    }
  }

  // TODO:  block?

  setWriteError();
  return 0;
}
Beispiel #16
0
size_t Serial_::write(uint8_t c)
{
	/* only try to send bytes if the high-level CDC connection itself 
	 is open (not just the pipe) - the OS should set lineState when the port
	 is opened and clear lineState when the port is closed.
	 bytes sent before the user opens the connection or after
	 the connection is closed are lost - just like with a UART. */
	
	// TODO - ZE - check behavior on different OSes and test what happens if an
	// open connection isn't broken cleanly (cable is yanked out, host dies
	// or locks up, or host virtual serial port hangs)
	if (_usbLineInfo.lineState > 0)	{
		int r = USB_Send(CDC_TX,&c,1);
		if (r > 0) {
			return r;
		} else {
			setWriteError();
			return 0;
		}
	}
	setWriteError();
	return 0;
}
Beispiel #17
0
void SingleAbsoluteMouse_::SendReport(void* data, int length)
{
	USB_Send(pluggedEndpoint | TRANSFER_RELEASE, data, length);
}
Beispiel #18
0
void WEAK HID_SendReport(u8 id, const void* data, int len)
{
	USB_Send(HID_TX, &id, 1);
	USB_Send(HID_TX | TRANSFER_RELEASE,data,len);
}
Beispiel #19
0
void SingleConsumer_::SendReport(void* data, int length)
{
	USB_Send(pluggedEndpoint | TRANSFER_RELEASE, data, length);
}
Beispiel #20
0
/**
	*	@brief	Send character via USB
	* 			
	* @param 	c		Char to send  
	* @return Void
	*/
void usbCommSendChar( uint8_t c )
{ 		
	USB_Send( c );
}
Beispiel #21
0
void HID_::SendReport(uint8_t id, const void* data, int len)
{
	USB_Send(pluggedEndpoint, &id, 1);
	USB_Send(pluggedEndpoint | TRANSFER_RELEASE, data, len);
}
Beispiel #22
0
/**
 * @brief Sends len bytes over USB. A wrapper around USART
 * @param data a pointer to the buffer of data to
 * @param len number of bytes to send from the buffer
 * @retval None.
 */
void USB_SendData(uint8_t *data, uint32_t len) {
  while(len--)
    USB_Send(*data++);
}
Beispiel #23
0
/**
 * @brief Receives an application from a sender and stores it in the fs.
 * @retval TRANSFER_OK if the receive and application store succeed.
 *         -TRANSFER_CMD_FAIL if the receive or store fail.
 */
TRANSFER_STATUS Cmd_RCV_APP(void) {
  uint8_t checksum, name_len, id, numPages, *page;
  uint16_t i, j;
  char name[FS_FILE_MAX_NAME_LEN];  
  uint32_t size, remaining, read_amt;    
  /*** Get # of characters in filename ***/
  checksum = 0;
  name_len = USB_Receive();
  checksum = USB_Receive();
  if((checksum+name_len) != 0xFF || name_len > FS_FILE_MAX_NAME_LEN-1) {
    USB_Send(TRANSFER_NAK);
    return TRANSFER_CMD_FAIL;
  }
  USB_Send(TRANSFER_ACK);
  /*** Get filename ***/
  checksum = 0;
  for(i = 0; i < name_len; i++) {
    name[i] = USB_Receive();
    checksum += name[i];
  }
  name[i] = '\0';
  checksum += USB_Receive();
  if(checksum != 0xFF) {
    USB_Send(TRANSFER_NAK);
    return TRANSFER_CMD_FAIL;
  }
  USB_Send(TRANSFER_ACK);
     
  /*** Get file size in pages ***/
  checksum = 0;
  size = USB_Receive() 
       | (USB_Receive() << 8)
       | (USB_Receive() << 16)
       | (USB_Receive() << 24);
  checksum += size & 0xFF;
  checksum += (size >> 8) & 0xFF;
  checksum += (size >> 16) & 0xFF;
  checksum += (size >> 24) & 0xFF;
  checksum += USB_Receive();
  
  numPages = FS_RoundPageUp(size); 
  id = FS_CreateFile(name, numPages);
  if (checksum != 0xFF || id == FS_MAX_FILES) {
    USB_Send(TRANSFER_NAK);
    return TRANSFER_CMD_FAIL;
  }
  USB_Send(TRANSFER_ACK);
  
  /*** Receive pages 1 at a time ***/
  remaining = size;  
  page = (uint8_t *)malloc(PAGE_SIZE);  
  for(i = 0; i < numPages; i++) {
    memset(page, 0, PAGE_SIZE); //Zero for funs
    checksum = 0;
    if(remaining < PAGE_SIZE)
      read_amt = remaining; //Don't read too much on the last page
    else
      read_amt = PAGE_SIZE; 
    for(j = 0; j < read_amt; j++) {
      page[j] = USB_Receive();
      checksum += page[j];
    }
    checksum += USB_Receive();
    FS_WriteFilePage(id, (uint32_t *)page, i);
    if (checksum != 0xFF || id == FS_MAX_FILES) {
      USB_Send(TRANSFER_NAK);
      FS_DeleteFile(id);
      free(page);
      return TRANSFER_CMD_FAIL;
    }
    USB_Send(TRANSFER_ACK);        
    remaining -= PAGE_SIZE;
  }
  free(page);
  return TRANSFER_OK;
}
void CDC_SendACM(void)
{
  USB_Send(CDC_ACM, &_cdcSerialState, sizeof(_cdcSerialState), 1);
}
Beispiel #25
0
/** \brief Transmit data to UART
 */
void data_transmit(uint8_t *s, uint8_t len) {
	USB_Send(s,len);
}
Beispiel #26
0
void checkRules(void)
{
//TODO: Hack!
	ruleState[0].ok = ruleOK;
	time_t now = time(NULL);

	for(ruleNum_t rule = 0; rule < ARRAY_SIZE(ruleData); rule++)
	{
		bool dependChanged = false;

		// Check if dependency is in state unknown or changed its value
		if(checkDependency(ruleData[rule].dependIndex, &dependChanged))
 		{
			// If the dependency is unknown, we can't proceed
			ruleState[rule].ok = ruleUnknown;
			continue;
		}

		// For ptLogic type we need to check more dependencies for unknown and changed values.
		if(ruleData[rule].type == ptLogic)
		{
			if(checkDependency(ruleData[rule].data.logic.second, &dependChanged) ||
			   checkDependency(ruleData[rule].data.logic.third, &dependChanged) ||
			   checkDependency(ruleData[rule].data.logic.fourth, &dependChanged))
			{
				// If a dependency is unknown, we can't proceed
				ruleState[rule].ok = ruleUnknown;
				continue;
	                }
		}

		// If we depend on a rule which didn't change in this run and our timer has not expired, skip this rule
		if(!dependChanged && now < ruleState[rule].timer)
			continue;

		// Start with the dependency rule value as resulting rule value
		ruleValue_t ruleValue = ruleState[ruleData[rule].dependIndex].value;
		// Reset State of this rule, but keep Flag ruleSendLater
		if(ruleState[rule].ok != ruleSendLater)
			ruleState[rule].ok = ruleOK;

		switch(ruleData[rule].type)
		{
			case ptLogic:
			{
				LogicType_t logictype = ruleData[rule].data.logic.type;
				ruleValue_t dependValueB = ruleState[ruleData[rule].data.logic.second].value;
				ruleValue_t dependValueC = ruleState[ruleData[rule].data.logic.third].value;
				ruleValue_t dependValueD = ruleState[ruleData[rule].data.logic.fourth].value;

				if((logictype & LogicINV_A) == LogicINV_A)
					ruleValue = ~ruleValue;
				if((logictype & LogicINV_B) == LogicINV_B)
					dependValueB = ~dependValueB;
				if((logictype & LogicINV_C) == LogicINV_C)
					dependValueC = ~dependValueC;
				if((logictype & LogicINV_D) == LogicINV_D)
					dependValueD = ~dependValueD;

				ruleValue_t Q1, Q2;
				if((logictype & LogicXOR) == LogicXOR)
				{
					Q1 = ruleValue ^ dependValueB;
					Q2 = dependValueC ^ dependValueD;
				} else {
					Q1 = ruleValue | dependValueB;
					Q2 = dependValueC | dependValueD;
				}
				if((logictype & LogicINV_Q1) == LogicINV_Q1)
					Q1 = ~Q1;
				if((logictype & LogicINV_Q2) == LogicINV_Q2)
					Q2 = ~Q2;
				if((logictype & LogicXOR) == LogicXOR)
					ruleValue = Q1 ^ Q2;
				else
					ruleValue = Q1 | Q2;

				if((logictype & LogicINV_Q) == LogicINV_Q)
					ruleValue = ~ruleValue;

				ruleState[rule].timer = timerOff;
			} break;

			case ptRelay:
			{
//TODO: Irgendwo muss DDR auch gesetzt werden
				if(ruleValue)
					*ruleData[rule].data.hw.port |= ruleData[rule].data.hw.bitValue;
				else
					*ruleData[rule].data.hw.port &= ~ruleData[rule].data.hw.bitValue;
				// Force a delay between each switching relay
				_delay_ms(50);

				ruleState[rule].timer = timerOff;
			} break;

			case ptTimeSwitch:
			{
				struct tm *tm = getStructTM(now);

				if((ruleData[rule].data.time.wdays & _BV(tm->tm_wday)) == 0)
				{
					ruleValue = 0;
					ruleState[rule].timer = getMidnight(tm);
					break;
				}

				time_t starttime = calculateTimestamp(tm, ruleData[rule].data.time.starthour, ruleData[rule].data.time.startmin);
				if(now < starttime)
				{
					ruleValue = 0;
					ruleState[rule].timer = starttime;
				} else {
					// Optimization: Remove countdown or calculate only one time (not every second)
	                                time_t stoptime = calculateTimestamp(tm, ruleData[rule].data.time.stophour, ruleData[rule].data.time.stopmin);
					if(now < stoptime)
					{
						ruleValue = stoptime - now;
					//TODO: Make Update-Interval configurable
						ruleState[rule].timer = now + 1;
					} else {
						ruleValue = 0;
						ruleState[rule].timer = getMidnight(tm);
					}
				}
			} break;

			case ptTrigger:
			{
				TriggerType_t triggertype = ruleData[rule].data.trigger.type;

				if(dependChanged && (((triggertype & TriggerMonoflopRetrigger) == TriggerMonoflopRetrigger) || ruleState[rule].timer == timerOff))
				{
					if((((triggertype & TriggerRising) == TriggerRising) && ruleValue) ||
					   (((triggertype & TriggerFalling) == TriggerFalling) && !ruleValue))
					{
						//TODO: Implement countdown?
						ruleValue = true;
						ruleState[rule].timer = now + (ruleData[rule].data.trigger.hour * (uint16_t)60 + ruleData[rule].data.trigger.min) * (uint32_t)60 + ruleData[rule].data.trigger.sec;
					} else {
						ruleValue = false;
					}
				}
				else if(ruleState[rule].timer != timerOff)
				{
					if(now < ruleState[rule].timer)
					{	// Stay on even if dependency switched off
						ruleValue = true;
					} else {
						ruleValue = false;
						ruleState[rule].timer = timerOff;
					}
				}
			} break;

			case ptSNTP:
			case ptRemote:
			{
				Packet_t sendPacket;
				// Check if USB Queue is free
				if(USB_isReady() && USB_prepareTS(&sendPacket))
				{
					int8_t length;
					const IP_Address_t ipCopy = ruleData[rule].data.IP;
					if(ruleData[rule].type == ptSNTP)
					{
						length = SNTP_GenerateRequest(sendPacket.data, &ipCopy, ruleData[rule].networkPort);
					} else { // ptRemote: Send Packet with empty body
						length = UDP_GenerateUnicast(sendPacket.data, &ipCopy, ruleData[rule].networkPort, sizeof(ruleValue_t));
						if(length > 0)
						{
							ruleValue_t *packetValue = (ruleValue_t *)(sendPacket.data + length);
							*packetValue = 0;
							length += sizeof(ruleValue_t);
						}
					}

					if(length > 0)
					{
						sendPacket.len = length;
						ruleState[rule].timer = now + 2;	// Timeout 2s in case of no answer;
					} else {
						sendPacket.len = -length;
						ruleState[rule].timer =  now + 1;	// Timeout 1s in case of missing ARP entry
					}
					USB_Send(sendPacket);
				}
				ruleState[rule].ok = ruleUnknown;
			} break;

			default:
			{
				ruleState[rule].ok = ruleUnknown;
				ruleState[rule].timer = timerOff;
			} break;
		}

		if(ruleState[rule].ok == ruleUnknown)
			continue;

		// Did the result of our rule change? Then set changeflag
		if(ruleState[rule].value != ruleValue)
		{
			ruleState[rule].value = ruleValue;
			ruleState[rule].ok = ruleChanged;
		}
	}
}