|
|
View previous topic :: View next topic |
Author |
Message |
Rob
Joined: 29 Jun 2010 Posts: 3
|
Two way communication via USB on 18f2455 |
Posted: Tue Jun 29, 2010 8:05 am |
|
|
hi folks,
I am currently writing an application for the 18f2455 device on ccs c. the pic should control an external dds chip from analog, connected via pin a0-02.
I use the following code (based on the compiler included example files)...
Code: |
//set to 1 to use a PIC with internal USB Peripheral
//set to 0 to use a National USBN960x peripheral
#define __USB_PIC_PERIF__ 1
////
#include <18F2455.h>
#include "AD9835.c"
//#define USB_CON_SENSE_PIN PIN_B2 //CCS 18F4550 development kit has optional conection sense pin
//~~~ 16MHZ OSCILLATOR CONFIGS ~~~//
// CPUDIV2 => MCU-Clock = 48 MHz
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL4,CPUDIV2,VREGEN
#use delay(clock=16000000)
/////////////////////////////////////////////////////////////////////////////
//
// CCS Library dynamic defines. For dynamic configuration of the CCS Library
// for your application several defines need to be made. See the comments
// at usb.h for more information
//
/////////////////////////////////////////////////////////////////////////////
#DEFINE USB_HID_DEVICE FALSE
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK //turn on EP1 for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK //turn on EP1 for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE 64 //size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE 8 //size to allocate for the rx endpoint 1 buffer
/////////////////////////////////////////////////////////////////////////////
//
// Include the CCS USB Libraries. See the comments at the top of these
// files for more information
//
/////////////////////////////////////////////////////////////////////////////
#include <pic18_usb.h>
#include "usb_desc.h" //USB Configuration and Device descriptors for this UBS device
#include <usb.c> //handles usb setup tokens and get descriptor reports
#define SIZE 512
#define CMD_NEW_FREQ 0x01
#define CMD_NEW_FREQ_SET 0x2
#define ACK 0xff
#define READY 0x64
void main( void )
{
int8 buf[SIZE];
unsigned int32 frequency = 0;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
InitialiseDDS();
usb_init_cs();
while( TRUE )
{
usb_task();
if(usb_enumerated()) {
if (usb_kbhit(1)) {
usb_get_packet(1,buf,8);
// valid incomming frame?
// CMD_NEW_FREQ - f1 - f2 -f3 -f4 * ACK
if ((buf[0] == CMD_NEW_FREQ) && (buf[5] == ACK))
{
// freq change
frequency = 0;
frequency = buf[1];
frequency<<=8;
frequency=frequency|buf[2];
frequency<<=8;
frequency=frequency|buf[3];
frequency<<=8;
frequency=frequency|buf[4];
SendFreqRegDDS(ConvertFrequency(frequency)); //convert to register value & send to DDS chip*/
}
buf[0]=CMD_NEW_FREQ_SET;
buf[5]=READY;
// send ack-frame to the pc
// CMD_NEW_FREQ_SET - f1 - f2 -f3 -f4 * READY
usb_puts( 1, buf, SIZE, 100 );
}
}
}
}
|
The dds chip should change his frequency (represented by f1-f2-f3-f4) when a valid frame is received. After that, the PIC send an ack-frame to
the PC-Application.
I also used a sniffing tool to observe the bus communication.
The Problem is, that the communication works only on the side from pc to pic. I can't get any data from the PIC back to my application. I have no idea where the problem is. Can somebody see the bug? HELP !!! I really get confused.
Last edited by Rob on Tue Jun 29, 2010 12:29 pm; edited 1 time in total |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Jun 29, 2010 11:31 am |
|
|
Code: | if ((buf[0] == CMD_NEW_FREQ) & (buf[5] == ACK)) | Change '&' to '&&'
Also change the LVP fuse to NOLVP. Less than 1% of the people on this forum are using the ancient Low Voltage Programmers. With LVP enabled the PIC is susceptible to noise on the LVP input pin.
Post your compiler version number.
Post the release date of your USB.c and pic18_usb.h (see the 'Version History' inside the file). |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Tue Jun 29, 2010 12:08 pm |
|
|
Are you deliberately using USB HID mode? Why don't you use CDC mode? |
|
|
Rob
Joined: 29 Jun 2010 Posts: 3
|
|
Posted: Tue Jun 29, 2010 12:37 pm |
|
|
ckielstra wrote: | Code: | if ((buf[0] == CMD_NEW_FREQ) & (buf[5] == ACK)) | Change '&' to '&&'
Also change the LVP fuse to NOLVP. Less than 1% of the people on this forum are using the ancient Low Voltage Programmers. With LVP enabled the PIC is susceptible to noise on the LVP input pin.
|
Yeah thanks a lot! It's not my day today (105°F on the desk and no AC)
ckielstra wrote: |
Post your compiler version number.
Post the release date of your USB.c and pic18_usb.h (see the 'Version History' inside the file). |
The compiler version is: 3.222 (yeah really old, i know).
USB.c is: June 20th, 2005
pic18_usb.h is: 06-20-05 Initial Release |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 29, 2010 1:26 pm |
|
|
Quote: |
//~~~ 16MHZ OSCILLATOR CONFIGS ~~~//
// CPUDIV2 => MCU-Clock = 48 MHz
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL4,CPUDIV2,VREGEN
#use delay(clock=16000000) |
I assume you have an external 16 MHz crystal, or 16 MHz oscillator
connected to the PIC's oscillator pin(s).
Your comments imply that you want the PIC's CPU to run at 48 MHz.
But your #use delay() is set for 16 MHz. Furthermore, your fuse setting
of CPUDIV2 will generate a CPU clock of 24 MHz. This must be fixed.
If your real intention is for the CPU clock to be 48 MHz, then you need to
use CPUDIV1, and the #use delay() needs to be set to 48 MHz. Example:
Quote: |
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL4,CPUDIV1,VREGEN
#use delay(clock=48000000)
|
You can prove this to yourself by running a simple LED blinking test
in hardware. I did this and the following code will blink an LED on pin B0
once per second. This is with a 16 MHz crystal installed on the board.
Code: |
#include <18F4550.h>
#fuses HSPLL,NOWDT,PUT,BROWNOUT,PLL4, CPUDIV1,NOLVP
#use delay(clock=48000000)
//======================================
void main(void)
{
while(1)
{
output_high(PIN_B0);
delay_ms(100);
output_low(PIN_B0);
delay_ms(900);
}
} |
|
|
|
Rob
Joined: 29 Jun 2010 Posts: 3
|
|
Posted: Tue Jun 29, 2010 2:38 pm |
|
|
PCM programmer wrote: |
the #use delay() needs to be set to 48 MHz.
|
thats right! mea culpa.
PCM programmer wrote: |
If your real intention is for the CPU clock to be 48 MHz, then you need to
use CPUDIV1,
|
Why CPUDIV1?
The Primary CLK frequency comes from the 96 MHz PLL and must divided by 2 (CPUDIV2), right?! Also CPUDIV1 is not defined in 18f2455-header file! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 29, 2010 2:46 pm |
|
|
It is in vs. 4.109. It has CPUDIV1 to 4.
Code: | #device PIC18F2455
#nolist
//////// Program memory: 12288x16 Data RAM: 2048 Stack: 31
//////// I/O: 23 Analog Pins: 13
//////// Data EEPROM: 256
//////// C Scratch area: 00 ID Location: 200000
.
.
.
//////// Fuses: WDT2048,WDT4096,WDT8192,WDT16384,WDT32768,HS,HSPLL,PLL1,PLL2
//////// Fuses: PLL3,PLL4,PLL5,PLL6,PLL10,PLL12,USBDIV,NOUSBDIV,CPUDIV1
//////// Fuses: CPUDIV2,CPUDIV3,CPUDIV4,VREGEN,NOVREGEN
////////
|
Also note that CCS calls the fuses CPUDIV1 to CPUDIV4. These are
the divisors (1 to 4) for the normal oscillator. The PLL has different
divisors (2 to 6), but you must still use the CPUDV1 to CPUDIV4 fuse
settings. Here is the correspondence:
CPUDIV1 = PLL postscaler divisor of 2.
CPUDIV2 = PLL postscaler divisor of 3.
CPUDIV3 = PLL postscaler divisor of 4.
CPUDIV4 = PLL postscaler divisor of 6. |
|
|
|
|
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
|