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

 
 
 
Reply to this topicStart new topic
> AT91SAM7X SPI PDC SD-card
Колька
сообщение Sep 22 2009, 14:42
Сообщение #1





Группа: Участник
Сообщений: 7
Регистрация: 22-09-09
Пользователь №: 52 517



Написал свою библиотеку по работе с SD-card. Все работает замечательно. Но есть одно "но". Отправку, прием я сделал без PDC.
Когда мне нужно принять 512 байт, я просто побайтно их последовательно принимаю. Проблема в следующем: настраиваю PDC и в результате приходит "каша". CS-ом дергаю сам. Никто не подскажет в чем может быть проблема? Скорость понижал не помогло. В общем буду рад любому совету.

Сообщение отредактировал Колька - Sep 22 2009, 14:44
Go to the top of the page
 
+Quote Post
Колька
сообщение Sep 22 2009, 16:13
Сообщение #2





Группа: Участник
Сообщений: 7
Регистрация: 22-09-09
Пользователь №: 52 517



Вот к примеру должно прочитатся:

01 02 03 04 05 06 00 00 00

а читается так:

02 04 06 08 0A 0C 0E 00 00


Получается что передача здвинута на бит. Не подскажете в чем может быть проблема?

Сообщение отредактировал Колька - Sep 22 2009, 16:20
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 22 2009, 16:46
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Вариантов "проблем" может быть много, так что код в студию.
Go to the top of the page
 
+Quote Post
Колька
сообщение Sep 22 2009, 17:11
Сообщение #4





Группа: Участник
Сообщений: 7
Регистрация: 22-09-09
Пользователь №: 52 517



Функция блочного считывания:
Код
uint8_t datablock_read(uint8_t* buff, uint32_t btr) {
  uint8_t token;

  uint32_t time = OSTime;

  while (1) {
    token = SPI_Read(0xFF);
    if (token != 0xFF)
      break;
    if ((OSTime - time) > 100)
      break;
  }

  if (token != 0xFE)
    return 0;

  #if USE_DMA        
    SPI_Read_PDC(buff, btr);
  #else
    do {
      SPI_Read(buff++);
    } while (btr -= 1);
  #endif
  SPI_Read(0xFF);
  SPI_Read(0xFF);

  return 1;
}

***** *

unsigned short SPI_Read(PSPI self, unsigned short data) {

  while ((BASE_SPI->SPI_SR &AT91C_SPI_TDRE) == 0)
;

  self->BASE_SPI->SPI_TDR = (data &0xFFFF);


  while (0 == (self->BASE_SPI->SPI_SR &AT91C_SPI_RDRF))
;

  return ((self->BASE_SPI->SPI_RDR) &0xFFFF);
}


short SPI_Read_PDC(PSPI self, void* data, unsigned short count) {

  self->BASE_SPI->SPI_RDR;
  self->BASE_SPI->SPI_SR;

  self->BASE_SPI_PDC->PDC_RPR = (unsigned int)data;
  self->BASE_SPI_PDC->PDC_RCR = count;

  self->BASE_SPI_PDC->PDC_PTCR = AT91C_PDC_RXTEN;
  self->BASE_SPI->SPI_IER = (AT91C_SPI_ENDRX);

  if (SPI_Send_PDC(self, dma_dummy, count) == count) {
    xSemaphoreTake(self->RXSemaphore, timeout);
  }

  self->BASE_SPI->SPI_IDR = AT91C_SPI_ENDRX;
  self->BASE_SPI_PDC->PDC_RCR = 0;

  (unsigned long)self->BASE_SPI->SPI_SR;
  (unsigned long)self->BASE_SPI->SPI_RDR;

  self->BASE_SPI_PDC->PDC_PTCR = AT91C_PDC_RXTDIS;

  unsigned short res = count - (self->BASE_SPI_PDC->PDC_RCR);

  return res;
}


dma_dummy - масив с 0xFF значениями. SPI_Send_PDC - запись, один в один такая же как и чтение, кроме регистров иннициализации отправки, а логика такая же поэтому не привожу.
Коэффициент деления: 2, при иннициализации 200. Параметры: AT91C_SPI_CPOL | AT91C_SPI_BITS_8

В общем при "#define USE_DMA 0" работает, а при "#define USE_DMA 1" нет sad.gif
Где ошибка у меня ошибка? Не подскажите?

Сообщение отредактировал Колька - Sep 22 2009, 17:16
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 22 2009, 19:11
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Колька @ Sep 22 2009, 21:11) *
SPI_Send_PDC - запись, один в один такая же как и чтение, кроме регистров иннициализации отправки, а логика такая же поэтому не привожу.

