|
|
  |
Не получается соединить STM32L152 и N25Q128! |
|
|
|
Mar 11 2014, 18:40
|
Группа: Участник
Сообщений: 14
Регистрация: 11-03-14
Пользователь №: 80 887

|
Кто работал с этой памятью, может кто-нибудь что-нибудь посоветовать?
|
|
|
|
|
Mar 12 2014, 03:02
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 28-06-13
Пользователь №: 77 311

|
Если это Micron Serial NOR Flash Memory то работал с N25Q256 и N25Q512. Они подобные. По размеру отличаются только.
|
|
|
|
|
Mar 12 2014, 03:33
|
Группа: Участник
Сообщений: 14
Регистрация: 11-03-14
Пользователь №: 80 887

|
Да оно! Не могу записать в память
|
|
|
|
|
Mar 12 2014, 03:42
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 28-06-13
Пользователь №: 77 311

|
Подключена как? Extended SPI режим или полный? Если extended то проверить куда подключены ноги "Write protect" и "Hold". Чтение с нее выполняется? Если можно прочитать то: 1. читаем статус командой RDSR. 2. проверяем в ответе бит WEL - Write Enable 3. если он не выставлен - разрешаем запись через команду WREN
|
|
|
|
|
Mar 12 2014, 03:55
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(Сергей Борщ @ Mar 12 2014, 07:37)  Или что-то неправильно делаете, или память дохлая или процессор или замыкание на плате. Вероятнее всего первое. Также стоит проверить биты защиты BP0:3 в регистре состояния. Мне встречались модели NOR Flash, у которых по-умолчанию все сектора были защищены от записи
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Mar 12 2014, 03:55
|
Группа: Участник
Сообщений: 14
Регистрация: 11-03-14
Пользователь №: 80 887

|
Если ничего не меняю изначально, то режим Extended SPI, так?!! Ноги подвешены к питанию VCC! Отсылаю команду 05h read status register, ответ 00h. Следовательно бит write enable =0. Делаю команду write enable 06h, опять читаю status register тоже самое 00h.
|
|
|
|
|
Mar 12 2014, 03:57
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(Sergiocars @ Mar 12 2014, 07:55)  Если ничего не меняю изначально, то режим Extended SPI, так?!! Ноги подвешены к питанию VCC! Отсылаю команду 05h read status register, ответ 00h. Следовательно бит write enable =0. Делаю команду write enable 06h, опять читаю status register тоже самое 00h. Скорее всего, что-то не то в настрйках интерфейса. Добейтесь нормального ответа на команду Read Id.
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Mar 12 2014, 04:04
|
Группа: Участник
Сообщений: 14
Регистрация: 11-03-14
Пользователь №: 80 887

|
Если в status register = 00h, то и биты BP0:3 все равны нулю, так?
|
|
|
|
|
Mar 12 2014, 04:05
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 28-06-13
Пользователь №: 77 311

|
Цитата(Sergiocars @ Mar 12 2014, 07:55)  Если ничего не меняю изначально, то режим Extended SPI, так?!! Ноги подвешены к питанию VCC! Отсылаю команду 05h read status register, ответ 00h. Следовательно бит write enable =0. Делаю команду write enable 06h, опять читаю status register тоже самое 00h. ну причин много если даже чтения нет: - дохлый чип - неверно подключен - неверно инициализирован SPI на процессоре CS программный или аппаратный? посмотреть бы еще на инициализацию SPI В программе
|
|
|
|
|
Mar 12 2014, 04:12
|
Группа: Участник
Сообщений: 14
Регистрация: 11-03-14
Пользователь №: 80 887

|
При команде read id 9eh выдает : 00 c1 00 00 00 01 00 00 01 00 06 00 08 40 00 00 e0 00 00 00 при 9fh тоже самое выдает
|
|
|
|
|
Mar 12 2014, 04:20
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 28-06-13
Пользователь №: 77 311

|
Цитата(Sergiocars @ Mar 12 2014, 08:12)  При команде read id 9eh выдает : 00 c1 00 00 00 01 00 00 01 00 06 00 08 40 00 00 e0 00 00 00 при 9fh тоже самое выдает это, imho, кривой ответ. на основании DS ответ на эту команду от памяти должен начинаться так: 20h, BAh, 18h, ... т.е. надо начинать смотреть с подключения и инициализации SPI в программе
|
|
|
|
|
Mar 12 2014, 04:21
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(Sergiocars @ Mar 12 2014, 08:12)  При команде read id 9eh выдает : 00 c1 00 00 00 01 00 00 01 00 06 00 08 40 00 00 e0 00 00 00 при 9fh тоже самое выдает Ну вот видите, совсем не то что должно быть. Проверяйте настройки интерфейса.
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Mar 12 2014, 04:28
|
Группа: Участник
Сообщений: 14
Регистрация: 11-03-14
Пользователь №: 80 887

