Jump to content
Sign in to follow this  
spirilis

My time with the Renesas RX

Recommended Posts

Kit is nice, just confusing searching through all the PDFs 'n crap to see how things work... I have been unimpressed at the user's guide for the kit in that it doesn't tell you the Pxx port ID for the LEDs 'n stuff, it just hints by telling you the chip's pin# (which I look up in the chip's datasheet to find the PORTx.BIT.Bx value)

 

HEW is an ugly application, e2studio is much prettier but slower (Eclipse-based). So far I'm getting the hang of it. Just haven't done anything interesting yet b/c I haven't learned how RSPI works (and that's needed to talk to the LCD display & PCM flash chip, plus I don't know how the LCD display works, I think it's a common controller but I'm a noob at that)

 

So far I'm just taking it 1 peripheral at a time. I anticipate the more complex ones (DMA, certainly ethernet) to take more than a week to figure out but it should be worthwhile I think.

 

The chip itself sounds amazing, like a Cortex-M4F (like the Stellaris LaunchPad) but with some extra goodies. I'm guessing it runs a bit faster than most of the M4F's out there too but I don't know. I don't have any specific applications in mind that need this kind of power anyhow.

 

 

I keep getting the urge to design a 40-pin launchpad XL boosterpack adapter board for this thing so I got more toys to play with.... I'm just a bit dismayed at how large apart the bottom & top headers are, would be too expensive to have professionally done IMO. Maybe a toner-transfer PCB job.

Share this post


Link to post
Share on other sites

Okay, I fibbed a little. I did install the software and played with the demo's. Then installed Win8, re-installed HEW and stuff but haven't played since.

 

Future Designs had a breakout board for the kit, free plus shipping. I ordered it... $10 for shipping, and they cancelled the order. What I was told is they produced 1:1, free kit to breakout, but people were ordering several so they ran out and have no plans for a replacement. It wasn't a good design though since it obscured the LCD. Unfortunately, I found out the breakout was NLA after soldering pins on to the board. :x Had I known that, I would've soldered them to the bottom of the board.

 

There is a demo benchmark included with the kit, and IIRC, it reports something like 165 DMIPS. That might be a usable comparison figure.

 

I agree, HEW is ugly. Segger debugger doesn't seem to obey its settings either.

 

I'm also annoyed they didn't include the JP7 jumper with the kit- it enables the on-board piezoelectric speaker.

Share this post


Link to post
Share on other sites

I'm also a little annoyed they put the LCD near the middle of the board instead of in the area they marked out as "CHARACTER LCD MODULE".

 

I think that's meant to be a pinout for a separate HD44780-compatible character LCD though. It is a little weird since it's marked as "LCD1"...

 

edit: nm, just read your previous post :)

Share this post


Link to post
Share on other sites

Man I'm tackling the Data Flash piece now, going in order from the list I made above.

 

That's some convoluted-ass shit. Actually it's best to think of the Data Flash as a peripheral, not a logical extension of the built-in ROM, even though it is controlled by the same controller. It feels a lot like talking to an external SPI EEPROM -- where you set a mode (or pull an SPI chip select line low) to enable it, then issue single-byte commands, then issue addresses and start writing data.

 

Difference here is, the mode is set with some SFR, then the "commands" are issued by writing to the memory addresses themselves -- using Byte-level writes denotes a "cmd", but Word-level writes denote actual data. Then after writing all your data to the flash you issue a byte-level command to "close" the session and poll a flash status bit in one of the flash SFRs.

 

Then there are lock-bit SFRs for locking the segments from read or program/erasure, so you have to enable those to allow reading or writing. Reading can occur by direct CPU access but the timing is slow, as it's based on the PCLK peripheral clock rate (3 PCLK cycles per word IIRC).

Share this post


Link to post
Share on other sites

I'm coming to the conclusion that the Data Flash on my board is faulty, but I can't be certain. There is a Demo app in HEW that uses the data flash and it seems to work correctly, however, I noticed in the code there's nothing actually *reading* the flash--and most of the commands just execute with no reporting of the pass/fail status. Maybe I'll modify that a bit and see if the demo app is actually failing.

Share this post


Link to post
Share on other sites

In either case, here's the code I came up with--it initializes the Flash Controller Unit, erases the first segment and then validates the first segment was erased.

 

It hangs with PD1 LED turning on--meaning that ILGLERR was thrown after issuing the PCLK Notification command, required to inform the flash controller how fast the PCLK is.

Strange.

 

hardware_setup.c


void HardwareSetup(void)
{
   SYSTEM.SCKCR.BIT.ICK = 0x00;  // ICLK = 96MHz
   SYSTEM.SCKCR.BIT.PCK = 0x01;  // PCLK = 48MHz
   SYSTEM.SCKCR.BIT.PSTOP1 = 1;
   SYSTEM.SCKCR.BIT.PSTOP0 = 1;
}

 

main code:


int main(void)
{
   unsigned int i;
   volatile unsigned int *df = (void*)0x00100000;  // Beginning of Data Flash 32KB block#0 (also word-access to issue FCU commands)
   volatile unsigned char *df_cmd = (void*)0x00100000;  // Byte-access to issue FCU commands
   volatile unsigned long *fcufw_source = (void*)0xFEFFE000, *fcuram = (void*)0x007F8000;

   PORTD.DDR.BYTE = 0xFF; PORTE.DDR.BYTE = 0x0F;
   PORTD.DR.BYTE = 0xFF; PORTE.DR.BYTE = 0xFF;  // All LEDs off
   /* LEDs:
    * D0 = Red
    * D1 = Red
    * D2 = Red
    * D3 = Green
    * D4 = Green
    * D5 = Green
    * D6 = Red
    * D7 = Red
    * E0 = Red
    * E1 = Green
    * E2 = Green
    * E3 = Green
    */

   // Step 1: Enable read/write lockbits for data flash segments
   FLASH.DFLRE0.WORD = 0x2DFF;
   FLASH.DFLRE1.WORD = 0xD2FF;
   FLASH.DFLWE0.WORD = 0x1EFF;
   FLASH.DFLWE1.WORD = 0xE1FF;

   // Step 2: Enter Program/Erase Mode
   // Step 2a: Disable interrupts
   FLASH.FAEINT.BIT.ROMAEIE = 0;
   FLASH.FAEINT.BIT.CMDLKIE = 0;
   FLASH.FAEINT.BIT.DFLAEIE = 0;
   FLASH.FAEINT.BIT.DFLRPEIE = 0;
   FLASH.FAEINT.BIT.DFLWPEIE = 0;
   // Step 2b: Initialize FCU controller, write firmware
   FLASH.FENTRYR.WORD = 0xAA00;
   FLASH.FCURAME.WORD = 0xC401;
   for (i=0; i<8192/4; i++) {
       fcuram[i] = fcufw_source[i];
   }
   //FLASH.FCURAME.WORD = 0xC400;
   // Step 2b: Reset FCU controller
   FLASH.FRESETR.WORD = 0xCC01;
   for (i=0; i<4000; i++) { i += 1; i -= 1; }
   FLASH.FRESETR.WORD = 0xCC00;
   FLASH.FWEPROR.BYTE = 0x02;
   FLASH.FENTRYR.WORD = 0xAA00;
   for (i=0; i<10; i++) ;
   FLASH.FENTRYR.WORD = 0xAA80;
   for (i=0; i<10; i++) ;
   // Step 2c: Clear Status
   if (FLASH.FSTATR0.BIT.ILGLERR) {
       if (FLASH.FASTAT.BYTE != 0x10)
           FLASH.FASTAT.BYTE = 0x10;
   }
   *df_cmd = 0x50;  // Issue Status Clear cmd
   // Step 2c: Enable master write status bit
   FLASH.FWEPROR.BYTE = 0x01;
   // Step 2d: Check for errors before continuing
   if (FLASH.FSTATR0.BYTE & 0x70) {
       PORTD.DR.BIT.B0 = 0;
       while(1) ;
   }
   // Step 2e: Issue Peripheral Clock Notification
   FLASH.PCKAR.WORD = 48;
   *df_cmd = 0xE9;
   *df_cmd = 0x03;
   *(volatile unsigned int*)df_cmd = 0x0F0F;
   *(volatile unsigned int*)df_cmd = 0x0F0F;
   *(volatile unsigned int*)df_cmd = 0x0F0F;
   *df_cmd = 0xD0;
   // Check if Peripheral Clock Notification caused an error
   while (!FLASH.FSTATR0.BIT.FRDY)
       ;
   if (FLASH.FSTATR0.BIT.ILGLERR) {
       PORTD.DR.BIT.B1 = 0;
       while(1) ;
   }

   // Step 3: Issue Flash Erase
   FLASH.FPROTR.WORD = 0x5501;  // Ignore lockbits
   *df_cmd = 0x20;
   *df_cmd = 0xD0;
   while (!FLASH.FSTATR0.BIT.FRDY)
       ;
   if (FLASH.FSTATR0.BIT.ILGLERR || FLASH.FSTATR0.BIT.ERSERR) {
       PORTD.DR.BIT.B2 = 0;
       while(1) ;
   }
   // Step 4: Exit P/E mode
   if (FLASH.FSTATR0.BYTE & 0x70) {
       if (FLASH.FSTATR0.BIT.ILGLERR)
           if (FLASH.FASTAT.BYTE != 0x10)
               FLASH.FASTAT.BYTE = 0x10;
   }
   *df_cmd = 0x50;
   FLASH.FENTRYR.WORD = 0xAA00;
   FLASH.FRDYIE.BIT.FRDYIE = 0;
   FLASH.FWEPROR.BYTE = 0x02;

   // Wait around doing nothing before we attempt to validate the segment is blank
   for (i=0; i<1048576; i++) { i *= 2; i /= 2; }

   // Step 5: Go back into P/E Mode
   FLASH.FENTRYR.WORD = 0xAA80;
   for (i=0; i<10; i++) ;
   // Step 5a: Clear Status
   if (FLASH.FSTATR0.BIT.ILGLERR) {
       if (FLASH.FASTAT.BYTE != 0x10)
           FLASH.FASTAT.BYTE = 0x10;
   }
   *df_cmd = 0x50;  // Issue Status Clear cmd
   // Step 5b: Enable master write status bit
   FLASH.FWEPROR.BYTE = 0x01;
   // Step 5c: Check for errors before continuing
   if (FLASH.FSTATR0.BYTE & 0x70) {
       PORTD.DR.BIT.B6 = 0;
       while(1) ;
   }
   // Step 6: Issue Flash Data Area Blank Check commands
   FLASH.FMODR.BIT.FRDMD = 1;
   FLASH.DFLBCCNT.BIT.BCSIZE = 1;
   *df_cmd = 0x71;
   *df_cmd = 0xD0;
   while (!FLASH.FSTATR0.BIT.FRDY)
       ;
   FLASH.FMODR.BIT.FRDMD = 0x00;
   // Make sure this isn't an illegal cmd
   if (FLASH.FSTATR0.BIT.ILGLERR) {
       FLASH.FENTRYR.WORD = 0xAA00;
       FLASH.FWEPROR.BYTE = 0x02;
       PORTD.DR.BIT.B7 = 0;
       while(1) ;
   }
   // Check if it's blank or not
   if (FLASH.DFLBCSTAT.BIT.BCST) {  // Not blank!
       PORTE.DR.BIT.B0 = 0;
       while(1) ;
   }

   // That's all for now.
   while(1) ;
   //
   return 0;
}

