CCS News RSS

Click here to view the PDF newsletters. Interested in receiving our newsletters in your inbox? Click here to subscribe.

Optimize Code Using Fixed-Point instead of Floating point with the CCS C Compiler

Thursday 24 June, 2021

Most embedded microprocessors and microcontrollers, including the Microchip PIC® MCU families, do not contain a hardware implemented floating-point calculator. This means that all float calculations must be implemented in software using integer arithmetic, which is very resource intensive. In turn, performance heavy applications and resource limited platforms may be unable to utilize floating point numbers in their implementation. The solution for this is to instead use fixed-point arithmetic, which is simplified by the CCS C Compiler's fixed type feature.

Fixed-point arithmetic is an implementation that uses a scaling factor to represent decimal numbers in integer form. The CCS C Compiler implements this using 16 or 32 bit integers and a scaling factor of 10-n. A fixed type can be declared as follows:

int16 _fixed(n) foo; where 0 < n < 6
int32 _fixed(n) foo; where 0 < n < 11

The value n determines the number of decimal places of accuracy the variable will contain, as well as the maximum representable value. Since n is part of the type and determines what instructions are generated, it must be given as a constant at compile time.

For int16 _fixed(2) : Max = 65,535 * 10-2 = 655.35
For int32 _fixed(5) : Max = 4,294,967,295 10-5 = 42,949.67295

The binary/hexadecimal representation for any number can then be determined by multiplying by the inverse of the scaling factor and converting.

237.16 * 10-2 = 23716 = 0x5CA4

The fixed type is compatible with another fixed type of the same n for the 4 basic arithmetic operations. They are not compatible with fixed types with a different n.

int16 _fixed(1) f1 = 5.5;
int16 _fixed(1) f2 = 2.5;
f1 + f2; //evaluates to 8.0
f1 - f2; //evaluates to 3.0
f1 * f2; //evaluates to 13.7
f1 / f2; //evaluates to 2.2

It can also perform arithmetics with literals and cast integers.

int16 _fixed(2) f1 = 22.14;
int16 i1 = 7;
f1 + 19.52; //evaluates to 41.66
f1 - (int16 _fixed(2)) i1; //evaluates to 15.14

The increment and decrement operations function the same in binary. This equates to adding or subtracting 1 times the scaling unit.

int16 _fixed(3) f1= 5.234;
f1++; //f1 = 5.235

Casting a fixed type to an integer will truncate the decimal places. This can also be used to isolate the digits after the decimal by subtracting the integer cast from the original.

int16 _fixed(2) f1 = 6.94;
int16 noDec = (int16) f1; //noDec = 6
int16 _fixed(2) decOnly = f1 - noDec; //decOnly = 0.94

The CCS C Compiler also supports using printf, sprintf, etc. with the fixed-point type using the "%w" format flag. It will print the value with no leading zeroes and digits after the decimal equal to the precision.

Code:
int16 _fixed(2) f1 = 1.5;
int16 _fixed(2) f2 = 22.78;
int16 _fixed(3) f3 = 5.21
printf("%w - %w - %w", f1, f2, f3);

Output:
1.50 - 22.78 - 5.210

Floating-point numbers have an inescapable error when representing decimal in which expressions that should evaluate to be equal will be off at a very low decimal point. This happens because some decimal numbers in base10, such as 0.1, cannot be perfectly represented in base2, thus causing a rounding error. This is similar to how 1/3 cannot be represented in base10 and is then rounded to 0.33... to whatever precision is needed. Since the CCS C Compiler's implementation of fixed-point uses a decimal scalar, there is 100% precision in base10. This makes it perfect for handling money and other values where this precision is necessary.

Fixed-point operations yield significant performance increases over floating-point. In order to quantify this, benchmarks were performed using a PIC18F45K22 and the CCS C Compiler. One of the on-chip timers was used to approximate the amount of time an arithmetic operation took. For both floating-point and 16 bit fixed-point at 2 places accuracy, each operation was timed and averaged 50 times on a spread of values. The average times for each could then be compared to generalize performance.