|
Инициализация порта:
RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
//PB15(MOSI), PB14(MISO), PB13(SCK), PB12(NSS) - AF, Push-Pull, AF5(SPI1) GPIOB->MODER |= GPIO_MODER_MODER15_1 | GPIO_MODER_MODER14_1 | GPIO_MODER_MODER13_1 | GPIO_MODER_MODER12_1; //Alternate function GPIOB->OTYPER &= ~(GPIO_OTYPER_OT_15 | GPIO_OTYPER_OT_14 | GPIO_OTYPER_OT_13 | GPIO_OTYPER_OT_11); //Push-Pull GPIOB->AFR[1] |= (5<<28 | 5<<24 | 5<<20 | 5<<16); //PB15, PB14, P13, PB12 = AF5
Инициализация spi:
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; // SPI2 SPI2->CR1 |= SPI_CR1_BR_2 | SPI_CR1_BR_0; //Baud rate SPI2->CR1 &= ~SPI_CR1_CPOL; // SPI2->CR1 &= ~SPI_CR1_CPHA; // SPI2->CR1 &= ~SPI_CR1_DFF; //8 SPI2->CR1 &= ~SPI_CR1_LSBFIRST; //MSB SPI2->CR1 |= SPI_CR1_SSM; // NSS SPI2->CR1 |= SPI_CR1_SSI; // SPI2->CR1 |= SPI_CR1_MSTR; // Master SPI2->CR1 |= SPI_CR1_SPE; // SPI2 enable
Функция отправки байта:
void spi_s(uint8_t data) { SPI2->DR = data; while(!(SPI2->SR & SPI_SR_TXE));
К примеру отсылка команды 06h:
SPI2->CR2 |= SPI_CR2_SSOE; программно понижаю СS spi_s(0x06); отправляю 06h for (i=0;i<100;i++); небольшую задержку чтоб точно все успело уйти SPI2->CR2 &= ~SPI_CR2_SSOE; программно повышаю СS
Сообщение отредактировал Sergiocars - Mar 12 2014, 04:30
|
|
|
|
|
Mar 12 2014, 04:40
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 28-06-13
Пользователь №: 77 311

|
Цитата(Sergiocars @ Mar 12 2014, 08:28)  Инициализация порта:
SKIP
Функция отправки байта:
void spi_s(uint8_t data) { SPI2->DR = data; while(!(SPI2->SR & SPI_SR_TXE));
К примеру отсылка команды 06h:
SPI2->CR2 |= SPI_CR2_SSOE; программно понижаю СS spi_s(0x06); отправляю 06h for (i=0;i<100;i++); небольшую задержку чтоб точно все успело уйти SPI2->CR2 &= ~SPI_CR2_SSOE; программно повышаю СS инициализация верно а вот передача/прием как то странно. не думаю что CS при такой инициализации будет верно работать. я инициализирую только MOSI,MISO,CLK ноги а CS дергаю сам как физическую и задержка не нужна если сделать вот так uint8_t spi_s(uint8_t data) { SPI2->DR = data; while (!(SPI2->SR & SPI_SR_RXNE)); return SPI2->DR; }
|
|
|
|
|
Mar 12 2014, 04:47
|
Группа: Участник
Сообщений: 14
Регистрация: 11-03-14
Пользователь №: 80 887

|
попробую дергать cs по другому и вечером отпишусь
|
|
|
|
|
Mar 12 2014, 04:59
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 28-06-13
Пользователь №: 77 311

|
Цитата(Sergiocars @ Mar 12 2014, 08:47)  попробую дергать cs по другому и вечером отпишусь вот, для примера, как у меня. все работает. инициализация CODE GPIOB->AFR[1] |= 0 | (AF5<<20) | (AF5<<24) | (AF5<<28) // AF5 - SPI2 | 0;
GPIOB->MODER = 0 | GPIO_MODER_MODER0 // | GPIO_MODER_MODER1 // | GPIO_MODER_MODER2 // | GPIO_MODER_MODER3 // | GPIO_MODER_MODER4 // | GPIO_MODER_MODER5_0 // SPI2_CS | GPIO_MODER_MODER6_0 // | GPIO_MODER_MODER7 // | GPIO_MODER_MODER8 // | GPIO_MODER_MODER9 // | GPIO_MODER_MODER10 // | GPIO_MODER_MODER11_0 // | GPIO_MODER_MODER12 // | GPIO_MODER_MODER13_1 // SPI2_SCK | GPIO_MODER_MODER14_1 // SPI2_MISO | GPIO_MODER_MODER15_1 // SPI2_MOSI | 0;
GPIOB->PUPDR = 0 //| GPIO_PUPDR_PUPDR0 // //| GPIO_PUPDR_PUPDR1 // //| GPIO_PUPDR_PUPDR2 // //| GPIO_PUPDR_PUPDR3 // //| GPIO_PUPDR_PUPDR4 // | GPIO_PUPDR_PUPDR5_0 // SPI2_CS //| GPIO_PUPDR_PUPDR6 // //| GPIO_PUPDR_PUPDR7 // //| GPIO_PUPDR_PUPDR8 // //| GPIO_PUPDR_PUPDR9 // //| GPIO_PUPDR_PUPDR10 // //| GPIO_PUPDR_PUPDR11 // //| GPIO_PUPDR_PUPDR12 // | GPIO_PUPDR_PUPDR13_0 // SPI2_SCK | GPIO_PUPDR_PUPDR14_1 // SPI2_MISO | GPIO_PUPDR_PUPDR15_1 // SPI2_MOSI | 0;
SPI2->CR1 = 0 | SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_MSTR | SPI_CR1_SSI | SPI_CR1_SSM | 0; SPI2->CR2 = 0; прием/передача CODE #define STORAGE_pinCS_HI { GPIOB->BSRRL = (1 << 5); } #define STORAGE_pinCS_LO { GPIOB->BSRRH = (1 << 5); }
uint8_t STORAGE_SRB(uint8_t Value) { SPI2->DR = Value; while (!(SPI2->SR & SPI_SR_RXNE)); return SPI2->DR; }
uint8_t STORAGE_CMD(uint8_t CMD, uint8_t WithReadResult) { uint8_t result = 0; STORAGE_pinCS_LO; ICP_msDelay(1); STORAGE_SRB(CMD); if (WithReadResult) result = STORAGE_SRB(0xFF); STORAGE_pinCS_HI; return (result); }
Сообщение отредактировал IgorKossak - Mar 12 2014, 06:04
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
Mar 16 2014, 20:12
|
Группа: Участник
Сообщений: 14
Регистрация: 11-03-14
Пользователь №: 80 887

|
А где ты включаешь SPI ? вот этот бит не устанавливаешь: SPI_CR1_SPE; ???
Подключил логический анализатор к CS MOSI MISO SCK все нормально посылается, CS нормально дергается установкой и снятием бита SSOE, как было изначально в моей программе!
Вставил твою функцию приема передачи байта, убрал задержки, на логическом анализаторе все идеально, но все равно ответ на readID один и тот же, может чип такой! Хотел спросить может запись делаю не так ?? Какой должен быть алгоритм записи подробно??? И про обвязку памяти хотел спросить какой вывод каким резистором и куда подтягивать, может куда конденсатор вставить, я уже про все варианты думаю, что может быть не правильно!!!
|
|
|
|
|
Mar 16 2014, 20:30
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
QUOTE (Sergiocars @ Mar 17 2014, 05:12)  И про обвязку памяти хотел спросить какой вывод каким резистором и куда подтягивать, может куда конденсатор вставить, я уже про все варианты думаю, что может быть не правильно!!! Кондёр по питанию нужен. Всё остальное в даташите. Можно по всем линиям данным резисторы 33 Ом поставить. Они помогут сгладить выбросы напряжения, если у вас крутые фронты. Не забывайте, что CS для этой микросхемы немного по-другому работает. Т.е. он должен быть в лог. 0 на время всей команды. Переход CS в лог. 1 обозначает для этой микросхемы сброс команды. Т.е. при передаче данных между байтами CS должен оставаться в лог. 0. Я не наю как это на STM32, но на LPC (арм от NXP) аппаратное управление CS пришлось переделать на программное. Обратите внимание также на максимально допустимые частоты интерфейса. Ну, а так - микросхема у меня завелась раза со второго. Правда чтение ID. Потом ещё намучился с тем, что минимально стираемый сектору неё 65 Кбайт. А памяти в контроллере - 32 Кбайт. А вот писать в неё можно по 256 байт максимум. В общем добейтесь чёткого ответа ID, это три байта 0x20, 0xBA, 0x18 (команда 0x9f).
--------------------
Выбор.
|
|
|
|
|
Mar 16 2014, 20:56
|
Группа: Участник
Сообщений: 14
Регистрация: 11-03-14
Пользователь №: 80 887

|
Скорость SPI ставлю маленькую 32 МГц / 64 = 500 КГц может скорость не та, которая нужна?
На сколько кондер поставить?
#W, #HOLD, S# (CS) Притянуты к +3V 10КОМ резисторами, а SCK к земле 10 КОМ резитором
|
|
|
|
|
Mar 16 2014, 22:00
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
QUOTE (Sergiocars @ Mar 17 2014, 05:56)  Скорость SPI ставлю маленькую 32 МГц / 64 = 500 КГц может скорость не та, которая нужна?
На сколько кондер поставить?
#W, #HOLD, S# (CS) Притянуты к +3V 10КОМ резисторами, а SCK к земле 10 КОМ резитором 0.1 мкФ керамику. Ну можно дополнительно тантал 4,7 мкФ. SCK к земле не надо притягивать. Минимальная частота, ЕМНИП, 0 Гц. Всё. Дальше ещё раз дебажите логическим анализатором. Если не работает - диаграммы в студию. Ну или можно заменить микросхему. было дело, что у меня выходила из строя по непонятным причинам. Возможно стататика. Обращаться нежно и осторожно.
--------------------
Выбор.
|
|
|
|
|
Mar 16 2014, 22:44
|
Группа: Участник
Сообщений: 14
Регистрация: 11-03-14
Пользователь №: 80 887

|
Перепаяю отпишу
посылаю команду 0x9f припаял на питание памяти 0,1 мкФ, отпаял 10 ком от SCK
|
|
|
|
|
Mar 17 2014, 01:46
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 28-06-13
Пользователь №: 77 311

|
Цитата(Sergiocars @ Mar 17 2014, 00:12)  А где ты включаешь SPI ? вот этот бит не устанавливаешь: SPI_CR1_SPE; ??? Разрешение работы у меня отдельно выполняется. Перед использованием. Но оно не влияет на работу SPI как такового. Цитата(Sergiocars @ Mar 17 2014, 00:12)  Подключил логический анализатор к CS MOSI MISO SCK все нормально посылается, CS нормально дергается установкой и снятием бита SSOE, как было изначально в моей программе! Не помню точно где, но читал какую то тему про STM32. Там был "разбор полетов" про аппаратный CS. Результат темы я для себя вынес следующий - CS обрабатывать программно, указывая это в регистрах настройки SPI. Цитата(Sergiocars @ Mar 17 2014, 00:12)  Вставил твою функцию приема передачи байта, убрал задержки, на логическом анализаторе все идеально, но все равно ответ на readID один и тот же, может чип такой! Хотел спросить может запись делаю не так ?? Какой должен быть алгоритм записи подробно??? Ну если анализатор все показывает верно, то вероятно чип битый. Есть возможность его поменять и попробовать чтение ID? Цитата(Sergiocars @ Mar 17 2014, 00:12)  И про обвязку памяти хотел спросить какой вывод каким резистором и куда подтягивать, может куда конденсатор вставить, я уже про все варианты думаю, что может быть не правильно!!! У меня нет как таковой обвязки: - CS, SCK, MOSI, MISO - в чистом виде на процессор - VCC, DQ2, DQ2 - на питание - VSS - земля
|
|
|
|
|
Mar 17 2014, 03:15
|
Группа: Участник
Сообщений: 14
Регистрация: 11-03-14
Пользователь №: 80 887

|
хорошо буду чип менять
|
|
|
|
|
Mar 17 2014, 18:41
|
Группа: Участник
Сообщений: 14
Регистрация: 11-03-14
Пользователь №: 80 887

|
Выложите пожалуйста функцию записи в память!!!
|
|
|
|
|
Mar 18 2014, 03:57
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 28-06-13
Пользователь №: 77 311

|
Цитата(Sergiocars @ Mar 17 2014, 22:41)  Выложите пожалуйста функцию записи в память!!! Именно записи страницы? А чтение нормально заработало? Или нужна именно функция записи данных по SPI для чтения с микросхемы?
|
|
|
|
|
Mar 18 2014, 05:05
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(Sergiocars @ Mar 17 2014, 22:41)  Выложите пожалуйста функцию записи в память!!! Пока не заработает команда чтения, про запись даже не стоит вспоминать. И еще, у Micron есть драйвера низкого уровня, можете найти их на странице: https://www.micron.com/products/support/nor-flash-software
Сообщение отредактировал Harvester - Mar 18 2014, 05:10
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Mar 18 2014, 09:39
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата(Sergiocars @ Mar 17 2014, 21:41)  Выложите пожалуйста функцию записи в память!!! n25q128 массово применяется не в одном серийном устройстве. Я бы советовал для начала обратится к ней используя софтовый spi. Приведённый ниже код взят из серийного проекта. В оригинале используется аппаратный spi, но процессор не STM, поэтому я привёл программный (ранее использовавшийся и также 100% рабочий). Надёюсь поможет Вам разобраться в проблеме. CODE //------------------------------------------- unsigned char SPIWriteChar(unsigned char cmd) { unsigned char i; unsigned char recv; recv = 0; for(i=0; i<8; i++) { if((cmd&0x80) != 0) { SPI_PORT_SET = MOSI; } else { SPI_PORT_CLR = MOSI; } SPI_PORT_SET = SCK; recv<<=1; if((SPI_PIN & MISO) != 0) { recv|=0x01; } SPI_PORT_CLR = SCK; cmd<<=1; } return recv; } //-------------------------------------------
//------------------------------------------- unsigned char SPIReadChar(void) { return SPIWriteChar(0x00); } //-------------------------------------------
//------------------------------------------- //макросы доступа к устройствам SPI void DESELECT_SPI(void) { //деактивируем все устройства SPI SPI_PORT_SET = nSS_SFLASH; SPI_PORT_CLR = SCK|MOSI; //устанавливаем выводы в исходное состояние } //-------------------------------------------
//------------------------------------------- void SELECT_SPI(unsigned int msk) { DESELECT_SPI(); //деактивируем все устройства SPI SPI_PORT_CLR = msk; //активируем необходимое } //-------------------------------------------
//------------------------------------------- //инициализация SPI void ConfigureSPI() { //настройка порта и начальных уровней SPI_DIR &= ~MISO; SPI_DIR |= SCK|MOSI; SPI_DIR |= nSS_SFLASH; SPI_PORT_SET = nSS_SFLASH; SPI_PORT_CLR = SCK|MOSI; } //------------------------------------------- CODE //-------------------------------- //------------------------------------ //коды команд работы с памятью enum { N25_WREN = 0x06, //write enable N25_WRDI = 0x04, //write disable N25_RDID = 0x9f, //read id N25_RDSR = 0x05, //read status register N25_WRSR = 0x01, //write status reg N25_WRLR = 0xe5, //write lock reg N25_RDLR = 0xe8, //red lock reg N25_READ = 0x03, //read data bytes N25_FAST_READ = 0x0b, //fast read data bytes N25_PP = 0x02, //page prog N25_SE = 0xd8, //sector erase 64k N25_SE_4K = 0x20, //sub sector erase 4k N25_BE = 0xc7, //bulk erase }; //------------------------------------
//------------------------------------ //биты регистра статуса enum { N25_WIP = 0x01, //write in progress N25_WIL = 0x02, //write enable latch status N25_BP2 = 0x04, // N25_BP1 = 0x08, // N25_BP0 = 0x10, // N25_SRWD = 0x80, //status register write disable }; //------------------------------------
//------------------------------------ //параметры памяти enum { //N25_SECTOR_NUM = 4096, //sectors by 4k N25_SECTOR_NUM = 2048, //sectors by 4k N25_SECTOR_SIZE = 4096, N25_PAGE_SIZE = 256, M25_PAGE_PER_SECTOR = N25_SECTOR_SIZE/N25_PAGE_SIZE, //4096/256=16 N25_PP_TM = 10, //таймаут записи страницы N25_SE_4K_TM = 1000, //таймаут стирания сектора }; //------------------------------------
//процедура разрешения записи в память void n25setWREN(void) { SELECT_SPI(nSS_SFLASH); //выбираем устройство spi SPIWriteChar(N25_WREN); //запись кода команды DESELECT_SPI(); //отпускаем устройство spi } //--------------------------------
//-------------------------------- //процедура запрещения записи в память void n25setWRDIS(void) { SELECT_SPI(nSS_SFLASH); //выбираем устройство spi SPIWriteChar(N25_WRDI); //запись кода команды DESELECT_SPI(); //отпускаем устройство spi } //--------------------------------
//-------------------------------- //ожидание завершения операции записи unsigned int n25waitBusy(unsigned int tm) { volatile unsigned int status; SELECT_SPI(nSS_SFLASH); //выбираем устройство spi SPIWriteChar(N25_RDSR); //запись кода команды for(unsigned int i=0; i<tm; i++) { status = SPIWriteChar(0x00); //читаем статус if((status & N25_WIP) == 0) { DESELECT_SPI(); //отпускаем устройство spi return 1; //оперция завершена } //ожидание паузы в 1 mS //for(volatile unsigned int j=0; j<(50*1000); j++); //пауза на исполнение delay_ms(1); } DESELECT_SPI(); //отпускаем устройство spi return 0; //ошибка таймаута } //--------------------------------
//-------------------------------- //процедура чтения страницы памяти void n25pageRead(unsigned char* buff, unsigned int page, unsigned int byte, unsigned int size) { unsigned int addr=0; //вычисляем физический адрес байта addr = page*N25_PAGE_SIZE+byte; SELECT_SPI(nSS_SFLASH); //выбираем устройство spi SPIWriteChar(N25_READ); //запись кода команды SPIWriteChar( (unsigned char) (addr>>16) ); //запись адреса SPIWriteChar( (unsigned char) (addr>>8) ); //запись адреса SPIWriteChar( (unsigned char) (addr>>0) ); //запись адреса while(size--) { *buff++ = SPIWriteChar(0x00); } DESELECT_SPI(); //отпускаем устройство spi } //-----------------------------
//-------------------------------- //процедура чтения сектора памяти void n25sectorRead(unsigned char* buff, unsigned int sector, unsigned int byte, unsigned int size) { unsigned int addr=0; //вычисляем физический адрес байта addr = sector*N25_SECTOR_SIZE+byte; SELECT_SPI(nSS_SFLASH); //выбираем устройство spi SPIWriteChar(N25_READ); //запись кода команды SPIWriteChar( (unsigned char) (addr>>16) ); //запись адреса SPIWriteChar( (unsigned char) (addr>>8) ); //запись адреса SPIWriteChar( (unsigned char) (addr>>0) ); //запись адреса while(size--) { *buff++ = SPIWriteChar(0x00); } DESELECT_SPI(); //отпускаем устройство spi } //-----------------------------
//-------------------------------- //процедура записи страницы памяти void n25pageWrite(unsigned char* buff, unsigned int page, unsigned int byte, unsigned int size) { unsigned int addr=0; //вычисляем физический адрес байта addr = page*N25_PAGE_SIZE+byte; n25setWREN(); //разрешаем запись в память SELECT_SPI(nSS_SFLASH); //выбираем устройство spi SPIWriteChar(N25_PP); //запись кода команды SPIWriteChar( (unsigned char) (addr>>16) ); //запись адреса SPIWriteChar( (unsigned char) (addr>>8) ); //запись адреса SPIWriteChar( (unsigned char) (addr>>0) ); //запись адреса //записываем данные while(size--) { SPIWriteChar(*buff++); } DESELECT_SPI(); //отпускаем устройство spi //ожидаем завершения операции n25waitBusy(N25_PP_TM); } //-----------------------------
//-------------------------------- //процедура записи сектора памяти void n25sectorWrite(unsigned char* buff, unsigned int sector, unsigned int size) { unsigned int page; unsigned int page_num; //вычисляем кол-во страниц и стартовый адрес страницы page = sector*M25_PAGE_PER_SECTOR; page_num = size/N25_PAGE_SIZE; for(unsigned int i=0; i<page_num; i++) { n25pageWrite(buff+i*N25_PAGE_SIZE, page+i, 0, N25_PAGE_SIZE); } } //-----------------------------
//-------------------------------- //процедура стирания сектора void n25sectorErase(unsigned int sector) { //вычисляем физический адре байта unsigned int addr = sector*N25_SECTOR_SIZE; n25setWREN(); //разрешаем запись в память SELECT_SPI(nSS_SFLASH); //выбираем устройство spi SPIWriteChar(N25_SE_4K); //запись кода команды SPIWriteChar( (unsigned char) (addr>>16) ); //запись адреса SPIWriteChar( (unsigned char) (addr>>8) ); //запись адреса SPIWriteChar( (unsigned char) (addr>>0) ); //запись адреса
DESELECT_SPI(); //отпускаем устройство spi //ожидаем завершения операции n25waitBusy(N25_SE_4K_TM); n25setWRDIS(); } //--------------------------------
//----------------------------- //инициализация памяти void n25xxInit(void) { n25setWRDIS(); } //-----------------------------
|
|
|
|
|
Mar 18 2014, 10:12
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
QUOTE (Harvester @ Mar 18 2014, 14:05)  Пока не заработает команда чтения, про запись даже не стоит вспоминать. +1. Чтение там элементарное. Запись маленько мудрёная (нужно проверять флаг занятости девайса). Но самое мудрёное будет сохранить куда-либо 64 Кбайт сектор перед тем, как его стереть, а затем перезаписать 256-байтовыми страницами  Если оперативы для кэша на борту мало, то будет очень медленно работать. Так, что мегабайта 2 ОЗУ бы надо) В общем, действительно сначала считайте уверенно JEDEC ID, и только потом двигайтесь дашльше.
--------------------
Выбор.
|
|
|
|
|
Mar 18 2014, 13:21
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(haker_fox @ Mar 18 2014, 14:12)  Но самое мудрёное будет сохранить куда-либо 64 Кбайт сектор перед тем, как его стереть, а затем перезаписать 256-байтовыми страницами  Если оперативы для кэша на борту мало, то будет очень медленно работать. Так, что мегабайта 2 ОЗУ бы надо) Не надо такого экстрима, вполне можно стирать субсекторами по 4К PS. Уже ответили
Сообщение отредактировал Harvester - Mar 18 2014, 13:21
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Mar 18 2014, 17:00
|
Группа: Участник
Сообщений: 14
Регистрация: 11-03-14
Пользователь №: 80 887

