|
|
View previous topic :: View next topic |
Author |
Message |
JAM2014
Joined: 24 Apr 2014 Posts: 138
|
Non-volatile memory dilemna..... |
Posted: Wed Jan 20, 2016 10:10 am |
|
|
Hi All,
I'm working on a design based on the PIC 16F1459. A new requirement late in the design requires that I store about 50 bytes of configuration data in non-volatile memory space. The 16F1459 does not have EEPROM. It looks like my options are:
1. Add a small serial EEPROM to my design
2. Use the internal flash memory storage on the 16F1459
3. Switch to a different PIC with EEPROM such as the 18F25K50
Any thoughts on what would be the 'best' option? At the moment, I'm at about 50% ROM usage, but I could see that being chewed up quickly if i have to put in a lot of code to implement option #2.
Jack |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 20, 2016 10:27 am |
|
|
What features of the 16F1459 are you using ? USB, CWG, UART, etc ?
What package are you using ? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Wed Jan 20, 2016 10:30 am |
|
|
I'd use a bigger PIC as you _always_ need more stuff, memory, I/O, etc. I see that PIC has USB. is that necessary? If so consider the cost/benefits of using a USB<>TTL module. Yes, cost $2 but frees up a LOT of codespace in the PIC as ALL the 'USB' stuff is in the module. Also module comes with a properly wired connector, couple of LEDS (you can remove to lower power) and, well, the module works. Most don't consider using the modules BUT if you actually price out your R&D time it may be cost effective, especially on small production runs of say 100 to 1000. Most tech don't like being an accountant but you should price out the product which includes R&D time. IE say you've spent 100 hrs getting USB in the PIC to work. That could easily be $5,000 or over 2500 modules and less than 5 hours to have a working product. Just something to consider.
As for choice of PIC, if possible choose one with more features than you need. Yes, a buck or two more BUT allows for FAST upgrades thus reducing R&D costs. Also you build a common core of code, personal libraries that you KNOW work. Jumping from PIC to PIC, especially series, can cost you a LOT of time (and money).
I use 28 and 40 pin PICs where 18 pinners would work BUT it's a lot easier and cheaper to just grab a 'big' PIC, build a 'proof of concept' product in a day or two and make the client happy. When he comes back wanting more, I can add code without needing to upgrade the hardware.
just points to consider.
Jay |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1908
|
|
Posted: Wed Jan 20, 2016 10:51 am |
|
|
Solely speaking to the memory aspect of your question....EEPROM built into a PIC doesn't have a high endurance. "Ordinary" SPI/I2C EEPROM is a better option, particularly if you're not going to be accessing/writing very often. If you will be writing often, then FRAM would be a better option. If you're writing/accessing extremely often, then MRAM is the longest life (most endurance) option. |
|
|
JAM2014
Joined: 24 Apr 2014 Posts: 138
|
|
Posted: Wed Jan 20, 2016 12:30 pm |
|
|
Hi All,
I'm using the USB and UART peripherals, and that's it. Package is a 20 pin SOIC. I'm not worried about endurance of the non-volatile memory, as the configuration I need to store will be done very infrequently.
Jack |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 20, 2016 12:46 pm |
|
|
Look at the 18F14K50. It has a similar pinout, and it has 256 bytes of
data eeprom. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Wed Jan 20, 2016 2:43 pm |
|
|
His existing chip can be used fairly easily, provided he is happy to work with the memory as a block.
The program memory on this chip has pages organised as 32*14bit words.
The chip has high endurance flash at 0x1f80.
A write using write_program_memory to this address, will write 32words, of which the low byte of each is the HEF (32bytes in each page).
If he organises the configuration data to be laid out as 32bytes occupying the low bytes of a 64byte array, he can (at the cost of 32bytes extra RAM), just write the whole lot with a single block write operation. The read can be done the same way. |
|
|
JAM2014
Joined: 24 Apr 2014 Posts: 138
|
|
Posted: Wed Jan 20, 2016 3:24 pm |
|
|
Hi,
Unfortunately, the 18F14K50 would need a crystal as it doesn't support ACT. I have room on my board for a (slightly) larger pin count PIC, but not a crystal.
The data that I need to store will *not* change often, and can be written/read all at one time in a block, so I'll investigate the write_program_memory option!
Thanks,
Jack |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Wed Jan 20, 2016 7:18 pm |
|
|
An option, perhaps?
Consider your 'config' data as bits NOT bytes. PICs are efficient in bit manipulation. Perhaps you can then 'pack' your 'config' data to use less memory ?
Might be worth investigating.
My energy management program breaks the day into 15 minute units so 96 bits = a 24 hour period. That's only 7 bits of a byte. Top bit is used for 'status' bit.
Jay |
|
|
JAM2014
Joined: 24 Apr 2014 Posts: 138
|
|
Posted: Thu Jan 21, 2016 10:32 am |
|
|
Hi,
The 'data' is bytes, not bits, so 'packing' isn't an option!
Quote: |
If he organises the configuration data to be laid out as 32bytes occupying the low bytes of a 64byte array, he can (at the cost of 32bytes extra RAM), just write the whole lot with a single block write operation. The read can be done the same way. |
By this, you don't mean byte 0 to byte 31 in the array, right? You mean the even bytes, ie. 0, 2, 4, 6, etc., right?
I tried a basic test of this functionality, and it kinda works, but I'm not *exactly* getting what I expect!
Code: |
if (!input(PGM))
{
//Here we are testing our ability to write to the Program Memory!
WifiLogin[0] = 'B';
WifiLogin[2] = 'a';
WifiLogin[4] = 'l';
WifiLogin[6] = 'd';
fprintf(Debug, "Begin Program Memory Write!\n\n\r");
write_program_memory(0x1f80, WifiLogin, 4);
fprintf(Debug, "End Program Memory Write!\n\n\r");
}
else
{
//Here we are testing our ability to read from the Program Memory!
fprintf(Debug, "Begin Program Memory Read!\n\n\r");
read_program_memory(0x1f80, WifiLogin, 4);
fprintf(Debug, "Element 0: %c\n\r", WifiLogin[0]);
fprintf(Debug, "Element 2: %c\n\r", WifiLogin[2]);
fprintf(Debug, "Element 4: %c\n\r", WifiLogin[4]);
fprintf(Debug, "Element 6: %c\n\r", WifiLogin[6]);
fprintf(Debug, "End Program Memory Read!\n\n\r");
}
|
Here is what I see on my debug screen:
Quote: |
Element 0: B
Element 2: a
Element 4:
Element 6:
|
Thanks,
Jack |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Thu Jan 21, 2016 11:16 am |
|
|
You need to understand the memory layout of the program memory.
It has pairs of bytes, comprising each word. The word is only 14bits, so in the RAM array, byte 0, has 8 bits usable, then byte 1, only has 6 bits. Then byte 2 has 8 bits and byte 3 has 6 bits again.
When implementing the HEF, Microchip only implemented it on the low byte of each word. So bytes 0, 2, 4, 6 etc..
So the HEF is read/written as the alternate bytes in the RAM array.
Now the flash & HEF, are written in 'pages' of 64 bytes (32 words). The pages only erase when you write to the first byte in a page. There are a total of 128bytes of HEF, occupying the low bytes of the last 128 words of the memory. So four pages at 0x1F80 0x1FA0 0x1FC0 0x1FE0.
You have to write 64 bytes to write each 32 words, which can be used to store 32 bytes in each page. The actual read and write code (provided you just write/read 64 byte blocks, is very small (only about 30 instructions). The hard work is preparing the data array to contain your data in a logical manner. |
|
|
JAM2014
Joined: 24 Apr 2014 Posts: 138
|
|
Posted: Thu Jan 21, 2016 11:39 am |
|
|
Hi Ttelmah,
I think I 'get' the program memory layout! Here is my array definition:
Code: |
int8 WiFiLogin[63];
|
So, I expect to be able to use WifiLogin[0], WifiLogin[2], WifiLogin[4], etc. for my data. These are the 'lower' 8 bits of the 14 bit word at that address.
I'm not sure why my test program doesn't work then? I'm writing to the program memory like this, and reading back the same way.
Compiler is PCM 5.050
Jack |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Thu Jan 21, 2016 11:46 am |
|
|
I don't think it'll like you writing only 63 bytes. The transfers are word wide. Must be an even number of bytes, both for read and write. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Thu Jan 21, 2016 11:52 am |
|
|
If it still doesn't work after switching to 64 bytes, have a look at:
<http://www.ccsinfo.com/forum/viewtopic.php?t=54018&highlight=flash>
I had to re-write the CCS functions a few compiler versions ago, for a similar chip, so they may still have problems for yours. |
|
|
JAM2014
Joined: 24 Apr 2014 Posts: 138
|
|
Posted: Tue Jan 26, 2016 2:51 pm |
|
|
Hi All,
It seems that my problem is due to a silicon errata on this chip related to writing to flash memory when the internal oscillator is greater than 4 Mhz.
http://ww1.microchip.com/downloads/en/DeviceDoc/80000546F.pdf
If I use this clock setting, which I need for USB, it doesn't work:
Code: |
#use delay(int=8MHz, clock=48MHz, USB_Full, act=USB)
|
If I use this clock setting, it works:
Code: |
#use delay(int=4MHz, clock=4MHz)
|
My project receives WiFi configuraton information via USB, and then no longer requires a USB connection. I'm thinking that I'll store the configuration temporarily until the USB cable is detached, switch the oscillator to the lower clock setting and write the program memory. Fortunately, in this case the project is NOT powered by the USB connection
Alternatively, if USB would work with an internal clock of 4 MHz then this would be even better, but I don't think this is possible?
Jack |
|
|
|
|
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
|