Share this post


Link to post
Share on other sites

Ah son of a gun, I got it...

 

I guess 'unsigned int' isn't 16-bits on the RX architecture.

The culprit:

 

*(volatile unsigned int*)df_cmd = 0x0F0F;

*(volatile unsigned int*)df_cmd = 0x0F0F;

*(volatile unsigned int*)df_cmd = 0x0F0F;

 

I included stdint.h and used "volatile uint16_t" this time and the PD1 LED didn't turn on.

However it doesn't seem to be completing either, so something else is probably wrong... More troubleshooting.

Share this post


Link to post
Share on other sites

Oh yeah, I guess "for (i=0; i<1048576; i++)" doesn't work when 'i' is an unsigned 16-bit int...

 

And boom, PD3 (green LED) is lit! Hallelujah!

 

Final code:


#include <stdint.h>
#include "iodefine.h"

int main(void)
{
   uint32_t i;
   volatile uint16_t *df = (void*)0x00100000;  // Beginning of Data Flash 32KB block#0 (also word-access to issue FCU commands)
   volatile uint8_t *df_cmd = (void*)0x00100000;  // Byte-access to issue FCU commands
   volatile uint32_t *fcufw_source = (volatile uint32_t *)0xFEFFE000UL, *fcuram = (volatile uint32_t *)0x007F8000UL;
   volatile uint32_t *fcufw_end = (volatile uint32_t *)0xFEFFFFFFUL;

   PORTD.DDR.BYTE = 0xFF; PORTE.DDR.BYTE = 0x0F;
   PORTD.DR.BYTE = 0xFF; PORTE.DR.BYTE = 0xFF;  // All LEDs off
   /* LEDs:
    * D0 = Red
    * D1 = Red
    * D2 = Red
    * D3 = Green
    * D4 = Green
    * D5 = Green
    * D6 = Red
    * D7 = Red
    * E0 = Red
    * E1 = Green
    * E2 = Green
    * E3 = Green
    */

   // Step 1: Enable read/write lockbits for data flash segments
   FLASH.DFLRE0.WORD = 0x2DFF;
   FLASH.DFLRE1.WORD = 0xD2FF;
   FLASH.DFLWE0.WORD = 0x1EFF;
   FLASH.DFLWE1.WORD = 0xE1FF;

   // Step 2: Enter Program/Erase Mode
   // Step 2a: Disable interrupts
   FLASH.FAEINT.BIT.ROMAEIE = 0;
   FLASH.FAEINT.BIT.CMDLKIE = 0;
   FLASH.FAEINT.BIT.DFLAEIE = 0;

   FLASH.FAEINT.BIT.DFLRPEIE = 0;
   FLASH.FAEINT.BIT.DFLWPEIE = 0;
   // Step 2b: Initialize FCU controller, write firmware
   FLASH.FENTRYR.WORD = 0xAA00;
   asm("nop"); asm("nop");
   FLASH.FRESETR.WORD = 0xCC01;
   FLASH.FCURAME.WORD = 0xC401;
   while (fcufw_source < fcufw_end)
       *fcuram++ = *fcufw_source++;
   //FLASH.FCURAME.WORD = 0xC400;
   // Step 2b: Reset FCU controller
   FLASH.FRESETR.WORD = 0xCC01;
   for (i=0; i<4000; i++) { asm("nop"); }
   FLASH.FRESETR.WORD = 0xCC00;
   while (!FLASH.FSTATR0.BIT.FRDY)
       ;
   FLASH.FENTRYR.WORD = 0xAA80;
   asm("nop"); asm("nop");
   // Step 2c: Clear Status
   if (FLASH.FSTATR0.BIT.ILGLERR) {
       if (FLASH.FASTAT.BYTE != 0x10)
           FLASH.FASTAT.BYTE = 0x10;
   }
   *df_cmd = 0x50;  // Issue Status Clear cmd
   // Step 2c: Enable master write bit
   FLASH.FWEPROR.BYTE = 0x01;
   // Step 2d: Check for errors before continuing
   if (FLASH.FSTATR0.BYTE & 0x70 || FLASH.FSTATR1.BIT.FCUERR) {
       PORTD.DR.BIT.B0 = 0;
       while(1) ;
   }
   // Step 2e: Issue Peripheral Clock Notification
   FLASH.PCKAR.WORD = 48;
   *df_cmd = 0xE9;
   *df_cmd = 0x03;
   *(volatile uint16_t*)df_cmd = 0x0F0F;
   *(volatile uint16_t*)df_cmd = 0x0F0F;
   *(volatile uint16_t*)df_cmd = 0x0F0F;
   *df_cmd = 0xD0;

   // Check if Peripheral Clock Notification caused an error
   while (!FLASH.FSTATR0.BIT.FRDY)
       ;
   if (FLASH.FSTATR0.BIT.ILGLERR) {
       PORTD.DR.BIT.B1 = 0;
       while(1) ;
   }

   // Step 3: Issue Flash Erase
   FLASH.FPROTR.WORD = 0x5501;  // Ignore lockbits
   *df_cmd = 0x20;
   *df_cmd = 0xD0;
   while (!FLASH.FSTATR0.BIT.FRDY)
       ;
   if (FLASH.FSTATR0.BIT.ILGLERR || FLASH.FSTATR0.BIT.ERSERR) {
       PORTD.DR.BIT.B2 = 0;
       while(1) ;
   }
   // Step 4: Exit P/E mode
   if (FLASH.FSTATR0.BYTE & 0x70) {
       if (FLASH.FSTATR0.BIT.ILGLERR)
           if (FLASH.FASTAT.BYTE != 0x10)
               FLASH.FASTAT.BYTE = 0x10;
   }
   *df_cmd = 0x50;
   FLASH.FENTRYR.WORD = 0xAA00;
   FLASH.FRDYIE.BIT.FRDYIE = 0;
   FLASH.FWEPROR.BYTE = 0x02;

   // Wait around doing nothing before we attempt to validate the segment is blank
   for (i=0; i<1048576; i++) { asm("nop"); }

   // Step 5: Go back into P/E Mode
   FLASH.FENTRYR.WORD = 0xAA80;
   asm("nop"); asm("nop");
   // Step 5a: Clear Status
   if (FLASH.FSTATR0.BIT.ILGLERR) {
       if (FLASH.FASTAT.BYTE != 0x10)
           FLASH.FASTAT.BYTE = 0x10;

   }
   *df_cmd = 0x50;  // Issue Status Clear cmd
   // Step 5b: Enable master write status bit
   FLASH.FWEPROR.BYTE = 0x01;
   // Step 5c: Check for errors before continuing
   if (FLASH.FSTATR0.BYTE & 0x70) {
       PORTD.DR.BIT.B6 = 0;
       while(1) ;
   }
   // Step 6: Issue Flash Data Area Blank Check commands
   FLASH.FMODR.BIT.FRDMD = 1;
   FLASH.DFLBCCNT.BIT.BCSIZE = 1;
   *df_cmd = 0x71;
   *df_cmd = 0xD0;
   while (!FLASH.FSTATR0.BIT.FRDY)
       ;
   FLASH.FMODR.BIT.FRDMD = 0x00;
   // Make sure this isn't an illegal cmd
   if (FLASH.FSTATR0.BIT.ILGLERR) {
       FLASH.FENTRYR.WORD = 0xAA00;
       FLASH.FWEPROR.BYTE = 0x02;
       PORTD.DR.BIT.B7 = 0;
       while(1) ;
   }
   // Check if it's blank or not
   if (FLASH.DFLBCSTAT.BIT.BCST) {  // Not blank!
       PORTE.DR.BIT.B0 = 0;
       while(1) ;
   }
   PORTD.DR.BIT.B3 = 0;

   // That's all for now.
   while(1) ;
   //
   return 0;
}

 

 

