Croman13n3c 0 5 марта, 2012 Опубликовано 5 марта, 2012 · Жалоба Имеем связку из 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 ) 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 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); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 5 марта, 2012 Опубликовано 5 марта, 2012 · Жалоба Вы бы написали, что эта чудо-библиотека делает в SSP_ConfigStructInit и SSP_Init. И это... у меня всё работает :-) LPC1768, AT45DB161D. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Croman13n3c 0 5 марта, 2012 Опубликовано 5 марта, 2012 · Жалоба 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 ничего не дала ( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 5 марта, 2012 Опубликовано 5 марта, 2012 · Жалоба Ну вот честное слово, лениво продираться через высосанные из пальца дефайны. Имхо, периферия на 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) - это слегка избыточно, но для проверки сойдёт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Croman13n3c 0 19 марта, 2012 Опубликовано 19 марта, 2012 · Жалоба Функция обмена по SPI была рабочая, проверил на другой плате ( подпаявшись на прямую, достал из загашника ). Чувствую дело в инициализации работы самой памяти. При старте делаю : delay_us(70); //power-up Vcc CS(LOW); delay_ms(20); //delay before write allowed CS(HI); CS как GPIO, остальные как SSP. Используется внутренняя подтяжка. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 20 марта, 2012 Опубликовано 20 марта, 2012 · Жалоба Ну работает же у меня! :-) Проверил ещё раз: на 0xD7 возвращается 0xAC на 0x9F возвращается 0x1F,0x26 (у меня объем памяти другой) Единственное, что Вы не указали - реализация CS(HI) / CS(LOW). Может, тут ошибка? Также, в теории, возможна дохлая микросхема. Проверяли на другой? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Croman13n3c 0 21 марта, 2012 Опубликовано 21 марта, 2012 · Жалоба Проверял, тоже самое. Различие в уровнях может вызывать такое поведение ( на отладочной плате пины с 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)); } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 21 марта, 2012 Опубликовано 21 марта, 2012 · Жалоба Нет, ну не нравятся мне эти супер-библиотеки! Вся эта супер-портабельная фигня заменяется ОДНОЙ строкой. 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); По делу: Описание того, что флеш и контроллер находятся на разных платах, я упустил... Осталось только проверить, что земли одинаковые, и хорошо связанные. О! И что ещё вспомнил!! Я ведь тоже м/с на "соплях" подвешивал! В даташите на эту флеш указано макс. время фронтов клока. Оно там не просто так указано, при превышении этого значения начинаются разные странные вещи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Croman13n3c 0 21 июня, 2012 Опубликовано 21 июня, 2012 · Жалоба Спаяв новую плату , всё магическим образом заработало Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uriy 5 6 декабря, 2012 Опубликовано 6 декабря, 2012 · Жалоба У меня точно такая же проблема, но контроллер STM32 а флешку пробовал at45db161 и at45db642. Спаяно 4 платы, одна работает без проблем. На трех на команду 9F читается 0x1E 0x00 0x00 0x00 именно такое значение выдает и флешка, видно осциллом. На плате имеются длинные дорожки к другой SPI микросхеме, та микросхема читается без каких либо проблем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SyncLair 0 6 декабря, 2012 Опубликовано 6 декабря, 2012 · Жалоба Простите, а разве нельзя просто частоту уменьшить если у вас паразитные емкости из-за плохого монтажа ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uriy 5 7 декабря, 2012 Опубликовано 7 декабря, 2012 · Жалоба Частоту итак понижал до 250 КГц. Проблема похоже решена. Воткнул последовательно сигнальным линиям резисторы 100 Ом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 10 декабря, 2012 Опубликовано 10 декабря, 2012 · Жалоба Простите, а разве нельзя просто частоту уменьшить если у вас паразитные емкости из-за плохого монтажа ? Повторюсь. У этих микросхем есть параметр SCR rise (fall) time, равный 0.1 V/ns min. Для 3 вольт питания это означает максимальное время фронта 30 наносекунд. По опыту, при превышении этих параметров будет работать именно так, как описано - читается всякая фигня, вне зависимости от самой частоты клока. При этом форма сигнала довольно хорошая... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uriy 5 11 декабря, 2012 Опубликовано 11 декабря, 2012 · Жалоба Поясню тоже на будущее для других. Возможно кому-то поможет. У меня тоже устройство состоит из двух лпат. На первой стоит STM32 и в паре сантиметров от нее AT45DB642. На другой плате ADE7878. Обе микросхемы висят на одной шине SPI. Суммарное расстояние до ADE порядка 30см. Межплатный разъем примерно по середине. У разъема стоят резисторы 100 Ом последовательно и кондеры 1000пф на землю. С емкостью я похоже переборщил. ADE отлично работает на длинной линии с таким резистором и емкостью. Попробовал снять кондеры, ADE по-прежнему работает. с SPI флеш ничего не изменилось. Запаял последовательно SPI флеш резисторы 100 Ом, кондеры по прежнему сняты. Все заработало. Но ведь эти резисторы опять же увеличили длительность фронта. Кондеры я ставил с целью избавится от отражений которые могли вызывать появление ложных фронтов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 12 декабря, 2012 Опубликовано 12 декабря, 2012 · Жалоба Кондеры я ставил с целью избавится от отражений которые могли вызывать появление ложных фронтов.Резисторы тоже. Завалили фронт, уменьшили спектр. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться