Jump to content

    

Прошивка QSPI из Keil.

Добрый вечер. Осваиваю ToucghGFX. На самодельной плате на основе STM32F746BG 

Добрался я до заливки картинок во внешнюю память.

SCT файл у меня такой

LR_IROM1 0x08000000 0x00200000  {    ; load region size_region
  intflash.bin 0x08000000 0x00200000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00030000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

LR_EROM1 0x90000000 0x01000000  {    ; load region size_region
  extflash.bin 0x90000000 0x01000000  {  ; load address = execution address
   *.o (ExtFlashSection)
  }
}
 

 

Добавлены следующие алгоритмы

6YYmb7wO.png

 

Поначалу ругалось на недостаток памяти для алгоритма, заткнулось когда установил 0x4000.

При попытке записи вначале происходит стирание, при этом видно, что обращение идет по правильному адресу, то есть по 0x90000000.

Однако спустя секунду выдается сообщение об истечении Flash Timeout

Я догадываюсь, что я просто не все настроил. В частности, у меня не такая qspi память, как в дисковери, а пара W25Q128JVSIQ с общим CS. Более того - у меня ремаппинг памяти, контроллер этого может не знать.

А посему вопросы.

1. Не обрубил ли я на корню возможность программирования внешней QSP flash, назначив нестандартные ноги, то есть задействовав ремаппинг?

2. Что делать дальше, как-то редактировать алгоритм или как?

Share this post


Link to post
Share on other sites
5 minutes ago, MementoMori said:

редактировать алгоритм

инструкции есть в доке на keil

Share this post


Link to post
Share on other sites

Спасибо, но нельзя ли как-то более адресно? В том доке, что в меню кейла, где-то на сайте? Что там, что там так сразу и не найдешь. 

 

Share this post


Link to post
Share on other sites
1 minute ago, MementoMori said:

Спасибо, но нельзя ли как-то более адресно? В том доке, что в меню кейла, где-то на сайте? Что там, что там так сразу и не найдешь. 

 

Открывайте папку Keil\ARM\Flash\

находите наиболее подходящий вариант, переделываете под себя, пересобираете, заливаете туда же

 

https://arm-software.github.io/CMSIS_5/Pack/html/flashAlgorithm.html

Share this post


Link to post
Share on other sites
2 minutes ago, MementoMori said:

Спасибо. А что насчет ремаппинга? 

Алгоритм переписывать так, чтобы он правильно работал с вашей платой.

Share this post


Link to post
Share on other sites

Насколько я понял, контроллер STM умеет сам шить внешнюю SPI-память посредством KEIL. То есть он как-то с ним общается, не имея внутри прошивки.  Нужно лишь раскидать данные по адресам. И если нужно писать во внутреннюю flash, то он будет писать по адресу 0x8000000, если во внешнюю - то он запустит у в себе модуль QSPI и запишет по адресу 0x9..... Но ведь ножки qspi ремаппятся. У меня они переназначены. Как контроллер будет программировать flash, не зная моей схемы? 

/* -----------------------------------------------------------------------------
 * Copyright (c) 2014 ARM Ltd.
 *
 * This software is provided 'as-is', without any express or implied warranty. 
 * In no event will the authors be held liable for any damages arising from 
 * the use of this software. Permission is granted to anyone to use this 
 * software for any purpose, including commercial applications, and to alter 
 * it and redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not 
 *    claim that you wrote the original software. If you use this software in
 *    a product, an acknowledgment in the product documentation would be 
 *    appreciated but is not required. 
 * 
 * 2. Altered source versions must be plainly marked as such, and must not be 
 *    misrepresented as being the original software. 
 * 
 * 3. This notice may not be removed or altered from any source distribution.
 *   
 *
 * $Date:        15. April 2014
 * $Revision:    V1.00
 *  
 * Project:      Flash Programming Functions for Micron M29W640Fx
 * --------------------------------------------------------------------------- */

/* History:
 *  Version 1.00
 *    Initial release
 */ 


#include "..\FlashOS.H"        // FlashOS Structures

#define M8(adr)  (*((volatile unsigned char  *) (adr)))
#define M16(adr) (*((volatile unsigned short *) (adr)))
#define M32(adr) (*((volatile unsigned long  *) (adr)))

#define STACK_SIZE   64        // Stack Size


union fsreg {                  // Flash Status Register
  struct b  {
    unsigned int q0:1;
    unsigned int q1:1;
    unsigned int q2:1;        // alternative toggle bit
    unsigned int q3:1;        // erase timer bit
    unsigned int q4:1;
    unsigned int q5:1;        // error bit
    unsigned int q6:1;        // toggle bit
    unsigned int q7:1;        // data polling bit
  } b;
  unsigned int v;
} fsr;

unsigned long base_adr;


/*
 * Check if Program/Erase completed using the toggle bit
 *    Parameter:      adr:  Block Start Address
 *    Return Value:   0 - OK,  1 - Failed
 */

int Polling (unsigned long adr) {
  unsigned int q6;

  fsr.v = M16(adr);
  q6 = fsr.b.q6;
  do {
    fsr.v = M16(adr);
    if (fsr.b.q6 == q6) return (0);  // Done
    q6 = fsr.b.q6;
    // if (fsr.b.q3 == 1) break;        // VPP not high enough
  } while (fsr.b.q5 == 0);           // Check for Timeout
  fsr.v = M16(adr);
  q6 = fsr.b.q6;
  fsr.v = M16(adr);
  if (fsr.b.q6 == q6) return (0);    // Done
  M16(adr) = 0xF0;                   // Reset Device
  return (1);                        // Failed
}


/*
 *  Initialize Flash Programming Functions
 *    Parameter:      adr:  Device Base Address
 *                    clk:  Clock Frequency (Hz)
 *                    fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
 *    Return Value:   0 - OK,  1 - Failed
 */

int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
  base_adr = adr;

  return (0);
}


/*
 *  De-Initialize Flash Programming Functions
 *    Parameter:      fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
 *    Return Value:   0 - OK,  1 - Failed
 */

int UnInit (unsigned long fnc) {
  return (0);
}


/*
 *  Erase complete Flash Memory
 *    Return Value:   0 - OK,  1 - Failed
 */

int EraseChip (void) {

  // Start Chip Erase Command
  M16(base_adr + (0x0555 << 1)) = 0xAA;
  M16(base_adr + (0x0AAA << 1)) = 0x55;
  M16(base_adr + (0x0555 << 1)) = 0x80;
  M16(base_adr + (0x0555 << 1)) = 0xAA;
  M16(base_adr + (0x0AAA << 1)) = 0x55;
  M16(base_adr + (0x0555 << 1)) = 0x10;

  return (Polling(base_adr));  // Wait until Erase completed
}


/*
 *  Erase Sector in Flash Memory
 *    Parameter:      adr:  Sector Address
 *    Return Value:   0 - OK,  1 - Failed
 */

int EraseSector (unsigned long adr) {

  // Start Erase Sector Command
  M16(base_adr + (0x0555 << 1)) = 0xAA;
  M16(base_adr + (0x0AAA << 1)) = 0x55;
  M16(base_adr + (0x0555 << 1)) = 0x80;
  M16(base_adr + (0x0555 << 1)) = 0xAA;
  M16(base_adr + (0x0AAA << 1)) = 0x55;
  M16(adr) = 0x30;

  return (Polling(adr));       // Wait until Erase completed
}


/*
 *  Program Page in Flash Memory
 *    Parameter:      adr:  Page Start Address
 *                    sz:   Page Size
 *                    buf:  Page Data
 *    Return Value:   0 - OK,  1 - Failed
 */

