Frequently Asked Questions

How can I create a custom variable definition that points to an external memory device? (or what is typemod?)

CCS provides a feature called typemod which can be used to define a memory region that can be RAM, program memory or external memory.

The usage is:

typemod <,read(),write(),start,end> name
  • read() - Defines the read function defined for this block of memory. The function must follow this prototype:
          read(int32 addr, int8 *ptr, int8 len)
    This function specifies to the compile how to read a block of data from this custom variable type. This function must be provided by the user and is application specific.
    Note: the function can be named something other than read()

  • write() - Defines the write function defined for this block of memory. The function must follow this prototype:
          write(int32 addr, int8 *ptr, int8 len)
    This function specifies to the compile how to write a block of data from this custom variable type. This function must be provided by the user and is application specific.
    Note: the function can be named something other than write()

  • start - Defines the start address of the specified memory. The first defined variable using this custom variable definition will start at this address.

  • end - Defines the end address of the specified memory. Therefore the maximum number of bytes of variables that can be defined for this custom variable definition is end-start.

  • name - Defines the name of this custom variable type. This is the name that will be used as the declarator when defining variables that will use this typemod.

If you do not specify a read() and write() function it will use the RAM in the PIC® MCU. This is useful if you want to create a custom variable defintion that is fixed to a specific bank.

For example:

typemod <,DataEE_Read, DataEE_Write, 5, 0xFF> DataEE
This would define a region called DataEE, and use addresses between 5 and 0xFF. DataEE_Read() and DataEE_Write() are your read and write functions, respectively.

Here is a full example that shows how typemod is used to create a custom variable definition to easily read and write to an AT29C1024 external flash:

#include <protoexternal.h>
#include <utility.c>
#include <at29c1024.c>

void ext_flash_read(int32 addr, int8 *ram, int8 bytes) {
   read_block_ext_flash_memory(addr,ram,bytes);
}

void ext_flash_write(int32 addr, int8 *ram, int8 bytes) {
   read_block_ext_flash_memory(addr,ram,bytes);
}  

typemod <,ext_flash_read, ext_flash_write,5,0xFF> flashmem;

int flashmem countm;

void main(void) {
   int count;
   int_ext_flash_memory();
   count=countm;
   while(TRUE) {
      show_binary_on_leds(count);
      wait_for_one_press();
      count++;
      countm=count;
   }
}

In the above example countm is using the custom variable definition fashmem. Any write to countm (the line countm=count) will call ext_flash_write(), and any read from countm (the line count=countm) will call ext_flash_read(). You can create any data type with typemod, including arrays, structures and unions.

You can also create a pointer to a typemod defined variable type. For example:

int flashmem ext_array[50];
int flashmem *ptr;
int i;

ptr=&ext_array[25];

i=*ptr;  //get ext_array[25] from the external flash memory

ptr++;   //point to ext_array[26]
*ptr=i;  //write to ext_array[26]

typemod can be used with any data provided that you specify functional read and write routines. For example, you can use typemod to easily read and write to the program memory (ROM) of the PIC® MCU.