|
|
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: 1362
|
|
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: Code: | if (theCRC = in_data[7]) { | Classic '=' instead of '=='.
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: 1362
|
|
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
|