Author Topic: CH32V003J4M6 - Does anyone have working code to write to Flash e.g., 0x1FFFF800  (Read 4258 times)

0 Members and 1 Guest are viewing this topic.

Offline dzairoTopic starter

  • Contributor
  • Posts: 10
  • Country: sk
I am trying to save data to the user Flash on a CH32V003J4M6, specifically in the last page at 0x1FFFF800. Nothing I try works.
Does anyone have a simple, proven, and working code snippet for erasing and writing to the user Flash on this chip? I don't need the theory, just code that works.

Thank you.
 

Offline microvia

  • Regular Contributor
  • *
  • Posts: 152
  • Country: fr
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 6464
  • Country: nz
I would assume this works also, it's a pretty minimal example but the other one looks more polished:

https://github.com/cnlohr/ch32fun/tree/master/examples/flashtest
 

Offline dzairoTopic starter

  • Contributor
  • Posts: 10
  • Country: sk
Hi. Then If want store any data need Erase last page (1024 bytes) or Is possible only last 64bytes ??
 

Online mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 14822
  • Country: gb
    • Mike's Electric Stuff
I am trying to save data to the user Flash on a CH32V003J4M6, specifically in the last page at 0x1FFFF800. Nothing I try works.
Does anyone have a simple, proven, and working code snippet for erasing and writing to the user Flash on this chip? I don't need the theory, just code that works.

Thank you.
There was an error in an early version of the library - a register that needed bit 16 set was incorrectly defined as 16 bits  wide.
I think  user options flash need specific commands to write. Here is some code I used to check and of necessary rewrite the user options to allow PD7 to be used as an output
Code: [Select]


 u32* fptr = (u32*) 0x1FFFF800;

    i = fptr[0] >> 16;
 

 // factory value 0xE817


   if ((i&0x18)!=0x18)
{ // set PD7 as output

FLASH_Unlock();
FLASH_EraseOptionBytes();
FLASH_UserOptionByteConfig(0x1F, 0, 0, 0);
FLASH_Unlock();
PFIC->CFGR=0xBEEF0080; //reset to re-read value
}

 
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline dzairoTopic starter

  • Contributor
  • Posts: 10
  • Country: sk
I'm confused from this ..
Flash menory 16k + bootloader + optin byte + user byte ?? toatal is total 18 432byt ? is it right ?
I sue mouRiver studio , and I see real data in flash ..  then in what positon are user bytes (64 bytes size ) .

I don't want change option bytes , only user .. and donw' want change bootlader or flash memory .. or
user flash is part of flash memory??

and this is not efective to erase 1k last page flash, is there option to erase last 64bytes only ??
 

Offline voltsandjolts

  • Supporter
  • ****
  • Posts: 3855
  • Country: gb
So many questions.
Maybe try switching to a different microcontroller which has documentation that is more correct/easier to understand.
NXP are good in this respect.
 

Offline dzairoTopic starter

  • Contributor
  • Posts: 10
  • Country: sk
..hmm.. I make procejct where I need cheap MCU ..
 

Online mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 14822
  • Country: gb
    • Mike's Electric Stuff
Might help if you said exactly what you are trying to do.
if it's saving configurations etc., easiest to use the last page of program flash.

This code will write one 32 bit word :
Code: [Select]

#define flashadr 0x08003fc0 // last page of flash

u32* flashptr = (u32*) flashadr;