The benchmarking results are as follows:
* Add (+): Fixed ~19.6 times faster than float.
* Subtract (-): Fixed ~19.4 times faster than float.
* Multiply (*): Float ~2.7 times faster than fixed.
* Divide (/): Fixed ~3.3 times faster than float.

The only operation that floating-point performs better is multiplication. This is logical since floats are stored in a multiplicative form (significand x baseexponent). However, fixed-point performs better on the other three, particularly on addition and subtraction.

There is also a program memory usage difference between implementing fixed-point and floatingpoint. The actual number of instructions it takes to implement the arithmetic operations is significantly different for both. The following program was compiled using both options for the PIC18F45K22.

#ifdef USE_FIXED
int16 _fixed(2) a, b, c;
#else
float a, b, c;
#endif

void main() {
a = 2.25;
b = 0.85;
c = a + b;
printf("Add: %w", c);
c = a - b;
printf("Subtract: %w", c);
c = a * b;
printf("Multiply: %w", c);
c = a / b;
printf("Divide: %w", c);
}

The compiled program's memory statistics were as follows.

Fixed Option:
* 364 instructions
* 0.84KB ROM usage
* 2.6% ROM usage

Float Option:
* 787 instructions
* 2.03KB ROM usage
* 6.3% ROM usage

Switching from the fixed implementation to float increased the instruction count by over 400. This may or may not be significant on the PIC18F45K22, depending on program complexity. However, at 32KB of ROM, it is on the higher end in terms of program memory. On the more limiting units in the PIC18 family, this would be an extremely significant amount of space or may not be significant on the PIC18F45K22, depending on program complexity. However, at 32KB of ROM, it is on the higher end in terms of program memory. On the more limiting units in the PIC18 family, this would be an extremely significant amount of space.



Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

Extreme Code Optimizer

Thursday 24 June, 2021

If you have a version 5 compiler there is an optimization feature you may not be aware of. For many chips there is an aggressive code optimizer available, optimizing for space instead of speed. The optimizer is able to search the entire compiled program to find repeating blocks of code whereby reducing all those repeating blocks into one shared sub-routine. Optimizer is executed during the final phase of the compile which presents the ability to cross a function boundary when performing the optimization. This can only be done on parts with a flexible call instruction and available stack, for example the PIC18 and PIC24 families of devices.

This optimization level can be achieved by adding this line of code into your project.
#opt compress

The average size reduction of program memory is approximately 15%. In some cases we have seen program memory reduced by 60%. Provided below are examples of compression levels:



Consider this example. When a program that passes &n seven times to two functions and the code needed to do that takes 6 instructions. On the right we show the normal optimization and on the right #opt compress.



For more information on other advanced Version 5 features please visit: www.ccsinfo.com/version5



Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

ADC2

Monday 17 May, 2021

Microchip has some chips out that they call ADC2. This is the ADC module with a computational unit. In addition to legacy mode of operation, the ADC2 module can be setup in Accumulate, Average, Burst Average or Low-Pass Filter modes of operation. When setup for Accumulate mode with each trigger of the ADC, the conversion result is added to the accumulator and the ADCNT register is incremented. When setup for Average mode with each trigger of the ADC the conversion result is added to the accumulator and when the specified number of triggers has been done, the average will be preformed on the accumulator. When setup for Burst Average mode, it is similar to Average mode the difference being that when the ADC is triggered, it will perform the specified number of conversions and then perform the average calculation. When setup for Low-Pass Filter mode with each trigger of the ADC, the conversion result is sent through the filter.

To support these modes of operation, the CCS C Compiler's built-in setup_adc() function has an optional 2nd and 3rd parameter to set some parameters when using these the new modes of operation. When using Accumulate, Average or Burst Average modes the 2nd parameter sets how much the accumulated value is divided by after each conversion. When using Low-Pass Filter mode the 2nd parameter sets the cut-off frequency of the filter. The 3rd parameter to the function sets the number of samples to be done before performing a threshold comparison for Average, Burst Average and Low-Pass Filter modes of operation.

