whale 6 26 мая, 2021 Опубликовано 26 мая, 2021 (изменено) · Жалоба Голова уже опухла, вроде читает но явно нули не пишет, все что можно прочитал, мануал 10 раз. Читает точно, стирает не знаю, но все биты единицы, где то засада после комента "пишем", нужно записать 64 бита вроде что и делается. // stm32g070 #define FLASH_KEY1 0x45670123 #define FLASH_KEY2 0xCDEF89AB #define FLASH_address 0x0801F800 // последняя страница uint32_t dwr, drd; void Flash_write(void) { //---------- разблокируем --------- FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY2; //---------- стираем ------------- while (FLASH->SR & FLASH_SR_BSY1); if (FLASH->SR & FLASH_SR_EOP) { FLASH->SR = FLASH_SR_EOP; } FLASH->CR |= FLASH_CR_PER; FLASH->CR |= (62<<FLASH_CR_PNB_Pos); // Задаем её адрес FLASH->CR |= FLASH_CR_STRT; while (!(FLASH->SR & FLASH_SR_EOP)); FLASH->SR = FLASH_SR_EOP; FLASH->CR &= ~FLASH_CR_PER; //--------- пишем -------------------- FLASH->CR |= FLASH_CR_PG; while(!(FLASH->SR & FLASH_SR_EOP)); *(uint32_t *)(FLASH_address) = 0;//dwr; *(uint32_t *)(FLASH_address+4) = 0;//dwr; while(!(FLASH->SR & FLASH_SR_EOP)); FLASH->CR &= ~(FLASH_CR_PG); //---------------------------------- FLASH->CR |= FLASH_CR_LOCK; } ///-------------------- Читает ------------------------- void Flash_read(void) { uint32_t address; address=0x0801F800; drd=(*(__IO uint32_t*) address); } Изменено 26 мая, 2021 пользователем whale Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 26 мая, 2021 Опубликовано 26 мая, 2021 · Жалоба У меня на этом камне такой код работает (правда, у меня в библиотеке номер бита, а не маска). //----------------------------------------------------------------------------- // int flash_write(const void *dst, const void *src, const DWORD size) //----------------------------------------------------------------------------- int flash_write(const void *dst, const void *src, const DWORD size) { DWORD *w_dst = (DWORD *)dst; DWORD *w_src = (DWORD *)src; if(FLASH->CR & (1 << FLASH_CR_LOCK)) { FLASH->KEYR = KEY1; FLASH->KEYR = KEY2; } while(FLASH->SR & (1 << FLASH_SR_BSY1)); FLASH->SR = 0 | (1 << FLASH_SR_OPERR) | (1 << FLASH_SR_PROGERR) | (1 << FLASH_SR_WRPERR) | (1 << FLASH_SR_PGAERR) | (1 << FLASH_SR_SIZERR) | (1 << FLASH_SR_PGSERR) | (1 << FLASH_SR_MISSERR) | (1 << FLASH_SR_FASTERR) | (1 << FLASH_SR_OPTVERR); for(int i = 0; i < size / sizeof(DWORD) / 2; i++) { FLASH->CR = (1 << FLASH_CR_PG); w_dst[0] = w_src[0]; w_dst[1] = w_src[1]; while((FLASH->SR) & (1 << FLASH_SR_BSY1)); if((w_dst[0] != w_src[0]) || (w_dst[1] != w_src[1])) return FLASH_RESULT_ERROR; w_dst += 2; w_src += 2; } return FLASH_RESULT_OK; } //----------------------------------------------------------------------------- // void flash_erase(const DWORD start, const DWORD size) //----------------------------------------------------------------------------- void flash_erase(const DWORD start, const DWORD size) { if(FLASH->CR & (1 << FLASH_CR_LOCK)) { FLASH->KEYR = KEY1; FLASH->KEYR = KEY2; } while(FLASH->SR & (1 << FLASH_SR_BSY1)); FLASH->SR = 0 | (1 << FLASH_SR_OPERR) | (1 << FLASH_SR_PROGERR) | (1 << FLASH_SR_WRPERR) | (1 << FLASH_SR_PGAERR) | (1 << FLASH_SR_SIZERR) | (1 << FLASH_SR_PGSERR) | (1 << FLASH_SR_MISSERR) | (1 << FLASH_SR_FASTERR) | (1 << FLASH_SR_OPTVERR); for(int i = (start / FLASH_PAGE_SIZE); i < ((start + size) / FLASH_PAGE_SIZE); i++) { FLASH->CR = (1 << FLASH_CR_PER) + (i << FLASH_CR_PNB); FLASH->CR = (1 << FLASH_CR_PER) + (i << FLASH_CR_PNB) + (1 << FLASH_CR_STRT); while(FLASH->SR & (1 << FLASH_SR_BSY1)); } } У вас тут FLASH->CR |= (62<<FLASH_CR_PNB_Pos); // Задаем её адрес точно нули в регистре, чтобы без очистки биты только устанавливать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
heavyC1oud 0 26 мая, 2021 Опубликовано 26 мая, 2021 · Жалоба 2 часа назад, whale сказал: #define FLASH_address 0x0801F800 // последняя страница 2 часа назад, whale сказал: FLASH->CR |= (62<<FLASH_CR_PNB_Pos); // Задаем её адрес последняя страница 63 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whale 6 26 мая, 2021 Опубликовано 26 мая, 2021 (изменено) · Жалоба 1 hour ago, adnega said: w_dst += 2; w_src += 2; А почему адрес увеличиваем на 2 если двойное слово 4 байта ? А наверно адресация двойными словами. У меня там на 4 скачет может по этому не работает. 1 hour ago, adnega said: точно нули в регистре По сбросу вроде нули должны, к тому же память читаются все 1 так что очистку можно пропустить ) 57 minutes ago, heavyC1oud said: последняя страница 63 с 63 тоже пробовал тоже самое 1 hour ago, adnega said: if((w_dst[0] != w_src[0]) || (w_dst[1] != w_src[1])) тут не понял, вы сравниваете адрес и данные ??? Изменено 26 мая, 2021 пользователем whale Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 27 мая, 2021 Опубликовано 27 мая, 2021 · Жалоба 7 часов назад, whale сказал: А почему адрес увеличиваем на 2 если двойное слово 4 байта ? А наверно адресация двойными словами. У меня там на 4 скачет может по этому не работает. Да, т.к. указатель на DWORD, то скакать будет по 8 байт. 7 часов назад, whale сказал: тут не понял, вы сравниваете адрес и данные ??? Я сравниваю записанные данные с источником. Если записалось не то, что записывали, то выход с ошибкой. У вас RCC_AHBENR_FLASH в RCC->AHBENR установлен? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlanDrakes 1 27 мая, 2021 Опубликовано 27 мая, 2021 (изменено) · Жалоба Я себе напсал такой код: // Разблокировка записи/стирания флеш-памяти uint8_t Flash_UnLock(void) { if (FLASH->CR & FLASH_CR_LOCK) { FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY2; }; return Flash_Lock_Status(); }; // Блокировка записи/стирания флеша void Flash_Lock(void) { FLASH->CR |= FLASH_CR_LOCK; }; // Проверка статуса блокировки. Если 1 - заблокирована. uint8_t Flash_Lock_Status(void) { // FLASH->CR[7] == LOCK bit. If 1 - locked while (FLASH->SR & FLASH_SR_BSY); return ((FLASH->CR & FLASH_CR_LOCK) & 0xFF); }; // Старание страницы. Принимается АДРЕС 0x08000000~0x08... // Может потребоваться переделать под номера страниц. uint8_t Flash_ErasePage(uint32_t Address) { uint16_t i; uint32_t Start; uint8_t DoErase = 0; if (Address < APP_SECTION_START) return -1; if (Address >= APP_SECTION_END) return -1; Start = (Address & 0x0801FC00); // 1024 bytes for (i=0; i<1024; i++) { if ( *(uint16_t*)(Start + i) != 0xFFFF) { DoErase = 1; break; }; }; if (DoErase) { if (Flash_Lock_Status() == 0) { __disable_irq(); // Single thread FLASH->CR &= ~(FLASH_CR_PER | FLASH_CR_MER | FLASH_CR_PG | FLASH_CR_OPTER | FLASH_CR_OPTPG); FLASH->CR |= FLASH_CR_PER; FLASH->AR = Start; FLASH->CR |= FLASH_CR_STRT; while (FLASH->SR & FLASH_SR_BSY) {}; FLASH->CR &= ~FLASH_CR_PER; __enable_irq(); // Interrupt mode return 0; } else { return -1; }; } else { return 0; }; }; // Запись двух байт в память по указанному адресу. Если результат отличается - возвзаращает 1, если совпадает - 0. uint8_t Flash_WriteWord(uint32_t Address, uint16_t Data) { while (FLASH->SR & FLASH_SR_BSY) {}; FLASH->CR &= ~(FLASH_CR_PER | FLASH_CR_MER | FLASH_CR_PG | FLASH_CR_OPTER | FLASH_CR_OPTPG); FLASH->CR |= FLASH_CR_PG; *(uint16_t*)(Address) = Data; while (FLASH->SR & FLASH_SR_BSY) {}; FLASH->CR &= ~(FLASH_CR_PER | FLASH_CR_MER | FLASH_CR_PG | FLASH_CR_OPTER | FLASH_CR_OPTPG); if (*(uint16_t*)(Address) == Data) { return 0; } else { return 1; }; }; Изменено 27 мая, 2021 пользователем AlanDrakes Добавил комментарии Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 27 мая, 2021 Опубликовано 27 мая, 2021 · Жалоба 9 минут назад, AlanDrakes сказал: Я себе напсал такой код: Смущает (т.к. G070): вроде, страница 2 кБ и писать нужно по 8 байт Цитата FLASH Main memory programming sequences The Flash memory is programmed 72 bits (64-bit data plus 8-bit ECC) at a time. Programming a previously programmed address with a non-zero data is not allowed. Any such attempt sets PROGERR flag of the FLASH status register (FLASH_SR). It is only possible to program a double word (2 x 32-bit data). • Any attempt to write byte (8 bits) or half-word (16 bits) sets SIZERR flag of the FLASH status register (FLASH_SR). • Any attempt to write a double word that is not aligned with a double word address sets PGAERR flag of the FLASH status register (FLASH_SR). Я так понял, что там ECC, поэтому дозаписывать в пределах 8 байт уже не получится. Ну и про 8, 16 бит явно написано, что будет ошибка. И отсутствие выравнивания на границу двойного слова (8 байт) - тоже ошибка. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 173 27 мая, 2021 Опубликовано 27 мая, 2021 · Жалоба 15 минут назад, adnega сказал: ...писать нужно по 8 байт... Писать нужно два раза по 32-битному слову, по адресам A и A + 4, где A - выровнен на границу двойного (64 бит) слова. В RM все об этом есть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whale 6 27 мая, 2021 Опубликовано 27 мая, 2021 (изменено) · Жалоба 1 hour ago, adnega said: У вас RCC_AHBENR_FLASH в RCC->AHBENR установлен? Точно пропустил ) надо попробовать, понапридумывают всяких флагов и что характерно в мануале в теме про флэш про это ни слов, пишут как для шпионов ) У меня было смутное подозрение что где то в RCC чего нить надо вставить но не нашел . Изменено 27 мая, 2021 пользователем whale Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whale 6 27 мая, 2021 Опубликовано 27 мая, 2021 (изменено) · Жалоба К сожалению тактирование было включено в дргуом модуле ( Буду ошибки смотреть. Изменено 27 мая, 2021 пользователем whale Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whale 6 27 мая, 2021 Опубликовано 27 мая, 2021 (изменено) · Жалоба Ура ! заработало в таком виде, для G70 висла на while (!(FLASH->SR & FLASH_SR_EOP)); и не работало *(uint32_t *)(FLASH_address) = 0;//dwr; Подскажите как удобнее разбить 4 байта на байты чтобы читать и записывать по отдельности, какая нить структура или сдвигать ? void Flash_init(void) { FLASH->ACR |= 2; // задержка 2 такта } ///-------------------- Записывает dwr ---------------------- void Flash_write(void) { err=0; errN=0; //---------- разблокируем --------- if(FLASH->CR & FLASH_CR_LOCK) { FLASH->KEYR = KEY1; FLASH->KEYR = KEY2; } else err = 1; errN++; //1 //---------- стираем ------------- while (FLASH->SR & FLASH_SR_BSY1); // пока BSY1==1 errN++; //2 if (FLASH->SR & FLASH_SR_EOP) FLASH->SR = FLASH_SR_EOP; FLASH->SR = 0 | FLASH_SR_OPERR | FLASH_SR_PROGERR | FLASH_SR_WRPERR | FLASH_SR_PGAERR | FLASH_SR_SIZERR | FLASH_SR_PGSERR // | FLASH_SR_MISSERR // не находит | FLASH_SR_FASTERR | FLASH_SR_OPTVERR; FLASH->CR |= FLASH_CR_PER; FLASH->CR |= (63<<FLASH_CR_PNB_Pos); // Задаем её адрес FLASH->CR |= FLASH_CR_STRT; while( FLASH->SR & FLASH_SR_BSY1); errN++;//3 FLASH->CR &= ~FLASH_CR_PER; if(FLASH->SR & FLASH_SR_PROGERR )err=2; //--------- пишем -------------------- FLASH->CR |= FLASH_CR_PG; (*(__IO uint32_t*)FLASH_address) = dwr; (*(__IO uint32_t*)(FLASH_address+4)) = dwr2; while(FLASH->SR & FLASH_SR_BSY1); errN++;//4 if(FLASH->SR & FLASH_SR_PROGERR )err= 3; if(FLASH->SR & FLASH_SR_SIZERR )err= 4; if(FLASH->SR & FLASH_SR_PGAERR )err= 5; if(FLASH->SR & FLASH_SR_WRPERR )err= 6; FLASH->CR &= ~FLASH_CR_PG; FLASH->CR |= FLASH_CR_LOCK; errN++;//5 //---------------------------------- } ///-------------------- Читает drd -------------------------- void Flash_read(void) { uint32_t address; address= FLASH_address; drd=(*(__IO uint32_t*) address); // Читать данные drd2=(*(__IO uint32_t*)( address+4)); // Читать данные } Изменено 27 мая, 2021 пользователем whale Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whale 6 27 мая, 2021 Опубликовано 27 мая, 2021 (изменено) · Жалоба немного гугления привело к такой рабочей штуке struct tpSettings { char d1,d2,d3,d4;}; struct tpSettings Flash_data1; uint32_t *source_data1 = (void *)&Flash_data1; вместо dwr/drd ставим *source_data1 и будет счастье. Изменено 27 мая, 2021 пользователем whale Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 27 мая, 2021 Опубликовано 27 мая, 2021 · Жалоба 5 часов назад, whale сказал: немного гугления привело к такой рабочей штуке До волшебного слова union не догуглили? Прочитайте об этом пару страниц в любой книжке по Си и многое станет делать проще. Не понадобится приведение указателей. Скрытый текст typedef union { uint32_t w; uint8_t b[4]; } tpSettings; tpSettings Flash_data1; uint32_t *source_data1 = &Flash_data1.w; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whale 6 27 мая, 2021 Опубликовано 27 мая, 2021 (изменено) · Жалоба все это лишняя суета Изменено 27 мая, 2021 пользователем whale Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 173 28 мая, 2021 Опубликовано 28 мая, 2021 · Жалоба 27.05.2021 в 08:52, AlanDrakes сказал: Я себе написал такой код... Вы как-то неравнодушны к символу "точка с запятой" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться