/****************************************************************************** * Function: static void UsbCbInitEP(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is called when the device becomes * initialized, which occurs after the host sends a * SET_CONFIGURATION (wValue not = 0) request. This * callback function should initialize the endpoints * for the device's usage according to the current * configuration. * * Note: None *****************************************************************************/ static void UsbCbInitEP(void) { USBEnableEndpoint(USBGEN_CMD_EP_NUM, USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP); USBEnableEndpoint(USBGEN_DATA_EP_NUM, USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP); UsbOutCmdHandle = USBGenRead(USBGEN_CMD_EP_NUM, (BYTE*)&OutCmdPacket, USBGEN_EP_SIZE); UsbOutDataHandle = USBGenRead(USBGEN_DATA_EP_NUM, (BYTE*)&OutDataPacket, USBGEN_EP_SIZE); }
// This function is called when the device becomes initialized, which occurs after the host sends a // SET_CONFIGURATION (wValue not = 0) request. This callback function should initialize the endpoints // for the device's usage according to the current configuration. void USBCBInitEP( void ) { // Enable the endpoint. USBEnableEndpoint( USBGEN_EP_NUM, USB_OUT_ENABLED | USB_IN_ENABLED | USB_HANDSHAKE_ENABLED | USB_DISALLOW_SETUP ); // Now begin waiting for the first packets to be received from the host via this endpoint. OutIndex = 0; OutHandle[0] = USBGenRead( USBGEN_EP_NUM, (BYTE *)&OutBuffer[0], USBGEN_EP_SIZE ); OutHandle[1] = USBGenRead( USBGEN_EP_NUM, (BYTE *)&OutBuffer[1], USBGEN_EP_SIZE ); // Initialize the pointer to the buffer which will return data to the host via this endpoint. InIndex = 0; InPacket = &InBuffer[0]; }
/****************************************************************************** * Function: void USBCBInitEP(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is called when the device becomes * initialized, which occurs after the host sends a * SET_CONFIGURATION (wValue not = 0) request. This * callback function should initialize the endpoints * for the device's usage according to the current * configuration. * * Note: None *****************************************************************************/ void USBCBInitEP(void) { //Enable the application endpoints USBEnableEndpoint(USBGEN_EP_NUM,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP); //Arm the application OUT endpoint, so it can receive a packet from the host USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE); }
void ProcessIO(void) { if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; /*if(USBGetDeviceState() == DETACHED_STATE) { if(I2CCount > 0) { ProcessCmd(OUTPacket); I2CCount = 0; } } else*/ if(!USBHandleBusy(USBGenericOutHandle)) { //if( OUTPacket[1] != MASTER_ADDRESS ) // I2CRelay(OUTPacket, USBGEN_EP_SIZE); //else ProcessCmd(OUTPacket); USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM, (BYTE*)&OUTPacket, USBGEN_EP_SIZE); } if(WQI != WQX && !USBHandleBusy(USBGenericInHandle)) { USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM, (BYTE*)&INPacket[WQX*USB_RECORD_SIZE], USB_RECORD_SIZE); WQX = (WQX+1) & 3; } } //end ProcessIO
/************************************************** * SWARMS Input PRECESSING * * * ****************************************************/ void ProcessSWARMSInput(void){ char commandSuccess; char SWARMSCommandID; if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; // this is where I should insert the code for specific control if(!USBHandleBusy(USBGenericOutHandle)) //Check if the endpoint has received any data from the host. { if(! canfitCommandInOutputCommandBuffer(5)){ //can't ensure reply -- just drop frame USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE); mLED_2_On(); mLED_1_Off() return; } SWARMSCommandID = OUTPacket[0]; if(IS_VALID_COMMAND){ commandSuccess = writeInputCommand(OUTPacket); switch(commandSuccess){ case fifoBufferStatusGood: //report success break; case fifoBufferStatusFull: //abort buffer full // mLED_2_Toggle(); SWARMSMakeCommandSuccess(SWARMSCommandID, FAILURE, NULL); //TODO: ADD FLAGS break; case fifoBufferStatusBadInputOversize: //abort buffer oversize input SWARMSMakeCommandSuccess(SWARMSCommandID, FAILURE, NULL); //TODO: ADD FLAGS break; case fifoBufferStatusBadInput: default: //notify bad command SWARMSMakeCommandSuccess(SWARMSCommandID, FAILURE, NULL); //TODO: ADD FLAGS break; } }else{ SWARMSMakeCommandSuccess(SWARMSCommandID, FAILURE, NULL); //TODO: ADD FLAGS } USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE); }
/******************************************************************** * モニタコマンド受信と実行. ******************************************************************** */ void ProcessIO(void) { // 返答パケットが空であること、かつ、 // 処理対象の受信データがある. if((ToPcRdy == 0) && (USBHandleBusy(USBGenericOutHandle)==0) ) { //受信データがあれば、受信データを受け取る. memcpy64((char*)&PacketFromPC,(char*)OUTPacket); //次の読み込みを発行する. USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket ,USBGEN_EP_SIZE); PacketToPC.raw[0]=Cmd0; // CMD ECHOBACK //コマンドに対応する処理を呼び出す. if(Cmd0==HIDASP_PEEK) {cmd_peek();} // メモリー読み出し. else if(Cmd0==HIDASP_POKE) {cmd_poke();} // メモリー書き込み. else if(Cmd0==HIDASP_JMP) {cmd_exec();} // 実行. else if(Cmd0==HIDASP_TEST) {cmd_echo();} // 接続テスト. else if(Cmd0==HIDASP_GET_STRING){cmd_get_string();} else if(Cmd0==HIDASP_USER_CMD) {cmd_user_cmd();} else if(Cmd0==HIDASP_SET_MODE) {cmd_set_mode();} } // 必要なら、返答パケットをバルク転送(EP1)でホストPCに返却する. if( ToPcRdy ) { if(!USBHandleBusy(USBGenericInHandle)) { memcpy64(INPacket,(char*)&PacketToPC); USBGenericInHandle=USBGenWrite(USBGEN_EP_NUM,(BYTE*)INPacket,USBGEN_EP_SIZE); ToPcRdy = 0; if(poll_mode!=0) { if( USBHandleBusy(USBGenericOutHandle) ) {//コマンドが来ない限り送り続ける. make_report(); } } } } }
/****************************************************************************** * Function: void USBCBInitEP(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is called when the device becomes * initialized, which occurs after the host sends a * SET_CONFIGURATION (wValue not = 0) request. This * callback function should initialize the endpoints * for the device's usage according to the current * configuration. * * Note: None *****************************************************************************/ void USBCBInitEP(void) { USBEnableEndpoint(USBGEN_EP_NUM,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP); USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE); }
static void processUsbCommands(void) { #if defined(USB_POLLING) // Check bus status and service USB interrupts. USBDeviceTasks(); // Interrupt or polling method. If using polling, must call // this function periodically. This function will take care // of processing and responding to SETUP transactions // (such as during the enumeration process when you first // plug in). USB hosts require that USB devices should accept // and process SETUP packets in a timely fashion. Therefore, // when using polling, this function should be called // regularly (such as once every 1.8ms or faster** [see // inline code comments in usb_device.c for explanation when // "or faster" applies]) In most cases, the USBDeviceTasks() // function does not take very long to execute (ex: <100 // instruction cycles) before it returns. #endif // Note: The user application should not begin attempting to read/write over the USB // until after the device has been fully enumerated. After the device is fully // enumerated, the USBDeviceState will be set to "CONFIGURED_STATE". if ((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; // As the device completes the enumeration process, the UsbCbInitEP() function will // get called. In this function, we initialize the user application endpoints (in this // example code, the user application makes use of endpoint 1 IN and endpoint 1 OUT). // The USBGenRead() function call in the UsbCbInitEP() function initializes endpoint 1 OUT // and "arms" it so that it can receive a packet of data from the host. Once the endpoint // has been armed, the host can then send data to it (assuming some kind of application software // is running on the host, and the application software tries to send data to the USB device). // If the host sends a packet of data to the endpoint 1 OUT buffer, the hardware of the SIE will // automatically receive it and store the data at the memory location pointed to when we called // USBGenRead(). Additionally, the endpoint handle (in this case UsbOutCmdHandle) will indicate // that the endpoint is no longer busy. At this point, it is safe for this firmware to begin reading // from the endpoint buffer, and processing the data. In this example, we have implemented a few very // simple commands. For example, if the host sends a packet of data to the endpoint 1 OUT buffer, with the // first byte = 0x80, this is being used as a command to indicate that the firmware should "Toggle LED(s)". if (!USBHandleBusy(UsbOutCmdHandle)) { // Check if the endpoint has received any data from the host. #if DEBUG unsigned char l = USBHandleGetLength(UsbOutCmdHandle); if (usbfifo_debug_operation.dump_usb_out == 1) { unsigned char b[16]; unsigned char i; putrsUSART("USB OUT: '"); for (i=0;i<l;++i) { if (i != 0) { while (BusyUSART()); putcUSART(' '); } sprintf(b, "%02x", OutCmdPacket[i]); putsUSART(b); } sprintf(b, "' len=%3d\r\n", l); putsUSART(b); } if (usbfifo_debug_operation.usb_loopback == 1) { unsigned char i; // Now check to make sure no previous attempts to send data to the host are still pending. If any attemps are still // pending, we do not want to write to the endpoint 1 IN buffer again, until the previous transaction is complete. // Otherwise the unsent data waiting in the buffer will get overwritten and will result in unexpected behavior. while (USBHandleBusy(UsbInCmdHandle)); for (i=0;i<l;++i) InCmdPacket[i] = OutCmdPacket[i]; // The endpoint was not "busy", therefore it is safe to write to the buffer and arm the endpoint. // The USBGenWrite() function call "arms" the endpoint (and makes the handle indicate the endpoint is busy). // Once armed, the data will be automatically sent to the host (in hardware by the SIE) the next time the // host polls the endpoint. Once the data is successfully sent, the handle (in this case UsbInCmdHandle) // will indicate the the endpoint is no longer busy. UsbInCmdHandle = USBGenWrite(USBGEN_CMD_EP_NUM, (BYTE*)&InCmdPacket, l); } #endif switch (OutCmdPacket[0]) { #if DEBUG case USBFIFO_CMD_DUMP_USB_OUT: usbfifo_debug_operation.dump_usb_out ^= 1; break; case USBFIFO_CMD_DUMP_FIFO_OUT: usbfifo_debug_operation.dump_fifo_out ^= 1; break; case USBFIFO_CMD_FIFO_LOOPBACK: usbfifo_debug_operation.fifo_loopback ^= 1; break; case USBFIFO_CMD_USB_LOOPBACK: usbfifo_debug_operation.usb_loopback ^= 1; break; #endif default: { unsigned char b[8]; putrsUSART("Unexpected cmd="); sprintf(b, "0x%2X\r\n", OutCmdPacket[0]); putsUSART(b); } break; } // Re-arm the OUT endpoint for the next packet: // The USBGenRead() function call "arms" the endpoint (and makes it "busy"). If the endpoint is armed, the SIE will // automatically accept data from the host, if the host tries to send a packet of data to the endpoint. Once a data // packet addressed to this endpoint is received from the host, the endpoint will no longer be busy, and the application // can read the data which will be sitting in the buffer. UsbOutCmdHandle = USBGenRead(USBGEN_CMD_EP_NUM, (BYTE*)&OutCmdPacket, USBGEN_EP_SIZE); } if (!USBHandleBusy(UsbOutDataHandle)) { #if USBGEN_EP_SIZE > FIFO_9403A_MAX_MSG_LEN #error "Transfer of more than FIFO_9403A_MAX_MSG_LEN not implemented" #endif unsigned char l = USBHandleGetLength(UsbOutDataHandle); unsigned char i; #if DEBUG if (usbfifo_debug_operation.dump_usb_out == 1) { unsigned char b[16]; putrsUSART("USB OUT: '"); for (i=0;i<l;++i) { if (i != 0) { while (BusyUSART()); putcUSART(' '); } sprintf(b, "%02x", OutDataPacket[i]); } sprintf(b, "' len=%3d\r\n", l); putsUSART(b); } if (usbfifo_debug_operation.usb_loopback == 1) { while (USBHandleBusy(UsbInDataHandle)); // ensure that FIFO data left the device for (i=0;i<l;++i) InDataPacket[i] = OutDataPacket[i]; /* FIXME: use real ping-pong */ UsbInDataHandle = USBGenWrite(USBGEN_DATA_EP_NUM, (BYTE*)&InDataPacket, l); while (USBHandleBusy(UsbInDataHandle)); // have to wait here as full ping-pong is not implemented // and thus we don't want data from FIFO override the data being sent here } #endif fifo9403aPush(l, 1); for (i=0;i<l;++i) fifo9403aPush(OutDataPacket[i], 1); UsbOutDataHandle = USBGenRead(USBGEN_DATA_EP_NUM, (BYTE*)&OutDataPacket, USBGEN_EP_SIZE); } }
/****************************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user routines. * It is a mixture of both USB and non-USB tasks. * * Note: None *****************************************************************************/ void USBUpdate(void) { byte data[2]; byte i; byte paramNum; ulong tempLong; USBDeviceTasks(); if ((USBDeviceState < CONFIGURED_STATE) || (USBSuspendControl==1)) { return; } //As the device completes the enumeration process, the USBCBInitEP() function will //get called. In this function, we initialize the user application endpoints (in this //example code, the user application makes use of endpoint 1 IN and endpoint 1 OUT). //The USBGenRead() function call in the USBCBInitEP() function initializes endpoint 1 OUT //and "arms" it so that it can receive a packet of data from the host. Once the endpoint //has been armed, the host can then send data to it (assuming some kind of application software //is running on the host, and the application software tries to send data to the USB device). //If the host sends a packet of data to the endpoint 1 OUT buffer, the hardware of the SIE will //automatically receive it and store the data at the memory location pointed to when we called //USBGenRead(). Additionally, the endpoint handle (in this case USBGenericOutHandle) will indicate //that the endpoint is no longer busy. At this point, it is safe for this firmware to begin reading //from the endpoint buffer, and processing the data. In this example, we have implemented a few very //simple commands. For example, if the host sends a packet of data to the endpoint 1 OUT buffer, with the //first byte = 0x80, this is being used as a command to indicate that the firmware should "Toggle LED(s)". if(!USBHandleBusy(USBGenericOutHandle) && //Check if the endpoint has received any data from the host. //Now check to make sure no previous attempts to send data to the host are still pending. If any attemps are still //pending, we do not want to write to the endpoint 1 IN buffer again, until the previous transaction is complete. //Otherwise the unsent data waiting in the buffer will get overwritten and will result in unexpected behavior. (!USBGenericInHandle || !USBHandleBusy(USBGenericInHandle))) { if (OUTPacket[USB_PACKET_LEN] < 7) { // message too short } else { usbActivityTimeout = 3000; // reset timeout (in ms) 3 seconds switch(OUTPacket[USB_PACKET_CMD]) { //Data arrived, check what kind of command might be in the packet of data. case USB_CMD_NULL: // 0x00 if (OUTPacket[USB_PACKET_LEN] != 7) { data[0] = USB_ERR_BAD_LEN; UsbSendResp(USB_RESP_BAD_MSG, data); } else { UsbSendResp(USB_RESP_NULL, data); } break; case USB_CMD_GET_VSTRING: if (OUTPacket[USB_PACKET_LEN] != 7) { data[0] = USB_ERR_BAD_LEN; UsbSendResp(USB_RESP_BAD_MSG, data); } else { UsbSendResp(USB_RESP_GET_VSTRING, data); } break; case USB_CMD_GET_CHAN: if (OUTPacket[USB_PACKET_LEN] != 7) { data[0] = USB_ERR_BAD_LEN; data[1] = 7; UsbSendResp(USB_RESP_BAD_MSG, data); } else if (OUTPacket[USB_PACKET_STR] >= NUM_STRINGS) { data[0] = USB_ERR_BAD_PRM; data[1] = 0; UsbSendResp(USB_RESP_BAD_MSG, data); } else if (!OUTPacket[USB_PACKET_MCT] || OUTPacket[USB_PACKET_MCT] > NUM_MCT) { data[0] = USB_ERR_BAD_PRM; data[1] = 1; UsbSendResp(USB_RESP_BAD_MSG, data); } else { UsbSendResp(USB_RESP_GET_CHAN, data); } break; case USB_CMD_GET_MIRRORS: if (OUTPacket[USB_PACKET_LEN] != 7) { data[0] = USB_ERR_BAD_LEN; data[1] = 7; UsbSendResp(USB_RESP_BAD_MSG, data); } else if (OUTPacket[USB_PACKET_STR] >= NUM_STRINGS) { data[0] = USB_ERR_BAD_PRM; data[1] = 0; UsbSendResp(USB_RESP_BAD_MSG, data); } else if (!OUTPacket[USB_PACKET_MCT] || OUTPacket[USB_PACKET_MCT] > NUM_MCT) { data[0] = USB_ERR_BAD_PRM; data[1] = 1; UsbSendResp(USB_RESP_BAD_MSG, data); } else { UsbSendResp(USB_RESP_GET_MIRRORS, data); } break; case USB_CMD_GET_STRING: if (OUTPacket[USB_PACKET_LEN] != 7) { data[0] = USB_ERR_BAD_LEN; data[1] = 7; UsbSendResp(USB_RESP_BAD_MSG, data); } else if (OUTPacket[USB_PACKET_STR] >= NUM_STRINGS) { data[0] = USB_ERR_BAD_PRM; data[1] = 0; UsbSendResp(USB_RESP_BAD_MSG, data); } else { UsbSendResp(USB_RESP_GET_STRING, data); } break; case USB_CMD_FIELD_STATE: if (OUTPacket[USB_PACKET_LEN] == 7) { UsbSendResp(USB_RESP_FIELD_STATE, data); } else if (OUTPacket[USB_PACKET_LEN] == 8) { FieldNewState(OUTPacket[USB_PACKET_DATA]); UsbSendResp(USB_RESP_FIELD_STATE, data); } else { data[0] = USB_ERR_BAD_LEN; data[1] = 7; UsbSendResp(USB_RESP_BAD_MSG, data); } break; case USB_CMD_GET_FCE: if (OUTPacket[USB_PACKET_LEN] == 7) { UsbSendResp(USB_RESP_GET_FCE, data); } else { data[0] = USB_ERR_BAD_LEN; data[1] = 7; UsbSendResp(USB_RESP_BAD_MSG, data); } break; case USB_CMD_GET_RTU: if (OUTPacket[USB_PACKET_LEN] == 7) { UsbSendResp(USB_RESP_GET_RTU, data); } else { data[0] = USB_ERR_BAD_LEN; data[1] = 7; UsbSendResp(USB_RESP_BAD_MSG, data); } break; case USB_CMD_SEND_MCT485: // 0x64 if (OUTPacket[USB_PACKET_LEN] >= 11 && OUTPacket[USB_PACKET_LEN] < MCT485_MAX_INDEX + 7) { //Mct485CannedMsg(MSG_ORIGIN_USB, // OUTPacket[USB_PACKET_STR], // OUTPacket[USB_PACKET_LEN]-7, // &OUTPacket[USB_PACKET_DATA]); usb485TxString = OUTPacket[USB_PACKET_STR]; usb485TxLen = OUTPacket[USB_PACKET_LEN]-7; for (i = 0; i < usb485TxLen; i++) { usb485TxBuffer[i] = OUTPacket[USB_PACKET_DATA+i]; } // clear 485 response buffer usb485RxLen = 0; UsbSendResp(USB_RESP_SEND_MCT485, data); } else { data[0] = USB_ERR_BAD_LEN; data[1] = 7; UsbSendResp(USB_RESP_BAD_MSG, data); } break; case USB_CMD_GET_MCT485: // 0x65 if (OUTPacket[USB_PACKET_LEN] == 7) { UsbSendResp(USB_RESP_GET_MCT485, data); } else { data[0] = USB_ERR_BAD_LEN; data[1] = 7; UsbSendResp(USB_RESP_BAD_MSG, data); } break; case USB_CMD_RTC: // 0x66 if (OUTPacket[USB_PACKET_LEN] == 7) { UsbSendResp(USB_RESP_RTC, data); } else if (OUTPacket[USB_PACKET_LEN] == 13) { RtcSetClock(&OUTPacket[USB_PACKET_DATA]); UsbSendResp(USB_RESP_RTC, data); } else { data[0] = USB_ERR_BAD_LEN; data[1] = 7; UsbSendResp(USB_RESP_BAD_MSG, data); } break; case USB_CMD_LOG: // 0x67 if (OUTPacket[USB_PACKET_LEN] == 7) { UsbSendResp(USB_RESP_LOG, data); } else if (OUTPacket[USB_PACKET_LEN] == 8) { if (OUTPacket[USB_PACKET_DATA] == 0) { DataLogFindFirstEntry(); } else if (OUTPacket[USB_PACKET_DATA] == 0xFF) { DataLogErase(); } UsbSendResp(USB_RESP_LOG, data); } else { data[0] = USB_ERR_BAD_LEN; data[1] = 7; UsbSendResp(USB_RESP_BAD_MSG, data); } break; case USB_CMD_DESICCANT: // 0x68 if (OUTPacket[USB_PACKET_LEN] == 7) { UsbSendResp(USB_RESP_DESICCANT, data); } else if (OUTPacket[USB_PACKET_LEN] == 9) { // manual force dessicant to set of outputs or state DesiccantNewState(OUTPacket[USB_PACKET_DATA], OUTPacket[USB_PACKET_DATA+1]); UsbSendResp(USB_RESP_DESICCANT, data); } else { data[0] = USB_ERR_BAD_LEN; data[1] = 7; UsbSendResp(USB_RESP_BAD_MSG, data); } break; case USB_CMD_SFC_PARAM: // 0x69 if (OUTPacket[USB_PACKET_LEN] == 8) { UsbSendResp(USB_RESP_SFC_PARAM, data); } else if (OUTPacket[USB_PACKET_LEN] > 8 && !(OUTPacket[USB_PACKET_LEN] & 0x03)) { // process one param at a time, prevents I2C queue entry overflow and avoids // I2C page boundary problems paramNum = OUTPacket[USB_PACKET_DATA]; i = USB_PACKET_DATA+1; while (i < OUTPacket[USB_PACKET_LEN]-2) { tempLong = OUTPacket[i++]; tempLong *= 256; tempLong += OUTPacket[i++]; tempLong *= 256; tempLong += OUTPacket[i++]; tempLong *= 256; tempLong += OUTPacket[i++]; ParamWrite(paramNum, tempLong); paramNum++; } UsbSendResp(USB_RESP_SFC_PARAM, data); } else { data[0] = USB_ERR_BAD_LEN; data[1] = 7; UsbSendResp(USB_RESP_BAD_MSG, data); } break; case USB_CMD_MEMORY: // 0x6A if (OUTPacket[USB_PACKET_LEN] == 11) { data[4] = 16; UsbSendResp(USB_RESP_MEMORY, data); } else { data[0] = USB_ERR_BAD_LEN; data[1] = 7; UsbSendResp(USB_RESP_BAD_MSG, data); } break; case USB_CMD_TEST: // 0x6B if (OUTPacket[USB_PACKET_LEN] == 8) { UsbSendResp(USB_RESP_TEST, data); for (tempLong = 0; tempLong < 1000000; tempLong++) { } if (OUTPacket[USB_PACKET_DATA] == 0x01) { Mct485Init(); } else if (OUTPacket[USB_PACKET_DATA] == 0x02) { StringInit(); } else if (OUTPacket[USB_PACKET_DATA] == 0x03) { FieldInit(); } else if (OUTPacket[USB_PACKET_DATA] == 0x04) { SoftReset(); } } else { data[0] = USB_ERR_BAD_LEN; data[1] = 7; UsbSendResp(USB_RESP_BAD_MSG, data); } break; } // switch (cmd) } // else process messages //Re-arm the OUT endpoint for the next packet: //The USBGenRead() function call "arms" the endpoint (and makes it "busy"). If the endpoint is armed, the SIE will //automatically accept data from the host, if the host tries to send a packet of data to the endpoint. Once a data //packet addressed to this endpoint is received from the host, the endpoint will no longer be busy, and the application //can read the data which will be sitting in the buffer. USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE); } // if }// UsbUpdate()
/****************************************************************************** * Function: void ServiceRequests(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: USB traffic can be generated * * Overview: This function takes in the commands from the PC from the * application and executes the commands requested * * Note: None *****************************************************************************/ void ServiceRequests(void) { BYTE index; //Check to see if data has arrived if(!USBHandleBusy(USBGenericOutHandle)) { //if the handle is no longer busy then the last //transmission is complete counter = 0; INPacket.CMD=OUTPacket.CMD; INPacket.len=OUTPacket.len; //process the command switch(OUTPacket.CMD) { case READ_VERSION: //dataPacket._byte[1] is len INPacket._byte[2] = MINOR_VERSION; INPacket._byte[3] = MAJOR_VERSION; counter=0x04; break; case ID_BOARD: counter = 0x01; if(OUTPacket.ID == 0) { mLED_3_Off();mLED_4_Off(); } else if(OUTPacket.ID == 1) { mLED_3_Off();mLED_4_On(); } else if(OUTPacket.ID == 2) { mLED_3_On();mLED_4_Off(); } else if(OUTPacket.ID == 3) { mLED_3_On();mLED_4_On(); } else counter = 0x00; break; case UPDATE_LED: #if defined(PIC18F87J50_PIM) || defined(PIC18F46J50_PIM) || defined(PIC18F47J53_PIM) blinkStatusValid = FALSE; #endif // LED1 & LED2 are used as USB event indicators. if(OUTPacket.led_num == 3) { if(OUTPacket.led_status) { mLED_3_On(); } else { mLED_3_Off(); } counter = 0x01; }//end if else if(OUTPacket.led_num == 4) { if(OUTPacket.led_status) { mLED_4_On(); } else { mLED_4_Off(); } counter = 0x01; }//end if else break; case SET_TEMP_REAL: temp_mode = TEMP_REAL_TIME; ResetTempLog(); counter = 0x01; break; case RD_TEMP: if(AcquireTemperature()) { INPacket._byte[1] = temperature.v[0]; INPacket._byte[2] = temperature.v[1]; counter=0x03; }//end if break; case SET_TEMP_LOGGING: temp_mode = TEMP_LOGGING; ResetTempLog(); counter=0x01; break; case RD_TEMP_LOGGING: counter = (valid_temp<<1)+2; // Update count in byte INPacket.len = (valid_temp<<1); for(index = valid_temp; index > 0; index--) { if(pTemp == 0) pTemp = 29; else pTemp--; INPacket._word[index] = temp_data[pTemp]; }//end for ResetTempLog(); // Once read, log will restart break; case RD_POT: { WORD_VAL w; mInitPOT(); w = ReadPOT(); INPacket._byte[1] = w.v[0]; INPacket._byte[2] = w.v[1]; counter=0x03; } break; case RESET: Reset(); break; default: break; }//end switch() if(counter != 0) { if(!USBHandleBusy(USBGenericInHandle)) { USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(BYTE*)&INPacket,counter); } }//end if //Re-arm the OUT endpoint for the next packet USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE); }//end if }//end ServiceRequests
/****************************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user routines. * It is a mixture of both USB and non-USB tasks. * * Note: None *****************************************************************************/ void ProcessIO(void) { //Blink the LEDs according to the USB device status, but only do so if the PC application isn't connected and controlling the LEDs. if(blinkStatusValid) { BlinkUSBStatus(); } //User Application USB tasks below. //Note: The user application should not begin attempting to read/write over the USB //until after the device has been fully enumerated. After the device is fully //enumerated, the USBDeviceState will be set to "CONFIGURED_STATE". if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; //As the device completes the enumeration process, the USBCBInitEP() function will //get called. In this function, we initialize the user application endpoints (in this //example code, the user application makes use of endpoint 1 IN and endpoint 1 OUT). //The USBGenRead() function call in the USBCBInitEP() function initializes endpoint 1 OUT //and "arms" it so that it can receive a packet of data from the host. Once the endpoint //has been armed, the host can then send data to it (assuming some kind of application software //is running on the host, and the application software tries to send data to the USB device). //If the host sends a packet of data to the endpoint 1 OUT buffer, the hardware of the SIE will //automatically receive it and store the data at the memory location pointed to when we called //USBGenRead(). Additionally, the endpoint handle (in this case USBGenericOutHandle) will indicate //that the endpoint is no longer busy. At this point, it is safe for this firmware to begin reading //from the endpoint buffer, and processing the data. In this example, we have implemented a few very //simple commands. For example, if the host sends a packet of data to the endpoint 1 OUT buffer, with the //first byte = 0x80, this is being used as a command to indicate that the firmware should "Toggle LED(s)". if(!USBHandleBusy(USBGenericOutHandle)) //Check if the endpoint has received any data from the host. { switch(OUTPacket[0]) //Data arrived, check what kind of command might be in the packet of data. { case 0x80: //Toggle LED(s) command from PC application. blinkStatusValid = FALSE; //Disable the regular LED blink pattern indicating USB state, PC application is controlling the LEDs. if(mGetLED_1() == mGetLED_2()) { mLED_1_Toggle(); mLED_2_Toggle(); } else { mLED_1_On(); mLED_2_On(); } break; case 0x81: //Get push button state command from PC application. INPacket[0] = 0x81; //Echo back to the host PC the command we are fulfilling in the first byte. In this case, the Get Pushbutton State command. // if(sw2 == 1) //pushbutton not pressed, pull up resistor on circuit board is pulling the PORT pin high if (UserSW == 1) { INPacket[1] = 0x01; } else //sw2 must be == 0, pushbutton is pressed and overpowering the pull up resistor { INPacket[1] = 0x00; } //Now check to make sure no previous attempts to send data to the host are still pending. If any attemps are still //pending, we do not want to write to the endpoint 1 IN buffer again, until the previous transaction is complete. //Otherwise the unsent data waiting in the buffer will get overwritten and will result in unexpected behavior. if(!USBHandleBusy(USBGenericInHandle)) { //The endpoint was not "busy", therefore it is safe to write to the buffer and arm the endpoint. //The USBGenWrite() function call "arms" the endpoint (and makes the handle indicate the endpoint is busy). //Once armed, the data will be automatically sent to the host (in hardware by the SIE) the next time the //host polls the endpoint. Once the data is successfully sent, the handle (in this case USBGenericInHandle) //will indicate the the endpoint is no longer busy. USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(BYTE*)&INPacket,USBGEN_EP_SIZE); } break; } //Re-arm the OUT endpoint for the next packet: //The USBGenRead() function call "arms" the endpoint (and makes it "busy"). If the endpoint is armed, the SIE will //automatically accept data from the host, if the host tries to send a packet of data to the endpoint. Once a data //packet addressed to this endpoint is received from the host, the endpoint will no longer be busy, and the application //can read the data which will be sitting in the buffer. USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE); } }//end ProcessIO
void ProcessIO(void) { char oldPGDtris; char PIN; static byte counter=0; int nBytes; unsigned long address; // When the device is plugged in, the leds give the numbers 1, 2, 3, 4, 5. //After configured state, the leds are controlled by the next lines in this function if((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1)) { BlinkUSBStatus(); return; } nBytes=USBGenRead((byte*)input_buffer,64); if(nBytes>0) { switch(input_buffer[0]) { case CMD_ERASE: setLeds(LEDS_ON | LEDS_WR); output_buffer[0]=bulk_erase(picfamily,pictype,input_buffer[1]); counter=1; setLeds(LEDS_ON); break; case CMD_READ_ID: setLeds(LEDS_ON | LEDS_RD); switch(picfamily) { case PIC24: case dsPIC30: read_code(picfamily,pictype,0xFF0000,(unsigned char*)output_buffer,2,3); break; case PIC18: case PIC18J: case PIC18K: read_code(picfamily,pictype,0x3FFFFE,(unsigned char*)output_buffer,2,3); //devid is at location 0x3ffffe for PIC18 devices break; case PIC16: set_vdd_vpp(picfamily, pictype, 0); read_code(picfamily,pictype,0x2006,(unsigned char*)output_buffer,2,3); //devid is at location 0x2006 for PIC16 devices break; } counter=2; setLeds(LEDS_ON); break; case CMD_WRITE_CODE: setLeds(LEDS_ON | LEDS_WR); address=((unsigned long)input_buffer[2])<<16| ((unsigned long)input_buffer[3])<<8| ((unsigned long)input_buffer[4]); output_buffer[0]=write_code(picfamily,pictype,address, (unsigned char*)(input_buffer+6),input_buffer[1],input_buffer[5]); counter=1; setLeds(LEDS_ON); break; case CMD_READ_CODE: setLeds(LEDS_ON | LEDS_RD); address=((unsigned long)input_buffer[2])<<16| ((unsigned long)input_buffer[3])<<8| ((unsigned long)input_buffer[4]); PIN=read_code(picfamily,pictype,address,(unsigned char*)output_buffer,input_buffer[1],input_buffer[5]); if(PIN==3)output_buffer[0]=0x3; counter=input_buffer[1]; setLeds(LEDS_ON); break; case CMD_WRITE_DATA: setLeds(LEDS_ON | LEDS_WR); address=((unsigned long)input_buffer[2])<<16| ((unsigned long)input_buffer[3])<<8| ((unsigned long)input_buffer[4]); output_buffer[0]=write_data(picfamily,pictype,address, (unsigned char*)(input_buffer+6),input_buffer[1],input_buffer[5]); counter=1; setLeds(LEDS_ON); break; case CMD_READ_DATA: setLeds(LEDS_ON | LEDS_RD); address=((unsigned long)input_buffer[2])<<16| ((unsigned long)input_buffer[3])<<8| ((unsigned long)input_buffer[4]); read_data(picfamily,pictype,address,(unsigned char*)output_buffer,input_buffer[1],input_buffer[5]); counter=input_buffer[1]; setLeds(LEDS_ON); break; case CMD_WRITE_CONFIG: setLeds(LEDS_ON | LEDS_WR); address=((unsigned long)input_buffer[2])<<16| ((unsigned long)input_buffer[3])<<8| ((unsigned long)input_buffer[4]); output_buffer[0]=write_config_bits(picfamily, pictype, address, (unsigned char*)(input_buffer+6),input_buffer[1],input_buffer[5]); counter=1; setLeds(LEDS_ON); break; case CMD_SET_PICTYPE: output_buffer[0]=set_pictype(input_buffer+1); //output_buffer[0]=1; //Ok counter=1; setLeds(LEDS_ON); break; case CMD_FIRMWARE_VERSION: strcpypgm2ram((char*)output_buffer,(const far rom char*)upp_version); counter=18; setLeds(LEDS_ON); break; case CMD_DEBUG: setLeds(LEDS_ON | LEDS_WR | LEDS_RD); switch(input_buffer[1]) { case 0: set_vdd_vpp(dsP30F, dsPIC30, 1); output_buffer[0]=1; counter=1; break; case 1: set_vdd_vpp(dsP30F, dsPIC30, 0); output_buffer[0]=1; counter=1; break; case 2: dspic_send_24_bits(((unsigned long)input_buffer[2])| ((unsigned long)input_buffer[3])<<8| ((unsigned long)input_buffer[4])<<16); output_buffer[0]=1; counter=1; break; case 3: nBytes = dspic_read_16_bits(1); output_buffer[0]=(unsigned char)nBytes; output_buffer[1]=(unsigned char)(nBytes>>8); counter=2; break; } break; case CMD_GET_PIN_STATUS: switch(input_buffer[1]) { case SUBCMD_PIN_PGC: if((!TRISPGC_LOW)&&(!PGC_LOW)) //3.3V levels { if(PGC) output_buffer[0] = PIN_STATE_3_3V; else output_buffer[0] = PIN_STATE_0V; } else //5V levels { if(PGC) output_buffer[0] = PIN_STATE_5V; else output_buffer[0] = PIN_STATE_0V; } counter=1; break; case SUBCMD_PIN_PGD: if(TRISPGD)//PGD is input { if(PGD_READ) output_buffer[0] = PIN_STATE_5V; else output_buffer[0] = PIN_STATE_0V; } else { if((!TRISPGD_LOW)&&(!PGD_LOW)) //3.3V levels { if(PGD) output_buffer[0] = PIN_STATE_3_3V; else output_buffer[0] = PIN_STATE_0V; } else //5V levels { if(PGD) output_buffer[0] = PIN_STATE_5V; else output_buffer[0] = PIN_STATE_0V; } } counter=1; break; case SUBCMD_PIN_VDD: if(VDD) output_buffer[0] = PIN_STATE_FLOAT; else output_buffer[0] = PIN_STATE_5V; counter = 1; break; case SUBCMD_PIN_VPP: counter=1; if(!VPP){output_buffer[0] = PIN_STATE_12V;break;} if(VPP_RST){output_buffer[0] = PIN_STATE_0V;break;} if(VPP_RUN){output_buffer[0] = PIN_STATE_5V;break;} output_buffer[0] = PIN_STATE_FLOAT; break; case SUBCMD_PIN_VPP_VOLTAGE: ReadAdc(output_buffer); counter=2; break; default: output_buffer[0]=3; counter=1; break; } break; case CMD_SET_PIN_STATUS: switch(input_buffer[1]) { case SUBCMD_PIN_PGC: switch(input_buffer[2]) { case PIN_STATE_0V: TRISPGC = 0; PGC = 0; TRISPGC_LOW = 1; PGC_LOW = 0; output_buffer[0]=1;//ok break; case PIN_STATE_3_3V: TRISPGC = 0; PGC = 1; TRISPGC_LOW = 0; PGC_LOW = 0; output_buffer[0]=1;//ok break; case PIN_STATE_5V: TRISPGC = 0; PGC = 1; TRISPGC_LOW = 1; PGC_LOW = 0; output_buffer[0]=1;//ok break; default: output_buffer[0]=3; break; } break; case SUBCMD_PIN_PGD: switch(input_buffer[2]) { case PIN_STATE_0V: TRISPGD = 0; PGD = 0; TRISPGD_LOW = 1; PGD_LOW = 0; output_buffer[0]=1;//ok break; case PIN_STATE_3_3V: TRISPGD = 0; PGD = 1; TRISPGD_LOW = 0; PGD_LOW = 0; output_buffer[0]=1;//ok break; case PIN_STATE_5V: TRISPGD = 0; PGD = 1; TRISPGD_LOW = 1; PGD_LOW = 0; output_buffer[0]=1;//ok break; case PIN_STATE_INPUT: TRISPGD_LOW = 1; TRISPGD = 1; output_buffer[0]=1;//ok break; default: output_buffer[0]=3; break; } break; case SUBCMD_PIN_VDD: switch(input_buffer[2]) { case PIN_STATE_5V: VDD = 0; output_buffer[0]=1; break; case PIN_STATE_FLOAT: VDD = 1; output_buffer[0]=1; break; default: output_buffer[0]=3; break; } break; case SUBCMD_PIN_VPP: switch(input_buffer[2]) { case PIN_STATE_0V: VPP = 1; VPP_RST = 1; VPP_RUN = 0; output_buffer[0]=1;//ok break; case PIN_STATE_5V: VPP = 1; VPP_RST = 0; VPP_RUN = 1; output_buffer[0]=1;//ok break; case PIN_STATE_12V: VPP = 0; VPP_RST = 0; VPP_RUN = 0; output_buffer[0]=1;//ok break; case PIN_STATE_FLOAT: VPP = 1; VPP_RST = 0; VPP_RUN = 0; output_buffer[0]=1;//ok break; default: output_buffer[0]=3; break; } break; default: output_buffer[0]=3; } counter=1; break; } } if(counter != 0) { if(!mUSBGenTxIsBusy()) USBGenWrite((byte*)&output_buffer,counter); counter=0; } }//end ProcessIO
/****************************************************************************** * Function: void ServiceRequests(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: USB traffic can be generated * * Overview: This function takes in the commands from the PC from the * application and executes the commands requested * * Note: None *****************************************************************************/ void ServiceRequests(void) { BYTE index; //Check to see if data has arrived if(!USBHandleBusy(USBGenericOutHandle)) { //if the handle is no longer busy then the last //transmission is complete counter = 0; INPacket.CMD=OUTPacket.CMD; INPacket.len=OUTPacket.len; //process the command switch(OUTPacket.CMD) { case READ_VERSION: //dataPacket._byte[1] is len INPacket._byte[2] = MINOR_VERSION; INPacket._byte[3] = MAJOR_VERSION; counter=0x04; break; case RD_SERIAL: { //***********Case to read the serial number of the pedalog device**********// INPacket._byte[1] = serial_str[0]; INPacket._byte[2] = serial_str[1]; INPacket._byte[3] = serial_str[2]; INPacket._byte[4] = serial_str[3]; counter=0x5; // This counter must be equal to the size of the data sent plus 1 } break; case RD_VOLTS: //***********Case to read the voltage when 0x40 sent via USB**********// // Voltage is a string XX.X INPacket._byte[1] = VoltStr[0]; INPacket._byte[2] = VoltStr[1]; INPacket._byte[3] = VoltStr[2]; INPacket._byte[4] = VoltStr[3]; counter=0x5; // This counter must be equal to the size of the data sent plus 1 break; case RD_AMPS: { //***********Case to read the current when 0x41 sent via USB**********// // Current is a string XX.XX INPacket._byte[1] = I_out_Str[0]; INPacket._byte[2] = I_out_Str[1]; INPacket._byte[3] = I_out_Str[2]; INPacket._byte[4] = I_out_Str[3]; INPacket._byte[5] = I_out_Str[4]; counter=0x6; // This counter must be equal to the size of the data sent plus 1 } break; case RD_POWER: { //***********Case to read the power when 0x42 sent via USB**********// // Power is a string XXX.X INPacket._byte[1] = P_O_Str[0]; INPacket._byte[2] = P_O_Str[1]; INPacket._byte[3] = P_O_Str[2]; INPacket._byte[4] = P_O_Str[3]; INPacket._byte[5] = P_O_Str[4]; counter=0x6; // This counter must be equal to the size of the data sent plus 1 } break; case RD_DATA: { //***********Case to read back all the data when 0x43 sent via USB**********// INPacket._byte[1] = VoltStr[0]; INPacket._byte[2] = VoltStr[1]; INPacket._byte[3] = VoltStr[2]; INPacket._byte[4] = VoltStr[3]; INPacket._byte[5] = I_out_Str[0]; INPacket._byte[6] = I_out_Str[1]; INPacket._byte[7] = I_out_Str[2]; INPacket._byte[8] = I_out_Str[3]; INPacket._byte[9] = I_out_Str[4]; INPacket._byte[10] = P_O_Str[0]; INPacket._byte[11] = P_O_Str[1]; INPacket._byte[12] = P_O_Str[2]; INPacket._byte[13] = P_O_Str[3]; INPacket._byte[14] = P_O_Str[4]; INPacket._byte[15] = E_O_Str_disp[0]; INPacket._byte[16] = E_O_Str_disp[1]; INPacket._byte[17] = E_O_Str_disp[2]; INPacket._byte[18] = E_O_Str_disp[3]; INPacket._byte[19] = E_O_Str_disp[4]; INPacket._byte[20] = E_O_Str_disp[5]; INPacket._byte[21] = E_O_Str_disp[6]; INPacket._byte[22] = P_Max_Str[0]; // MAX POWER INPacket._byte[23] = P_Max_Str[1]; INPacket._byte[24] = P_Max_Str[2]; INPacket._byte[25] = P_Max_Str[3]; INPacket._byte[26] = P_Max_Str[4]; INPacket._byte[27] = P_Ave_Str[0]; // AVERAGE POWER INPacket._byte[28] = P_Ave_Str[1]; INPacket._byte[29] = P_Ave_Str[2]; INPacket._byte[30] = P_Ave_Str[3]; INPacket._byte[31] = P_Ave_Str[4]; INPacket._byte[32] = total_run_time_s_str[0]; // TIME TAKEN INPacket._byte[33] = total_run_time_s_str[1]; INPacket._byte[34] = total_run_time_s_str[2]; INPacket._byte[35] = total_run_time_s_str[3]; INPacket._byte[36] = total_run_time_s_str[4]; INPacket._byte[37] = total_run_time_s_str[5]; INPacket._byte[38] = total_run_time_s_str[6]; INPacket._byte[39] = total_run_time_s_str[7]; INPacket._byte[40] = total_run_time_s_str[0]; // TIME TAKEN INPacket._byte[41] = total_run_time_s_str[1]; INPacket._byte[42] = total_run_time_s_str[2]; INPacket._byte[43] = total_run_time_s_str[3]; INPacket._byte[44] = total_run_time_s_str[4]; INPacket._byte[45] = total_run_time_s_str[5]; INPacket._byte[46] = total_run_time_s_str[6]; INPacket._byte[47] = total_run_time_s_str[7]; INPacket._byte[48] = serial_str[0]; INPacket._byte[49] = serial_str[1]; INPacket._byte[50] = serial_str[2]; INPacket._byte[51] = serial_str[3]; counter=52; // This counter must be equal to the size of the data sent plus 1 } break; case RESET: Reset(); break; default: Nop(); break; }//end switch() if(counter != 0) { if(!USBHandleBusy(USBGenericInHandle)) { USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(BYTE*)&INPacket,counter); } }//end if //Re-arm the OUT endpoint for the next packet USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE); }//end if }//end ServiceRequests
/****************************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user * routines. It is a mixture of both USB and * non-USB tasks. * * Note: None *****************************************************************************/ void ProcessIO(void) { //Blink the LEDs according to the USB device status, but only do so if the PC application isn't connected and controlling the LEDs. if(blinkStatusValid) { BlinkUSBStatus(); } // Check if the device is enumerated and is ready to accept commands. if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; if(!USBHandleBusy(USBGenericOutHandle)) //Check if the endpoint has received any data from the host. { switch(OUTPacket[0]) //Data arrived, check what kind of command might be in the packet of data. { case 'A': if(!USBHandleBusy(USBGenericInHandle)) { if(OUTPacket[1] == '0') { ADCON0bits.ADON = 0; // Switch off ADC. ADCON0 &= 0xF0; // Select channel 0 ADCON0bits.ADON = 1; ADCON0bits.GO = 1; // Wait if conversion is happening while(ADCON0bits.DONE); INPacket[0] = ADRESL; INPacket[1] = ADRESH; } else if(OUTPacket[1] == '1') { ADCON0bits.ADON = 0; // Switch off ADC. ADCON0 &= 0xF0; // Select channel ADCON0bits.CHS0 = 1; ADCON0bits.ADON = 1; ADCON0bits.GO = 1; // Wait if conversion is happening while(ADCON0bits.DONE); INPacket[0] = ADRESL; INPacket[1] = ADRESH; } USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(BYTE*)&INPacket,USBGEN_EP_SIZE); } break; case 0x80: //Toggle LED(s) command from PC application. blinkStatusValid = FALSE; //Disable the regular LED blink pattern indicating USB state, PC application is controlling the LEDs. if(mGetLED_1() == mGetLED_2()) { mLED_1_Toggle(); mLED_2_Toggle(); } else { mLED_1_On(); mLED_2_On(); } break; case 0x81: //Get push button state command from PC application. if(!USBHandleBusy(USBGenericInHandle)) { //The endpoint was not "busy", therefore it is safe to write to the buffer and arm the endpoint. INPacket[0] = 0x81; //Echo back to the host PC the command we are fulfilling in the first byte. In this case, the Get Pushbutton State command. if(sw2 == 1) //pushbutton not pressed, pull up resistor on circuit board is pulling the PORT pin high { INPacket[1] = 0x01; } else //sw2 must be == 0, pushbutton is pressed and overpowering the pull up resistor { INPacket[1] = 0x00; } // Arm back the handle. USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(BYTE*)&INPacket,USBGEN_EP_SIZE); } break; } USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE); } }//end ProcessIO
void ServiceRequests( void ) { BYTE num_return_bytes; // Number of bytes to return in response to received command. BYTE cmd; // Store the command in the received packet. // Process packets received through the primary endpoint. if ( !USBHandleBusy( OutHandle[OutIndex] ) ) { num_return_bytes = 0; // Initially, assume nothing needs to be returned. // Got a packet, so start getting another packet while we process this one. OutPacket = &OutBuffer[OutIndex]; // Store pointer to just-received packet. OutPacketLength = USBHandleGetLength( OutHandle[OutIndex] ); // Store length of received packet. cmd = OutPacket->cmd; blink_counter = NUM_ACTIVITY_BLINKS; // Blink the LED whenever a USB transaction occurs. switch ( cmd ) // Process the contents of the packet based on the command byte. { case ID_BOARD_CMD: // Blink the LED in order to identify the board. blink_counter = 50; InPacket->cmd = cmd; num_return_bytes = 1; break; case INFO_CMD: // memcpy( ( void * )( (BYTE *)InPacket ), (void *)&sdBuf, sizeof( sdBuf ) ); InPacket->_dword[0] = numBlocks; InPacket->_word[2] = rdBlockSize; InPacket->_word[3] = wrBlockSize; InPacket->_word[4] = eraseSize; num_return_bytes = 16; break; // Return a packet with information about this USB interface device. InPacket->cmd = cmd; memcpypgm2ram( ( void * )( (BYTE *)InPacket + 1 ), (const rom void *)&device_info, sizeof( DEVICE_INFO ) ); // InPacket->device_info.checksum = calc_checksum( (CHAR8 *)InPacket, sizeof( DEVICE_INFO ) ); num_return_bytes = sizeof( DEVICE_INFO ) + 1; // Return information stored in packet. break; case READ_EEDATA_CMD: InPacket->cmd = OutPacket->cmd; for(buffer_cntr=0; buffer_cntr < OutPacket->len; buffer_cntr++) { InPacket->data[buffer_cntr] = ReadEeprom((BYTE)OutPacket->ADR.pAdr + buffer_cntr); } num_return_bytes = buffer_cntr + 5; break; case WRITE_EEDATA_CMD: InPacket->cmd = OutPacket->cmd; for(buffer_cntr=0; buffer_cntr < OutPacket->len; buffer_cntr++) { WriteEeprom((BYTE)OutPacket->ADR.pAdr + buffer_cntr, OutPacket->data[buffer_cntr]); } num_return_bytes = 1; break; case RESET_CMD: // When resetting, make sure to drop the device off the bus // for a period of time. Helps when the device is suspended. UCONbits.USBEN = 0; lcntr = 0xFFFF; for(lcntr = 0xFFFF; lcntr; lcntr--) ; Reset(); break; default: num_return_bytes = 0; break; } /* switch */ // This command packet has been handled, so get another. OutHandle[OutIndex] = USBGenRead( USBGEN_EP_NUM, (BYTE *)&OutBuffer[OutIndex], USBGEN_EP_SIZE ); OutIndex ^= 1; // Point to next ping-pong buffer. // Packets of data are returned to the PC here. // The counter indicates the number of data bytes in the outgoing packet. if ( num_return_bytes != 0U ) { InHandle[InIndex] = USBGenWrite( USBGEN_EP_NUM, (BYTE *)InPacket, num_return_bytes ); // Now send the packet. InIndex ^= 1; while ( USBHandleBusy( InHandle[InIndex] ) ) { ; // Wait until transmitter is not busy. } InPacket = &InBuffer[InIndex]; } } } /* ServiceRequests */
/** * Check for incoming data in the USB buffer. If found, process it and * fill the USB buffer with data to be returned to the USB host. */ void ServiceRequests(void) { uint32_t rate; if(USBGenRead((byte*)&dataPacket,sizeof(dataPacket))) { // Pointer to the data packet uint8_t* usbptr = dataPacket._byte; uint8_t* usbcmd = usbptr; uint8_t* usblen = usbptr + 1; usbptr += 2; // Points to beginning of payload // When writing data to the buffer, usbptr must always // point to the next free byte in the buffer. // Switch on the command byte of the USB packet we got from the PC switch(dataPacket.CMD) { case READ_VERSION: *usbptr++ = MINOR_VERSION; *usbptr++ = MAJOR_VERSION; break; case LOGIC_GET_SRATE: rate = getSampleRate(); *usbptr++ = (rate >> 24) & 0xFF; *usbptr++ = (rate >> 16) & 0xFF; *usbptr++ = (rate >> 8) & 0xFF; *usbptr++ = rate & 0xFF; // Returned is like [CMD, 0x04, MSB, {}, {}, LSB] break; case LOGIC_CONFIG: // Firstly configure the analyser options if(!logicConfig(*usbptr)) { *usbcmd = LOGIC_ERROR; *usbptr++ = ERROR_INVALID_CONFIG; break; } // Now the sample rate if(!setSampleRate((uint32_t*)(usbptr+1))) { *usbcmd = LOGIC_ERROR; *usbptr++ = ERROR_INVALID_SAMPLE_RATE; break; } // And finally the number of samples if(!setSampleNumber((uint32_t*)(usbptr+5))) { *usbcmd = LOGIC_ERROR; *usbptr++ = ERROR_INVALID_SAMPLE_NUMBER; break; } // Return 3 bytes, payload is '1' for success [CMD, 0x03, 0x01] *usbptr++ = 0x01; break; case LOGIC_ARM: // return [CMD, LEN, RESULT] logicStart(); *usbptr++ = 0x01; break; case LOGIC_POLL: // return [POLL, LEN, STATE] *usbptr++ = getLogicState(); if(getLogicState() == LOGIC_INPROGRESS) { *(uint32_t*)usbptr = writeptr; usbptr += 4; } break; case LOGIC_DATA: if(getLogicState() == LOGIC_END) { usbptr = fillUSBBuffer(usbptr); break; } else if(getLogicState() == LOGIC_END_DATA) { *usbcmd = LOGIC_ERROR; *usbptr++ = ERROR_END_OF_DATA; break; } else { *usbcmd = LOGIC_ERROR; *usbptr++ = ERROR_DATA_UNAVAILABLE; break; } // The following command breaks the the command/response // protocol defined for the Logic Analyser, in order that they be // back compatible with the provided example PC interface. // (They are missing length field). case BLINK_LED_COMMAND: // [0xEE, Onstate] LATDbits.LATD1 = *++usbcmd; break; case GET_ADC_COMMAND: // [0xED. 8-bit data] *usbptr++ = _calcPrescaler(1000UL); break; case LOGIC_RESET: logicReset(); *usbptr++ = 0x01; break; case PING: break; case RESET: Reset(); break; default: // We didn't understand the command the PC sent, so error *usbcmd = LOGIC_ERROR; *usbptr++ = ERROR_CMD_NOT_FOUND; break; } // Calculate the length of the data in the transmit buffer *usblen = usbptr - usbcmd; // If we've put data into the send buffer, then transmit if(*usblen != 0 && !mUSBGenTxIsBusy()) USBGenWrite((byte*)&dataPacket,*usblen); }