Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

C question - having array access same points in RAM

Status
Not open for further replies.

toodles

New Member
I'm attempting to setup my 18F4550 with 2 or more different sets of USB code, depending on buttons pressed when powered on. The USB code modules will both use HID, but with different in and out buffer sizes. All of the USB code I've seen uses a #pragma udata line that specifies where the buffer will be, in one of the pages of memory that is shared directly with the USB code in the code page from 0x400-0x4FF. Both of them declare the areas for the EP0-EP15, and then the endpoint buffers.

What I need to know is how can I define arrays access specific sections of memory. Let's say the buffer size for USB1 is 0x10 bytes, and the buffer size for USB2 is 0x18 bytes. I'll need a way to define four arrays:
unsigned char USB1OUT[0x10] starting at address 0x480
unsigned char USB1IN[0x10] starting at address 0x490
unsigned char USB2OUT[0x18] starting at address 0x480
unsigned char USB2IN[0x18] starting at address 0x498

Can anyone help point out to me how to do this?
 
I think what you want to do is use a pointer and assign the address you need to the pointer. When you declare an array you are allocating ADDITIONAL memory.
 
Check out the use of a "union". It might not do exactly what you want but it may come close enough.

The "pointer" would work except that you want to make a static reference to the arrays.

I'm thinking you can have static arrays or very efficient storage allocation but not both.
 
This code shows how the union works and how to address each buffer. What the example does not do is locate the buffers in the right place.

I have not done this with C18 but in general it goes like this. You need a 32 byte section setup at memory location 0x480 (linker script). Tell the compiler to put USBbits in that section by using a directive in the C source. The named memory section (code block) may already exist if you are using a USB aware linker script.

Run this code in the simulator and you can see how the buffers share memory.

HTH

Code:
#pragma	config OSC = INTIO2, WDT = OFF, LVP = OFF
#include <p18f1320.h>
#include <delays.h>

// directive to locate in memory goes here
union {
  struct {
    unsigned char USB1OUT[10];
    unsigned char USB1IN[10];
  };
  struct {
    unsigned char USB2OUT[18];
    unsigned char USB2IN[18];
  };
} USBbits;

void main(void)
{
	USBbits.USB1OUT[0] = 0x5A;
	USBbits.USB1IN[0]  = 0x3C;   
	Nop();
}
 
I understand unions and appreciate the idea, I just don't think I could cleanly implement it. I'd have to update or tweak the union for every one of the USB modules as they get implemented and that doesn't seem to be a very modularized way of doing it.

What I've done so far, and it seems to be working with what I have now, is to go ahead and use the #pragma to define an unsigned char USBRAM[256] in the ram page, made a array of the buffer descriptors *BUFDESC=&USBRAM[0], #defines the in and out buffers for each endpoint 0-15 (yes, I know I wont be using more than couple.) so BD2I is replaced with BUFDESC[3]. And lastly made an unsigned char *USBBUFFERRAM=&BUFDESC[32] so I have a pointer to the ram past the buffer descriptors. (The pointer here and following pointers are stored in regular #pragma udata for the linker to locate wherever it likes)

So for each module, I have the buffers defined as
unsigned char *EPBUF0IN=&USBBUFFERRAM;
unsigned char *EPBUF0OUT=&USBBUFFERRAM[MAXPACKETSIZE];
unsigned char *EPBUF1IN=&USBBUFFERRAM[MAXPACKETSIZE*2];
...etc. for however many I need within the remaining RAM. (MAXPACKETSIZE will be different between modules as needed, but I doubt any will be >8.)

Thanks for the help guys.
 
I understand unions and appreciate the idea, I just don't think I could cleanly implement it. I'd have to update or tweak the union for every one of the USB modules as they get implemented and that doesn't seem to be a very modularized way of doing it

It does exactly what you asked for in you first post.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top