View previous topic :: View next topic |
Author |
Message |
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
USB using too much RAM |
Posted: Wed May 19, 2010 10:22 am |
|
|
I need a 1024 array of 16-bit variables in my USB application with the PIC18F26J50. I am getting the "Not enough RAM for all variables" compile error. I tried modifying the PIC18F_usb.c file to:
Code: | #elif ((getenv("DEVICE")=="PIC18F24J50") || (getenv("DEVICE")=="PIC18F25J50") || \
(getenv("DEVICE")=="PIC18F26J50") || (getenv("DEVICE")=="PIC18F44J50") || \
(getenv("DEVICE")=="PIC18F45J50") || (getenv("DEVICE")=="PIC18F46J50"))
#define __USB_46J50__
#define USB_TOTAL_RAM_SPACE ((int16)getenv("RAM")-0xC00)
#define USB_RAM_START 0x400
#define USB_NUM_UEP 16
#define USB_LAST_ALLOWED_ENDPOINT 16 |
I changed:
Code: | #define USB_TOTAL_RAM_SPACE ((int16)getenv("RAM")-0x400) |
to:
Code: |
#define USB_TOTAL_RAM_SPACE ((int16)getenv("RAM")-0xC00) |
I'm thinking the USB_RAM_START is dedicated at 0x400 (Buffer descriptors) so I cannot change it to 0xC00 (changing it allows compile!?! but will cause driver not to be found in windows). So the next question becomes how to tell the compiler to allocate the back 2K end (or split it up some how) of RAM for the array and not for USB. Anyone know how this is done?
BTW, not really concerned too much with any performance hit right now. No ultra high speed stuff going on. Connecting with Windows 2000 32-bit computer. PCWH 4.107 compiler.
-Matt _________________ -Matt |
|
|
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
|
Posted: Wed May 19, 2010 12:13 pm |
|
|
Seriously, isn't there any documentation around with instructions on how to configure the USB? Or does CCS just expect you to use their default configurations? _________________ -Matt |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 19, 2010 12:20 pm |
|
|
Are you compiling a CCS example ? Hopefully you are, because then
I could also compile it and look at the problem. If so, post the filename.
If you're not using a CCS example, then try using one of them and get
it to fail in the same way. Then post the filename. I need something
to test. (And post a list of hopefully the very minimal changes that you
did to it). |
|
|
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
|
Posted: Wed May 19, 2010 1:33 pm |
|
|
Here you go. Based on the ex_usb_serial.c code.
Code: | #include <18F26J50.h>
#device adc=10
#FUSES NODEBUG
#FUSES NOXINST
#FUSES STVREN
#FUSES PRIMARY
#FUSES PLLDIV2
#FUSES NOWDT
#FUSES CPUDIV2
#FUSES PROTECT
#FUSES NOIESO
#FUSES NOFCMEN
#FUSES NOLPT1OSC
#FUSES NOT1DIG
#FUSES INTRC_PLL_IO
//#FUSES INTRC_IO
#FUSES WDT128
#FUSES RTCOSC_T1
#FUSES DSWDTOSC_INT
#FUSES NODSWDT
#FUSES NODSBOR
#FUSES DSWDT2147483648
#FUSES MSSPMSK7
#FUSES NOIOL1WAY
#FUSES NOWPCFG
#FUSES WPFP
#FUSES WPEND
#FUSES WPDIS
#use delay(clock=24000000)
#ZERO_RAM
#include <stdio.h>
#include <stdlib.h>
#define USB_CON_SENSE_PIN PIN_C2 //Voltage level converted
#define USB_USE_FULL_SPEED 0
#include <usb_cdc.h>
#BYTE port_a = 0x0F80//0x05
#BYTE port_b = 0x0F81//0x06
#BYTE port_c = 0x0F82//0x07
#define a_dir 0x5B //directional running
#define a_dirs 0x5B //directional sleep
#define a_def 0x00
#define b_dir 0xF6 //directional running
#define b_dirs 0xF6 //directional sleep
#define b_def 0x00
#define c_dir 0x4E //directional running
#define c_dirs 0x4E //directional sleep
#define c_def 0x00
#define sleepf PIN_B0
/************ Main ****************/
void main()
{
int i, j, address, value;
long array[1024];
int up;
setup_adc(ADC_OFF); //disable ADC
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_4);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_oscillator(OSC_8MHZ|OSC_NORMAL|OSC_PLL_ON|OSC_IDLE_MODE);
set_tris_a(a_dirs); //settup port directions
set_tris_b(b_dirs);
port_b_pullups(FALSE); //Don't need pull ups
set_tris_c(c_dirs);
port_a = a_def; //default pin states
port_b = b_def;
port_c = c_def;
enable_interrupts(GLOBAL);
usb_init_cs();
while(1)
{
output_bit(sleepf,0); //sleep
usb_task();
if (usb_enumerated())
{
if (usb_cdc_kbhit())
{
for(up = 0;up<1024;up++)
{
array[up] = up;
}
}
}
}
} |
Results in "Not enough RAM for all variables" error. If you change array to int, it compiles with ~80% RAM. I did a search in this forum the other day and one result gave me a hint on the PIC18_usb.c file configuration. The file has changed since that post though so I was trying mess around with it myself.
-Matt _________________ -Matt |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 19, 2010 1:54 pm |
|
|
If I take the array out of main() and make it a global, then it compiles OK.
Example:
Code: |
long array[1024]; // Use global array
/************ Main ****************/
void main()
{
int i, j, address, value;
// long array[1024];
int up;
|
|
|
|
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
|
Posted: Wed May 19, 2010 2:41 pm |
|
|
Haha, you know when I was trying to get a program to post for you I was trying that out. I was using the ex_usb_serial.c file itself and the device used in that example must have less RAM. It worked in my program also.
Thanks!
So the compiler just doesn't check for local variable when it is deciding how much RAM it can share with USB or something? My program is now only using 65% RAM. That's a big difference. _________________ -Matt |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Wed May 19, 2010 2:42 pm |
|
|
In usb.h, there is a define section:
Code: |
//set to false to opt for less RAM, true to opt for less ROM
#ifndef USB_OPT_FOR_ROM
#define USB_OPT_FOR_ROM TRUE
#endif
|
If you define
#define USB_OPT_FOR_ROM FALSE
Before you load usb.h, the USB code will take less RAM, but more ROM
It makes a very significant difference.
Best Wishes |
|
|
|