• AVR Freaks

Helpful ReplyHot![SOLVED] Temperature Indicator Module AND Device Information Area

Author
VincenzoV
Starting Member
  • Total Posts : 41
  • Reward points : 0
  • Joined: 2011/02/06 10:41:25
  • Location: Monticello Brianza - LC - Italy
  • Status: offline
2019/07/22 00:58:52 (permalink)
0

[SOLVED] Temperature Indicator Module AND Device Information Area

Hi all
 
I need to read temperature from Temperature Indicator Module AND read data from Device Information Area in PIC18 K42. Latest MCC, compiler and MPALBX.
 
ADCC work in Burst Average Mode, with Interrupt Thresohold enabled (ISR is empty, only clear flag), all code from MCC. During conversion CPU sleep and wake up with interrupt thresohold. This code works:
 
#include "mcc_generated_files/mcc.h"
#define MV -3.684
 
 
 
 
 
 
 
adc_result_t ADCC_LowNoise(adcc_channel_t channel) {
    ADPCH = channel; // select the A/D channel
    ADCON0bits.ADON = 1; // Turn on the ADC module
    ADCON0bits.ADCONT = 0; //Disable the continuous mode.
    ADCON0bits.ADGO = 1; // Start the conversion
    CPUDOZEbits.IDLEN = 0; // Sleep CPU
    SLEEP();
    return (ADCC_GetFilterValue()); // Conversion finished, return the result
}

void main(void) {
    volatile float TemperatureTIM;
    volatile float ADCmeas, ADCdia, FVRA2X;
    SYSTEM_Initialize(); // Initialize the device
    INTERRUPT_GlobalInterruptHighEnable(); // Enable high priority global interrupts
    ADCdia = 2414;
    FVRA2X = 2035;
    // ADCdia = (float) FLASH_ReadWord(0x003F002C); // Read TSHR2 from DIA
    // FVRA2X = (float) FLASH_ReadWord(0x003F0032); // Read FVRA2X from DIA
    while (1) {
        NOP(); // #1
        ADCmeas = ADCC_LowNoise(channel_Temp);
        NOP(); // #2
        TemperatureTIM = 90 + (ADCmeas - ADCdia) * FVRA2X / (4095 * MV);
        __delay_ms(100);
    }
}

If I un-comment lines with "FLASH_ReadWord()" (from MCC) code stops: NOP#1 is executed, but before NOP#2 there is a CPU reset.
" FVRA 2X = (float) FLASH_ReadWord(0x003F0032);" works fine.
 
Thanks in advance
post edited by VincenzoV - 2019/07/22 11:23:30

Vincenzo Villa - https://www.vincenzov.net
#1
ric
Super Member
  • Total Posts : 23185
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: Temperature Indicator Module AND Device Information Area 2019/07/22 02:00:51 (permalink)
0
Which "PIC18 K42." precisely?
Why are you casting the values to "float" ?

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#2
JPortici
Super Member
  • Total Posts : 706
  • Reward points : 0
  • Joined: 2012/11/17 06:27:45
  • Location: Grappaland
  • Status: offline
Re: Temperature Indicator Module AND Device Information Area 2019/07/22 02:01:08 (permalink)
3 (1)
What's the cause of the reset? (content of the reset registers)
Another obvious thing to do would be to load the data and THEN convert to float to see where the program actually hangs
 
Anyway if you want to use a different function, in the past i've written here about how XC8 is smart enough to use table read instructions without having to resort to assembly, also in relation to the K42 series because there are some gotchas.
 
Basically, you're going to have to use pointers to const (and there's a subtle difference between pointer to const and pointer to __rom regarding the size of the pointer and therefore the ability to access the area outside program memory, or the first 64kB)

uint16_t read_flashLoc(__uint24 address) {
  uint16_t const *progmem_ptr;
  address &= 0xFFFFFE;
  progmem_ptr = (uint16_t const *) address;
  return *progmem_ptr;
}

 
this is from my bootloader for the K42 series. I read the configuration this way
 
#3
VincenzoV
Starting Member
  • Total Posts : 41
  • Reward points : 0
  • Joined: 2011/02/06 10:41:25
  • Location: Monticello Brianza - LC - Italy
  • Status: offline
Re: Temperature Indicator Module AND Device Information Area 2019/07/22 03:35:05 (permalink)
0
@Ric
 
> Which "PIC18 K42." precisely?
PIC18LF26K42

> Why are you casting the values to "float" ?
No special reason ... I tried with a uint16_t, the same
 
Thanks!

Vincenzo Villa - https://www.vincenzov.net
#4
VincenzoV
Starting Member
  • Total Posts : 41
  • Reward points : 0
  • Joined: 2011/02/06 10:41:25
  • Location: Monticello Brianza - LC - Italy
  • Status: offline
Re: Temperature Indicator Module AND Device Information Area 2019/07/22 03:41:11 (permalink)
0
@JPortici
 
> What's the cause of the reset? (content of the reset registers)
I'm unsure... pcon0=0x34, pcon1=0x00 (Memory Violation?)
 
> use a different function
The same...
 
Grazie

Vincenzo Villa - https://www.vincenzov.net
#5
oliverb
Super Member
  • Total Posts : 204
  • Reward points : 0
  • Joined: 2009/02/16 13:12:38
  • Location: 0
  • Status: offline
Re: Temperature Indicator Module AND Device Information Area 2019/07/22 05:11:39 (permalink)
0
I'm interested in this too. I have some code that DOES get to a result (but wrong), so later when I'm home I'll try to post it.
Meantime have you tried a non-sleeping implementation, just polling the go/done bit?
 
I've also just noticed you appear to enable global interrupts, but I can't actually see an interrupt handler. From memory I seem to recall that for interrupt-wake-from-sleep you enabled the individual/peripheral interrupt, but not the global one. This meant the PIC would wake but continue from after the sleep instruction.
 
Have you checked if the watchdog timer is enabled? Normally for a test program it wouldn't be but if WDT is on and the program sticks at the ADC step then I would expect a WDT reset?
 
The version I'm trying uses a crystal-derived clock so it is non-sleeping.
 
post edited by oliverb - 2019/07/22 05:18:18
#6
mbrowning
Just a Member
  • Total Posts : 1455
  • Reward points : 0
  • Joined: 2005/03/16 14:32:56
  • Location: Melbourne, FL
  • Status: offline
Re: Temperature Indicator Module AND Device Information Area 2019/07/22 06:09:07 (permalink) ☄ Helpfulby VincenzoV 2019/07/22 11:22:13
4 (1)
According to the datasheet, NVMCON1bits.NVMREG must be 1 or 3 for DIA or config word access.
" FVRA 2X = (float) FLASH_ReadWord(0x003F0032);" works fine.

The stock MCC generated FLASH_ReadWord() function sets NVMCON1bits.NVMREG = 2
this is from my bootloader for the K42 series. I read the configuration this way

Are you setting NVMCON1bits.NVMREG to 1 (or 3) prior to calling read_flashLoc()?
 
Does NVMCON1bits.NVMREG not matter for reads (contrary to the datasheet)?
 

Oh well - there's always next year
#7
JPortici
Super Member
  • Total Posts : 706
  • Reward points : 0
  • Joined: 2012/11/17 06:27:45
  • Location: Grappaland
  • Status: offline
Re: Temperature Indicator Module AND Device Information Area 2019/07/22 06:48:04 (permalink) ☄ Helpfulby VincenzoV 2019/07/22 11:22:29
4 (1)
My code gets compiled to use table reads, the assembly output loads the table pointer register, excecutes TBLRD (with the eventual pre/post inc/dec) and returns the value in the tablat register.
Is the NVM controller involved in this, at all? Because i'm not setting the NVMREG bits prior calling the function. I've actually never had (and i use the function also to read program memory, i mentioned configuration to note the ability to go outside the program memory space)
so i must have been extremely lucky that my units never crashed to date.
I will however test it as soon as possible.
 
About the MEMV bit the datasheet says
If the CPU executes outside the valid execution area, a
memory execution violation reset occurs.
The invalid execution areas are:
1. Addresses outside implemented program
memory (see Table 5-1).
2. Storage Area Flash (SAF) inside program
memory, if it is enabled.

It talks about excecution, not access.
 
And then i wonder: What IF SAF is enabled and adding the flash read moves the ADCC_LowNoise function in SAF area?
As i wrote in another thread the linker is not currently aware of the SAF and you have to manually reserve the space
post edited by JPortici - 2019/07/22 06:49:14
#8
VincenzoV
Starting Member
  • Total Posts : 41
  • Reward points : 0
  • Joined: 2011/02/06 10:41:25
  • Location: Monticello Brianza - LC - Italy
  • Status: offline
Re: Temperature Indicator Module AND Device Information Area 2019/07/22 11:04:01 (permalink)
0
@oliverb
 
 
> Meantime have you tried a non-sleeping implementation, just polling the go/done bit?
It works
 
> I can't actually see an interrupt handler
Only "empty" ISR from MCC, clear the ADCC Threshold interrupt flag ()     PIR1bits.ADTIF = 0;

> Have you checked if the watchdog timer is enabled?
Not enabled
 
Thanks
post edited by VincenzoV - 2019/07/22 11:34:05

Vincenzo Villa - https://www.vincenzov.net
#9
VincenzoV
Starting Member
  • Total Posts : 41
  • Reward points : 0
  • Joined: 2011/02/06 10:41:25
  • Location: Monticello Brianza - LC - Italy
  • Status: offline
Re: Temperature Indicator Module AND Device Information Area 2019/07/22 11:20:03 (permalink)
0
@mbrowning
 
> The stock MCC generated FLASH_ReadWord() function sets NVMCON1bits.NVMREG = 2
 