In addition to the updates to the setup_adc() function, the built-in functions adc_write() and adc_read() have been added to write and read some the other registers used by the ADC2 module. For example when setup for Low-Pass Filter mode, the filtered result is stored in the ADFLTRH and ADFLTRL registers. After the calculation is completed the adc_read() function can be then be used to read the filtered result, for example:

Result = adc_read(ADC_FILTER);

Another feature of the ADC2 module is the ability to set a trigger source to start a conversion. To support this feature the built-in function set_adc_trigger() has been added to the CCS C Compiler. For example the following can be used to setup the ADC2 module to trigger the conversion when Timer 2 period match occurs:

set_adc_trigger(ADC_TRIGGER_TIMER2);

The following is an example using the CCS C Compiler to setup and use the ADC2 module for Low-Pass Filter mode, see ex_lowpass_filter_adc2.c in the PICCExamples folder for entire example:

setup_timer_2(T2_CLK_INTERNAL | T2_DIV_BY_128, 155, 10);

//~10ms period, 100ms interrupt

setup_adc_ports(ADC_PIN, VSS_VDD);
setup_adc(ADC_LOW_PASS_FILTER_MODE | ADC_CLOCK_INTERNAL |
ADC_TAD_MUL_255 | ADC_THRESHOLD_INT_END_OF_CALCULATION,
FILTER_CUT_OFF_FREQ, ADC_READINGS);

set_adc_channel(ADC_CHANNEL);
set_adc_trigger(ADC_TRIGGER_TIMER2);

while(TRUE)
{
if(interrupt_active(INT_AD_THRESHOLD))
{
FilteredResult= adc_read(ADC_FILTER);
clear_interrupt(INT_AD_THRESHOLD);
}
}

Conditioning ADC data has become a standard requirement for dealing with analog voltages. Even a small amount of noise can disrupt your application. The ADC2 modules can save a lot of processing time to automate the most common filtering operations. See the ex_adc2_trigger.c example program in the compiler example directory for a full program.



Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

Introduction to the EZ App Lynx Library

Monday 17 May, 2021

The EZ App Lynx compiler library, Android Application, and iOS Application can add some neat capabilities to your PIC® MCU project. With a Bluetooth® interface, this allows a user's embedded project to interface to a smart device.



The technique used to do this does not require to write an app for the phone. In the above diagram, the micro sends the text to display on the initially blank screen. It then requests a button be put on the screen. The generic app available from CCS simply does anything the PIC® MCU tells it to.



The same certified app available in the smart device stores (for free) can be used for any number of PIC® MCU programs. Each program makes the display and operation it's own. Graphics and logs can be sent to the smart device or you can required the app download the images from the web.



At the PIC® MCU, a simple library is used call EZ APP LYNX and is included with all IDE compilers. An example program looks like this:

void main(void) {
ezapp_field_index_t pot;
EZAppInit(); //EZ App Lynx API

pot = EZAppAddFieldAnalogValueScaled(
"POT_A1",
EZAPP_ANALOG_TYPE_GAS_GAUGE,
0, //min
1023, //max
330, //scaling
2 //decimal points, 3.30
);

for(;;) {
EZAppTask(); //EZ App Lynx API to keep Bluetooth up
EZAppSetValue(pot, read_adc());
}
}

The library has a number of buttons, indicators, sliders and much more. Here is an example inserting a background on the smart device display:



Charts and graphics are easy to do as well:
An easy way to get started is using the development kit that includes a plug in Bluetooth® module, ready to start communicating with a smart device.



More information about EZ App Lynx, visit: http://www.ccsinfo.com/content.php?page=ez-app





Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

Programmable Switch Mode Controller (PSMC)

Monday 17 May, 2021

Pulse Width Modulation (PWM) capability was first added to the PIC® microcontroller line using the Capture/Compare/PWM (CCP) unit. Since then we have seen the enhanced CCP (ECCP) and a variety of power and motor control PWM modules each with its own features. The PWM module is called the Programmable Switch Mode Controller (PSMC). This is the most sophisticated PWM yet and is on chips like the PIC16F1789.