int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {
  int i;

  for (i = 0; i < ((sz+1)/2); i++)  {
    // Start Program Command
    M16(base_adr + (0x0555 << 1)) = 0xAA;
    M16(base_adr + (0x0AAA << 1)) = 0x55;
    M16(base_adr + (0x0555 << 1)) = 0xA0;
    M16(adr) = *((unsigned short *) buf);
    if (Polling(adr) != 0) return (1);
    buf += 2;
    adr += 2;
  }
  return (0);
}

Открыл первое попавшееся.

Это алгоритм? Здесь же ничего кроме операций присваивания. Нужно писать полноценную программу инициализации периферии, GPIO?

Share this post


Link to post
Share on other sites
3 minutes ago, MementoMori said:

Насколько я понял, контроллер STM умеет сам шить внешнюю SPI-память посредством KEIL. То есть он как-то с ним общается, не имея внутри прошивки.  Нужно лишь раскидать данные по адресам. И если нужно писать во внутреннюю flash, то он будет писать по адресу 0x8000000, если во внешнюю - то он запустит у в себе модуль QSPI и запишет по адресу 0x9..... Но ведь ножки qspi ремаппятся. У меня они переназначены. Как контроллер будет программировать flash, не зная моей схемы? 

Почитайте по ссылке, не ленитесь )) 

Там еще ссылки. Схема работы объяснена на пальцах. 

Share this post


Link to post
Share on other sites

Схему, разъясненную на пальцах, понял. Как взять шаблон, как отредактировать. Не вдаваясь в специфику своих микросхем просто попробовал довести эту схему до того, чтобы у меня в списке алгоритмов появилось что-то новое. Получилось. 

Но нигде не увидел про настройки самого контроллера.

За это отвечает функция Init? Туда можно записывать любой код? Мне ведь нужно настроить периферию, GPIO, включать mapping mode. Все это делается тут?

int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {

  /* Add your Code */
  return (0);                                  // Finished without Errors
}

 

Share this post


Link to post
Share on other sites

Да все там есть! Поройтесь в других примерах. Или вы предлагаете все это делать за вас?

Share this post


Link to post
Share on other sites
2 minutes ago, Forger said:

Или вы предлагаете все это делать за вас?

А что, так можно, да?)))))

Хорошо, пороюсь.  Просто нахожусь в некотором испуге от того, что не подумал об этом на этапе проектирования платы....

Крамольный вопрос.... может у кого есть алгоритм под W25Q128 ?

Share this post


Link to post
Share on other sites

Конечно есть !

Есть такой паренёк - google

Задаёте вопрос

https://www.google.com/search?q=keil+flash+W25Q128

и смотрите левой кнопкой мыши первые 5-6 ссылок.

Хоть марсоход на Марсе можно прошивать.

Share this post


Link to post
Share on other sites
17 hours ago, MementoMori said:

Насколько я понял, контроллер STM умеет сам шить внешнюю SPI-память посредством KEIL. То есть он как-то с ним общается, не имея внутри прошивки.

Общается точно так-же как и с внутренней флеш памятью - грузит в рам свою прошивку, запускает её, и подкидывает/забирает данные через буфер обмена в той-же рам памяти.

Это к вопросу о том где искать - дык оно там, рядом.

Share this post


Link to post
Share on other sites

 

 

Из папки C:\Program Files (x86)\STMicroelectronics\STM32 ST-LINK Utility\ST-LINK Utility\ExternalLoader\N25Q256A_STM32L476G-EVAL_Cube\Projects\STM32L476G_EVAL\Examples\QSPI\N25Q256A_STM32L476G-EVAL

Скачал вот такой проект   https://cloud.mail.ru/public/4xAK/3p6Wyj79b

С виду - то что мне надо - описание микросхемы - и инициализация периферии. Только отредактировать инициализацию и подстроить под память.

 

Это оно или нет?

 

Смущает то, что при компиляции генерируется не то, что обычно, а некий файл .stldr, а в списке алгоритмов эта микросхема не появляется.

Share this post


Link to post
Share on other sites

ST Link Utility -> External Loader -> Add External Loader - это сюда похоже

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