void SMP_sendData(void) { /** * Send sampled data over USB * * Waits for a buffer to be ready to send and then sends it */ SMP_LAST_TRANSMISSION = 0; // write the data buffer to the USB if(!mUSBGenTxIsBusy()) { // wait for the send buffer to be ready to send while(!(SMP_BUFFER_STATE[SMP_SEND_BUFFER_NUM] & SMP_BUF_RTS)); // send it USBGenWrite((BYTE*)(SMP_BUFFER+(SMP_SEND_BUFFER_NUM*1024)),1024); // unset RTS for the previous buffer SMP_BUFFER_STATE[(SMP_SEND_BUFFER_NUM+SMP_NUM_BUFFERS-1)%SMP_NUM_BUFFERS] &= ~SMP_BUF_RTS; } else { // ERROR } // move to the next buffer SMP_SEND_BUFFER_NUM = (SMP_SEND_BUFFER_NUM + 1) % SMP_NUM_BUFFERS; }
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
/** * 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); }