The PSMC allows for standard PWM, complementary PWM, shutdown control and deadband control like some of the older modules. It also allows for high resolution on the duty and frequency, as well variable frequency. It can for example do 3 phase 6 step PWM.

Input pins, comparator outputs and CCP triggers can be used not only to control shutdown, but to control if the PWM is running, or to start or stop a cycle.

Some PIC® MCU devices have as many as 4 independent units and the units can optionally be synchronized with each other.

The compiler functions are:
setup_psmc(unit, mode, period, period_time,
rising_edge, rise_time,
falling_edge, fall_time);

psmc_pins(unit, pins_used, pins_active_low);

psmc_duty(unit, fall_time);

psmc_deadband(unit, rising_edge, falling_edge);

psmc_blanking(unit, rising_edge, rise_time, falling_edge, fall_time);

psmc_shutdown(unit, option, source, pins_high);

psmc_freq_adjust(unit, freq_adjust);

psmc_modulation(unit, options);

psmc_sync(slave_unit, master_unit, options);

The following is a short example program that shows off some of the features:
#include <16f1789.h>
#use delay(osc=20mhz)

#define us(time) (int16)(time*(getenv("CLOCK")/1000000))

void main(void) {

setup_psmc(1, PSMC_ECCP_BRIDGE_FORWARD,
PSMC_EVENT_TIME | PSMC_SOURCE_FOSC | PSMC_DIV_2, us(100),
PSMC_EVENT_TIME, us(10),
PSMC_EVENT_TIME, us(35));

psmc_deadband(1, us(2), us(4));
psmc_modulation(1, PSMC_MOD_IN_PIN);
psmc_pins(1, PSMC_A | PSMC_B | PSMC_C | PSMC_D);

setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(sAN0);
set_adc_channel(0);

while(TRUE) {
psmc_duty(1, us(((read_adc()*(int16)10)/25)) );
}
}



Other examples are included with the compiler download and begin with EX_PSMC_



Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

The CCS Compiler Comes with DMX512 Bus Lighting Drivers

Thursday 22 April, 2021

DMX512 is a serial protocol that is commonly used to control stage lighting and effects. It was originally intended as a standardized method for controlling light dimmers. It soon became the primary method for linking controllers, a lighting console for example, to dimmers and special effect devices such as fog machines and intelligent lights.

A DMX512 network employs a multi-drop bus topology with nodes strung together in a daisy chain. A network consist of a single DMX512 controller, which is the master of the network and only transmitter, and one or more slave devices. Each slave device has an IN connector and usually an OUT or THRU connector, were as the controller only has an OUT connector. The controller's OUT connector is connected via a DMX512 cable to the first slave's IN connector. A second cable then links the OUT or THRU connector of the first slave to the IN connector of the next slave in the chain, and so on until all slaves are connected. The specification requires a terminator to be connected to the final OUT or THRU connector of the last slave on the daisy chain.

A DMX512 network is called a "DMX universe." The OUT connector on a DMX512 controller can control a single universe. Each universe operates up to 512 channels with each channel's parameter ranging between 0 and 255. A controller simply changes the values of these parameters.

For the DMX512 protocol, the controller transmits asynchronous serial data at 250 kbits/s. The data format is fixed at one start bit, eight data bits, and two stop bits. Each data frame consists of the following, a break, mark-after-break, slot 0 (Start Code) and up to 512 slots of channel data, each containing one byte. The break, which signals the end of one packet and the start of another, cause the slaves to start reception and also serves as a position reference for the data bytes within in the packet. The first slot, slot 0, is reserved for a start code that specifies the type of data in the packet.

The CCS C Compiler comes with a DMX512 driver, dmx.c, which can be used to develop code for either a DMX512 controller or a DMX512 slave device. When setup for a DMX512 controller the following functions are provided, DMXInit() to initialize the driver, DMXSetChannel() to set the specified channel to the specified value, DMXGetChannel() to get the current set value for the specified channel, and DMXCommit() to transmit the DMX512 channel data to the slave device. When setup for a DMX512 slave device the following functions are provided, DMXInit() to initialize the driver, DMXKbhit() to determine if new data as been received, and DMXGetd() to retrieve the DMX data.

