Перейти к содержанию
    

MementoMori

Свой
  • Постов

    1 340
  • Зарегистрирован

  • Посещение

Весь контент MementoMori


  1. И для ядра и для STM32F7 установлены. Вот скрин из обычного проекта Так Паки устанавливаются для конкретного Project или для Keil в целом? И вот еще что, обратил внимание - в алгоритме у меня значится Device Database, в простом проекте - Software Pack, причем ниспадающее меню неактивно (см. Скрины). Кнопка "select software pack" тоже неактивна. Может особенности какие есть для проектов-алгоритмов, потому я и не могу переключить. А DevicePack я устанавливаю по ссылке и, вроде бы все успешно. Но каждый раз мне предлагается его снова скачать.
  2. А по-моему было там такое.
  3. Вопрос возник из одной темы, обсуждаемой в разделе АРМ, но я все же считаю нужным обсудить его отдельно. Делаю алгоритм для программирования внешней QUAD SPI флеш средствами KEIL. Контроллер STM32F746 В папке Keil\arm\Flash взял шаблон. При работе шаблона возникли проблемы (включение тактирования qspi вешает программу). В ходе ковыряний я заподозрил, что дело в неправильном выборе целевого устройства в настройках. Залез в настройки Ни ядра M7, ни контроллеров серии M7 нет. Хотя у меня все библиотеки установлены, открываю другие проекты Там все есть. Когда я открываю шаблон в папке C:\Keil_v5\ARM\Flash\Template, то он пишет Жму Install, скачиваю файл, устанавливаю - бестолку. Что я делаю не так?
  4. Вы издеваетесь? Или посты мои не читаете? Вы понимаете разницу между общим и частным. Примеры дают общее представление о принципах. А у меня проблема частная: Еще раз повторяю!!!!!!! Я взял шаблон из папки кейла! Для тех кто в танке - шаблон - это тот же пример, который вы мне предлагаете посмотреть, но без кода внутри функций. Проверил! Keil его с успехом прогоняет, так как функции шаблона возвращают ноль всегда. Я добавляю туда единственную строку, самую первую из пункта 5.2.1. мануала https://www.st.com/content/ccc/resource/technical/document/application_note/group0/b0/7e/46/a8/5e/c1/48/01/DM00227538/files/DM00227538.pdf/jcr:content/translations/en.DM00227538.pdf которым Вы такого же вопрошающего тыкали в лицо на radiokote, спрашивая при этом, зачитал ли он его до дыр. И после этой единственной строки шаблон перестает работать дальше функции init Как работает шаблон, я уже понял, почитав эти самые примеры. Что нужно делать дальше? Реализовывать под конкретные контроллер и память. А на этом польза примеров из папки кейла заканчивается, потому что по F7 и n25q128 примеров нет. Тогда зачем вы даете мне бесполезные советы?
  5. Попробуйте то, с чего начинаю я и с чего у меня начинаются глюки: /* Enable the QSPI interface clock */ RCC->AHB3ENR |= 0x00000002; После того, как я это добавляю EraseSector перестает вызываться.
  6. Я не спорю с теми, кто говорит, что дел на 15 минут. Насколько я понял этот процесс - ничуть не сложнее чем настроить FATFs под какую-нибудь память. Я лет 5 назад настраивал и под флеш и под SD и под внутреннюю память контроллера - по полчаса уходило. А тут больше недели бьюсь и проблема не пойми в чем. У вас или у Владислава не найдется в закромах примера под QSPI? компилирующегося. Работающего? Под конкретные контроллер и память я переделаю сам. Но чтоб ХОТЯ БЫ не было той проблемы, что я описал выше (в том посту текст на желтом фоне) ? Дальше я сам как-нибудь.
  7. Судя по всему, долго и муторно. Но вот Владислав утверждает что 15 минут на код и 15 минут на отладку.
  8. ОК! Я последовал Вашему совету. Выкинул нафиг HAL, взял шаблон, пустой, скомпилировал, подключил - функции вызываются (видно что KEIL перебирает адреса, не выдавая сообщений об ошибке, ведь функции возвращают 0). Только добавляю в функцию init включение тактирования QSPI (чистые регистры, безо всяких калокубов, таймеров, прерываний) RCC->AHB3ENR |= RCC_AHB3ENR_QSPIEN; как все встает колом. Функция EraseSector не вызывается, Keil ждет таймаута и ругается. Что-то не так с шаблоном. Я честно все сделал по мануалу (а он не предполагает изменения настроек шаблона). Ну что с ним не так? Я прошу, глянуть проект - это шаблон кейловский, без изменений (кроме FlashDevice), в него добавлена всего лишь одна строка.https://cloud.mail.ru/public/5Ghh/3Hv6gbCb1
  9. Вы меня посылаете читать мануал? То есть даете абстрактный совет. Вот и я вам отвечу про vtor и примеры тем же образом - перечитайте тему и все мои посты внимательно. В ней содержится ответ на ваш вопрос. Это то же самое, что читать мануал, только проще, тут всего 4 страницы. Так же как во мне мои вопросы выдают любителя-дилетанта, так же и ваш вопрос выдвает в вас того чукчу, который не читатель, а писатель. Извините, если показался грубым.
  10. Спасибо за Ваши советы, обязательно учту их, но когда причина неработоспособности кода фактически локализована и остается ее только устранить - то хочется сделать именно это, а не переписывать заново код работы с qspi (который хорошо себя показал в обычном проекте). Что касается таблицы векторов прерывания - она конечно же есть в файле .s. А вот про ее перенос я как-то не подумал. Я любитель и делала это один раз, лет пять назад, когда писал бутлодер. У меня один вопрос - адрес таблицы векторов должен указывать в ОЗУ, начинающийся с 0х20000000? А куда конкретно и как понять, куда?
  11. В общем, причина всех неудач найдена. У меня почему-то не работает sys_tick. В соответствующих функциях Hal_GetTick() возвращает ноль. В результате не отрабатываются таймауты при работе с qspi. В сети пишут про обработку прерывания systick_handler, но оно у меня даже не вызывается. Вопросами а включены ли прерывания, а каков приоритет, я даже не задаюсь - функция HAL_Init все это отрабатывает. В обычном проекте я вставляю эту функцию первой же строкой в main(), после чего все работает как часы. Отсчет времени не работает, даже если меняю systick на TIM6. Его прерывание также не вызывается. То есть проблема со всеми прерываниями. Скажите, а могут ли быть какие препятствия для прерываний, если код не обычный а является алгоритмом прошивки? Я вот помню, что когда как-то раз делал бутлодер, нужно было менять что-то в таблице векторов прерываний... здесь ничего такого не надо делать?
  12. Не факт. Я писал уже выше - выдранный мной откуда-то код работы с qspi дважды вызывал hal_qspi_init. В основной программе контроллеру было пофиг, а вот в алгоритме это приводило к глюкам. Убрал строку - в основной программе ничего не произошло, а в алгоритме заработал вызов функций. То есть, с виду проблема в проекте, на деле же - с кодом. У меня еще страннность - стирание секторов работает только со второго раза всегда. То есть запускаешь прошивание первый раз - выдается ошибка, запускаешь второй раз - перебираются адреса.
  13. Ах, да... я вас спутал с еще одним товарищем по несчастью с, которым списался на эту тему. Глянул Ваш код. Скажите, а вы увкрены, что все, что прописано в spiflash.c, в случае успеха возвращает 0, а при неудаче 1? А то ведь если наоборот, то алгоритм в случае ошибки будет думать, что все ОК. Насчет Вашего кода - он привлекательно прости, но вот я неуверен, что смогу настроить spi на те же ноги - у меня qspi, да еще и в нестандартной конфигурации, с ремаппингом. Вечером гляну.
  14. Открывал я вашу прошивку - понятное дело она не заливает, так как функции заливки не прописаны. И понятно, почему ошибку не выдает - базовые функции возвращают 0. Попробую залить. Я вечером еще попробую поиграться с таймаутами, еще почищу HAL код, функция стирания сектора у меня вызывается. Но после мнимого их стирания почему то не вызывается ProgramPage. А дебаггер при этом пишет, что хочет залить прошивку, но указывает при этом адрес 0х8хххх. То ли он пропускает этот этап и пытается писать во внутреннюю флеш, то ли он хочет писать во внешнюю, но ошибается адресом.
  15. В общем, чистка кода инициализации помогла функция стирания секторов стала вызываться, правда возвращает ошибку. Видимо, дебаггер очень капризен к нагромождениям кода HAL. В основной программе работа с qspi идет без проблем, тот же код, вставленный в шаблон дает ошибку на этапе включения разрешения записи. Еще более странным является то, что дебаггер отказывается работать с алгоритмом, если включаешь HSE. Так и должно быть?
  16. Вот содержимое target.lin Вы об этом? ; Linker Control File (scatter-loading) ; PRG 0 PI ; Programming Functions { PrgCode +0 ; Code { * (+RO) } PrgData +0 ; Data { * (+RW,+ZI) } } DSCR +0 ; Device Description { DevDscr +0 { FlashDev.o } } Я полагаю, производитель в этом файле разместил все что нужно. По крайней мере, в мануале про доп. настройки такого рода ничего не написано. Функции-то стандартные, неужели производитель чего-то недоразместил?
  17. А что служит причиной того, что KEil избегает обращения к соответствующей области памяти? Я ничего с шаблоном не делал, кроме инициализации GPIO. Он нулевый. И, так сказать, настроенный производителем. При этом в правильности настройки мной GPIO я не сомневаюсь - в функции init ножка меняет свое состояние по команде.
  18. А проблема невызова функций не возникала? Или возникала, но вы ее решили по мануалу? В котором, по вашему, она описана и приведен способ ее решения?
  19. Может хватит уже из меня дурака делать? Я перечитал мануал, посмотрел примеры. Пожалуйста. Из подпапки Test, что в папке с шаблоном /* Test EraseSector Function -----------------------------------------------*/ ret = Init(0x08000000, 8000000, 1); // Initialize Flash Programming Functions // Device Base Address = 0x08000000 // Clock Frequency = 8MHz for (n = FlashDevice.DevAdr; n < (FlashDevice.DevAdr + FlashDevice.szDev); n += FlashDevice.szPage) { ret |= EraseSector(n); // Test Sector Erase } // Verify Erase for (n = 0; n < FlashDevice.szDev; n++) { if (M8(FlashDevice.DevAdr + n) != FlashDevice.valEmpty) { ret = 1; // Error break; } } ret |= UnInit (1); // Uninitialize Flash Programming Functions /* Test ProgramPage Function -----------------------------------------------*/ ret |= Init(0x08000000, 8000000, 2); // Initialize Flash Programming Functions for (n = FlashDevice.DevAdr; n < (FlashDevice.DevAdr + FlashDevice.szDev); n += FlashDevice.szPage) { ret |= ProgramPage(n, FlashDevice.szPage, buf); // Test Page Programming } Казалось бы, ура! Вот оно. В функцию init подставляешь параметр, которым определяется действие - стирать или писать и все. Лезем в функцию init - и что видим int Init (unsigned long adr, unsigned long clk, unsigned long fnc) { base_adr = adr & ~(BANK1_SIZE - 1); // Align to Size Boundary // Zero Wait State FLASH->ACR = 0x00000000; // Unlock Flash FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY2; #ifdef STM32F10x_1024 FLASH->KEYR2 = FLASH_KEY1; // Flash bank 2 FLASH->KEYR2 = FLASH_KEY2; #endif // Test if IWDG is running (IWDG in HW mode) if ((FLASH->OBR & 0x04) == 0x00) { // Set IWDG time out to ~32.768 second IWDG->KR = 0x5555; // Enable write access to IWDG_PR and IWDG_RLR IWDG->PR = 0x06; // Set prescaler to 256 IWDG->RLR = 4095; // Set reload value to 4095 } return (0); } Анализом параметров fnc и clk даже не пахнет. И это не шаблон, это пример. Кто вызывает ProgramPage, EraseSector - дебаггер (что мне кажется более логичным) или программист, прописывая вызовы этих функций черти где, непонятно. У меня дебаггер их не вызывает. Вы в самом деле считаете что все настолько прозрачно и понятно, что об этом стыдно спрашивать?
  20. Да вы что? И ответ на вопрос, начинающийся словами "правильно ли я понимаю..", тоже в мануалах имеется?
  21. Я вроде бы простой вопрос задал. Не спрашивал, что у меня не так. Спросил лишь, как должно быть и правильно ли я понимаю логику работы системы. А вам бы поглумиться...
  22. Вернемся к алгоритму, в который я попытался вставить код для микросхемы, с которой нет проблем, то есть n25q128, ее же и пытаюсь прошить алгоритмом через кейл. У меня почему-то кроме init не вызывается ни одна функция шаблона. Я убрал весь код, кроме того, что необходим для включения светодиода. В каждую функцию шаблона я вставил строку включения светодиода. После нее return 0. Светодиод зажигается лишь, если его включать из init. Остальные функции не вызываются. Вы писали о простейших и пустых функциях, которые возвращают ок (или "0"). В шаблоне, который есть в кейле, по сути так и сделано - там во всех четырех функциях пусто и каждая из них возвращает 0. Я правильно понимаю, что если этот пустой алгоритм скомпилировать то при попытке прошить флеш она не прошьется по факту, но кейл подумает, что все ОК? У меня подклбючение хоть изначального шаблона, хоть шаблона со вставленными функциями выдает ошибку истечения таймаута. Разве кейлу недостаточно того, что функции шаблона возвращают 0 ?
  23. Да. Но хочу отметить - я сейчас работаю только с одной флеш. Пока что. Подозреваю что что-то не так с Dymmy cycles. В микроновской памяти есть такой вот регистр - READ VOLATILE CONFIGURATION REGISTER 85h (стр.27 даташита) Общение с ним такое: static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi) { QSPI_CommandTypeDef s_command; uint8_t reg; /* Initialize the read volatile configuration register command */ s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; s_command.Instruction = READ_VOL_CFG_REG_CMD; s_command.AddressMode = QSPI_ADDRESS_NONE; s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; s_command.DataMode = QSPI_DATA_1_LINE; s_command.DummyCycles = 0; s_command.NbData = 1; s_command.DdrMode = QSPI_DDR_MODE_DISABLE; s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; /* Configure the command */ if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Reception of the data */ if (HAL_QSPI_Receive(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Enable write operations */ if (QSPI_WriteEnable(hqspi) != QSPI_OK) { return QSPI_ERROR; } /* Update volatile configuration register (with new dummy cycles) */ s_command.Instruction = WRITE_VOL_CFG_REG_CMD; MODIFY_REG(reg, N25Q128A_VCR_NB_DUMMY, (N25Q128A_DUMMY_CYCLES_READ_QUAD << POSITION_VAL(N25Q128A_VCR_NB_DUMMY))); /* Configure the write volatile configuration register command */ if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Transmission of the data */ if (HAL_QSPI_Transmit(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } return QSPI_OK; } В винбондовской такого регистра нет. И как эту функцию перенастроить под W25Q128 - я пока не пойму. Но - ее отключение при работе с микроновской памятью ни к каким последствиям не приводит.
  24. С работой с QSPI разобрался. На плате DISCO есть n25q128 (https://www.farnell.com/datasheets/1674445.pdf) - чтение, запись, блоками, страницами, стирание целиком, все, что нужно для алгоритма, работает. Дело за малым - с учетом отличий, адаптировать код под другую микросхему - W25Q128JV ( https://www.winbond.com/resource-files/w25q128jv revf 03272018 plus.pdf ). Микросхемы по структуре, принципам работы и даже распиновке идентичны. И имеющаяся у меня библиотека под N25Q128 вполне себе с ней работает. Я читал регистры (о производителе, статусные регистры) - программа выдает адекватные данные. Проверяю просто for (uint16_t i=0;i<256;i++) WRITE_BUF[i]=i; RESULT3=BSP_QSPI_Write(WRITE_BUF, 0x00000100, 256); HAL_Delay(100); RESULT4=BSP_QSPI_Read(READ_BUF, 0x00000100, 256); Функции стирания чипа, записи блока, чтения из блока ошибок не возвращают. С одним лишь но. Все прочитанные байты равны 0xFF. Даже не пойму, что сбоит - чтение или запись или все вместе. Какие либо ошибки программы или монтажа на своей плате исключаю по одной простой причине - меняю друг с другом микросхемы памяти на дискавери и на своей плате - дискавери bp w25q128 читает 0xFF, моя плата с напаянной n25q128 работает нормально. Значит чем-то эти микросхемы отличаются, а какое именно отличие играет роль - я не пойму. Полез я (еще до перепаек) в дефайны. Да, они отличаются, но лишь теми регистрами, которые в функциях чтения и записи не затронуты. Вот дефайны W25Q128 ( ----------------- - то что отличается, ========= - то что отличается только названием, но суть и значения те же, ++++++ - то, что есть в одной микросхеме и нет в другой) #define W25Q128FV_FLASH_SIZE 0x1000000 /* 128 MBits => 16MBytes */ #define W25Q128FV_SECTOR_SIZE 0x10000 /* 256 sectors of 64KBytes */ #define W25Q128FV_SUBSECTOR_SIZE 0x1000 /* 4096 subsectors of 4kBytes */ #define W25Q128FV_PAGE_SIZE 0x100 /* 65536 pages of 256 bytes */ #define W25Q128FV_DUMMY_CYCLES_READ 4 -------- #define W25Q128FV_DUMMY_CYCLES_READ_QUAD 10 #define W25Q128FV_BULK_ERASE_MAX_TIME 250000 #define W25Q128FV_SECTOR_ERASE_MAX_TIME 3000 #define W25Q128FV_SUBSECTOR_ERASE_MAX_TIME 800 /** * @brief W25Q128FV Commands */ /* Reset Operations */ #define RESET_ENABLE_CMD 0x66 #define RESET_MEMORY_CMD 0x99 #define ENTER_QPI_MODE_CMD 0x38 #define EXIT_QPI_MODE_CMD 0xFF /* Identification Operations */ #define READ_ID_CMD 0x90 ----------- #define DUAL_READ_ID_CMD 0x92 ++++++++++ #define QUAD_READ_ID_CMD 0x94 +++++++++ #define READ_JEDEC_ID_CMD 0x9F =========== /* Read Operations */ #define READ_CMD 0x03 #define FAST_READ_CMD 0x0B #define DUAL_OUT_FAST_READ_CMD 0x3B #define DUAL_INOUT_FAST_READ_CMD 0xBB #define QUAD_OUT_FAST_READ_CMD 0x6B #define QUAD_INOUT_FAST_READ_CMD 0xEB /* Write Operations */ #define WRITE_ENABLE_CMD 0x06 #define WRITE_DISABLE_CMD 0x04 /* Register Operations */ #define READ_STATUS_REG1_CMD 0x05 ======== #define READ_STATUS_REG2_CMD 0x35 ++++++++ #define READ_STATUS_REG3_CMD 0x15 ++++++++ #define WRITE_STATUS_REG1_CMD 0x01 ======== #define WRITE_STATUS_REG2_CMD 0x31 +++++++ #define WRITE_STATUS_REG3_CMD 0x11 +++++++ /* Program Operations */ #define PAGE_PROG_CMD 0x02 #define QUAD_INPUT_PAGE_PROG_CMD 0x32 ========== /* Erase Operations */ #define SECTOR_ERASE_CMD 0x20 ========= #define CHIP_ERASE_CMD 0xC7 ========== #define PROG_ERASE_RESUME_CMD 0x7A #define PROG_ERASE_SUSPEND_CMD 0x75 /* Flag Status Register */ #define W25Q128FV_FSR_BUSY ((uint8_t)0x01) /*!< busy */ #define W25Q128FV_FSR_WREN ((uint8_t)0x02) /*!< write enable */ #define W25Q128FV_FSR_QE ((uint8_t)0x02) /*!< quad enable */ Вот дефайны N25Q128 #define N25Q128A_FLASH_SIZE 0x1000000 /* 128 MBits => 16MBytes */ #define N25Q128A_SECTOR_SIZE 0x10000 /* 256 sectors of 64KBytes */ #define N25Q128A_SUBSECTOR_SIZE 0x1000 /* 4096 subsectors of 4kBytes */ #define N25Q128A_PAGE_SIZE 0x100 /* 65536 pages of 256 bytes */ #define N25Q128A_DUMMY_CYCLES_READ 8 --------- #define N25Q128A_DUMMY_CYCLES_READ_QUAD 10 #define N25Q128A_BULK_ERASE_MAX_TIME 250000 #define N25Q128A_SECTOR_ERASE_MAX_TIME 3000 #define N25Q128A_SUBSECTOR_ERASE_MAX_TIME 800 /** * @brief N25Q128A Commands */ /* Reset Operations */ #define RESET_ENABLE_CMD 0x66 #define RESET_MEMORY_CMD 0x99 /* Identification Operations */ #define READ_ID_CMD 0x9E ----------- #define READ_ID_CMD2 0x9F ============ #define MULTIPLE_IO_READ_ID_CMD 0xAF +++++++++ #define READ_SERIAL_FLASH_DISCO_PARAM_CMD 0x5A ++++++++++ /* Read Operations */ #define READ_CMD 0x03 #define FAST_READ_CMD 0x0B #define DUAL_OUT_FAST_READ_CMD 0x3B #define DUAL_INOUT_FAST_READ_CMD 0xBB #define QUAD_OUT_FAST_READ_CMD 0x6B #define QUAD_INOUT_FAST_READ_CMD 0xEB /* Write Operations */ #define WRITE_ENABLE_CMD 0x06 #define WRITE_DISABLE_CMD 0x04 /* Register Operations */ #define READ_STATUS_REG_CMD 0x05 ========= #define WRITE_STATUS_REG_CMD 0x01 ========= #define READ_LOCK_REG_CMD 0xE8 +++++ #define WRITE_LOCK_REG_CMD 0xE5 +++++ #define READ_FLAG_STATUS_REG_CMD 0x70 +++++ #define CLEAR_FLAG_STATUS_REG_CMD 0x50 +++++ #define READ_NONVOL_CFG_REG_CMD 0xB5 +++++ #define WRITE_NONVOL_CFG_REG_CMD 0xB1 +++++ #define READ_VOL_CFG_REG_CMD 0x85 ++++++ #define WRITE_VOL_CFG_REG_CMD 0x81 ++++++ #define READ_ENHANCED_VOL_CFG_REG_CMD 0x65 +++++ #define WRITE_ENHANCED_VOL_CFG_REG_CMD 0x61 ++++++ /* Program Operations */ #define PAGE_PROG_CMD 0x02 #define DUAL_IN_FAST_PROG_CMD 0xA2 #define EXT_DUAL_IN_FAST_PROG_CMD 0xD2 #define QUAD_IN_FAST_PROG_CMD 0x32 ======== #define EXT_QUAD_IN_FAST_PROG_CMD 0x12 /* Erase Operations */ #define SUBSECTOR_ERASE_CMD 0x20 ++++++++++ #define SECTOR_ERASE_CMD 0xD8 =========== #define BULK_ERASE_CMD 0xC7 =========== #define PROG_ERASE_RESUME_CMD 0x7A #define PROG_ERASE_SUSPEND_CMD 0x75 /* One-Time Programmable Operations */ #define READ_OTP_ARRAY_CMD 0x4B +++++++++ #define PROG_OTP_ARRAY_CMD 0x42 +++++++++ /** * @brief N25Q128A Registers */ /* Status Register */ #define N25Q128A_SR_WIP ((uint8_t)0x01) /*!< Write in progress */ #define N25Q128A_SR_WREN ((uint8_t)0x02) /*!< Write enable latch */ #define N25Q128A_SR_BLOCKPR ((uint8_t)0x5C) /*!< Block protected against program and erase operations */ #define N25Q128A_SR_PRBOTTOM ((uint8_t)0x20) /*!< Protected memory area defined by BLOCKPR starts from top or bottom */ #define N25Q128A_SR_SRWREN ((uint8_t)0x80) /*!< Status register write enable/disable */ /* Nonvolatile Configuration Register */ #define N25Q128A_NVCR_LOCK ((uint16_t)0x0001) /*!< Lock nonvolatile configuration register */ #define N25Q128A_NVCR_DUAL ((uint16_t)0x0004) /*!< Dual I/O protocol */ #define N25Q128A_NVCR_QUAB ((uint16_t)0x0008) /*!< Quad I/O protocol */ #define N25Q128A_NVCR_RH ((uint16_t)0x0010) /*!< Reset/hold */ #define N25Q128A_NVCR_ODS ((uint16_t)0x01C0) /*!< Output driver strength */ #define N25Q128A_NVCR_XIP ((uint16_t)0x0E00) /*!< XIP mode at power-on reset */ #define N25Q128A_NVCR_NB_DUMMY ((uint16_t)0xF000) /*!< Number of dummy clock cycles */ /* Volatile Configuration Register */ #define N25Q128A_VCR_WRAP ((uint8_t)0x03) /*!< Wrap */ #define N25Q128A_VCR_XIP ((uint8_t)0x08) /*!< XIP */ #define N25Q128A_VCR_NB_DUMMY ((uint8_t)0xF0) /*!< Number of dummy clock cycles */ /* Enhanced Volatile Configuration Register */ #define N25Q128A_EVCR_ODS ((uint8_t)0x07) /*!< Output driver strength */ #define N25Q128A_EVCR_VPPA ((uint8_t)0x08) /*!< Vpp accelerator */ #define N25Q128A_EVCR_RH ((uint8_t)0x10) /*!< Reset/hold */ #define N25Q128A_EVCR_DUAL ((uint8_t)0x40) /*!< Dual I/O protocol */ #define N25Q128A_EVCR_QUAD ((uint8_t)0x80) /*!< Quad I/O protocol */ /* Flag Status Register */ #define N25Q128A_FSR_PRERR ((uint8_t)0x02) /*!< Protection error */ #define N25Q128A_FSR_PGSUS ((uint8_t)0x04) /*!< Program operation suspended */ #define N25Q128A_FSR_VPPERR ((uint8_t)0x08) /*!< Invalid voltage during program or erase */ #define N25Q128A_FSR_PGERR ((uint8_t)0x10) /*!< Program error */ #define N25Q128A_FSR_ERERR ((uint8_t)0x20) /*!< Erase error */ #define N25Q128A_FSR_ERSUS ((uint8_t)0x40) /*!< Erase operation suspended */ #define N25Q128A_FSR_READY ((uint8_t)0x80) /*!< Ready or command in progress */
×
×
  • Создать...