|
LPC1756+AT45DB081D, Ошибка чтения регистра dataflash |
|
|
|
Mar 5 2012, 11:36
|
Участник

Группа: Участник
Сообщений: 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);
|
|
|
|
|
 |
Ответов
(1 - 14)
|
Mar 5 2012, 12:31
|
Участник

Группа: Участник
Сообщений: 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 ничего не дала (
|
|
|
|
|
Mar 5 2012, 15:52
|

Профессионал
    
Группа: Свой
Сообщений: 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) - это слегка избыточно, но для проверки сойдёт.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Mar 19 2012, 08:54
|
Участник

Группа: Участник
Сообщений: 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. Используется внутренняя подтяжка.
|
|
|
|
|
Mar 21 2012, 05:25
|
Участник

Группа: Участник
Сообщений: 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)); } }
|
|
|
|
|
Mar 21 2012, 15:24
|

Профессионал
    
Группа: Свой
Сообщений: 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); По делу: Описание того, что флеш и контроллер находятся на разных платах, я упустил... Осталось только проверить, что земли одинаковые, и хорошо связанные. О! И что ещё вспомнил!! Я ведь тоже м/с на "соплях" подвешивал! В даташите на эту флеш указано макс. время фронтов клока. Оно там не просто так указано, при превышении этого значения начинаются разные странные вещи.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Jun 21 2012, 13:03
|
Участник

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

|
Спаяв новую плату , всё магическим образом заработало
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|