| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| t1d 
 
 
 Joined: 10 Feb 2015
 Posts: 4
 
 
 
			    
 
 | 
			
				| Noob Catch 22 |  
				|  Posted: Tue Feb 10, 2015 3:57 am |   |  
				| 
 |  
				| I am new to electronics and have built a PCB for a particular oscilloscope. It is a simple circuit and I will end up with something more useful than just blinking LEDs. 
 The author only posted the CCS .c code. He did not post the hex code for the chip; 18F4550. I missed this very important detail, because he wrote "(hex)" in the title to the .c file.
 
 I do not have CCS and do not know anyone that does. I need someone to compile the code into hex. And, if hex comes in different versions, I need it in a version that will load onto the chip with some free program... I have the MPLAB freewares.
 
 Here is the link to the project site:
 http://www.semifluid.com/2006/03/28/pic18f2550-usb-hid-io/#more-23
 
 I am using the version for the 18F4550 chip. The files are at the end of the commentary, just before the reader questions, in "Update 2." I think I need the version with the bootloader.
 
 I do not intend to be asking for something that is against the rules. Please forgive me, if I am.
 
 Here is the code. (Didn't see how to attach the file?) I think it was written with CCS PCWH 3.249. Thank you for your help.
 
 
  	  | Code: |  	  | //////////////////////////////////////////////////////////////////////////////// //                 PIC18F4550 USB HID IO
 //
 // Filename     : 18F4550 USB HID CRC IO.c
 // Programmer   : Steven Cholewiak, www.semifluid.com
 // Version      : Version 1.0 - 12/18/2006
 // Remarks      : More information on the circuit can be found at:
 //                http://www.semifluid.com/PIC18F2550_usb_hid_io.html
 ////////////////////////////////////////////////////////////////////////////////
 
 #define __USB_PIC_PERIF__ 1
 
 #include <18F4550.h>
 #device ADC=8
 #fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
 #use delay(clock=48000000)
 
 #build(reset=0x1, interrupt=0x8)          // Necessary for Bootloader
 #ORG 0x0F00,0x0FFF {}                     // Necessary for Bootloader
 
 #use rs232(stream=PC, baud=115200, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
 
 // CCS Library dynamic defines
 #DEFINE USB_HID_DEVICE  TRUE //Tells the CCS PIC USB firmware to include HID handling code.
 #define USB_EP1_TX_ENABLE  USB_ENABLE_INTERRUPT   //turn on EP1 for IN bulk/interrupt transfers
 #define USB_EP1_TX_SIZE    64  //allocate 64 bytes in the hardware for transmission
 #define USB_EP1_RX_ENABLE  USB_ENABLE_INTERRUPT   //turn on EP1 for OUT bulk/interrupt transfers
 #define USB_EP1_RX_SIZE    64  //allocate 64 bytes in the hardware for reception
 
 // CCS USB Libraries
 #include <pic18_usb.h>   //Microchip 18Fxx5x hardware layer for usb.c
 #include <usb_desc_hid 8-byte.h>   //USB Configuration and Device descriptors for this UBS device
 #include <usb.c>        //handles usb setup tokens and get descriptor reports
 
 void usb_debug_task(void) {
 static int8 last_connected;
 static int8 last_enumerated;
 int8 new_connected;
 int8 new_enumerated;
 
 new_connected=usb_attached();
 new_enumerated=usb_enumerated();
 
 if (new_connected && !last_connected) {
 printf("\r\n\nUSB connected, waiting for enumaration...");}
 if (!new_connected && last_connected) {
 printf("\r\n\nUSB disconnected, waiting for connection...");}
 if (new_enumerated && !last_enumerated) {
 printf("\r\n\nUSB enumerated by PC/HOST");}
 if (!new_enumerated && last_enumerated) {
 printf("\r\n\nUSB unenumerated by PC/HOST, waiting for enumeration...");}
 
 last_connected=new_connected;
 last_enumerated=new_enumerated;
 }
 
 #INT_RDA
 void serial_isr()                         // Serial Interrupt
 {
 int8 uReceive;
 
 disable_interrupts(GLOBAL);            // Disable Global Interrupts
 
 uReceive = fgetc(PC);
 
 switch (uReceive) {
 case 0x12: {
 if (fgetc(PC) == 0x34 & fgetc(PC) == 0x56 & fgetc(PC) == 0x78 & fgetc(PC) == 0x90) #asm reset #endasm
 }
 break;
 }
 
 enable_interrupts(GLOBAL);                // Enable Global Interrupts
 }
 
 int calc_crc(int oldcrc, int newbyte) {
 // Please see: http://pdfserv.maxim-ic.com/arpdf/AppNotes/app27.pdf
 
 int shift_reg, data_bit, sr_lsb, fb_bit, j;
 shift_reg=oldcrc;
 for(j=0; j<8; j++) {   // for each bit
 data_bit = (newbyte >> j) & 0x01;
 sr_lsb = shift_reg & 0x01;
 fb_bit = (data_bit ^ sr_lsb) & 0x01;
 shift_reg = shift_reg >> 1;
 if (fb_bit)
 shift_reg = shift_reg ^ 0x8c;
 }
 return(shift_reg);
 }
 
 #define theSampleSize            512
 
 #define usbConfirmAction         0
 #define usbCheckStatus           1
 #define usbReadRam               2
 #define usbWriteRam              3
 #define usbReadADC               4
 #define usbReadADCnTimes         5
 #define usbReadADCPeriod         6
 #define usbReadADCnTimesMS       7
 #define usbClearRam              8
 #define usbSetRamByte            9
 #define usbSetUseCRC             10
 #define usbClearUseCRC           11
 #define usbReadADCnTimesUS       12
 #define usbReadPort              13
 #define usbWritePort             14
 #define usbReadPin               15
 #define usbWritePin              16
 #define usbError                 66
 
 void main() {
 int1 useCRC;
 int8 in_data[8];
 int8 out_data[8];
 int8 adcData[theSampleSize];
 int8 theCRC, tempADC, currentADCpin;
 int16 n, approxUS, approxMS, period;
 
 SETUP_ADC_PORTS(AN0_TO_AN4);
 SETUP_ADC(ADC_CLOCK_DIV_64);
 SETUP_TIMER_0(RTCC_INTERNAL|RTCC_DIV_1);
 SETUP_TIMER_1(T1_DISABLED);
 SETUP_TIMER_2(T2_DISABLED, 127, 1);
 SETUP_TIMER_3(T3_INTERNAL | T3_DIV_BY_8);
 SETUP_CCP1(CCP_OFF);
 SETUP_CCP2(CCP_OFF);
 enable_interrupts(INT_RDA);
 enable_interrupts(GLOBAL);
 
 usb_init();
 useCRC = true;
 currentADCpin = 0;
 set_adc_channel(0);
 delay_ms(1);
 
 while (TRUE) {
 usb_task();
 usb_debug_task();
 if (usb_enumerated()) {
 if (usb_kbhit(1)) {
 usb_get_packet(1, in_data, 8);
 
 if (useCRC) {
 theCRC = 0;
 theCRC = calc_crc(theCRC,in_data[0]);
 theCRC = calc_crc(theCRC,in_data[1]);
 theCRC = calc_crc(theCRC,in_data[2]);
 theCRC = calc_crc(theCRC,in_data[3]);
 theCRC = calc_crc(theCRC,in_data[4]);
 theCRC = calc_crc(theCRC,in_data[5]);
 theCRC = calc_crc(theCRC,in_data[6]);
 }
 else {
 theCRC = in_data[7];
 }
 
 if (theCRC = in_data[7]) {
 out_data[0] = 255;
 out_data[1] = 255;
 out_data[2] = 255;
 out_data[3] = 255;
 out_data[4] = 255;
 out_data[5] = 255;
 out_data[6] = 255;
 
 switch (in_data[0]) {
 case usbReadRam: {
 if (make16(in_data[1],in_data[2]) <= theSampleSize) {
 out_data[0] = usbConfirmAction;
 out_data[1] = usbReadRam;
 out_data[2] = in_data[1];
 out_data[3] = in_data[2];
 out_data[4] = adcData[make16(in_data[1],in_data[2])];
 }
 else {
 out_data[0] = usbError;
 out_data[1] = usbReadRam;
 out_data[2] = in_data[1];
 out_data[3] = in_data[2];
 }
 }
 break;
 case usbWriteRam: {
 if (make16(in_data[1],in_data[2]) <= theSampleSize) {
 adcData[make16(in_data[1],in_data[2])] = in_data[3];
 out_data[0] = usbConfirmAction;
 out_data[1] = usbWriteRam;
 out_data[2] = in_data[1];
 out_data[3] = in_data[2];
 out_data[4] = in_data[3];
 }
 else {
 out_data[0] = usbError;
 out_data[1] = usbWriteRam;
 out_data[2] = in_data[1];
 out_data[3] = in_data[2];
 out_data[4] = in_data[3];
 }
 }
 break;
 case usbReadADC: {
 if (in_data[1] != 255 & in_data[1] != currentADCpin) {
 currentADCpin = in_data[1];
 set_adc_channel(currentADCpin);
 delay_ms(1);
 }
 tempADC = READ_ADC();
 out_data[0] = usbConfirmAction;
 out_data[1] = usbReadADC;
 out_data[2] = tempADC;
 out_data[3] = in_data[1];
 }
 break;
 case usbReadADCnTimes: {
 if (make16(in_data[1],in_data[2]) <= theSampleSize) {
 if (in_data[3] != 255 & in_data[3] != currentADCpin) {
 currentADCpin = in_data[3];
 set_adc_channel(currentADCpin);
 delay_ms(1);
 }
 set_timer3(0);
 for (n=0;n<make16(in_data[1],in_data[2]);n++)
 {
 adcData[n] = READ_ADC();
 }
 period = get_timer3();   // 1000/((clock/4)/8) for ms
 out_data[0] = usbConfirmAction;
 out_data[1] = usbReadADCnTimes;
 out_data[2] = in_data[1];
 out_data[3] = in_data[2];
 out_data[4] = in_data[3];
 }
 else {
 out_data[0] = usbError;
 out_data[1] = usbReadADCnTimes;
 out_data[2] = in_data[1];
 out_data[3] = in_data[2];
 out_data[4] = in_data[3];
 }
 }
 break;
 case usbReadADCPeriod: {
 out_data[0] = usbConfirmAction;
 out_data[1] = usbReadADCPeriod;
 out_data[2] = make8(period,1);
 out_data[3] = make8(period,0);
 }
 break;
 case usbReadADCnTimesUS: {
 if (make16(in_data[1],in_data[2]) <= theSampleSize) {
 if (in_data[5] != 255 & in_data[5] != currentADCpin) {
 currentADCpin = in_data[5];
 set_adc_channel(currentADCpin);
 delay_ms(1);
 }
 approxUS = make16(in_data[3],in_data[4]);
 for (n=0;n<make16(in_data[1],in_data[2]);n++)
 {
 set_timer3(0);
 adcData[n] = READ_ADC();
 while (get_timer3() * 2/3 < approxUS);   // 1000000/((clock/4)/8)
 }
 out_data[0] = usbConfirmAction;
 out_data[1] = usbReadADCnTimesUS;
 out_data[2] = in_data[1];
 out_data[3] = in_data[2];
 out_data[4] = in_data[3];
 out_data[5] = in_data[4];
 out_data[6] = in_data[5];
 }
 else {
 out_data[0] = usbError;
 out_data[1] = usbReadADCnTimesUS;
 out_data[2] = in_data[1];
 out_data[3] = in_data[2];
 out_data[4] = in_data[3];
 out_data[5] = in_data[4];
 out_data[6] = in_data[5];
 }
 }
 break;
 case usbReadADCnTimesMS: {
 if (make16(in_data[1],in_data[2]) <= theSampleSize) {
 if (in_data[5] != 255 & in_data[5] != currentADCpin) {
 currentADCpin = in_data[5];
 set_adc_channel(currentADCpin);
 delay_ms(1);
 }
 approxMS = make16(in_data[3],in_data[4]);
 for (n=0;n<make16(in_data[1],in_data[2]);n++)
 {
 set_timer3(0);
 adcData[n] = READ_ADC();
 while (get_timer3() * 1/1500 < approxMS);   // 1000/((clock/4)/8)
 }
 out_data[0] = usbConfirmAction;
 out_data[1] = usbReadADCnTimesMS;
 out_data[2] = in_data[1];
 out_data[3] = in_data[2];
 out_data[4] = in_data[3];
 out_data[5] = in_data[4];
 out_data[6] = in_data[5];
 }
 else {
 out_data[0] = usbError;
 out_data[1] = usbReadADCnTimesMS;
 out_data[2] = in_data[1];
 out_data[3] = in_data[2];
 out_data[4] = in_data[3];
 out_data[5] = in_data[4];
 out_data[6] = in_data[5];
 }
 }
 break;
 case usbClearRam: {
 for (n=0;n<512;n++)
 {
 adcData[n] = 0;
 }
 out_data[0] = usbConfirmAction;
 out_data[1] = usbClearRam;
 }
 break;
 case usbSetRamByte: {
 for (n=0;n<512;n++)
 {
 adcData[n] = in_data[1];
 }
 out_data[0] = usbConfirmAction;
 out_data[1] = usbSetRamByte;
 out_data[2] = in_data[1];
 }
 break;
 case usbSetUseCRC: {
 useCRC = true;
 out_data[0] = usbConfirmAction;
 out_data[1] = usbSetUseCRC;
 }
 break;
 case usbClearUseCRC: {
 useCRC = false;
 out_data[0] = usbConfirmAction;
 out_data[1] = usbClearUseCRC;
 }
 break;
 case usbReadPort: {
 out_data[0] = usbConfirmAction;
 out_data[1] = usbReadPort;
 out_data[2] = input_b();
 }
 break;
 case usbWritePort: {
 output_b(in_data[1]);
 out_data[0] = usbConfirmAction;
 out_data[1] = usbWritePort;
 out_data[2] = in_data[1];
 }
 break;
 case usbReadPin: {
 out_data[0] = usbConfirmAction;
 out_data[1] = usbReadPin;
 out_data[2] = in_data[1];
 switch (in_data[1]) {
 case 0: out_data[3] = input(PIN_B0); break;
 case 1: out_data[3] = input(PIN_B1); break;
 case 2: out_data[3] = input(PIN_B2); break;
 case 3: out_data[3] = input(PIN_B3); break;
 case 4: out_data[3] = input(PIN_B4); break;
 case 5: out_data[3] = input(PIN_B5); break;
 case 6: out_data[3] = input(PIN_B6); break;
 case 7: out_data[3] = input(PIN_B7); break;
 }
 }
 break;
 case usbWritePin: {
 switch (in_data[1]) {
 case 0: output_bit(PIN_B0, in_data[2] & 1); break;
 case 1: output_bit(PIN_B1, in_data[2] & 1); break;
 case 2: output_bit(PIN_B2, in_data[2] & 1); break;
 case 3: output_bit(PIN_B3, in_data[2] & 1); break;
 case 4: output_bit(PIN_B4, in_data[2] & 1); break;
 case 5: output_bit(PIN_B5, in_data[2] & 1); break;
 case 6: output_bit(PIN_B6, in_data[2] & 1); break;
 case 7: output_bit(PIN_B7, in_data[2] & 1); break;
 }
 out_data[0] = usbConfirmAction;
 out_data[1] = usbWritePin;
 out_data[2] = in_data[1];
 out_data[3] = in_data[2];
 }
 break;
 }
 if (useCRC) {
 theCRC = 0;
 theCRC = calc_crc(theCRC,out_data[0]);
 theCRC = calc_crc(theCRC,out_data[1]);
 theCRC = calc_crc(theCRC,out_data[2]);
 theCRC = calc_crc(theCRC,out_data[3]);
 theCRC = calc_crc(theCRC,out_data[4]);
 theCRC = calc_crc(theCRC,out_data[5]);
 theCRC = calc_crc(theCRC,out_data[6]);
 out_data[7] = theCRC;
 }
 
 usb_put_packet(1, out_data, 8, USB_DTS_TOGGLE);
 }
 
 delay_ms(1);
 }
 }
 }
 }
 | 
 |  |  
		|  |  
		| jeremiah 
 
 
 Joined: 20 Jul 2010
 Posts: 1401
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Feb 10, 2015 9:13 am |   |  
				| 
 |  
				| The "(hex)" next to the filename is a separate link and goes directly to the .hex file that  you need.  You can download that and use whatever flash programming device that you have to download it to the chip. |  |  
		|  |  
		| t1d 
 
 
 Joined: 10 Feb 2015
 Posts: 4
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Feb 10, 2015 12:58 pm |   |  
				| 
 |  
				| Oh my gosh... I feel so foolish... Thank you for your help... |  |  
		|  |  
		| ckielstra 
 
 
 Joined: 18 Mar 2004
 Posts: 3680
 Location: The Netherlands
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Feb 10, 2015 2:16 pm |   |  
				| 
 |  
				| Couldn't help to spot a few problems: Classic '=' instead of '=='. 	  | Code: |  	  | if (theCRC = in_data[7]) { | 
 Now the test for a valid CRC will always succeed, except for a CRC value zero, then the program won't do what you expect.
 
 The author also confuses '&' and '&&'. It works but doesn't reflect his intentions.
 
 Inside the serial interrupt routine it is not required to disable the Global interrupt as the hardware is doing this automatically. A few lines lower however, enabling the Global interrupt again is a bug. Normally the hardware handles this too. If another interrupt is waiting to be served then it would fire immediately, not allowing the current interrupt to restore its saved context with undefined behaviour as a result.
 |  |  
		|  |  
		| t1d 
 
 
 Joined: 10 Feb 2015
 Posts: 4
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Feb 11, 2015 10:48 am |   |  
				| 
 |  
				| Okay, this is way out of my league  I take it that this error, "==," is in the .c code. I might be able to make this correction, but then I have no way to recompile the code into hex. I have been in contact with the author and he doesn't think he has the compiler anymore, either. 
 I was able to load the hex file onto the PIC with PICKit2. However, the dashboard, which was written in Visual Basic, says that the usb device is "disconnected."
 
 I am still working through it all and wondering what to do...
 
 Any suggestions would be welcomed. Your help is very much appreciated.
 |  |  
		|  |  
		| jeremiah 
 
 
 Joined: 20 Jul 2010
 Posts: 1401
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Feb 11, 2015 12:59 pm |   |  
				| 
 |  
				| Did you try the demo version of CCS? |  |  
		|  |  
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Feb 11, 2015 1:53 pm |   |  
				| 
 |  
				| I thought of that too, but unfortunately the demo version only has 15% of the drivers and example files.  It may not have all the USB driver files.
 But it could be tried:
 http://www.ccsinfo.com/ccsfreedemo.php
 |  |  
		|  |  
		| t1d 
 
 
 Joined: 10 Feb 2015
 Posts: 4
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Feb 11, 2015 3:52 pm |   |  
				| 
 |  
				| Good suggestion. I'll keep that in mind... |  |  
		|  |  
		|  |  
  
	| 
 
 | You cannot post new topics in this forum You cannot reply to topics in this forum
 You cannot edit your posts in this forum
 You cannot delete your posts in this forum
 You cannot vote in polls in this forum
 
 |  
 Powered by phpBB © 2001, 2005 phpBB Group
 
 |