In addition to the driver, the CCS C Compiler also provides the following two examples: ex_dmx_controller.c and ex_dma_slave.c, showing how to use the DMX512 driver to build code for a DMX512 controller and a DMX512 slave device.


Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

Long Range RF Communications

Thursday 22 April, 2021

Introducing the new CCS Long Range RF Development Kit. LoRa® is low-power wide-area network protocol that can be used to periodically communicate sensor data. LoRa® uses a proprietary spread spectrum modulation that is similar to and a derivative of Chip Spread Spectrum (CSS) modulation. This allows for long-range transmission, up to 9 miles, with low power consumption. This makes it ideal for battery applications that only needs to periodically transmit sensor data.

The CCS Long Range RF Development Kit comes with two development boards with Microchip's RN2903 modules. The RN2903 modules are designed to communicate using LoRa® modulation using the US frequency band. This is everything needed to develop a LoRa® peer-to-peer (P2P) implementation. The development kit's exercise manual has several exercises for setting up testing different types of LoRa® P2P networks using the provided RN2903 and LoRa® P2P drivers.

Additionally, the development kit can be used the to develop code to communicate on a LoRaWAN®network. LoRaWAN® is a upper level network protocol, developed by the LoRa® Alliance, that uses LoRa® modulation for creating a cloud-based network. In LoRaWAN® networks end-devices periodically send messages to a gateway, which forwards it to a network server which in turn forwards the message to an application server. Any response for the end-device is then forward back in the reverse order. The development kit can be used to develop and test end-devices for a LoRaWAN® implementation, using the provided RN2903 and LoRaWAN® driver. Testing the LoRaWAN® end-device will require at minimum an external LoRaWAN® gateway, not provided with the Long Range RF Development Kit.

LoRaWAN® is a mark used under license from the LoRa Alliance®. Use of the LoRa Alliance® and LoRa Alliance® Member marks is pursuant to license from the LoRa Alliance®.


Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

Using Overloading to Deal with Mixed ROM and RAM Data

Thursday 22 April, 2021

The CCS C Compiler supports C++ like function overloading. Function overloading allows the user to develop two functions with the same name, but have different parameters or return types. The CCS C Compiler can distinguish between RAM and ROM pointers when overloading. This is useful on the PIC® MCU which uses the Harvard architecture, meaning accessing the RAM and ROM is different. Since accessing RAM and ROM is different, the compiler needs to know which one the user is accessing so it can use the proper method.

Here is a simple example of function overloading using ROM and RAM pointers:

int Checksum(rom char * ptr) {

int cs;
while(*ptr!=0) // *ptr reads from ROM
cs += *ptr;

return cs;
}

int Checksum(char * ptr) {
int cs;
while(*ptr!=0) // *ptr reads from RAM
cs += *ptr;

return cs;
}

...
char data[10] = "Foo Bar";
const char hex[] = "0123456789ABCDEF";

label_cs = checksum("Hello World"); // Calls first funct
hex_cs = checksum(hex); // Calls first funct
data_cs = checksum(data); // Calls second funct

Checksum() has two functions, one for handling ROM pointers and one for handling RAM pointers. In the CCS C Compiler the 'rom' keyword specifies the ROM flash memory, if this is not specified the CCS C Compiler will use RAM. When Checksum() is called with the "Hello World" as a 'rom char *'

Some compiler built in functions deal with conversions from ROM to RAM pointers. For example strcpy() has two forms:
strcpy(ramstring, "Hello World");
strcpy(ramstring, buffer);

This is so the compiler can easily deal with awkward syntactical issues like this:
char string[] = "ABCDEFGHIJ";

ROM string moved to RAM and string is a RAM pointer. The CCS C Compiler also supports this syntax with all the appropriate conversions:
char string[10];
string = "Hello World";