Next step: Modularize those steps, then add a data flash write -- followed by re-read -- to validate it.

Share this post


Link to post
Share on other sites

Seriously... put that together with RobG's hardware serial color display booster pack and ... 8-)

 

Yes, I jest. And, I appreciate your documentation of the trial and tribulation.

Share this post


Link to post
Share on other sites

Got a rudimentary library (which needs much expansion) together, debugged it and successfully wrote 2 16-bit integers and read it back (and then tried writing a slightly different integer & read back the original one, showing that errors correctly).

 

Library-

dataflash_rx62n.c


/*
* dataflash_rx62n.c
*
*  Created on: Nov 30, 2012
*      Author: spirilis
*/

#include <stdint.h>
#include "iodefine.h"
#include "dataflash_rx62n.h"

/* Assumes 48MHz PCLK, does not use interrupts. */

volatile uint8_t *df_start = (void*)0x00100000UL;

void _dataflash_PE_mode();
void _dataflash_PE_exit();
uint8_t _dataflash_needs_reset();

uint8_t dataflash_init()
{
   uint32_t i=0;
   volatile uint32_t *fcufw_source = (volatile uint32_t *)0xFEFFE000UL, *fcuram = (volatile uint32_t *)0x007F8000UL;
   volatile uint32_t *fcufw_end = (volatile uint32_t *)0xFEFFFFFFUL;

   // Step 1: Enable read/write lockbits for data flash segments
   FLASH.DFLRE0.WORD = 0x2DFF;
   FLASH.DFLRE1.WORD = 0xD2FF;
   FLASH.DFLWE0.WORD = 0x1EFF;
   FLASH.DFLWE1.WORD = 0xE1FF;

   // Step 2: Enter Program/Erase Mode
   // Step 2a: Disable interrupts
   FLASH.FAEINT.BIT.ROMAEIE = 0;
   FLASH.FAEINT.BIT.CMDLKIE = 0;
   FLASH.FAEINT.BIT.DFLAEIE = 0;
   FLASH.FAEINT.BIT.DFLRPEIE = 0;
   FLASH.FAEINT.BIT.DFLWPEIE = 0;
   // Step 2b: Initialize FCU controller, write firmware

   FLASH.FAEINT.BIT.DFLWPEIE = 0;
   // Step 2b: Initialize FCU controller, write firmware
   FLASH.FENTRYR.WORD = 0xAA00;
   asm("nop"); asm("nop");
   FLASH.FCURAME.WORD = 0xC401;
   while (fcufw_source < fcufw_end)
       *fcuram++ = *fcufw_source++;
   // Step 2b: Reset FCU controller
   FLASH.FRESETR.WORD = 0xCC01;
   for (i=0; i<4000; i++) { asm("nop"); }
   FLASH.FRESETR.WORD = 0xCC00;
   while (!FLASH.FSTATR0.BIT.FRDY)
       ;
   FLASH.FENTRYR.WORD = 0xAA80;
   asm("nop"); asm("nop");
   // Step 2c: Clear Status
   if (FLASH.FSTATR0.BIT.ILGLERR) {
       if (FLASH.FASTAT.BYTE != 0x10)
           FLASH.FASTAT.BYTE = 0x10;
   }
   *df_start = 0x50;  // Issue Status Clear cmd
   // Step 2c: Enable master write bit
   FLASH.FWEPROR.BYTE = 0x01;
   // Step 2d: Check for errors before continuing
   if (FLASH.FSTATR0.BYTE & 0x70 || FLASH.FSTATR1.BIT.FCUERR) {
       return 0;
   }
   // Step 2e: Issue Peripheral Clock Notification
   FLASH.PCKAR.WORD = 48;
   *df_start = 0xE9;
   *df_start = 0x03;
   *(volatile uint16_t*)df_start = 0x0F0F;
   *(volatile uint16_t*)df_start = 0x0F0F;
   *(volatile uint16_t*)df_start = 0x0F0F;
   *df_start = 0xD0;
   // Check if Peripheral Clock Notification caused an error
   while (!FLASH.FSTATR0.BIT.FRDY)
       ;
   if (FLASH.FSTATR0.BIT.ILGLERR) {

       return 0;
   }

   _dataflash_PE_exit();
   return 1;   // Data Flash and FCU fully initialized
}