void writeflash(u32 flashdata)
    {

#define FLASH_CTLR_PAGEER  0x20000 // defs in header are wrong - declared as u16
#define FLASH_CTLR_PAGEPG 0x10000 // defs in header are wrong - declared as u16
#define FLASH_CTLR_BUFLD 0x40000 // defs in header are wrong - declared as u16
#define FLASH_CTLR_BUFRST 0x80000


    FLASH->KEYR = 0x45670123;
    FLASH->KEYR = 0xCDEF89AB;
    FLASH->MODEKEYR = 0x45670123;
    FLASH->MODEKEYR = 0xCDEF89AB;
    FLASH->ADDR = (u32) flashptr;
    FLASH->CTLR = FLASH_CTLR_PAGEER;

    FLASH->CTLR = FLASH_CTLR_STRT | FLASH_CTLR_PAGEER;

    while( FLASH->STATR & FLASH_STATR_BSY);

    FLASH->CTLR = FLASH_CTLR_PAGEPG;
    FLASH->CTLR = FLASH_CTLR_BUFRST | FLASH_CTLR_PAGEPG;
    while( FLASH->STATR & FLASH_STATR_BSY );
    FLASH->ADDR = (u32) flashptr;

    flashptr[0] = flashdata;
    FLASH->CTLR |= FLASH_CTLR_BUFLD | FLASH_CTLR_PAGEPG;
    while ( FLASH->STATR & FLASH_STATR_BSY );

    FLASH->CTLR = FLASH_CTLR_STRT | FLASH_CTLR_PAGEPG;
    while( FLASH->STATR & FLASH_STATR_BSY );

    }
To read the flash word :
Code: [Select]
   i = flashptr[0];
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline dzairoTopic starter

  • Contributor
  • Posts: 10
  • Country: sk
Hi all.
Problem .
If try my code to store and read data from Flash then I make from MCU brick  :palm: .. not only one .. 5pcs .. and I don't know how to get it unbrick .

This code :
Code: [Select]
uint8_t SaveFlash(const uint8_t EraseOnly)
{
        __disable_irq();
    FLASH->KEYR = FLASH_KEY1;
    FLASH->KEYR = FLASH_KEY2;
    FLASH->MODEKEYR = FLASH_KEY1;
    FLASH->MODEKEYR = FLASH_KEY2;
    FLASH->ACTLR = (FLASH->ACTLR & ~FLASH_ACTLR_LATENCY) | FLASH_ACTLR_LATENCY_1;
  if( FLASH->CTLR & 0x8080  ) // Testuje ci je zamknuta pamet alebo nieco ine, ma byt 0
{
return 1;
}
uint32_t * ptr = (uint32_t*)USER_MEMORY_BASE;
//Erase Page
FLASH->CTLR = CR_PAGE_ER;
FLASH->ADDR = (intptr_t)ptr;
FLASH->CTLR = CR_STRT_Set | CR_PAGE_ER;
while( FLASH->STATR & FLASH_STATR_BSY );  // Takes about 3ms.
if( ptr[0] != 0xffffffff )
{
return 2;
}
// Clear buffer and prep for flashing.
FLASH->CTLR = CR_PAGE_PG;  // synonym of FTPG.
FLASH->CTLR = CR_BUF_RST | CR_PAGE_PG;
FLASH->ADDR = (intptr_t)ptr;  // This can actually happen about anywhere toward the end here.
// Note: It takes about 6 clock cycles for this to finish.

int i;
for( i = 0; i < 16; i++ )
{
if (EraseOnly) ptr[i] = 0xFFFFFFFF;
        else ptr[i] = 0xabcd1234 + i; //Write to the memory
FLASH->CTLR = CR_PAGE_PG | FLASH_CTLR_BUF_LOAD; // Load the buffer.
while( FLASH->STATR & FLASH_STATR_BSY );  // Only needed if running from RAM.
}
// Actually write the flash out. (Takes about 3ms)
FLASH->CTLR = CR_PAGE_PG|CR_STRT_Set;
while( FLASH->STATR & FLASH_STATR_BSY );
if( ptr[0] != 0xabcd1234 )
{
return 3;
}
    __enable_irq();
    return 0;
}

I'm creazy from this .. not only sotware problem .. upload code .. bum.. my MCU is brick .. help me unbrick MCU .. 
I sue easy chepa WCHlink from aliexpress .. what happend ..
 

Online mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 14822
  • Country: gb
    • Mike's Electric Stuff