Note that %s in a printf() is able to figure out if the string is in RAM or ROM however most string functions in string.h do not have overloaded versions for ROM data. For example if you want to do strcat(string,"...") then you must first make a function like this:

char *strcat(char *s1, rom char *s2)
{
unsigned char *s;

for (s = s1; *s != '\0'; ++s);
while(*s2 != '\0')
{
*s = *s2;
++s;
++s2;
}

*s = '\0';
return(s1);
}

Here is a more complex example of function overloading based on ROM and RAM pointers:

struct {
union {
rom char* pRom;
char* pRam;
};
int1 isRom;
} savedString;

void SetSavedString(rom char* pRom) {
savedString.pRom = pRom;
savedString.isRom = TRUE;
}

void SetSavedString(char* pRam) {
savedString.pRam = pRam;
savedString.isRom = FALSE;
}

void PrintSavedString(void) {
if(savedString.isRom)
printf("%s", savedString.pRom);
else
printf("%s", savedString.pRam);
}

SetSavedString((rom char*)"Hello World");
SetSavedString((char*) "foo bar");

SetSavedString() saves a (char*) or (rom char*) depending on what was passed in by the user to memory, and sets a flag denoting the type of pointer that is being used. The PrintSavedString() checks the flag to select the proper pointer, and prints the string.


Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

PIC® MCU Address Spaces - Part 3

Thursday 18 March, 2021

In part one we covered the two hardware address spaces in the PIC® MCU and how they can be used from C. Part two explained how a developer defines virtual address spaces. In this article we will detail how some PIC® MCUs have their own alternative address spaces and how the C compiler deals with them.

First, we must have a basic understanding about the fundamental addressing at the hardware level. Consider a PIC16F887 part and the instruction to add a memory value to the working register and put the result in the working register. The 14 bit instruction looks like this:
0 0 0 1 1 1 0 a a a a a a a

The aaaaaaa is the address in memory to get the data from. Notice there are only 7 bits so the address range is 0-127. In order to gain access to the rest of memory, there are some bank select bits. If the bank select bits are set to 010 then the instruction with aaaaaaa set to 0000001 will actually access memory location 0100000001. Fortunately, the compiler (at least the CCS C compiler) takes care of setting the right bank select bits before any instruction that needs the bits changed. There is a similar method used for program memory where the bits are called the page select bits. That comes into play with goto's and calls.



The following topics cover special features in some PIC® MCU parts that allow for a more effective way to access memory.

Mid-range Shared RAM
Even the old PIC chips had some special function registers duplicated in every bank, so there is no need to switch banks to access a popular register, like the status register. Many of the newer PIC® MCUs also have some general purpose RAM duplicated in all the banks. For example, on the PIC16F887 locations 0x70-0x7F reference the same RAM locations regardless of the bank bit setting. That means 0x70 and 0x1F0 are the same location. It is for this reason the compiler scratch locations begin at 0x70.



Mid-range Linear Address Space
On the mid-range parts the special function registers typically are at the start of each bank. For example 0x00 to 0x1F are SFR and 0x20-0x7F is general RAM. Then 0x80 to 0x1F are SFR and 0xA0 to 0xFF has general RAM. This means the largest data structure a user can have in RAM is 96 bytes or 80 bytes if there is shared RAM. If the user needs a larger array for example, they would need to split it into two smaller arrays.

On some mid-range PIC® MCUs there is an extended instruction set (4 and 5 digit parts after the F). In these parts there is a second way to access RAM called linear addressing. The linear address space has all the general purpose RAM locations and none of the SFR's. The entire general purpose RAM is put at location 0x2000 and up. Location 0x2000 is the same as 0x20. Location 0x02050 is the same as 0xA0. Now users can have data structures as large as memory can hold. The only way to address using the linear method is using indirection via the FSR registers. In the CCS C Compiler anytime a user accesses a data item using a variable index the linear addressing method is used if available on the part.

