CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

dsPic33FJ128GP708A RAM Storage Problem.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
David Pouzar



Joined: 20 Sep 2005
Posts: 27

View user's profile Send private message Visit poster's website

dsPic33FJ128GP708A RAM Storage Problem.
PostPosted: Thu May 10, 2018 12:06 pm     Reply with quote

I am still moving from 18f4685 to 33FJ128GP708A. Now I can not get my RAM Storage to work. Ideas?
Code:

unsigned int16 const cal_start=33050; //Min 32768
unsigned int16 const cal_end=33224;   //Max 33224
#reserve cal_start:cal_end
unsigned int16 min_adc_psi;
#locate min_adc_psi=33050

if I disable the #locate the system will boot up, if enabled it does not start up.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu May 10, 2018 7:51 pm     Reply with quote

OK I don't use that PIC and have never used those directives
but I'll take a stab at it....
After reading what #RESERVE and #LOCATE do, I'm thinking the #LOCATE cannot be the same address as the #RESERVE.
The compile 'reserves' a chunk of code(can't be used) then.....it's asked to 'locate' data within that 'reserved' spot, I can see why the program locks up.
I'm sure someone KNOWS what's going on and there may be a better/proper way to code so that it works the way you want it to.

Jay
David Pouzar



Joined: 20 Sep 2005
Posts: 27

View user's profile Send private message Visit poster's website

PostPosted: Fri May 11, 2018 6:21 am     Reply with quote

thank for the input.. I am going to make a test program. And see if I can solve the mystery.. Maybe you are right. That could be a difference between Pic18f4685 and ds33FJ128GP708A.
David Pouzar



Joined: 20 Sep 2005
Posts: 27

View user's profile Send private message Visit poster's website

Reserve or not to Reserve that is the question
PostPosted: Fri May 11, 2018 7:29 am     Reply with quote

Hi wise programmers
I am trying to convert code from a PIC18F4685 to a dsPIC33FJ128GP708A. I made a simplified program but is still puzzles me what am I missing. The variable min_adc_psi is ok as long as I do not try to #locate it in the reserve area like I did this in old days of PIC18F4685. My mission is to be able to store variables in certain RAM location so I can make a copy of them in external EEPROM. Ideas would be vary welcomed on how to do this. I have subs in that I will fill in once I get past this issue. Thank

Code:

#include "main.h"
#include "pin_defines.h"
#include "lcd420Flex.h"
#USE RS232(parity=N,/*xmit=RS232_TX,rcv=RS232_RX,*/bits=8,stream=COMM1,uart1,errors,TIMEOUT=1500,BRGH1OK,BAUD=115200,ENABLE=RS485_DE)
#use rs232(parity=N,/*xmit=RS232_TX,rcv=RS232_RX,*/bits=8,stream=COMM2,uart2,errors,TIMEOUT=1500,BRGH1OK,BAUD=115200,ENABLE=RS485_DE_B)
#use i2c(Master,sda=SDA1,scl=SCL1,stream=i2c,FAST=100000,RESTART_WDT,FORCE_SW) // Standard pins for I2C
void write_eeprom_ext(int32 address, char data); //write to an external eeprom
char read_eeprom_ext(int32 address); //read a byte for the external eeprom
int8 read(unsigned int32 address); //return a value for eeprom
void write(unsigned int32 address, unsigned int8 value); //write a value to the eeprom
void read_eeprom_values(); //read values out of the external eeprom
void initialize(); //setup the system
void main(); //the main routine
//unsigned int16 const cal_start=0x4000; //Min
//unsigned int16 const cal_end=cal_start+2;   //Max
//#reserve cal_start:cal_end
unsigned int16 min_adc_psi;
//#locate min_adc_psi=cal_start
int1 eeprom_errors_flag;
// Write a byte at the address in the EEPROM new
void write_eeprom_ext(int32 address, char data)
   {
   int i;
   char datar;
   int32 address2;
   int addresshi;
   int addresslo;
//   short p_i2c_mode;
   int write_ext;
   int read_ext;
   int ack;
   //does the value need to be changed
   datar= read_eeprom_ext(address);
   if(datar==data)
   {
       return; //data is the same no write needed
   }
   write_ext=0xA0;
   read_ext=0xA1;
   address2=address&0x7FFFF;// force address consistency
   while (address2>=0x20000)
   {
          address2-=0x20000;// chip address space
          write_ext+=2;    // next chip
          read_ext+=2;
   }
   if(address2>=0x10000)// block address space
   {
          address2-=0x10000;
          write_ext+=8; // second block in the chip
          read_ext+=8;
   }
 
   addresslo=(address2);
   address2>>=8;
   addresshi=(address2);
   eeprom_errors_flag=1;
   for (i=0;i<3;i++)
   {
      i2c_start(i2c);
      i2c_write(i2c,write_ext);
      i2c_write(i2c,addresshi); //upper address
      i2c_write(i2c,addresslo); //lower address
      i2c_write(i2c,data);
      i2c_stop(i2c);
      ack=1;   // EEPROM does not ACK when not ready
      while(ack&(i<100))
      {
        i2c_start(i2c);
        ack=i2c_write(i2c,write_ext); // ACK will end the loop (active low)
        i2c_stop(i2c);
        i++;
      }
    i2c_start(i2c);
    ack=i2c_write(i2c,write_ext); // ACK will end the loop (active low)
      i2c_write(i2c,addresshi); //upper address
      i2c_write(i2c,addresslo); //lower address
      i2c_start(i2c);
      i2c_write(i2c,read_ext);
      datar=i2c_read(i2c,0);     
      i2c_stop(i2c);
      if(data==datar){
            eeprom_errors_flag=0;
           break;
        }
      }

   }
// Read a byte from address in EEPROM new
char read_eeprom_ext(int32 address)
{
   char data;
   int32 address2;
   int addresshi;
   int addresslo;
//   short p_i2c_mode;
   int write_ext;
   int read_ext;
   //load lowest locations
   write_ext=0xA0;
   read_ext=0xA1;
   address2=address&0x7FFFF;// force address consistency
   while (address2>=0x20000)
   {
          address2-=0x20000;// chip address space
          write_ext+=2;    // next chip
          read_ext+=2;
   }
   if(address2>=0x10000)// block address space
   {
          address2-=0x10000;
          write_ext+=8; // second block in the chip
          read_ext+=8;
   }
   addresslo=(address2);
   address2>>=8;
   addresshi=(address2);
   i2c_start(i2c);
   i2c_write(i2c,write_ext);
   i2c_write(i2c,addresshi);
   i2c_write(i2c,addresslo);
   i2c_start(i2c);
   i2c_write(i2c,read_ext);
   data=i2c_read(i2c,0);   
   i2c_stop(i2c);

   return(data);
}
int8 read(unsigned int32 address) //return a value for eeprom
{
    return(read_eeprom_ext(address));
}
void write(unsigned int32 address, unsigned int8 value) //write a value to the eeprom
{
    write_eeprom_ext(address, value);
}
void read_eeprom_values()
{
    restart_wdt();
}
void initialize()
{
    unsigned int8 tday_old; //get the stored date
   
    setup_wdt(WDT_1S|WDT_ON);
    setup_adc(ADC_CLOCK_INTERNAL);
    setup_timer1(TMR_EXTERNAL_RTC|TMR_DIV_BY_1,0XCCC);  //32.768K Xtal hooked up to timer1 inputs //100ms clock
//    setup_timer1(TMR_DISABLED);
    setup_timer2(TMR_DISABLED);
    setup_timer3(TMR_DISABLED);
    setup_timer4(TMR_DISABLED); //250HZ clock 4ms clock enabled in the keyboard routine
    setup_timer5(TMR_DISABLED);
    setup_timer6(TMR_DISABLED);
    setup_timer7(TMR_DISABLED);   
    setup_timer8(TMR_DISABLED);
    setup_timer9(TMR_DISABLED);
//    setup_psp(PSP_DISABLED);
    setup_spi(SPI_SS_DISABLED);
//    setup_compare(COMPARE_OFF);
//    SETUP_VREF(FALSE);
    output_high(VDRIVE_CTS);
   
    SETUP_OSCILLATOR(OSC_CRYSTAL|OSC_SECONDARY);
    //DISABLE KEYBOARD INPUT BUFFER
    OUTPUT_BIT(INPUT_OE,1);
    //DISABLE RELAY OUTPUTS BUFFER
    OUTPUT_BIT(RELAY_LE,0);
    i2c_init(1); //turn on i2c
    ext_int_edge(1,H_TO_L);
    restart_wdt();
    lcd_init();
    lcdclear();
    min_adc_psi=156;
    int x;
    x=0;
    retry_1:
   if(read(1021)=='1'&&read(1022)=='0'&&read(1023)=='6')
      {
         read_eeprom_values();

         //update_cal=1;
         }
   else
       {
       if(x<3)
       {
           x++;
         restart_wdt();
         delay_ms(250);
           goto retry_1;
       }
       write(1021,'1');
       write(1022,'0');
       write(1023,'6');
       }
}
void main()
{
    initialize();
    while(1)
    {
        lcdposition(0x00);
        printf(sendlcddata,"min_adc_psi= %3lu",min_adc_psi);
        restart_wdt();
    }
}

here is the main.h

Code:

#include "33FJ128GP708A.h"
#device ICSP=1
#device ADC=12


//#FUSES FRC                      //FAST RC OSCILLATOR
#FUSES HS                       //HIGH SPEED CRYSTAL
//#FUSES WDT                      //Watch Dog Timer
//#FUSES WPRES32                  //Watch Dog Timer PreScalar 1:32
//#FUSES WPOSTS11                 //Watch Dog Timer PostScalar 1:1024
#fuses NOWRTB           //Boot block not write protected
#fuses NOBSS          //No boot segment
#fuses NORBS          //No Boot RAM defined
#FUSES NOSSS                    //NO SECURE SEGMENT
#fuses NORSS          //No secure segment RAM
#fuses NOWRT          //Program memory not write protected
#fuses NOPROTECT      //Code not protected from reading
#fuses IESO           //Internal External Switch Over mode enabled
#fuses PUT16          //Power On Reset Timer value 16ms
#FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOJTAG                   //JTAG disabled
#FUSES NODEBUG                    //NODEBUG WITH ICD
#FUSES NORBS                    //NO BOOT RAM DEFINED
#fuses PR             //Primary Oscillator
#FUSES SOSC                      //SECONDARY OSC
#fuses ICSP1          //ICD uses PGC1/PGD1 pins
#fuses LPRC           //Internal low power RC Oscillator
#fuses WINDIS           //Watchdog Window Select
#BUILD (stack=4096)
//#use delay(internal=7.37M,restart_wdt)
//#use spi(MASTER, SPI1, BAUD=1000000, MODE=0, BITS=8, ENABLE=PIN_b2, ENABLE_ACTIVE=0, stream=VDRIVE)

#use delay(xtal=14.745M,restart_wdt)

#define DELAY 100

David Pouzar



Joined: 20 Sep 2005
Posts: 27

View user's profile Send private message Visit poster's website

PostPosted: Fri May 11, 2018 9:30 am     Reply with quote

After debugging and looking at results the issue is with
Code:
const unsigned int16  cal_start=0x2000; //Min
const unsigned int16  cal_end=cal_start+2;   //Max


If is used like this it will lockup:
Code:

#reserve 0x2000:0x2004
unsigned int16 min_adc_psi;
#locate min_adc_psi=cal_start


if the actual value is used like below no lockup:
Code:
#reserve 0x2000:0x2004
unsigned int16 min_adc_psi;
#locate min_adc_psi=0x2000


You do not need to define #reserve since the #locate does that for you.
I would love to know the reason why?
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri May 11, 2018 10:50 am     Reply with quote

It suggests the pre-processor is not correctly resolving the const values. I must admit I do wonder 'why' you use these?. Wasted memory space. Just use a #define instead.
The only reason to use the variable rather than the #define is for a more strongly 'typed' language, where this will allow syntax checking. CCS doesn't do this, so why not use the #define?
There is a problem with your values though. An int16 is not large enough. Remember the DsPIC RAM memory model does support sizes beyond 64K. It supports multiple pages each of 64K. Though your chip doesn't have this the physical memory model does. It may be the operation is not liking converting the 16bit value.
David Pouzar



Joined: 20 Sep 2005
Posts: 27

View user's profile Send private message Visit poster's website

PostPosted: Fri May 11, 2018 11:05 am     Reply with quote

I need to store the RAM values also in an external EEPROM location for backup. That is why I want to have them in certain locations. This would allow for example the user setting to be restored after a program upgrade.
David Pouzar



Joined: 20 Sep 2005
Posts: 27

View user's profile Send private message Visit poster's website

PostPosted: Fri May 11, 2018 11:14 am     Reply with quote

Code:

#include "main.h"
#include "pin_defines.h"
#include "lcd420Flex.h"
#use i2c(Master,sda=SDA1,scl=SCL1,stream=i2c,FAST=100000,RESTART_WDT,FORCE_SW) // Standard pins for I2C

void initialize(); //setup the system
void main(); //the main routine
const unsigned int16  cal_start=0x2000; //Min was suppose be able to use as the start of my eeprom storage, but it does not work
const unsigned int16  cal_end=cal_start+2;   //Max
//#reserve 0x2000:0x2100
float32 pmult2;
#locate pmult2 = 8192
float32 pmult;
#locate  pmult  =  8196
float32 pmult3;
#locate pmult3 = 8200
float32 v24mult;
#locate v24mult = 8204

void initialize()
{
    setup_wdt(WDT_1S|WDT_ON);
    setup_adc(ADC_CLOCK_INTERNAL);
    setup_timer1(TMR_EXTERNAL_RTC|TMR_DIV_BY_1,0XCCC);  //32.768K Xtal hooked up to timer1 inputs //100ms clock
//    setup_timer1(TMR_DISABLED);
    setup_timer2(TMR_DISABLED);
    setup_timer3(TMR_DISABLED);
    setup_timer4(TMR_DISABLED); //250HZ clock 4ms clock enabled in the keyboard routine
    setup_timer5(TMR_DISABLED);
    setup_timer6(TMR_DISABLED);
    setup_timer7(TMR_DISABLED);   
    setup_timer8(TMR_DISABLED);
    setup_timer9(TMR_DISABLED);
//    setup_psp(PSP_DISABLED);
    setup_spi(SPI_SS_DISABLED);
//    setup_compare(COMPARE_OFF);
//    SETUP_VREF(FALSE);
    output_high(VDRIVE_CTS);
   
    SETUP_OSCILLATOR(OSC_CRYSTAL|OSC_SECONDARY);
    //DISABLE KEYBOARD INPUT BUFFER
    OUTPUT_BIT(INPUT_OE,1);
    //DISABLE RELAY OUTPUTS BUFFER
    OUTPUT_BIT(RELAY_LE,0);
    i2c_init(1); //turn on i2c
    ext_int_edge(1,H_TO_L);
    restart_wdt();
    lcd_init();
    lcdclear();
    pmult2=1.23;
    pmult=2.34;
    pmult3=3.45;
    v24mult=4.56;
}
void main()
{
    initialize();
    while(1)
    {
        lcdposition(0x00);
        printf(sendlcddata,"%10.4w",pmult2);
        lcdposition(lcd_line_two);
        printf(sendlcddata,"%10.4w",pmult);
        lcdposition(lcd_line_three);
        printf(sendlcddata,"%10.4w",pmult3);
        lcdposition(lcd_line_four);
        printf(sendlcddata,"%10.4w",v24mult);
        restart_wdt();
    }
}


I set the values to in initialize:
Code:

pmult2=1.23;
pmult=2.34;
pmult3=3.45;
v24mult=4.56;

The screen is showing
106728.2596
107516.7887
107982.3567
108330.4837

ideas?
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri May 11, 2018 1:15 pm     Reply with quote

Using a #define doesn't stop you from using the reserve:
Code:

#define cal_start 0x2000
#define cal_end cal_start+2


The code will work as you have been using it, and like this the compiler should accept it.
David Pouzar



Joined: 20 Sep 2005
Posts: 27

View user's profile Send private message Visit poster's website

It been awhile still having RAM issues
PostPosted: Fri Jun 01, 2018 2:59 pm     Reply with quote

I was looking at the Microchip spec sheet for 33FJ128GP708A and am confused on what location I am suppose to use to store my reserved RAM data. If I understand the comments right I can not store my int8, int16 because they are too small?
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jun 03, 2018 5:56 pm     Reply with quote

OK... I'll take a stab at this as I downloaded the datasheet, so bear with me...
I read that 0x2000... is called "DMA RAM", I assume the 'buffer' the PIC uses when doing DMA accesses. IF so, that 'bank' of RAM is 'set aside' and probably shouldn't be used for 'general purpose' RAM.
Perhaps you can try a portion of the 'Y-RAM' starting at 0x1800 and see what happens ?
I'm still trying to see why you need to reserve RAM to save to EEPROM...
I did read that RAM is 'word' organised ( 16 bits) so if you have an odd number of 8 bit variables,say 3, I'd add a 4th 'dummy' variable to keep the data on proper word boundaries.

Like I said, just trying to help...
Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Jun 04, 2018 12:01 am     Reply with quote

I just don't see the point of the #reserve....

You can put anything you want into an external memory. #reserve doesn't make it any easier, and just stops the compiler from optimising things.

Easiest thing is just to create a structure containing your configuration data and just write this to the eeprom or read this from the eeprom. It's address tells you where it is. Nothing more is needed.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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