Searching \ for '[PIC] Read Flash of PIC16F916' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/memory.htm?key=flash
Search entire site for: 'Read Flash of PIC16F916'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] Read Flash of PIC16F916'
2012\04\06@081454 by AdiCH

flavicon
face

Hi

I try to read the flash ROM of my PIC16F916 to calculate a checksum.
I use the MPLAB and the PICC v9.83 Compiler.

I tried this c function:

unsigned int ReadFlash( unsigned int address ) {
  EEADRL = address%256;
  EEADRH = address/256;
  EEPGD = 1; // program memory
  RD = 1;    // read
  ;
  ;
  return EEDATH*256 + EEDATL;
}

and everything in assembler:

unsigned char low3;
unsigned char high3;

unsigned int dataFlash;

void main() {

  #asm
     BCF        _STATUS, 5
     BCF        _STATUS, 6
     MOVF       _low3, W
     BSF        _STATUS, 6
     MOVWF      _EEADR
     BCF        _STATUS, 6
     MOVF       _high3, W
     BSF        _STATUS, 6
     MOVWF      _EEADRH
     BSF        _STATUS, 5
     BSF        _EECON1, 7
     BSF        _EECON1, 0
     NOP
     NOP
     BCF        _STATUS, 5
     MOVF       _EEDATH, W
     MOVWF      _dataFlash+1
     CLRF       _dataFlash
     MOVF       _EEDATA, W
     IORWF      _dataFlash, F
     MOVLW      0       IORWF      _dataFlash+1, F
  #endasm
}

But both are not working, if I debug it most of the time the register EEDATA
and EEDATH have the right value. But if I copy it to the variable dataFlash
it is 0.

With the mikroC compiler is a function to read the flash that works. But I
can not use this compiler because the build hex file is much bigger and has
no space on the PIC.

Any idea what is wrong or how I can read the flash ROM?

thanks

Adrian
-- View this message in context: old.nabble.com/Read-Flash-of-PIC16F916-tp33623645p33623645.html
Sent from the PIC - [PIC] mailing list archive at Nabble.com.

2012\04\06@090224 by Neil

flavicon
face
In the statement "return EEDATH*256 + EEDATL;"  what's probably happening is that the variable/register EEDATH is not sized properly to handle being multiplied by 256.  Try creating a temporary unsigned int, copying EEDATH to that, then adding EEDATL to it, and then return it.

Cheers,
-Neil.


On 4/6/2012 8:14 AM, AdiCH wrote:
{Quote hidden}

> Adrian

2012\04\10@044108 by Michael Rigby-Jones

flavicon
face


{Quote hidden}

I'm not surprised the assembler version is not working, the code for transferring the data from EEDATH/EEDATA into 'dataflash' is visibly wrong; I have added comments below:

MOVF       _EEDATH, W                ; EEDATH is now in W
MOVWF      _dataFlash+1                ; EEDATH is now in MSB of 'dataflash'
CLRF       _dataFlash                ; LSB of 'dataflash' is now zero
MOVF       _EEDATA, W                ; EEDATA is now in W
IORWF      _dataFlash, F        ; EEDATA is now in LSB of 'dataflash'
MOVLW      0                        ; W=0
IORWF      _dataFlash+1, F        ; MSB of 'dataflash' is now zero.

Why not do this?

MOVF       _EEDATH, W                ; EEDATH is now in W
MOVWF      _dataFlash+1                ; EEDATH is now in MSB of 'dataflash'
MOVF       _EEDATA, W                ; EEDATA is now in W
MOVWF      _dataFlash, F        ; EEDATA is now in LSB of 'dataflash'


Please note I have not checked that your bank switching is correct; it would be much better to use macros to do this if your compiler supports this in inline assembler.


In the C version it looks like you are assuming that a line that contains only a semicolon will be converted into a NOP operation, are you certain this is the case? In the compilers I use a semicolon by itself will not produce any code, and you might need to use inline assembler to insert a NOP (or your compiler may provide a macro to do this).

Also be very careful using the modulo operator to extract high and low bytes from a word. A modulo operation is very expensive in terms of CPU cycles.  The optimiser may fix this if it notices you are doing a simple byte move operation, but don't count on it.  A simple bit shift/mask is a much better idea:

EEADRL = address & 0xFF;
EEADRH = address >> 8;

Cheers

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

More... (looser matching)
- Last day of these posts
- In 2012 , 2013 only
- Today
- New search...