реклама на сайте
подробности

 
 
> LPC1756+AT45DB081D, Ошибка чтения регистра dataflash
Croman13n3c
сообщение Mar 5 2012, 11:36
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 26
Регистрация: 1-02-11
Пользователь №: 62 630



Имеем связку из LPC1756 и AT45DB081D через блок SSP в режиме SPI.
Пытаюсь считать Manufacturer ID (opcode - 0x9f)
По приему в буфеер оказывается значение 0x1E 0x00 0x00 0x00 (должно быть 0x1F 0x25 0x00 0x00).
Посмотрев осцилом на линии на первый взгляд всё порядке : cs опущен, тактирование идет, опкод заносится и от at45 приходит 0x1E( вместо ожидаемого).
Может кто с таким уже сталкивался , в чём может быть причина такого поведения ?

Инициализация SSP в SPI Mode 0 (P0.15,16,17,18 -- CLK,!CS,MISO,MOSI )
CODE

DataFlashSSP_CFG.CPHA=SSP_CPHA_FIRST;
DataFlashSSP_CFG.CPOL=SSP_CPOL_LO;
DataFlashSSP_CFG.ClockRate=1000000;
DataFlashSSP_CFG.Mode=SSP_MASTER_MODE;
DataFlashSSP_CFG.FrameFormat=SSP_FRAME_SPI;
DataFlashSSP_CFG.Databit = SSP_DATABIT_8;
SSP_ConfigStructInit(&DataFlashSSP_CFG);
SSP_Init(LPC_SSP0, &DataFlashSSP_CFG);

CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_SSP0, CLKPWR_PCLKSEL_CCLK_DIV_2);

SSP_Cmd(LPC_SSP0, ENABLE);

/* ждем пока освободится*/
while( LPC_SSP0->SR & SSP_SR_BSY ) { ; }

/* очистка FIFO */
while( LPC_SSP0->SR & SSP_SR_RNE ) {
volatile uint32_t dummy = LPC_SSP0->DR;
(void)dummy;


Чтение Manufacturer ID

CODE

CS(LOW):
delay_us(10);
LPC_SSP0->DR = 0x9f;
while (LPC_SSP0->SR & SSP_SR_BSY ) { ; }
rx_data=LPC_SSP0->DR;

for (i=0;i<4;i++)
{
LPC_SSP0->DR = 0xFF;
while (LPC_SSP0->SR & SSP_SR_BSY ) { ; }
buf[i] = LPC_SSP0->DR;
}
CS(HI);
delay_ms(1);

Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 14)
esaulenka
сообщение Mar 5 2012, 12:02
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Вы бы написали, что эта чудо-библиотека делает в SSP_ConfigStructInit и SSP_Init.

И это... у меня всё работает :-) LPC1768, AT45DB161D.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
Croman13n3c
сообщение Mar 5 2012, 12:31
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 26
Регистрация: 1-02-11
Пользователь №: 62 630



SSP_ConfigStructInit и SSP_Init стандартные функции из nxp lpx17xx cmsis library.

SSP_ConfigStructInit - инициализирует поля структуры настроек SSP значениями по умолчанию.
SSP_Init - установка скорости, параметров из DataFlashSSP_CFG, подача питания и тактирования на модуль.

P.S 1 ошибка в моем коде - SSP_ConfigStructInit должна находится в начале первого блока с кодом.
P.P.S настройка в режим SPI Mode 3 ничего не дала (
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Mar 5 2012, 15:52
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Ну вот честное слово, лениво продираться через высосанные из пальца дефайны. Имхо, периферия на NXP документирована достаточно хорошо, чтобы не использовать ещё какие-то дополнительные библиотеки.

Например, неочевидно мне, что тут пишут в CR1. Надо прочитать Ваш исходник, заголовок драйвера и сам драйвер, и только потом смотреть в даташит.
Код
    tmp = SSP_ConfigStruct->Mode & SSP_CR1_BITMASK;
    // Write back to CR1
    SSPx->CR1 = tmp;


Рабочий код обмена с SPI:

Код
#define        SPI_REG(reg)    SSP1->reg

#define        SPI_WAIT_READY()                while (SPI_REG(SR) & SPI_SR_BUSY)


//    Процедура инициализации (возвращает код ошибки)
dword    SPI_Init(void)
{
    // устанавливается в стартапе: SSP1 on, PCLK = CCLK
    //PCONP |= BIT(10);
    //CLKSEL (PCLKSEL0, 1, 20);

    SPI_DISABLE_ALL_CHIP();

    SPI_REG(CPSR)    =    6;
    SPI_REG(CR0)    =    0x0007;
    SPI_REG(IMSC)    =    0x0;
    SPI_REG(DMACR)    =    0x0;
    SPI_REG(CR1)    =    0x2;

    while    (SPI_REG(SR) & SPI_SR_RNE)
        SPI_REG(DR);
    return 0;
}

//    Процедура запуска одного цикла работы
dword    SPI_Run    (dword    aSendByte)
{
    SPI_REG(DR)    =    aSendByte;
    SPI_WAIT_READY();
    return    SPI_REG(DR);
}


ChipSelect сконфигурирован как GPIO, остальные ноги - как SSP (в другом модуле, здесь не видно).
После перехода CS low->high рекомендую добавить несколько (я сделал десяток) nop'ов - у контроллера ноги весьма быстрые, память может не "почуствовать" деактивации. Хотя, как я вижу, уже есть delay_ms(1) - это слегка избыточно, но для проверки сойдёт.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
Croman13n3c
сообщение Mar 19 2012, 08:54
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 26
Регистрация: 1-02-11
Пользователь №: 62 630



Функция обмена по SPI была рабочая, проверил на другой плате ( подпаявшись на прямую, достал из загашника ).
Чувствую дело в инициализации работы самой памяти.

При старте делаю :

Код
delay_us(70); //power-up Vcc
CS(LOW);
delay_ms(20); //delay before write allowed
CS(HI);


CS как GPIO, остальные как SSP. Используется внутренняя подтяжка.
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Mar 20 2012, 11:41
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Ну работает же у меня! :-) Проверил ещё раз:
на 0xD7 возвращается 0xAC
на 0x9F возвращается 0x1F,0x26 (у меня объем памяти другой)