It can get to weird states - the memory at 1FFFF800 includes write-protect bits, so if you have programmed there, that will cause problems.
From Mounriver studio try flash->configuration and click the open padlock symbol to erase code protection.
The WCH-link utility can also be useful for reprogramming messed up chips
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline dzairoTopic starter

  • Contributor
  • Posts: 10
  • Country: sk
not working..
Code: [Select]
20:07:20:555>> Connected RISC-V mode WCH-Link Cnt:1
20:07:20:603>> Connected RISC-V mode WCH-Link Cnt:1
20:07:27:109>> Begin to clear all code flash...
20:07:27:125>> Succeed!

Code: [Select]
20:08:34:460>> Connected RISC-V mode WCH-Link Cnt:1
20:08:34:507>> Connected RISC-V mode WCH-Link Cnt:1
20:08:42:002>> Begin to set chip type...
20:08:42:084>> Failed,the chip type is not matched or status of chip is wrong!

What is wrong..

On first .. MCU start reset in cycle .. and then total brick ..


 

Offline voltsandjolts

  • Supporter
  • ****
  • Posts: 3855
  • Country: gb
..hmm.. I make procejct where I need cheap MCU ..

Cheap. Well, that depends how much you value your time. And ours.
 

Offline dzairoTopic starter

  • Contributor
  • Posts: 10
  • Country: sk
..in 10kpcs production is MCU price very important ..
chip what just restart in cycles , using WCH Link Utlity I set any bits and now working good..
But brics not working ..
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17824
  • Country: fr
The datasheet mentions 64-byte pages (see Memory characteristics), the RM also mentions 64-bytes pages (see Flash Memory Organisation), but the SDK seems to only implement erasing by "1K pages".

The docs are confusing. They seem to mention two modes, standard programming and fast programming. The fast programming mode would be the only one apparently able to erase only by 64-byte pages. But as far as I've seen, the SDK doesn't seem to implement it.

I have noticed for other WCH MCUs that their SDK would often evolve and remove fast flash programming support, for a reason unknown, as there's unfortunately no errata sheet that I know of for any of them.

Don't get me wrong, WCH MCUs are great overall, but I do not like the absence of errata sheets and the way  they tend to be too secretive about errata overall, which seems to be relatively common among chinese vendors.
 

Offline dzairoTopic starter

  • Contributor
  • Posts: 10
  • Country: sk
...yes, I alos think there is problem.. I try use last 64bytes of end of flash .. and if try erase first .. then erase not only 64bytes.. I try this today..I will see ..

thanks.
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 6464
  • Country: nz
It only takes one person to figure this out and document it for the community...
 

Offline mark03

  • Frequent Contributor
  • **
  • Posts: 782
  • Country: us
