void usb_eth_tx(uint8_t ep, uint8_t stat) { int len; int i; if (!packet_pending || bytes_to_send == 0) { ETH_DEV_DBG_INFO("usb_eth_tx, send buffer is empty, packet_pending=%d", packet_pending); usbEnableNAKInterrupts(0); return; } len = MIN(bytes_to_send - bytes_sent, MAX_PACKET_SIZE); usbWrite(ep, ((uint8_t*) &send_buffer)+bytes_sent, len); bytes_sent += len; ETH_DEV_DBG_INFO("usb_eth_tx: send %d bytes, frame data sent %d/%d", len, bytes_sent, bytes_to_send); if (bytes_sent >= bytes_to_send) { /* finished sending data */ for (i=0; i< bytes_to_send;i++) { send_buffer[i] = 0; } bytes_to_send = 0; bytes_sent = 0; packet_pending = 0; } }
cell pawn_usbWrite( AMX * amx, const cell * params ) { (void)amx; int length; amx_StrLen( (cell*)params[1], &length ); #define STR_LEN 32 static char stri[ STR_LEN ]; amx_GetString( stri, (cell *)params[1], 0, length ); stri[ STR_LEN-1 ] = '\0'; usbWrite( stri ); return 0; }
static void vcomBulkIn(uint8_t EP, uint8_t EPStatus) { int i; if (fifoAvailable(&txfifo) == 0) { usbEnableNAKInterrupts(0); return; } for (i = 0; i < MAX_PACKET_SIZE; i++) if (!fifoGet(&txfifo, &_vcom_buffer[i])) break; if (i > 0) usbWrite(EP, _vcom_buffer, i); }
void usb_rndis_notification(uint8_t ep, uint8_t stat) { if (stat & EP_STATUS_DATA) return; /* next buffer is full, wait */ if (rndisResponseReady) { //ETH_DEV_DBG_INFO("rndis notification: Yes! status=%02x\n",stat); usbWrite(ep, rndisResponseAvailable, 8); } else { //ETH_DEV_DBG_INFO("rndis notification: no... status=%02x\n",stat); } eth_nak_interrupts &= ~INACK_II; usbEnableNAKInterrupts(eth_nak_interrupts); //usbEnableNAKInterrupts(0); return; }
void usbTest(void) { char TestString[] = "This is a functionality test of the USB driver\0"; int i = 0; for (i = 0; i < sizeof(TestString); i++) { usbWrite(TestString[i]); } printf("USB Done\0"); }
PacketUsbCdc::Status PacketUsbCdc::sendPacket( char* packet, int length ) { if( exit == true ) return PacketInterface::IO_ERROR; QByteArray outgoingPacket; outgoingPacket.append( END ); // Flush out any spurious data that may have accumulated int size = length; while( size-- ) { switch(*packet) { // if it's the same code as an END character, we send a special //two character code so as not to make the receiver think we sent an END case END: outgoingPacket.append( ESC ); outgoingPacket.append( ESC_END ); break; // if it's the same code as an ESC character, we send a special //two character code so as not to make the receiver think we sent an ESC case ESC: outgoingPacket.append( ESC ); outgoingPacket.append( ESC_ESC ); break; //otherwise, just send the character default: outgoingPacket.append( *packet ); } packet++; } // tell the receiver that we're done sending the packet outgoingPacket.append( END ); if( UsbSerial::OK != usbWrite( outgoingPacket.data( ), outgoingPacket.size( ) ) ) { monitor->deviceRemoved( QString(portName) ); // shut ourselves down return PacketInterface::IO_ERROR; } else return PacketInterface::OK; }
void usb_cdc_ecm_tx(uint8_t ep, uint8_t stat) { int len; int i; //printf(" cdc_ecm tx "); if (!stat & EP_STATUS_NACKED) { DBG("tx endpoint interrupt, but not NAK"); return; } if (!packet_pending || bytes_to_send == 0) { ETH_DEV_DBG_INFO("usb_eth_tx, send buffer is empty, packet_pending=%d", packet_pending); eth_nak_interrupts &= ~INACK_BI; usbEnableNAKInterrupts(eth_nak_interrupts); return; } len = MIN(bytes_to_send - bytes_sent, MAX_PACKET_SIZE); usbWrite(ep, ((uint8_t*) &send_buffer)+bytes_sent, len); bytes_sent += len; if (bytes_sent >= bytes_to_send /* we sent all the data */ && len < MAX_PACKET_SIZE) /* and we don't need to send a zero-length termination packet */ { /* finished sending data */ rndisTxPackets++; bytes_to_send = 0; bytes_sent = 0; packet_pending = 0; //eth_nak_interrupts &= ~INACK_BI; //usbEnableNAKInterrupts(eth_nak_interrupts); } }
static void sendResponse(Packet_t* packet) { static uint8_t packetBuffer[MAX_PACKET_SIZE]; Packet_t* outPacket = (Packet_t*)packetBuffer; uint8_t packetType = packet->header.msgType >> 1; uint32_t idx; outPacket->header.startByte[0] = START_BYTE_1; outPacket->header.startByte[1] = START_BYTE_2; outPacket->header.CRC8 = 0xCC; outPacket->header.msgType = packet->header.msgType | 1; outPacket->header.seqNumber = packet->header.seqNumber; outPacket->header.packetLen = response[packetType].responseDataLen + sizeof(PacketHeader_t); for (idx = 0; idx < response[packetType].responseDataLen; idx++) { outPacket->data[idx] = response[packetType].responseData[idx]; } //outPacket->header.CRC8 = crc8(outPacket, outPacket->header.packetLen); usbWrite(packetBuffer, outPacket->header.packetLen); }
static void usb_cdc_ecm_tx(uint8_t ep, uint8_t stat) { int len; // Not a NAK interrupt - irrelevant //if (!stat & EP_STATUS_NACKED) { // return; //} // if nothing to send anymore - disable NAK interrupts if (send_ring.size == 0) { eth_nak_interrupts &= ~INACK_BI; usbEnableNAKInterrupts(eth_nak_interrupts); return; } if (stat & EP_STATUS_DATA) { return; } // get first buffer from the ring and send it starting from current point volatile usb_buffer_t* buffer = &send_ring.buffers[send_ring.begin]; // calculate how much bytes are left and limit it with maximal USB packet size len = MIN(buffer->length - buffer->current, MAX_USB_PACKET_SIZE); // send the bytes and update current position inside the buffer usbWrite(ep, buffer->data + buffer->current, len); buffer->current += len; // in case we finished sending the current buffer, // check whether the sent USB packet was shorter than maximal - that's how // we notify the host about end of frame. // If so, free the buffer from the ring (host is already notified) // Otherwise do nothing, so the next time zero length packet will be sent. if (buffer->length == buffer->current && len < MAX_USB_PACKET_SIZE) { usbring_free_buffer(&send_ring); } }
int32_t usbWriteByte(uint8_t data) { return usbWrite(&data, 1); }
/**************************************************************************** Function : hexWrite Description : Writes (and optionally verifies) currently-open hex file to UBW32 device. Parameters : char Verify (1) vs. write (0). Returns : ErrorCode ERR_NONE on success, else various other values as defined in ubw32.h. Notes : UBW32 device and hex file are both assumed already open and valid; no checks performed here. ****************************************************************************/ ErrorCode hexWrite(const char verify) { char *ptr,pass; ErrorCode status; int checksum,i,end,offset; short bufLen; unsigned int len,type,addrHi,addrLo,addr32,addrSave; for(pass=0;pass<=verify;pass++) { offset = 0; /* Start at beginning of hex file */ bufLen = 0; /* Hex buffer initially empty */ addrHi = 0; /* Initial address high bits */ addrSave = 0; /* PIC start addr for hex buffer contents */ addr32 = 0; if(pass) (void)printf("\nVerifying:"); for(;;) { /* Each line in file */ /* Line start contains length, 16-bit address and type */ if(3 != sscanf(&hexFileData[offset],":%02x%04x%02x", &len,&addrLo,&type)) return ERR_HEX_SYNTAX; /* Position of %02x checksum at end of line */ end = offset + 9 + len * 2; /* Verify checksum on first (write) pass */ if(!pass) { for(checksum = 0,i = offset + 1;i < end; checksum = (checksum + (0x100 - atoh(i))) & 0xff,i += 2); if(atoh(end) != checksum) return ERR_HEX_CHECKSUM; } /* Process different hex record types. Using if/else rather than a switch in order to better handle EOF cases (allows simple 'break' rather than goto or other nasties). */ if(0 == type) { /* Data record */ /* If new record address is not contiguous with prior record, issue accumulated hex data (if any) and start anew. */ if((addrHi + addrLo) != addr32) { addr32 = addrHi + addrLo; if(bufLen) { if(ERR_NONE != (status = issueBlock(addrSave,bufLen,pass))) return status; bufLen = 0; } addrSave = addr32; } /* Parse bytes from line into hexBuf */ for(i = offset + 9;i < end;i += 2) { hexBuf[bufLen++] = atoh(i); /* Add to hex buffer */ /* If buffer is full, issue block and start anew */ if(sizeof(hexBuf) == bufLen) { if(ERR_NONE != (status = issueBlock(addrSave,bufLen,pass))) return status; bufLen = 0; } /* Increment address, wraparound as per hexfile spec */ if(0xffffffff == addr32) { /* Wraparound. If any hex data, issue and start anew. */ if(bufLen) { if(ERR_NONE != (status = issueBlock(addrSave,bufLen,pass))) return status; bufLen = 0; } addr32 = 0; } else { addr32++; } /* If issueBlock() used, save new address for next block */ if(!bufLen) addrSave = addr32; } } else if(1 == type) { /* EOF record */ break; } else if(4 == type) { /* Extended linear address record */ if(1 != sscanf(&hexFileData[offset+9],"%04x",&addrHi)) return ERR_HEX_SYNTAX; addrHi <<= 16; addr32 = addrHi + addrLo; /* Assume this means a noncontiguous address jump; issue block and start anew. The prior noncontiguous address code should already have this covered, but in the freak case of an extended address record with no subsequent data, make sure the last of the data is issued. */ if(bufLen) { if(ERR_NONE != (status = issueBlock(addrSave,bufLen,pass))) return status; bufLen = 0; addrSave = addr32; } } else { /* Unsupported record type */ return ERR_HEX_RECORD; } /* Advance to start of next line (skip CR/LF/etc.), unless EOF */ if(NULL == (ptr = strchr(&hexFileData[end+2],':'))) break; offset = ptr - hexFileData; } /* At end of file, issue any residual data (counters reset at top) */ if(bufLen && (ERR_NONE != (status = issueBlock(addrSave,bufLen,pass)))) return status; /* Make sure last data is flushed (issueBlock() does this automatically if less than 56 bytes...but if the last packet is exactly this size, an explicit flush is done here). */ if(!pass && (bufLen == 56)) { DEBUGMSG("Completing"); usbBuf[0] = PROGRAM_COMPLETE; if(ERR_NONE != (status = usbWrite(1,0))) return status; } #ifdef DEBUG (void)printf("PASS %d of %d COMPLETE\n",pass,verify); #endif } return ERR_NONE; }
/**************************************************************************** Function : issueBlock Description : Send data over USB bus to UBW32. Parameters : unsigned int Destination address on PIC device. char Byte count (max 56). char Verify vs. write. Returns : ErrorCode ERR_NONE on success, or error code as returned from usbWrite(); ****************************************************************************/ static ErrorCode issueBlock( const unsigned int addr, const char len, const char verify) { ErrorCode status; #ifdef DEBUG (void)printf("Address: %08x Len %d\n",addr,len); #else (void)putchar('.'); fflush(stdout); #endif bufWrite32(usbBuf,1,addr); usbBuf[5] = len; if(verify) { DEBUGMSG("Verifying"); usbBuf[0] = GET_DATA; if(ERR_NONE == (status = usbWrite(6,1))) { #ifdef DEBUG int i; if(memcmp(&usbBuf[64 - len],hexBuf,len)) { (void)puts("Verify FAIL\nExpected:"); (void)printf("NA NA NA NA NA NA NA NA - "); for(i=0;i<(56-len);i++) (void)printf("NA "); for(i=0;i<len;i++) (void)printf("%02x ",hexBuf[i]); (void)putchar('\n'); fflush(stdout); return ERR_VERIFY; } else { (void)puts("Verify OK"); return ERR_NONE; } #else return (memcmp(&usbBuf[64 - len],hexBuf,len) ? ERR_VERIFY : ERR_NONE); #endif } } else { DEBUGMSG("Writing"); usbBuf[0] = PROGRAM_DEVICE; /* Regardless of actual byte count, data packet is always 64 bytes. Following the header, the bootloader wants the data portion 'right justified' within packet. Odd. */ memcpy(&usbBuf[64 - len],hexBuf,len); if((ERR_NONE == (status = usbWrite(64,0))) && (len < 56)) { /* Short data packets need flushing */ DEBUGMSG("Completing"); usbBuf[0] = PROGRAM_COMPLETE; status = usbWrite(1,0); } } #ifdef DEBUG if(status != ERR_NONE) (void)puts("ERROR"); #endif return status; }
//------------------------------------------------------------------------------ static void sendCmdReply(Application *app, uint8_t cmd, uint8_t *data, uint8_t size) { usbWrite(app, &cmd, 1); usbWrite(app, data, size); }
/**************************************************************************** Function : issueBlock Description : Send data over USB bus to device. Parameters : unsigned int Destination address on PIC device. char Byte count (max 56). char Verify vs. write. Returns : ErrorCode ERR_NONE on success, or error code as returned from usbWrite(); ****************************************************************************/ static ErrorCode issueBlock( unsigned int addr, char len, char verify) { ErrorCode status; #ifdef DEBUG (void)printf("Address: %08x Len %d\n",addr,len); #else (void)putchar('.'); fflush(stdout); #endif // check device memory blocks are programmable if ( verifyBlockProgrammable( &addr, &len ) ) { #ifdef DEBUG printf( "Skip data on address %04x with length %d\n", addr, len ); #endif return ERR_NONE; } // length must be even if ( len & 1 ) { #ifdef DEBUG printf( "Add one byte to data on address %04x with length %d\n", addr, len ); #endif hexBuf[ len++ ] = 0xff; } /* Short data packets need flushing */ if (!verify && len == 0 && !Flushed) { DEBUGMSG("Completing"); usbBuf[0] = PROGRAM_COMPLETE; status = usbWrite(1,0); Flushed= 1; return status; } bufWrite32(usbBuf,1,addr / bytesPerAddress); usbBuf[5] = len; if(verify) { DEBUGMSG("Verifying"); usbBuf[0] = GET_DATA; if(ERR_NONE == (status = usbWrite(6,1))) { #ifdef DEBUG int i; if(memcmp(&usbBuf[64 - len],hexBuf,len)) { (void)puts("Verify FAIL\nExpected:"); (void)printf("NA NA NA NA NA NA NA NA - "); for(i=0;i<(56-len);i++) (void)printf("NA "); for(i=0;i<len;i++) (void)printf("%02x ",hexBuf[i]); (void)putchar('\n'); fflush(stdout); return ERR_VERIFY; } else { (void)puts("Verify OK"); return ERR_NONE; } #else return (memcmp(&usbBuf[64 - len],hexBuf,len) ? ERR_VERIFY : ERR_NONE); #endif } } else { DEBUGMSG("Writing"); usbBuf[0] = PROGRAM_DEVICE; /* Regardless of actual byte count, data packet is always 64 bytes. Following the header, the bootloader wants the data portion 'right justified' within packet. Odd. */ memcpy(&usbBuf[64 - len],hexBuf,len); if((ERR_NONE == (status = usbWrite(64,0))) && (len < 56)) { /* Short data packets need flushing */ DEBUGMSG("Completing"); usbBuf[0] = PROGRAM_COMPLETE; status = usbWrite(1,0); } // flag if external code may need to flush before next write Flushed= (len < 56); } #ifdef DEBUG if(status != ERR_NONE) (void)puts("ERROR"); #endif return status; }
UsbSerial::UsbStatus UsbSerial::usbWriteChar( char c ) { usbWrite( &c, 1 ); return OK; }
void usb_rndis_tx(uint8_t ep, uint8_t stat) { int len; int i; //DBG("rndis tx\n"); if (!stat & EP_STATUS_NACKED) { DBG("tx endpoint interrupt, but not NAK"); return; } if (!packet_pending || bytes_to_send == 0) { ETH_DEV_DBG_INFO("usb_eth_tx, send buffer is empty, packet_pending=%d", packet_pending); eth_nak_interrupts &= ~INACK_BI; usbEnableNAKInterrupts(eth_nak_interrupts); return; } if (bytes_sent == 0) { /* prepend rndis header */ memset(rndisPacketHeader,0,44); uint32ToLittleEndian(1,rndisPacketHeader); // type uint32ToLittleEndian(44+bytes_to_send,rndisPacketHeader+4); uint32ToLittleEndian(44-8,rndisPacketHeader+8); // type uint32ToLittleEndian(bytes_to_send,rndisPacketHeader+12); // type /* copy start of frame to buffer */ len = MIN(bytes_to_send, 64-44); memcpy(rndisPacketHeader + 44, send_buffer, len); usbWrite(ep, rndisPacketHeader, 44+len); bytes_sent += len; //DBG("sent header and %d bytes out of %d",len,bytes_to_send); } else { len = MIN(bytes_to_send - bytes_sent, MAX_PACKET_SIZE); usbWrite(ep, ((uint8_t*) &send_buffer)+bytes_sent, len); bytes_sent += len; //DBG("usb_eth_tx: send %d bytes, frame data sent %d/%d", // len, bytes_sent, bytes_to_send); } if (bytes_sent >= bytes_to_send) { /* finished sending data */ //DBG("usb_rndis_tx: send done... (%d bytes)",bytes_to_send); //for (i=0; i< bytes_to_send;i++) { // send_buffer[i] = 0; //} rndisTxPackets++; bytes_to_send = 0; bytes_sent = 0; packet_pending = 0; //eth_nak_interrupts &= ~INACK_BI; //usbEnableNAKInterrupts(eth_nak_interrupts); } }