|
Я перепаял чип на другой такой же с 8ю ногами, а потом и с 16ю ногами, ответ на read id такой же!!! , может я купил не micron, а какого-нибудь другого производителя!!! Хотя покупал микрон, но может подсунули другое!!! По поводу чтения из памяти вроде работает, ответ на команду 03h по адресу 000000h вот такой ffffffffffffffffffff........h и так далее, но когда пишешь командой 02h по адресу 000000h , а потом читаешь командой 03h по тому же самому адресу читается полный бред, не то что ты записал, а иногда просто нули по этому адресу!!!
Сообщение отредактировал Sergiocars - Mar 18 2014, 17:20
|
|
|
|
|
Mar 18 2014, 23:44
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
QUOTE (Sergiocars @ Mar 19 2014, 02:00)  какого-нибудь другого производителя!!! N25 это Numonyx. Как они могут коррелировать с микроном - не знаю. QUOTE (Harvester @ Mar 18 2014, 22:21)  Не надо такого экстрима, вполне можно стирать субсекторами по 4К PS. Уже ответили Гм, судя по доке QUOTE For devices with bottom or top architecture, at the bottom (or top) of the addressable area there are 8 boot sectors, each one having 16 4Kbytes subsectors. я так понимаю, что нельзя всю флешь стирать 4 Кб секторами, можно стереть 16 таких секторов в "верхней" и "нижней" части микросхемы... или я сильно ошибься?
--------------------
Выбор.
|
|
|
|
|
Mar 19 2014, 04:29
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(haker_fox @ Mar 19 2014, 03:44)  N25 это Numonyx. Как они могут коррелировать с микроном - не знаю. Может когда-то это и был Numonyx, но сейчас это Micron Цитата(haker_fox @ Mar 19 2014, 03:44)  Гм, судя по доке Цитата For devices with bottom or top architecture, at the bottom (or top) of the addressable area there are 8 boot sectors, each one having 16 4Kbytes subsectors.
Хм. Из документации, скачанной с сайта Micron: Цитата The device is subsector, sector, or bulk-erasable, but not page-erasable. Bits are erased from zero through one. The memory is configured as 16,777,216 bytes (8 bits each); 256 sectors (64KB each); 4096 subsectors (4KB each); and 65,536 pages (256 bytes each); Кто-то из нас заблуждается. Цитата(Sergiocars @ Mar 18 2014, 21:00)  Я перепаял чип на другой такой же с 8ю ногами, а потом и с 16ю ногами, ответ на read id такой же!!! А почему ответ должен быть другим? Обмен-то как был неправильным, так и остался.  А теперь серьезно: В интерфейсе SPI всего две критичные настройки - фаза тактового сигнала (CPHA) и полярность тактового сигнала (CPOL). Их комбинация определяет режим интерфейса. Очевидно, что таких комбинаций всего 4. Чтобы исключить заморочки с формированием строба, подключаете вход S# памяти к свободному выходу микроконтроллера и управляете им программно. Перебираете все 4 комбинации - как минимум, одна из них должна быть правильной. PS Не могу сказать про данный конкретный МК, но все аппаратные SPI, которые мне встречаллись, выставляли сигнал строба только на время приема/передачи посылки. Для работы с памятью это не подходит и стробом в любом случае приходилось управлять программно
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Mar 19 2014, 06:17
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата(Sergiocars @ Mar 18 2014, 20:00)  Я перепаял чип на другой такой же с 8ю ногами, а потом и с 16ю ногами, ответ на read id такой же!!! , может я купил не micron, а какого-нибудь другого производителя!!! Micron или не Micron практически в 100% случаев фиолетово. Коды команд и процедуры работы с подобными микросхемами памяти совпадают. Посмотрите на процедуры работы с памятью из поста #29, сравните и найдите какие у Вас есть отличия. Я приводил 100% рабочий код. Задействуйте в конце концов софтовый SPI с полным контролем MISO/MOSI/SCK/nCS. Как Вам правильно подсказали многие аппаратные SPI активируют nCS только на одну транзакцию, что абсолютно недопустимо для работы с этой памятью. Поэкспериментируйте с программным управлением nCS и аппаратной передачей по SPI. Я работал с памятью N25, M95, W25 и все они заводились с полпинка. При этом ниодна микросхема не идёт залоченной от записи. Все они изначально готовы к нормальной работе.
|
|
|
|
|
Mar 19 2014, 06:32
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(mempfis_ @ Mar 19 2014, 10:17)  При этом ниодна микросхема не идёт залоченной от записи. Все они изначально готовы к нормальной работе. А вот на это полагаться не стоит, бывает и по другому  Как пример - SST25VF064C от Microchip. По умолчанию у нее все сектора защищены от записи. Я сам когда с этим столкнулся, был неприятно удивлен - замена производителя памяти потребовала выпуска новой прошивки. Так что лучше принудительно очистить все биты защиты от записи при старте программы.
Сообщение отредактировал Harvester - Mar 19 2014, 06:33
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Mar 19 2014, 11:24
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(haker_fox @ Mar 19 2014, 14:49)  А можете название микросхемы, с которой работаете, подсказать? Мне сейчас в проекте уже фиолетово, там 32 Мб SDRAM, и буфер 64 Кб выделить не проблема. Но ради спортивного интереса... Спасибо) Честно говоря, я с ней не работаю  Но дока по обсуждаемой мсх в прикрепленном файле
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Mar 28 2014, 18:06
|
Группа: Участник
Сообщений: 14
Регистрация: 11-03-14
Пользователь №: 80 887