Right! And change TBLPTR registers.
Inside ISR there is ADCC_SetADTIInterruptHandler() funtionn and if fails if runned after FLASH_ReadWord, I thiink for changed TBLPTR... So I write my own function... And it works!
 

uint8_t FLASH_ReadByte_vv(uint32_t flashAddr) {
NVMCON1bits.NVMREG = 2;
uint8_t saveTBLPTRU, saveTBLPTRH, saveTBLPTRL;
saveTBLPTRU = TBLPTRU;
saveTBLPTRH = TBLPTRH;
saveTBLPTRL = TBLPTRL;
TBLPTRU = (uint8_t) ((flashAddr & 0x00FF0000) >> 16);
TBLPTRH = (uint8_t) ((flashAddr & 0x0000FF00) >> 8);
TBLPTRL = (uint8_t) (flashAddr & 0x000000FF);
asm("TBLRD");
TBLPTRU = saveTBLPTRU;
TBLPTRH = saveTBLPTRH;
TBLPTRL = saveTBLPTRL;
return (TABLAT);
}
uint16_t FLASH_ReadWord_vv(uint32_t flashAddr) {
return ((((uint16_t) FLASH_ReadByte_vv(flashAddr + 1)) << 8) | (FLASH_ReadByte_vv(flashAddr)));
}
 

 
> Does NVMCON1bits.NVMREG not matter for reads (contrary to the datasheet)?
 
@mbrowning
 
> The stock MCC generated FLASH_ReadWord() function sets NVMCON1bits.NVMREG = 2
Right! And change TBLPTR registers.
Inside ISR there is ADCC_SetADTIInterruptHandler() and if fails if runned after FLASH_ReadWord, I thiink for changed TBLPTR... So I write my own function... And Work!
 

uint8_t FLASH_ReadByte_vv(uint32_t flashAddr) {
NVMCON1bits.NVMREG = 2;
uint8_t saveTBLPTRU, saveTBLPTRH, saveTBLPTRL;
saveTBLPTRU = TBLPTRU;
saveTBLPTRH = TBLPTRH;
saveTBLPTRL = TBLPTRL;
TBLPTRU = (uint8_t) ((flashAddr & 0x00FF0000) >> 16);
TBLPTRH = (uint8_t) ((flashAddr & 0x0000FF00) >> 8);
TBLPTRL = (uint8_t) (flashAddr & 0x000000FF);
asm("TBLRD");
TBLPTRU = saveTBLPTRU;
TBLPTRH = saveTBLPTRH;
TBLPTRL = saveTBLPTRL;
return (TABLAT);
}
uint16_t FLASH_ReadWord_vv(uint32_t flashAddr) {
return ((((uint16_t) FLASH_ReadByte_vv(flashAddr + 1)) << 8) | (FLASH_ReadByte_vv(flashAddr)));
}
 

 
> Does NVMCON1bits.NVMREG not matter for reads (contrary to the datasheet)?
 
It looks like it doesn't matter

Vincenzo Villa - https://www.vincenzov.net
#10
mbrowning
Just a Member
  • Total Posts : 1455
  • Reward points : 0
  • Joined: 2005/03/16 14:32:56
  • Location: Melbourne, FL
  • Status: offline
Re: Temperature Indicator Module AND Device Information Area 2019/07/22 11:38:16 (permalink) ☄ Helpfulby VincenzoV 2019/07/22 11:53:27
4 (1)
I looked at my custom DIA/config read function (based loosely on the MCC flash read function) and I saved only the upper table pointer byte. I couldn't remember for sure why I did that, but I think that since the upper byte would be 0x00 for program flash accesses (on <=64Kbyte flash devices)  C assumed that TBLPTRU was always 0x00 and thus program data accesses failed after the device read changed it.
 
 

Oh well - there's always next year
#11
VincenzoV
Starting Member
  • Total Posts : 41
  • Reward points : 0
  • Joined: 2011/02/06 10:41:25
  • Location: Monticello Brianza - LC - Italy
  • Status: offline
Re: Temperature Indicator Module AND Device Information Area 2019/07/22 11:55:51 (permalink)
5 (1)
@mbrowning
> I saved only the upper table pointer byte
It works, I used after MCC flash read function:

ADCdia = FLASH_ReadWord(0x003F002C); // Read TSHR2 from DIA
FVRA2X = FLASH_ReadWord(0x003F0032); // Read FVRA2X from DIA
TBLPTRU=0;


Vincenzo Villa - https://www.vincenzov.net
#12
mbrowning
Just a Member
  • Total Posts : 1455
  • Reward points : 0
  • Joined: 2005/03/16 14:32:56
  • Location: Melbourne, FL
  • Status: offline
Re: Temperature Indicator Module AND Device Information Area 2019/07/22 12:49:35 (permalink)
0
Good to know. Thanks for the update.

Oh well - there's always next year
#13
Jump to:
© 2019 APG vNext Commercial Version 4.5