PIC18 Access Space
On the PIC18 parts most instructions have what is called an access bit to select what address space is used in the instruction. In the normal mode, the addressing works like the PIC16 using bank select bits somewhere else to fully specify the address. However, if the access bit is 0 then the address in the instruction is used to access only certain registers. The add instruction on the PIC18F4520 looks like this:
0 0 1 0 0 1 0 x a a a a a a a a

When x (the access bit) is 1 the address in the instruction is combined with the bank select bits to form the physical address.



When x is 0 then the physical address depends on the value of the address. With lower addresses then the remaining address bits are used as-is to get the physical address without using the bank select bits. For example, 00000001 will give users physical address 1 regardless of the bank select bit setting. This is kind of like the shared RAM feature in the PIC16. When the address is higher (0x80 and up on the PIC18F4520) then 0xF80 is added to the address over the cutoff to get the physical address. This allows for access to special function registers regardless of the bank select bit setting. Be aware however that different PIC18 parts have a different split between general purpose RAM and the SFR's in the access space. The PIC18F4520 has 128 bytes in each however the PIC18F4550 has only 96 bytes in general RAM and the rest in SFR's.

It should also be pointed out the PIC18 has a special double word instruction that can copy from any RAM address to any other RAM address.

PIC18 XINST
Most PIC18 parts have a XINST bit in the configuration fuses. When this bit is set the way the general purpose RAM is accessed when the access bit is set is modified. Instead of accessing the RAM directly the address is first added to the contents of another register. The intent with this feature is to make the using local variables easier in C code where users could have variables on a stack. This would allow for recursive functions. Since this feature is either on or off for the whole CCS has decided not to add support in the compiler for XINST because of the rare need for recursion and the inefficiencies caused by using this mode.

PIC24/DSPIC Extended RAM
On the 24 bit parts, the bank select bits were removed. Looking at the same add instruction it looks like this:
1 0 1 1 0 1 0 0 0 0 0 a a a a a a a a a a a a a

That means the instruction has direct access to RAM locations 0-1FFF (8K). That is a lot but many of these parts have more RAM than that. There are two ways to access RAM above 1FFF. First is to indirectly access the RAM using a 16 bit pointer (64K). This does require an extra instruction or two but is not as bad as it sounds since many instructions allow indirect addressing using one of the working registers. The other method is to use a special instruction to copy to/from any address 0-FFFF (64K) and a working register.

In summary, we have a great way to access 8K of RAM and there is a method to get at RAM over 8K but the method needs to be repeated for each access.

PIC24/DSPIC PSV Mode
Access to program memory (for constants) requires some extra steps to set up some registers and grab the data. The 24 bit parts have a mode that can be used to map the upper 32K of RAM addresses on to a selected area of program memory. This can be used to access constants in program memory as easily as if they were in RAM. When doing this, users loose access to the upper 32K of RAM. By default the CCS Compiler does not use this technique because in general it seems additional RAM is more important than fast access to ROM. A lot of the Microchip example code does use PSV mode so there is support in the CCS compiler to allow for easier porting.

#device PSV=16 // Turns on PSV mode
const char serial_number[] = {"123456789"}; // Saved in ROM
...
sn = atol32(serial_number); // Is accessed by a RAM address


Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

Use the IDE Column Editing Feature to Quickly Edit Repetitive Text

Thursday 18 March, 2021

There are situations where there is a need to make repetitive but identical changes to each line, or copy a block of text and then add the same text or spacing to each line when editing source code. Column editing allows a way to enter or delete text on multiple rows at once.

Access this feature by pressing the CTRL key while making a selection with the left mouse button. This enables selecting a rectangular region to be able to type to replace its contents, paste over it, or delete it.

The following are some examples.

1. Editing identical variable types



In the above illustration, column select the "int" type, and then simply type "unsigned int", to all 3 lines at once.

2. Working with Enums



Above shows a selected rectangle consisting of all of the enum variants to avoid copying the spacing. Pasting it into the switch statement maintains its tabbing. Next insert "case" into each line by simply column select the space before "SHAPE" and type "case".


Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

 Displaying 31 to 40 (of 220 articles)   Result Pages: [<< Prev]   1  2  3  4  5 ...  [Next >>]