Единственное, что Вы не указали - реализация CS(HI) / CS(LOW). Может, тут ошибка?

Также, в теории, возможна дохлая микросхема. Проверяли на другой?


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
Croman13n3c
сообщение Mar 21 2012, 05:25
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 26
Регистрация: 1-02-11
Пользователь №: 62 630



Проверял, тоже самое.
Различие в уровнях может вызывать такое поведение ( на отладочной плате пины с 3,3 В , а питание платки с dataflash 3 В) ?
Код
#define LOW 0
#define HI  1

void CS (uint8_t type)
{
   if (type)
     {
        GPIO_SetValue(0, (1 << 16)); // Set Value on PIN  - port num , pin  
     }
   else
     {
        GPIO_ClearValue(0, (1 << 16));
     }
}
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Mar 21 2012, 15:24
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Нет, ну не нравятся мне эти супер-библиотеки!
Вся эта супер-портабельная фигня заменяется ОДНОЙ строкой.
CODE

void GPIO_SetValue(uint8_t portNum, uint32_t bitValue)
{
LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum);

if (pGPIO != NULL) {
pGPIO->FIOSET = bitValue;
}
}

static LPC_GPIO_TypeDef *GPIO_GetPointer(uint8_t portNum)
{
LPC_GPIO_TypeDef *pGPIO = NULL;

switch (portNum) {
case 0:
pGPIO = LPC_GPIO0;
break;
case 1:
pGPIO = LPC_GPIO1;
break;
case 2:
pGPIO = LPC_GPIO2;
break;
case 3:
pGPIO = LPC_GPIO3;
break;
case 4:
pGPIO = LPC_GPIO4;
break;
default:
break;
}

return pGPIO;
}

Код
LPC_GPIO0->FIOSET = (1UL<<16);


По делу:
Описание того, что флеш и контроллер находятся на разных платах, я упустил...
Осталось только проверить, что земли одинаковые, и хорошо связанные.

О! И что ещё вспомнил!! Я ведь тоже м/с на "соплях" подвешивал! В даташите на эту флеш указано макс. время фронтов клока. Оно там не просто так указано, при превышении этого значения начинаются разные странные вещи.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
Croman13n3c
сообщение Jun 21 2012, 13:03
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 26
Регистрация: 1-02-11
Пользователь №: 62 630



Спаяв новую плату , всё магическим образом заработало
Go to the top of the page
 
+Quote Post
uriy
сообщение Dec 6 2012, 08:07
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606



У меня точно такая же проблема, но контроллер STM32 а флешку пробовал at45db161 и at45db642. Спаяно 4 платы, одна работает без проблем. На трех на команду 9F читается 0x1E 0x00 0x00 0x00 именно такое значение выдает и флешка, видно осциллом.
На плате имеются длинные дорожки к другой SPI микросхеме, та микросхема читается без каких либо проблем.
Go to the top of the page
 
+Quote Post
SyncLair
сообщение Dec 6 2012, 21:09
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 209
Регистрация: 6-01-12
Пользователь №: 69 197



Простите, а разве нельзя просто частоту уменьшить если у вас паразитные емкости из-за плохого монтажа ?


--------------------
Go to the top of the page
 
+Quote Post
uriy
сообщение Dec 7 2012, 20:48
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606



Частоту итак понижал до 250 КГц. Проблема похоже решена. Воткнул последовательно сигнальным линиям резисторы 100 Ом.
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Dec 10 2012, 10:28
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(SyncLair @ Dec 7 2012, 01:09) *
Простите, а разве нельзя просто частоту уменьшить если у вас паразитные емкости из-за плохого монтажа ?

Повторюсь. У этих микросхем есть параметр SCR rise (fall) time, равный 0.1 V/ns min. Для 3 вольт питания это означает максимальное время фронта 30 наносекунд.

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


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
uriy
сообщение Dec 11 2012, 05:08
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606



Поясню тоже на будущее для других. Возможно кому-то поможет.
У меня тоже устройство состоит из двух лпат.
На первой стоит STM32 и в паре сантиметров от нее AT45DB642. На другой плате ADE7878. Обе микросхемы висят на одной шине SPI.
Суммарное расстояние до ADE порядка 30см. Межплатный разъем примерно по середине.
У разъема стоят резисторы 100 Ом последовательно и кондеры 1000пф на землю. С емкостью я похоже переборщил.
ADE отлично работает на длинной линии с таким резистором и емкостью.
Попробовал снять кондеры, ADE по-прежнему работает. с SPI флеш ничего не изменилось.
Запаял последовательно SPI флеш резисторы 100 Ом, кондеры по прежнему сняты. Все заработало.
Но ведь эти резисторы опять же увеличили длительность фронта.
Кондеры я ставил с целью избавится от отражений которые могли вызывать появление ложных фронтов.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 12 2012, 07:52
Сообщение #15


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (uriy @ Dec 11 2012, 07:08) *
Кондеры я ставил с целью избавится от отражений которые могли вызывать появление ложных фронтов.
Резисторы тоже. Завалили фронт, уменьшили спектр.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 10:20
Рейтинг@Mail.ru


Страница сгенерированна за 0.01496 секунд с 7
ELECTRONIX ©2004-2016