Напрасно, ибо вот это абсолютно не понятно:
Код
  if (SPI_Send_PDC(self, dma_dummy, count) == count) {
    xSemaphoreTake(self->RXSemaphore, timeout);
  }

Кто, где, когда и при каких условиях это семафор ставит?
Go to the top of the page
 
+Quote Post
Колька
сообщение Sep 22 2009, 19:29
Сообщение #6





Группа: Участник
Сообщений: 7
Регистрация: 22-09-09
Пользователь №: 52 517



Мне кажется дело не в том. Вот заменил функцию SPI_Read_PDC, что бы было более понятно, результат тот жеsad.gif((
Код
short SPI_Read_PDC(PSPI self, void* data, unsigned short count) {

    PSPI_BASE->SPI_RPR = (UINT)buff; // destination address
    PSPI_BASE->SPI_RCR = btr; // number of frames (here: frame=byte)
    // SPI PDC TX buffer (dummy bytes):
    PSPI_BASE->SPI_TPR = (UINT)dma_dummy; // source address
    PSPI_BASE->SPI_TCR = btr; // number of frames (here: frame=byte)
    
    PSPI_BASE->SPI_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTEN;
        
    while( !( (PSPI_BASE->SPI_SR) & AT91C_SPI_RXBUFF ) ) {
        // wait for RX Buffer Full (counters 0)
    }
}

Проблемы не могут идти от каких-то особенностей карты или PDC-режима?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 22 2009, 19:56
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Колька @ Sep 22 2009, 23:29) *
Проблемы не могут идти от каких-то особенностей карты или PDC-режима?

Да нет там особенностей никаких, функция у Вас вполне честная. Разве что отключением SPI можно получить какой-нибудь glitch на SCK и, как следствие, смещение на бит.
Go to the top of the page
 
+Quote Post
Колька
сообщение Sep 22 2009, 20:07
Сообщение #8





Группа: Участник
Сообщений: 7
Регистрация: 22-09-09
Пользователь №: 52 517



Пока сам для себя причину не выяснил, так как ещё новичек, но вот так работает:

Цитата
short SPI_Read_PDC(PSPI self, void* data, unsigned short count) {
PSPI_BASE->SPI_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;

PSPI_BASE->SPI_RPR = (UINT)buff; // destination address
PSPI_BASE->SPI_RCR = btr; // number of frames (here: frame=byte)
// SPI PDC TX buffer (dummy bytes):
PSPI_BASE->SPI_TPR = (UINT)dma_dummy; // source address
PSPI_BASE->SPI_TCR = btr; // number of frames (here: frame=byte)

PSPI_BASE->SPI_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTEN;

while( !( (PSPI_BASE->SPI_SR) & AT91C_SPI_RXBUFF ) ) {
// wait for RX Buffer Full (counters 0)
}
}
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 22 2009, 20:10
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Теоретически такое возможно, если PDC использовался ранее. Но сдвига данных на бит никогда не встречал.
Go to the top of the page
 
+Quote Post
Колька
сообщение Sep 22 2009, 20:13
Сообщение #10





Группа: Участник
Сообщений: 7
Регистрация: 22-09-09
Пользователь №: 52 517



Жаль что осциллографа нет что бы проверить как сигнал формируется. Но примерно сам для себя причину неполадок я понял. Всем спасибо.
Go to the top of the page
 
+Quote Post
Колька
сообщение Sep 23 2009, 10:38
Сообщение #11





Группа: Участник
Сообщений: 7
Регистрация: 22-09-09
Пользователь №: 52 517



Попутный вопрос возник. У всех ли SD-картах размер сектора равняется 512?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 23 2009, 11:03
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



По первой спецификации все обязаны поддерживать блоки в 512 байт:
Цитата
It is a mandatory requirement that SD Memory Card shall have a capability to transfer blocks of 512 Bytes.
...
A card supporting block write shall always be able to accept a block of data defined by WRITE_BL_LEN and its
512bytes derivatives (for example: If write block length=1024bytes then write blocks of 1024 and 512bytes are supported).


Во второй спецификации размер блока строго фиксирован на 512.
Go to the top of the page
 
+Quote Post
head_sk
сообщение Sep 23 2009, 11:06
Сообщение #13


Частый гость
**

Группа: Участник
Сообщений: 80
Регистрация: 3-07-09
Пользователь №: 50 897



CMD16 - Selects a block length in bytes for all following block commands (read & write).

Как уже было упомянуто размер блока 512 фиксировано. Но в своей программе я выполняю данную команду с параметром 512, для совместимости со всеми карточками.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 13:33
Рейтинг@Mail.ru


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