|
Начал дергать СS отдельно пином порта, все заработало!!!! Спасибо всем, особенно zealot, harvester, haker_fox!!!!
|
|
|
|
|
Jun 27 2017, 12:19
|
Участник

Группа: Участник
Сообщений: 17
Регистрация: 25-05-10
Пользователь №: 57 521

|
Здравствуйте, используем память N25Q512A13GF840 на модуле phyCORE-Vybrid, на модуле установлен Линукс, файловая система флешки ubi. Память перестает работать через некоторое время. Никто не сталкивался с такой проблемой?
|
|
|
|
|
Oct 3 2017, 13:58
|
Частый гость
 
Группа: Участник
Сообщений: 136
Регистрация: 13-05-11
Пользователь №: 64 972

|
Всем доброго времени суток.
Работаю с N25Q256 по интерфейсу SPI extended. Идентификатор микросхемы командой READ ID считывается верно. Пытаюсь записать/читать в память. Для этого ставлю выставляю бит Write Enable в статусном регистре. Проверяю - бит установлен. Пишу массив из 32-х байт по нулевому адресу. Последующее считывание статусного регистра показывает, что бит занятости (busy) устанавливается на какое-то время, т.е. команда выполняется. После того, как бит занятости сбрасывается, пытаюсь считать эти же 32 байта по нулевому адресу. Считываются нули. Собственно в этом и проблема.
При этом, если перед командой чтения, проверить статусный регистр, то выяснится, что бит Write Enable там уже сброшен. Как будто его нужно выставлять перед каждой записью. Можно было бы предположить, что после команды записи, SPI перестает правильно все читать: и статусный регистр, и данные. Но при этом команда READ ID правильно считывает идентификатор девайса, т.е. она не поломалась.
В общем такие пироги. Буду благодарен за помощь в разрешении вопроса.
|
|
|
|
|
Oct 4 2017, 05:12
|
Группа: Участник
Сообщений: 12
Регистрация: 27-01-17
Пользователь №: 95 180

|
Цитата(RoadRunner @ Oct 3 2017, 19:58)  Всем доброго времени суток.
Работаю с N25Q256 по интерфейсу SPI extended. Идентификатор микросхемы командой READ ID считывается верно. Пытаюсь записать/читать в память. Для этого ставлю выставляю бит Write Enable в статусном регистре. Проверяю - бит установлен. Пишу массив из 32-х байт по нулевому адресу. Последующее считывание статусного регистра показывает, что бит занятости (busy) устанавливается на какое-то время, т.е. команда выполняется. После того, как бит занятости сбрасывается, пытаюсь считать эти же 32 байта по нулевому адресу. Считываются нули. Собственно в этом и проблема.
При этом, если перед командой чтения, проверить статусный регистр, то выяснится, что бит Write Enable там уже сброшен. Как будто его нужно выставлять перед каждой записью. Можно было бы предположить, что после команды записи, SPI перестает правильно все читать: и статусный регистр, и данные. Но при этом команда READ ID правильно считывает идентификатор девайса, т.е. она не поломалась.
В общем такие пироги. Буду благодарен за помощь в разрешении вопроса. Прошу простить за вопрос - а перед записью данных в сектор 0 (вероятно, командой программирования страницы Page Program 0x02) Вы сектор очищаете (стираете) командой Sector Erase 0x20? Или Вы в этот сектор еще никогда не записывали и считается, что сектор чист? Действительно, бит Write Enable сбрасывается аппаратно после КАЖДОЙ операции записи/программирования или стирания. Т.е. перед каждой операцией записи/программирования/стирания нужно посылать команду Write Enable 0x06.
|
|
|
|
|
Oct 4 2017, 05:23
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(RoadRunner @ Oct 3 2017, 20:58)  Считываются нули. Собственно в этом и проблема. Видимо сектор надо было предварительно стереть. Цитата(RoadRunner @ Oct 3 2017, 20:58)  Как будто его нужно выставлять перед каждой записью. Так и есть. Почитайте даташит на чип.
|
|
|
|
|
Oct 4 2017, 08:31
|
Частый гость
 
Группа: Участник
Сообщений: 136
Регистрация: 13-05-11
Пользователь №: 64 972

|
Цитата(TrestConsom @ Oct 4 2017, 08:12)  Прошу простить за вопрос - а перед записью данных в сектор 0 (вероятно, командой программирования страницы Page Program 0x02) Вы сектор очищаете (стираете) командой Sector Erase 0x20? Или Вы в этот сектор еще никогда не записывали и считается, что сектор чист? Я только стер всю флеш командой Bulk Erase. Думал, что этого достаточно. Я вообще не думал, что это необходимо - в доке вроде указаний на то, что обязательно стирать перед записью нет. Там только везде напоминают, что Write Enable надо выставить. Попробую стереть предварительно, отпишусь, что получится. Спасибо за совет.
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|