pokk 0 9 ноября, 2019 Опубликовано 9 ноября, 2019 (изменено) · Жалоба Не могу не как понять почему запись по 16bit не работает, устанавливает флаг ошибки PGPERR (Programming parallelism error) и записывает все равно 32bit Из Дашашита Quote PSIZE[1:0]:Program size These bits select the program parallelism. 00 program x8 01 program x16 10 program x32 11 program x64 uint8_t FLASH_Program_16Bit(uint32_t address,uint16_t data) { while(!flash_ready()); //Ожидаем готовности флеша к записи FLASH->CR = FLASH_CR_PG //Разрешаем программирование флеша |1*FLASH_CR_PSIZE_0 //PSIZE[1:0]:Program size |0*FLASH_CR_PSIZE_1; // 01 program x16 *(__IO uint32_t*)address = (uint16_t)data; //Пишем 2 байта while(!flash_ready());//Ждем завершения операции if(!check_EOP())return 0; FLASH->CR &= ~(FLASH_CR_PG); //Запрещаем программирование флеша return check_EOP(); } Запись по 32bit работает uint8_t FLASH_Program_32bit(uint32_t address,uint32_t data) { while(!flash_ready()); //Ожидаем готовности флеша к записи FLASH->CR = FLASH_CR_PG //Разрешаем программирование флеша |0*FLASH_CR_PSIZE_0 //PSIZE[1:0]:Program size |1*FLASH_CR_PSIZE_1; // 10 program x32 *(__IO uint32_t*)address = (uint32_t)data; //Пишем 4 байта while(!flash_ready());//Ждем завершения операции if(!check_EOP())return 0; FLASH->CR &= ~(FLASH_CR_PG); //Запрещаем программирование флеша return check_EOP(); } Изменено 9 ноября, 2019 пользователем pokk Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 9 ноября, 2019 Опубликовано 9 ноября, 2019 · Жалоба 45 minutes ago, pokk said: *(__IO uint32_t*)address = (uint16_t)data; //Пишем 2 байта Из мануала: Quote 3. Perform the data write operation(s) to the desired memory address (inside main memory block or OTP area): – Byte access in case of x8 parallelism – Half-word access in case of x16 parallelism – Word access in case of x32 parallelism – Double word access in case of x64 parallelism Установили 16 бит, а пишете 32. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 9 ноября, 2019 Опубликовано 9 ноября, 2019 · Жалоба Благодарю, так и знал что где-то элементарная ошибка которую упускаю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 9 ноября, 2019 Опубликовано 9 ноября, 2019 · Жалоба FLASH->CR = FLASH_CR_PG //Разрешаем программирование флеша |0*FLASH_CR_PSIZE_0 //PSIZE[1:0]:Program size |1*FLASH_CR_PSIZE_1; // 10 program x32 Зачем вы меняете значение ВСЕХ битовых полей регистра, когда вам нужно изменить только два? Не боитесь записью всего регистра испортить то, что лежит вне интересующих вас разрядов? Разделите это на 2 операции: установка битового поля PSIZE и разрешение программирования с использованием метода чтение-модификация-запись. Тогда ничего постороннего не пострадает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 9 ноября, 2019 Опубликовано 9 ноября, 2019 · Жалоба 2 часа назад, Darth Vader сказал: Зачем вы меняете значение ВСЕХ битовых полей регистра, когда вам нужно изменить только два? Так и следует делать. А чтобы "не бояться" нужно мануал на периферию читать. Да к тому же из приведённого кода никак не следует что автор "меняет значение ВСЕХ битовых полей регистра". А вот "FLASH->CR &= ~(FLASH_CR_PG);" - тут чтение совершенно лишнее, достаточно только записи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 9 ноября, 2019 Опубликовано 9 ноября, 2019 · Жалоба 49 minutes ago, jcxz said: Да к тому же из приведённого кода никак не следует что автор "меняет значение ВСЕХ битовых полей регистра". Присваивание нового значения регистру потенциально может изменить любое битовое поле в нём. А не только те, что хотел изменить автор. Например, в приведённой строке он "попутно" сбрасывает биты ERRIE и IOPIE (25 и 24 позиции). А если до этого они были выставлены в 1? Намеренно, чтобы получить запрос на прерывания по этим событиям. А после такой записи в регистр логика работы программы нарушится и надо будет искать, а почему же программа не заходит в обработчик прерываний, которые я разрешил? А потом оказывается, что в функции записи флеша ты, сам того не желая, сбрасываешь разрешения на эти прерывания. А всё потому, что делаешь запись вместо чтения-модификации-запись. Я не настаиваю. Я предупреждаю и предостерегаю о возможных последствиях. Запись надо применять осторожно, точно убедившись, что значения всех соседних бит в регистре можно безнаказанно занулять. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 9 ноября, 2019 Опубликовано 9 ноября, 2019 · Жалоба 30 минут назад, Darth Vader сказал: Например, в приведённой строке он "попутно" сбрасывает биты ERRIE и IOPIE (25 и 24 позиции). А если до этого они были выставлены в 1? А если нет? Если не были выставлены? Очевидно что это - не весь код, а только его кусок. По которому нельзя сделать таких выводов. Если где-то в начале кода содержимое регистра было проинициализировано, все биты? А потом дальше, последующими записями изменяются только нужные биты в регистре, а в другие записываются те же значения, что были раньше (так как предыдущее значение их известно). Я всегда так делаю в своих драйверах. Какой смысл читать регистр, если его значение известно из предыдущего кода? Чтобы замедлить работу программы и сделать её более громоздкой? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 9 ноября, 2019 Опубликовано 9 ноября, 2019 · Жалоба 49 minutes ago, jcxz said: А если нет? Если не были выставлены? Очевидно что это - не весь код, а только его кусок. По которому нельзя сделать таких выводов. Это законченный унифицированный кусок кода, оформленный в функцию. Он не должен иметь таких побочных действий. Если бы это был просто выдранный из контекста кусок кода - я бы согласился. Но для функции такое поведение недопустимо. Она не должна изменять (портить) того, что её не касается. Если она это делает - значит она неправильно спроектирована либо реализована. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 9 ноября, 2019 Опубликовано 9 ноября, 2019 · Жалоба 2 часа назад, Darth Vader сказал: Если бы это был просто выдранный из контекста кусок кода - я бы согласился. Но для функции такое поведение недопустимо. Она не должна изменять (портить) того, что её не касается. Кто Вам сказал, что она что-то "портит"? Если функция - часть некоего драйвера (часть его API) и в данном драйвере какие-то биты каких-то используемых регистров периферии (периферии принадлежащей этому драйверу) имеют предопределённое значение (например - установлены на этапе инициализации драйвера), то почему эта функция не может туда эти значения записать? Раз она их определённо "знает", то зачем ей их читать из этого регистра? Она может сразу записать туда нужную константу, сформированную в build-time. А может эта функция - вообще не часть API, а какая-то внутренняя функция драйвера (что скорей всего и есть). Какие-то надуманные ограничения.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 9 ноября, 2019 Опубликовано 9 ноября, 2019 · Жалоба 22 minutes ago, jcxz said: Какие-то надуманные ограничения Пусть автор сам решает. Моё дело предупредить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться