|
|
View previous topic :: View next topic |
Author |
Message |
David Pouzar
Joined: 20 Sep 2005 Posts: 27
|
dsPic33FJ128GP708A RAM Storage Problem. |
Posted: Thu May 10, 2018 12:06 pm |
|
|
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: 9245 Location: Greensville,Ontario
|
|
Posted: Thu May 10, 2018 7:51 pm |
|
|
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
|
|
Posted: Fri May 11, 2018 6:21 am |
|
|
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
|
Reserve or not to Reserve that is the question |
Posted: Fri May 11, 2018 7:29 am |
|
|
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
|
|
Posted: Fri May 11, 2018 9:30 am |
|
|
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: 19545
|
|
Posted: Fri May 11, 2018 10:50 am |
|
|
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
|
|
Posted: Fri May 11, 2018 11:05 am |
|
|
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
|
|
Posted: Fri May 11, 2018 11:14 am |
|
|
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: 19545
|
|
Posted: Fri May 11, 2018 1:15 pm |
|
|
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
|
It been awhile still having RAM issues |
Posted: Fri Jun 01, 2018 2:59 pm |
|
|
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: 9245 Location: Greensville,Ontario
|
|
Posted: Sun Jun 03, 2018 5:56 pm |
|
|
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: 19545
|
|
Posted: Mon Jun 04, 2018 12:01 am |
|
|
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. |
|
|
|
|
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
|