It only takes one person to figure this out and document it for the community...
Does anyone stop to ask WHY we are reduced to reverse-engineering the parts sold to us by companies which [presumably?] already have the answers?  (and if they *don't* know the answers, why on earth would I trust their technical chops enough to choose their products in the first place?)

I will start paying more attention to RISC-V when a vendor offers a standard of documentation up to, let's say, the level of ST Microelectronics.  That is hardly a high bar.

I know this is mainly a China thing and not a RISC-V thing, but it is frightening to consider that this could be the future of embedded development.  Countless millions of hours of wasted and lost productivity.  Sheer, shortsighted madness :palm:
 

Offline dzairoTopic starter

  • Contributor
  • Posts: 10
  • Country: sk
Quote
mark03

"Yes, it’s true, but I have a very good reason for doing it. I'm designing a very small PCB for a Chinese product with few SMD components, so a low price is a very important option. I've been using Atmel products for 30 years—their datasheets are perfect, with 300 or more pages and everything well-documented. But do Atmel (Microchip) MCUs cost $0.10 in quantities of a thousand? The price of the ATTiny85 was too high for my project. So, I tried to find the best, most affordable Chinese MCU, and the CH32V003J4M6 is my favorite. I used Deepseek and Gemini to help me with the programming, and step by step, everything is working now.

Now, back to my problem: I want to use the internal Flash memory (an external EEPROM costs around $0.01 in quantities of 10,000) to store no more than 64 bytes, and possibly more in the future. I've been searching for a code to do this. All my tests of changing the Option Bytes have resulted in the MCU not working properly. Also, changing a special bit and using pin PD1 as SWIO sets only PD1, which bricks the chip—a very cheap brick, but a brick nonetheless.

Then, with help from
Quote
Bruce Hoult
and
Quote
microvia
, I found and analyzed some code, and now I have a working solution. But how do I test if a Flash erase operation erases only 64 bytes or a full 1024-byte page?

I did the following:

Created a file flash_test.h with 2048 bytes of test data.

Modified the Link.ld file to store this test data at the end of the Flash section (Deepseek helped me with this).

Compiled and flashed the MCU.

Used the WCH Link Utility to read the complete Flash memory and save it as a binary file.

Then, I used my code to erase a part of the Flash memory. I used the following addresses:
Code: [Select]
#define USER_MEMORY_BASE 0x08003FC0
#define USER_MEMORY_SIZE 64
I also tried another address (my testing data is 2048 bytes, so I used an address within this range). I then read the entire Flash again and compared the files. The result was that only 64 bytes were erased after the erase page command. I set the last 64 bytes at 0x08003FC0 and will continue to use this section, hoping the MCU doesn't get bricked.
Here is my eeprom.h file
Code: [Select]
// Adresa user memory podla dokumentивcie
#define USER_MEMORY_BASE 0x08003FC0
#define USER_MEMORY_SIZE 64

#define FLASH_KEY1                 ((uint32_t)0x45670123)
#define FLASH_KEY2                 ((uint32_t)0xCDEF89AB)
#define CR_STRT_Set                ((uint32_t)0x00000040)
#define CR_LOCK_Set                ((uint32_t)0x00000080)
#define CR_PAGE_PG                 ((uint32_t)0x00010000)
#define CR_PAGE_ER                 ((uint32_t)0x00020000)
#define CR_BUF_LOAD                ((uint32_t)0x00040000)
#define CR_BUF_RST                 ((uint32_t)0x00080000)


uint8_t read_bytes(uint8_t start_addr, uint8_t *buffer, uint8_t length);
uint8_t SaveFlash(const uint8_t EraseOnly);
void print_full_memory(void);

and eeprom.c

Code: [Select]
#include <ch32v00x_it.h>

#include "eeprom.h"
#include <ch32v00x_flash.h>

uint8_t read_bytes(uint8_t start_addr, uint8_t *buffer, uint8_t length)
{
    if (start_addr >= USER_MEMORY_SIZE || buffer == NULL) return 0;
    if (start_addr + length > USER_MEMORY_SIZE) length = USER_MEMORY_SIZE - start_addr;
    __disable_irq();
    for (uint8_t i = 0; i < length; i++) {
        buffer[i] = *((volatile uint8_t*)(USER_MEMORY_BASE + start_addr + i));
    }
    __enable_irq();
    return length;
}

uint8_t SaveFlash(const uint8_t EraseOnly)
{
        __disable_irq();
    FLASH->KEYR = FLASH_KEY1;
    FLASH->KEYR = FLASH_KEY2;
    FLASH->MODEKEYR = FLASH_KEY1;
    FLASH->MODEKEYR = FLASH_KEY2;
    FLASH->ACTLR = (FLASH->ACTLR & ~FLASH_ACTLR_LATENCY) | FLASH_ACTLR_LATENCY_1;
  if( FLASH->CTLR & 0x8080  ) // Testuje ci je zamknuta pamet alebo nieco ine, ma byt 0
{
    __enable_irq();
return 1;
}
uint32_t * ptr = (uint32_t*)USER_MEMORY_BASE;
//Erase Page
FLASH->CTLR = CR_PAGE_ER;
FLASH->ADDR = (intptr_t)ptr;
FLASH->CTLR = CR_STRT_Set | CR_PAGE_ER;
while( FLASH->STATR & FLASH_STATR_BSY );  // Takes about 3ms.
if( ptr[0] != 0xffffffff )
{
    __enable_irq();
return 2;
}
// Clear buffer and prep for flashing.
FLASH->CTLR = CR_PAGE_PG;  // synonym of FTPG.
FLASH->CTLR = CR_BUF_RST | CR_PAGE_PG;
FLASH->ADDR = (intptr_t)ptr;  // This can actually happen about anywhere toward the end here.
// Note: It takes about 6 clock cycles for this to finish.
int i;
for( i = 0; i < 16; i++ )
{
if (EraseOnly) ptr[i] = 0xFFFFFFFF;
        else ptr[i] = 0xabcd1234 + i; //Write to the memory
FLASH->CTLR = CR_PAGE_PG | FLASH_CTLR_BUF_LOAD; // Load the buffer.
while( FLASH->STATR & FLASH_STATR_BSY );  // Only needed if running from RAM.
}
// Actually write the flash out. (Takes about 3ms)
FLASH->CTLR = CR_PAGE_PG|CR_STRT_Set;
while( FLASH->STATR & FLASH_STATR_BSY );
if( ptr[0] != 0xabcd1234 )
{
    __enable_irq();
return 3;
}
    __enable_irq();
    return 0;
}




void print_full_memory(void)
{
    uint8_t buffer[64];
   
    // Na
    read_bytes(0, buffer, USER_MEMORY_SIZE);
   
    printf("\r\n=== User memory (64B) ===\r\n");
    printf("---------------------------------------------------------\r\n");
    for (uint8_t i = 0; i < 64; i += 16) {
        printf("%02X: ", i);
        for (uint8_t j = 0; j < 16; j++) {
            printf("%02X ", buffer[i + j]);
        }
        printf("\r\n");
    }
    printf("\r\n=========================================\r\n");
}




I use MounRiver Studio ..

This is my teting code .. not finall code ..  this is only if any interesting.. and yes , of course .. many bugs ..

Any ideas ??


Best reagrds.
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 6464
  • Country: nz
It only takes one person to figure this out and document it for the community...
Does anyone stop to ask WHY we are reduced to reverse-engineering the parts sold to us by companies which [presumably?] already have the answers?  (and if they *don't* know the answers, why on earth would I trust their technical chops enough to choose their products in the first place?)

Sure that would be nice, but it's not a show-stopper. It takes fuck-all time and money (on a 10c part!) to test it and figure it out yourself, and then you know for sure. If it was a $1000 part then sure I'd like to know before I bought one.

No doubt they do know the answers themselves. But they're writing reference material not tutorials, and when things are always done in a particular way experts who know it might not realise that it needs to be spelled out for the less expert.

Can't say I'm bothered. Much of my career is based on getting things to do stuff that the manufacturer hasn't considered and, if asked, will say can't be done or isn't supported. An early example was when the Apple Laserwriter came out with the amazing Postscript language a graphics library built in, and an RS-422 serial port for LocalTalk, I asked both Apple and Data General whether I could connect it to a DG MV/10000 supermini and both said no. I looked at the specs, figured that RS-232 and RS-422 were actually compatible with the right cable, and made one up. And proceeded to happily for the next two years write PL/I code that queried flat files and DG/SQL databases and output PostScript.

Quote
I will start paying more attention to RISC-V when a vendor offers a standard of documentation up to, let's say, the level of ST Microelectronics.  That is hardly a high bar.

The same manufacturer makes a range of Arm-based chips, and very popular 8051 and USB chips that sell in the billions.
 
The following users thanked this post: ali_asadzadeh

Offline ali_asadzadeh

  • Super Contributor
  • ***
  • Posts: 2139
  • Country: ca
Quote
Then, I used my code to erase a part of the Flash memory. I used the following addresses:
Thanks for sharing the code, I would definitely needed it in a project in future. >:D
ASiDesigner, Stands for Application specific intelligent devices
I'm a Digital Expert from 8-bits to 64-bits
 

Offline dzairoTopic starter

  • Contributor
  • Posts: 10
  • Country: sk
Hi all , I do smoe changes ...

eeprom.h
Code: [Select]
// Adresa user memory pod?a dokumentивcie

#define USER_MEMORY_SIZE 64
#define ERASE 1
#define FILL  0

// Definície pre lepšiu čitateľnosť
#define FLASH_ERROR_INVALID_POSITION  1
#define FLASH_ERROR_LOCKED            2
#define FLASH_ERROR_ERASE_FAILED      3
#define FLASH_ERROR_WRITE_FAILED      4
#define FLASH_ERROR_VERIFY_FAILED     5

extern volatile uint8_t Base0Buffer[USER_MEMORY_SIZE];

uint8_t read_bytes(uint8_t start_addr, uint8_t *buffer, uint8_t length);
uint8_t SaveFlash(const uint8_t EraseOnly,const uint8_t FlashPosition,volatile uint8_t *InBuffer);
void print_full_memory(void);

eeprom.c

Code: [Select]
#include <ch32v00x_it.h>
#include <ch32v00x_flash.h>

// vlastne subory
#include "eeprom.h"

//vlastne konstanty
#define USER_MEMORY_BASE_0 0x08003F00
#define USER_MEMORY_BASE_1 0x08003F40
#define USER_MEMORY_BASE_2 0x08003F80
#define USER_MEMORY_BASE_3 0x08003FC0

#define FLASH_KEY1                 ((uint32_t)0x45670123)
#define FLASH_KEY2                 ((uint32_t)0xCDEF89AB)
#define CR_STRT_Set                ((uint32_t)0x00000040)
#define CR_LOCK_Set                ((uint32_t)0x00000080)
#define CR_PAGE_PG                 ((uint32_t)0x00010000)
#define CR_PAGE_ER                 ((uint32_t)0x00020000)
#define CR_BUF_LOAD                ((uint32_t)0x00040000)
#define CR_BUF_RST                 ((uint32_t)0x00080000)

// Premenne pre fungovanie
volatile uint8_t Base0Buffer[USER_MEMORY_SIZE];

uint8_t read_bytes(uint8_t start_addr, uint8_t *buffer, uint8_t length)
{
    if (start_addr >= USER_MEMORY_SIZE || buffer == NULL) return 0;
    if (start_addr + length > USER_MEMORY_SIZE) length = USER_MEMORY_SIZE - start_addr;
    __disable_irq();
    for (uint8_t i = 0; i < length; i++) {
        buffer[i] = *((volatile uint8_t*)(USER_MEMORY_BASE_0 + start_addr + i));
    }
    __enable_irq();
    return length;
}

uint8_t SaveFlash(const uint8_t EraseOnly, const uint8_t FlashPosition,volatile  uint8_t *InBuffer)
{
    if (FlashPosition > 3) return 1; // Neplatná pozícia
    __disable_irq();
    // Odomknutie flash
    FLASH->KEYR = FLASH_KEY1;
    FLASH->KEYR = FLASH_KEY2;
    FLASH->MODEKEYR = FLASH_KEY1;
    FLASH->MODEKEYR = FLASH_KEY2;   
    // Nastavenie latencie
    FLASH->ACTLR = (FLASH->ACTLR & ~FLASH_ACTLR_LATENCY) | FLASH_ACTLR_LATENCY_1;
    // Kontrola stavu flash
    if (FLASH->CTLR & 0x8080) // Testuje či je zamknutá pamäť
    {
        FLASH->CTLR = FLASH_CTLR_LOCK; // Zamknúť flash
        __enable_irq();
        return 2; // Flash je zamknutá alebo chyba
    }
    uint32_t *ptr = (uint32_t*)(USER_MEMORY_BASE_0 + (USER_MEMORY_SIZE * FlashPosition));
    // Mazanie stránky
    FLASH->CTLR = FLASH_CTLR_PER; // Page erase
    FLASH->ADDR = (uint32_t)ptr;
    FLASH->CTLR = FLASH_CTLR_STRT | FLASH_CTLR_PER;
    while (FLASH->STATR & FLASH_STATR_BSY); // Čakanie na dokončenie
    // Kontrola vymazania
    if (ptr[0] != 0xFFFFFFFF)
    {
        FLASH->CTLR = FLASH_CTLR_LOCK; // Zamknúť flash
        __enable_irq();
        return 3; // Chyba mazania
    }
    if (EraseOnly)
    {
        // Iba mazanie - už hotové
        FLASH->CTLR = FLASH_CTLR_LOCK; // Zamknúť flash
        __enable_irq();
        return 0;
    }
    // Zápis dát do flash
FLASH->CTLR = CR_PAGE_PG;  // synonym of FTPG.
FLASH->CTLR = CR_BUF_RST | CR_PAGE_PG;
FLASH->ADDR = (intptr_t)ptr;  // This can actually happen about anywhere toward the end here.
    for (int i = 0; i < 16; i++) // 16 slov = 64 bytov
    {
        uint32_t data = ((uint32_t)InBuffer[(i * 4) + 0] << 0)  |
                        ((uint32_t)InBuffer[(i * 4) + 1] << 8)  |
                        ((uint32_t)InBuffer[(i * 4) + 2] << 16) |
                        ((uint32_t)InBuffer[(i * 4) + 3] << 24);
       
        ptr[i] = data; // Zápis slova
FLASH->CTLR = CR_PAGE_PG | FLASH_CTLR_BUF_LOAD; // Load the buffer.
while( FLASH->STATR & FLASH_STATR_BSY ){};  // Only needed if running from RAM.
       
    }
    // Finalizácia zápisu
FLASH->CTLR = CR_PAGE_PG|CR_STRT_Set;
while( FLASH->STATR & FLASH_STATR_BSY ){};
    FLASH->CTLR &= ~FLASH_CTLR_PG; // Vypni bit pre zapis
    // Kontrola celého zápisu
    for (int i = 0; i < 16; i++)
    {
        uint32_t expected = ((uint32_t)InBuffer[(i * 4) + 0] << 0)  |
                           ((uint32_t)InBuffer[(i * 4) + 1] << 8)  |
                           ((uint32_t)InBuffer[(i * 4) + 2] << 16) |
                           ((uint32_t)InBuffer[(i * 4) + 3] << 24);
       
        if (ptr[i] != expected)
        {
            FLASH->CTLR = FLASH_CTLR_LOCK; // Zamknúť flash
            __enable_irq();
            return 5; // Chyba overenia
        }
    }

    // Zamknutie flash
    FLASH->CTLR = FLASH_CTLR_LOCK;
    __enable_irq();
    return 0; // Úspech
}




// Pre debugovanie
// Funkcia na v?pis celej pam?te
void print_full_memory(void)
{
    uint8_t buffer[64];
   
    // Na
    read_bytes(0, buffer, USER_MEMORY_SIZE);
   
    // Vypик? hlavi?ku
    printf("\r\n=== User memory (64B) ===\r\n");
    printf("---------------------------------------------------------\r\n");
    // Vypик? hex
    for (uint8_t i = 0; i < 64; i += 16) {
        printf("%02X: ", i);
        for (uint8_t j = 0; j < 16; j++) {
            printf("%02X ", buffer[i + j]);
        }
        printf("\r\n");
    }
    printf("\r\n=========================================\r\n");
}


code to test in main.c
Code: [Select]
        print_full_memory();

    for (int i = 0; i < 64; i++) {
        Base0Buffer[i] = i + 0x21; // Dáta: 0x10, 0x11, 0x12, ...
    }

        SaveFlash(0,0,Base0Buffer);
        print_full_memory();
        SaveFlash(1,0,Base0Buffer);
        print_full_memory();

}

all other chagnes .. lock flash , or ... make from MCU brick .. ( two guys dead..  :phew:) still don't know what exactly happend .. but this I test .. and working ..
 
The following users thanked this post: ali_asadzadeh


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

- - -
-->