|
LPC1768 + AT45DB с использованием SSP |
|
|
|
May 26 2012, 13:37
|
Участник

Группа: Участник
Сообщений: 59
Регистрация: 11-12-11
Пользователь №: 68 798

|
Добрый день, коллеги. Волею судьбы пришлось использовать ARM в разработке. Столкнулись с такой проблемой. Нужно связать LPC1768 и AT45DB321. Опыт работы с этой датафлеш есть предостаточный, но все на PIC. Так вот, в чем проблема. Если использовать модуль SPI, вопросов не возникает, рабочий код для PIC был портирован практически без изменений и работает. Все бы ничего, но скорость обмена не более 12МГц. Датафлеш позволяет обмениваться быстрее, что собственно и нужно. При использовании SSP возникают нюансы, а именно: включается буфер FIFO глубиной 8 слов. Пока он не заполнен до верху, получается, невозможно считать данные. Допустим, кто знаком с работой датафлеши, на запрос о статусе надо принять всего единственный байт. Невозможно его получить, пока 8 раз не запросишь. Это разве удобства? А если выполнить блочное чтение, значит, нужно читать на 8 байт больше, что бы считать на вершине буфера свой нужный последний? Или я чего-то не понимаю? Почему у модуля УАРТ можно указать глубину буфера Фифо, тут нельзя. Как дали, так и кушать? Может кто подскажет, как проще выкрутиться? Заранее спасибо.
|
|
|
|
|
 |
Ответов
|
May 27 2012, 08:47
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(aaarrr @ May 27 2012, 11:32)  1. Нет ни малейшей необходимости заполнять FIFO полностью. При запросе статуса просто пишем два байта, затем два байта читаем. Во втором находим искомый статус. Все. Точно. Читал AT45 (правда на lpc11. но у них очень похожий SSP, может вам подойдёт): CODE void InitLpcSSP0_IO() { // сброс SSP0 LPC_SYSCON->PRESETCTRL |= (1<<0); // тактирование SSP0 LPC_SYSCON->SYSAHBCLKCTRL |= (1<<11); // делитель на 2 LPC_SYSCON->SSP0CLKDIV = 0x02; /* SSP I/O config */
/* SSP MISO */ LPC_IOCON->PIO0_8 &= ~0x07; LPC_IOCON->PIO0_8 |= 0x01; /* SSP MOSI */ LPC_IOCON->PIO0_9 &= ~0x07; LPC_IOCON->PIO0_9 |= 0x01;
// SCK на вывод 2.11 LPC_IOCON->SCK_LOC = 1; LPC_IOCON->PIO2_11 = 0x01; // Enable AHB clock to the GPIO domain. LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6); // SSP SSEL is a GPIO pin LPC_IOCON->PIO0_2 &= ~0x07; // port0, bit 2 is set to GPIO output and high LPC_GPIO0->DIR|=1<<2; LPC_GPIO0->DATA|=1<<2; }
void InitSSP0() { // Set DSS data to 8-bit, // Frame format SPI, //CPOL = 0, CPHA = 0, and SCR is 15 LPC_SSP0->CR0 = 0x0707;
// SSPCPSR clock prescale register, //master mode, minimum divisor is 0x02 LPC_SSP0->CPSR = 0x2;
for ( unsigned char i = 0; i < FIFOSIZE; i++ ) { unsigned char Dummy = LPC_SSP0->DR; /* clear the RxFIFO */ }
/* Enable the SSP Interrupt */ //NVIC_EnableIRQ(SSP0_IRQn);
/* Device select as master, SSP Enabled */ /* Master mode */ LPC_SSP0->CR1 = (1<<1);
/* Set SSPINMS registers to enable interrupts */ /* enable all error related interrupts */ // SSPIMSC_RORIM | SSPIMSC_RTIM; LPC_SSP0->IMSC = (1<<0)|(1<<1); }
void SSP0_SendData(uint8_t *buf, uint16_t Length ) { uint32_t i; uint8_t Dummy = Dummy;
for ( i = 0; i < Length; i++ ) { /* Move on only if NOT busy and TX FIFO not full. */ while ( (LPC_SSP0->SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF ); LPC_SSP0->DR = *buf; buf++;
while ( (LPC_SSP0->SR & (SSPSR_BSY|SSPSR_RNE)) != SSPSR_RNE ); //Whenever a byte is written, MISO FIFO counter increments, Clear FIFO //on MISO. Otherwise, when SSP0Receive() is called, previous data byte //is left in the FIFO. Dummy = LPC_SSP0->DR; } }
void SSP0_Receive(uint8_t *buf, uint16_t Length) { uint32_t i;
for ( i = 0; i < Length; i++ ) { //As long as Receive FIFO is not empty, I can always receive. // If it's a loopback test, clock is shared for both TX and RX, // no need to write dummy byte to get clock to get the data // if it's a peer-to-peer communication, SSPDR needs to be written //before a read can take place. LPC_SSP0->DR = 0xFF; /* Wait until the Busy bit is cleared */ while ( (LPC_SSP0->SR & (SSPSR_BSY|SSPSR_RNE)) != SSPSR_RNE ); *buf = LPC_SSP0->DR; buf++; } } unsigned char AT45_GetStatus() { SSP0_CS_Clr();
uint8_t cmd_code=0xD7; SSP0_SendData(&cmd_code, 1); uint8_t status; SSP0_Receive(&status, 1);
SSP0_CS_Set();
return status; }
|
|
|
|
|
May 27 2012, 13:05
|
Участник

Группа: Участник
Сообщений: 59
Регистрация: 11-12-11
Пользователь №: 68 798

|
Цитата(_Артём_ @ May 27 2012, 11:47)  Точно. Читал AT45 (правда на lpc11. но у них очень похожий SSP, может вам подойдёт): Спасибо, обязательно пригодится. В понедельник и попробуем.
|
|
|
|
|
May 28 2012, 13:31
|
Участник

Группа: Участник
Сообщений: 59
Регистрация: 11-12-11
Пользователь №: 68 798

|
Всем спасибо, кто откликнулся. Дело действительно в работе под отладчиком. Тоесть сами по себе процедуры работы были правильными. Нужно было только поставить точку останова не на чтении данных из буфера фифо, а чуть ниже. Тогда микроконтрлллер забирал бы данные своим кодом, а не отладчик. Все работает нормально.
|
|
|
|
Сообщений в этой теме
TAutomatic LPC1768 + AT45DB с использованием SSP May 26 2012, 13:37 jcxz Не очень понятно в чём проблема? Работаю именно с ... May 26 2012, 14:33 TAutomatic Ну мне кажется, я достаточно подробно описал, в ЧЕ... May 26 2012, 15:57 aaarrr Цитата(TAutomatic @ May 26 2012, 17:37) Д... May 26 2012, 16:07 TAutomatic Цитата(aaarrr @ May 26 2012, 19:07) Это н... May 26 2012, 16:20  aaarrr Цитата(TAutomatic @ May 26 2012, 20:20) .... May 26 2012, 16:35  TAutomatic У коллеги, кстати, тоже не так работает, как хотел... May 26 2012, 16:45   jcxz Цитата(TAutomatic @ May 26 2012, 22:45) У... May 26 2012, 17:25    TAutomatic Цитата(jcxz @ May 26 2012, 20:25) Это как... May 26 2012, 17:43 DmitryM Цитата(TAutomatic @ May 26 2012, 17:37) Д... May 27 2012, 06:22 _Артём_ Цитата(DmitryM @ May 27 2012, 09:22) А ка... May 27 2012, 06:26  DmitryM Цитата(_Артём_ @ May 27 2012, 10:26) Смыс... May 27 2012, 06:34 TAutomatic Цитата(DmitryM @ May 27 2012, 09:22) А ка... May 27 2012, 07:45
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|