void _dataflash_PE_mode()
{
   // Enable Data Flash writing
   FLASH.FENTRYR.WORD = 0xAA80;
   asm("nop"); asm("nop");
   // Enable Master Write bit
   FLASH.FWEPROR.BYTE = 0x01;
   /* Clear Status (note: we need FENTRYD set before we can do this, b/c we're
    * writing a command to a pointer in the data flash addr space)
    */
   if (FLASH.FSTATR0.BIT.ILGLERR) {
       if (FLASH.FASTAT.BYTE != 0x10)
           FLASH.FASTAT.BYTE = 0x10;
   }
   *df_start = 0x50;  // Issue Status Clear cmd
}

void _dataflash_PE_exit()
{
   // Disable Data Flash writing
   FLASH.FENTRYR.WORD = 0xAA00;
   asm("nop"); asm("nop");
   // Disable Master Write bit
   FLASH.FWEPROR.BYTE = 0x02;
}

uint8_t _dataflash_needs_reset()
{
   return FLASH.FSTATR1.BIT.FCUERR;
}


uint8_t dataflash_is_blank(void* flashaddr)
{
   _dataflash_PE_mode();
   if (_dataflash_needs_reset()) {
       if (!dataflash_init())
           return 255;
       _dataflash_PE_mode();
   }

   FLASH.FMODR.BIT.FRDMD = 1;
   FLASH.DFLBCCNT.BIT.BCSIZE = 1;
   *(volatile uint8_t *)flashaddr = 0x71;
   *(volatile uint8_t *)flashaddr = 0xD0;
   while (!FLASH.FSTATR0.BIT.FRDY)
       ;
   FLASH.FMODR.BIT.FRDMD = 0;
   if (FLASH.FSTATR0.BIT.ILGLERR) {
       _dataflash_PE_exit();
       return 255;
   }
   _dataflash_PE_exit();
   if (FLASH.DFLBCSTAT.BIT.BCST) {
       return 0;
   }
   return 1;
}

uint8_t dataflash_erase(void* flashaddr)
{
   _dataflash_PE_mode();
   if (_dataflash_needs_reset()) {
       if (!dataflash_init())
           return 0;
       _dataflash_PE_mode();
   }

   *(volatile uint8_t *)flashaddr = 0x20;
   *(volatile uint8_t *)flashaddr = 0xD0;
   while (!FLASH.FSTATR0.BIT.FRDY)
       ;
   if (FLASH.FSTATR0.BIT.ILGLERR || FLASH.FSTATR0.BIT.ERSERR) {
       _dataflash_PE_exit();
       return 0;
   }
   _dataflash_PE_exit();
   return 1;
}

uint8_t dataflash_write(void* flashaddr, void* buffer, uint8_t bytes)
{
   uint16_t i;
   volatile uint8_t *fa = (volatile uint8_t *)flashaddr;
   uint8_t *bytebuf = (uint8_t *)buffer;

   if (bytes < 1 || bytes > 128 || bytes % 2 != 0)
       return 0;  // Not supporting >128 byte writes yet, maybe work on that later
   if (bytes < 9 && (fa-df_start) % 8 != 0)
       return 0;  // Only write on properly aligned boundaries please...
   if (bytes > 8 && (fa-df_start) % 128 != 0)
       return 0;  // Ditto (but for 128-byte writes)...

   _dataflash_PE_mode();
   if (_dataflash_needs_reset()) {
       if (!dataflash_init())
           return 0;
       _dataflash_PE_mode();
   }

   if (bytes > 8) { // 128-byte page mode
       *fa = 0xE8;
       *fa = 0x40;  // 128-bytes
       for (i=0; i<128; i+=2) {
           if (bytes) {
               *(volatile uint16_t *)fa = (uint16_t) (bytebuf[i] | (bytebuf[i+1] << 8));
               bytes -= 2;

           } else
               *(volatile uint16_t *)fa = 0x0000;
       }
       *fa = 0xD0;
   } else {
       *fa = 0xE8;
       *fa = 0x04;  // 8-bytes
       for (i=0; i<8; i+=2) {
           if (bytes) {
               *(volatile uint16_t *)fa = (uint16_t) (bytebuf[i] | (bytebuf[i+1] << 8));
               bytes -= 2;
           } else
               *(volatile uint16_t *)fa = 0x0000;
       }
       *fa = 0xD0;
   }
   while (!FLASH.FSTATR0.BIT.FRDY)
       ;
   if (FLASH.FSTATR0.BIT.ILGLERR || FLASH.FSTATR0.BIT.PRGERR) {
       _dataflash_PE_exit();
       return 0;
   }
   _dataflash_PE_exit();
   return 1;
}

 

dataflash_rx62n.h


/*
* dataflash_rx62n.h
*
* Created on: Nov 30, 2012
* Author: spirilis
*/

#ifndef DATAFLASH_RX62N_H_
#define DATAFLASH_RX62N_H_

#include <stdint.h>

uint8_t dataflash_init();
uint8_t dataflash_is_blank(void *);
uint8_t dataflash_erase(void *);
uint8_t dataflash_write(void *, void *, uint8_t);

#endif /* DATAFLASH_RX62N_H_ */

 

Main program-

/***********************************************************************/
/*                                                                     */
/*      PROJECT NAME :  df_writeread                                   */
/*      FILE         :  df_writeread.c                                 */
/*      DESCRIPTION  :  Main Program                                   */
/*      CPU SERIES   :  RX600                                          */
/*      CPU TYPE     :  RX62N                                          */
/*                                                                     */
/*      This file is generated by e2studio.                        */
/*                                                                     */
/***********************************************************************/




#include <stdint.h>
#include "iodefine.h"
#include "dataflash_rx62n.h"

int main(void)
{
   int i;
   uint16_t buf[16];
   uint8_t j;
   volatile uint16_t *df = (void *)0x00100000UL;  // Beginning of Data Flash 32KB block#0

   PORTD.DDR.BYTE = 0xFF; PORTE.DDR.BYTE = 0x0F;
   PORTD.DR.BYTE = 0xFF; PORTE.DR.BYTE = 0xFF;  // All LEDs off
   /* LEDs:
    * D0 = Red
    * D1 = Red
    * D2 = Red
    * D3 = Green
    * D4 = Green
    * D5 = Green
    * D6 = Red
    * D7 = Red
    * E0 = Red 
    * E1 = Green    

    * E2 = Green
    * E3 = Green
    */
   if (!dataflash_init()) {
       PORTD.DR.BIT.B0 = 0;
       while(1) ;
   }
   if ( (j = dataflash_is_blank((void*)df)) != 1 ) {
       if (j == 255) {  // Error
           PORTD.DR.BIT.B1 = 0;
           while(1) ;
       }
       if (!dataflash_erase((void*)df)) {
           PORTD.DR.BIT.B1 = 0;
           while(1) ;
       }
   } else {
       //PORTD.DR.BIT.B4 = 0;
   }
   buf[0] = 0xDEAD;
   buf[1] = 0xBEEF;
   if (!dataflash_write((void*)df, buf, sizeof(uint16_t)*2)) {
       PORTD.DR.BIT.B2 = 0;
       while(1) ;
   }

   if (df[0] != 0xDEAD || df[1] != 0xBEEF) {
       PORTD.DR.BIT.B6 = 0;  // Failed
   } else {
       PORTD.DR.BIT.B3 = 0;  // Success
   }
   // That's all for now.
   while(1) ;
   //
   return 0;
}

 

The dataflash_write() function just writes a whole segment, nuking any unused bytes with zeroes, max seg size is 128 and it must be an even # of bytes. The dataflash_erase() function performs erasure on a whole 2KB page, so the whole solution is rather crude.

 

Renesas publishes a "Virtual EEPROM" library that's based on their SimpleFLASH middleware library, but I kinda hate the way they write their libs, just looks clunky. I don't anticipate using this too much but hey.... I'll have to cook up my own simple library at some point anyhow.

 

Either way, it feels good to have finally tamed this beast. That's all the RX work I'm doing this week.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×