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

 
 
> SD card: 512 blocks limit.
pitt
сообщение May 7 2015, 20:44
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672



Sorry for using English - I don't have russian keyboard.
Here is my problem: I'm writing blocks 512 bytes each on consecutive sectors of SDHC card. Hardware is STM3240G-EVAL. No file system, no OS no interrupts except SDIO and DMA serving SDIO. The goal is to test the software and measure my access speed: average and lowest. When I'm writing 256 blocks(CMD25) at a time loop of 1000 times I don't have issues except sometimes(5%) access time is more than 10 times greater than average. Don't know why but it is. When I'm writing 512 blocks Average speed is the same but lowest is almost 20 times above average. And the last thing: as soon as I'm trying to write >512 blocks I'm getting instantly FEIF...
Please share your thoughts and knowledge.

Thank you in advance.

Google translator:
Вот моя проблема: я пишу блоки 512 байт каждый на подряд секторов SDHC карты. Аппаратное STM3240G-EVAL. Нет файловая система, нет ОС нет прерывания кроме SDIO и DMA служащая для SDIO.Целью является для тестирования программного обеспечения и измерения мою скорость доступа: средний и низкий. Когда я пишу 256 блоков (CMD25) в петле времени в 1000 раз меня нет проблем, кроме иногда(5%) время доступа более чем в 10 раз больше, чем в среднем. Не знаю почему, но это так. Когда я пишу 512 блоков Средняя скорость же, но низкая почти в 20 раз выше среднего. И последнее: как только я пытаюсь написать> 512 блоков я получаю мгновенно FEIF ...
Пожалуйста, поделитесь своими мыслями и знаниями.


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 21)
Dr.Alex
сообщение May 7 2015, 21:26
Сообщение #2


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

Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863



Цитата(pitt @ May 7 2015, 23:44) *
sometimes(5%) access time is more than 10 times greater than average.

I guess it is normal.
I did not ever bother to test access time for each of that small blocks because I needed *highest* possible write speed which is achievable with BIG chunks only (got over 100 Mbps with regular class-10 or UHS-I cards).


Цитата(pitt @ May 7 2015, 23:44) *
And the last thing: as soon as I'm trying to write >512 blocks I'm getting instantly FEIF...

You'd better try STMcube HAL. It works (with some issues time to time discussed here).
Also you can try Chibios alone with its HAL.
Go to the top of the page
 
+Quote Post
pitt
сообщение May 8 2015, 00:00
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672



Цитата(Dr.Alex @ May 7 2015, 17:26) *
You'd better try STMcube HAL. It works (with some issues time to time discussed here).
Also you can try Chibios alone with its HAL.

Подобное творение - STMcube HAL, можно рассматривать исключительно как референс, что я и делал, но ответов на многочисленные вопросы, никак не раскрытые в Reference Manual оно не дает.
Chibios тоже использую, но предпочитаю освоить "материальную часть", а не полагаться на других.
Пример:
Код
#if (defined(STM32F4XX) || defined(STM32F2XX))
  /* Wait until DMA channel enabled to be sure that all data transferred.*/

/***********************************************/  
while (sdcp->dma->stream->CR & STM32_DMA_CR_EN);
/***********************************************/

  /* DMA event flags must be manually cleared.*/
  dmaStreamClearInterrupt(sdcp->dma);

  SDIO->ICR = STM32_SDIO_ICR_ALL_FLAGS;
  SDIO->DCTRL = 0;
  osalSysUnlock();

  /* Wait until interrupt flags to be cleared.*/
  /*while (((DMA2->LISR) >> (sdcp->dma->ishift)) & STM32_DMA_ISR_TCIF)
    dmaStreamClearInterrupt(sdcp->dma);*/
#else

Ну да, прекрасный образчик лупа: пусть остальные занимаются прерываниями пока мы ждем-с...
И, кстати, а зачем флаги ошибок проверять, когда можно все почистить?
Может у меня не свежая версия или ну фантазии, например, не хватает...

Могу и другие примеры привести...


Если у Вас есть код/образчик многоблоковой записи через DMA, буду очень признателен за возможность ознакомиться: есть вопросы с очередностью операций и, особенно, с флагом FEIE.

Спасибо за ответ.

Сообщение отредактировал pitt - May 8 2015, 00:21


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 8 2015, 04:18
Сообщение #4


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(pitt @ May 8 2015, 05:00) *
Если у Вас есть код/образчик многоблоковой записи через DMA, буду очень признателен за возможность ознакомиться: есть вопросы с очередностью операций и, особенно, с флагом FEIE.

Ссылка на отличные примеры по работе с SDIO: вот. Мне они очень помогли.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 8 2015, 07:44
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(pitt @ May 8 2015, 02:44) *
I don't have issues except sometimes(5%) access time is more than 10 times greater than average. Don't know why but it is. When I'm writing 512 blocks Average speed is the same but lowest is almost 20 times above average.

Это нормально. Многоблочная запись пишет сектора в некоторый буфер (ОЗУ) внутри карты. Когда карта решает, что в нём данных накопилось некоторое кол-во,
она выполняет физическую запись накополенного в буфере. И в конце, при получении Stop Transfer, пишет остаток. В эти моменты и получаете задержки.
Это хорошо видно на осциллограмме: после большинства блоков BUSY короткий, но после некоторых - длинный.
Либо выполняется стирание данных в тех блоках, в которые пойдёт запись. Вы команду ACMD23 перед многоблочной записью выполняете? Я вот не выполнял. Может с ней задержки будут меньше.

Насчёт 512 блоков подряд не очень понял - у меня вроде не было проблем. Хотя надо посмотреть в сторону такого параметра SD-карты как "минимальный стираемый блок" (есть в CSD).
Как я наблюдал на многих картах, он может иметь размер около 64кБ. Может быть с этим связано.

Цитата(pitt @ May 8 2015, 06:00) *
Если у Вас есть код/образчик многоблоковой записи через DMA, буду очень признателен за возможность ознакомиться: есть вопросы с очередностью операций и, особенно, с флагом FEIE.

Я писал для SPI-интерфейса. 2-3 месяца назад (LPC1788). Мой драйвер позволяет пользовательскому уровню работать либо напрямую (операции одноблочного чтения и многоблочного продолженного чтения;
однобочной записи и многоблочной продолженной записи), либо через FatFS. При этом если в ПО есть две задачи, одна из которых обращается напрямую, а другая - через FatFS, то они не будут мешать друг другу. FatFS работает через мой драйвер (он выполняет роль низкоуровневого доступа к SD).
Естественно - никаких ожиданий в глухих лупах нет - используется uCOS и её объекты синхронизации. Более того - есть поддержка работы службы снижения потребления питания
(есть нотификации в службу о периодах работы/простоя драйвера) для возможности ухода в сон устройства.
В моём драйвере передача блоков данных/команд идёт через DMA, ожидание готовности - периодическая программная посылка 0xFF в SPI с прерыванием по приёму с таймаутом.
Вряд-ли Вам чем-то поможет кусок моего исходника, но всё-таки выложу:
CODE
//Переходит сюда после успешного обнаружения и идентификации SD-карты.
//Здесь обрабатываются запросы операций от пользователей SD-сервиса
//прикладного уровня.
static FFaza FazaIdle()
{
SDact act;
u32 i, j, n;
u8 typ;
do {
ILivePing(ILIVE_SD);
act.op = act.OP_NONE;
if (!sdReq) {
IdleBegin(IDLE_READY_SD);
MboxPend(sdMbox, ms2tkt(300));
if (!Pdat(PIN_SD_INSERT)) return (FFaza)FazaIdle;
LogsCR(COL_BLACK "Card removed");
return (FFaza)FazaRestart;
}
} while (!(n = Prepare(&act)));
IdleEnd(IDLE_READY_SD);
MboxAccept(sdMbox);
while (1) {
if (act.op == act.OP_WAIT_READY) StartAct();
else if (act.op == act.OP_TRIM) {
if (cardType <= CARD_MMC) {
sdCompletes[act.user](NULL);
return (FFaza)FazaIdle;
}
#ifdef SD_ARG_CHK
SDassert(act.trim.start <= act.trim.end, REGION_SDREQ_TRIM);
#endif
StartAct();
if ((j = act.trim.start) < sdCapacity) {
j -= j % sdEraseSize;
if (cardType != CARD_SD2_BLOCK) j <<= SD_SECTOR_LEN;
if (SendCmd(CM_SET_ERASE_START, j)) FazaIdleRestart(&act);
if ((j = act.trim.end) >= sdCapacity) j = sdCapacity - 1;
j = j - j % sdEraseSize + sdEraseSize - 1;
if (cardType != CARD_SD2_BLOCK) j <<= SD_SECTOR_LEN;
if (SendCmd(CM_SET_ERASE_END, j)) FazaIdleRestart(&act);
if (SendCmd(CM_ERASE)) FazaIdleRestart(&act);
}
} else if (act.op != act.OP_NONE) break;
sdCompletes[act.user](&act.rw.buf);
SDsselOff();
OffSpi();
return (FFaza)FazaIdle;
}
#ifdef SD_ARG_CHK
SDassert(act.rw.buf && act.rw.sector < sdCapacity &&
act.rw.secOfs < SD_SECTOR_LEN, REGION_SDREQ_RW);
#endif
for (typ = 0; ; ) {
ILivePing(ILIVE_SD);
if ((uint)(act.op - act.OP_READ_1) <= act.OP_READ_N - act.OP_READ_1) {
if (sector != act.rw.sector || !sectorValid) {
while (1) {
if (!typ) if (StartAct()) break;
i = CM_READ_MULTIPLE_BLOCK;
if (n == 1 << SD_SECTOR_LEN && act.op == act.OP_READ_1)
i = CM_READ_SINGLE_BLOCK;
typ = i - CM_READ_MULTIPLE_BLOCK;
u32 jj = act.rw.sector;
if (cardType != CARD_SD2_BLOCK) jj <<= SD_SECTOR_LEN;
if (SendCmd(i, jj)) FazaIdleRestart(&act);
break;
}
if (RcvDataPacket(sh.sectorBuf, 1 << SD_SECTOR_LEN,
ms2tkt(100)) >= 0) break;
sector = act.rw.sector;
sectorValid = 1;
}
i = act.rw.secOfs;
if ((j = (1 << SD_SECTOR_LEN) - i) > n) j = n;
memcpy(act.rw.buf, &sh.sectorBuf[i], j);
if ((i = act.rw.secOfs + j) >> SD_SECTOR_LEN) {
act.rw.sector++;
i = 0;
}
act.rw.secOfs = i;
} else {
i = DataCRC(act.rw.buf, j = 1 << SD_SECTOR_LEN);
while (1) {
if (typ) WaitR1b();
else if (StartAct()) {
WaitR1b();
break;
}
typ = sectorValid = 0;
int ii = CM_WRITE_MULTIPLE_BLOCK;
if (n == 1 << SD_SECTOR_LEN && act.op == act.OP_WRITE_1) {
typ = TOKEN_DATA - TOKEN_DATA_WMB;
ii = CM_WRITE_BLOCK;
}
u32 jj = act.rw.sector;
if (cardType != CARD_SD2_BLOCK) jj <<= SD_SECTOR_LEN;
if (SendCmd(ii, jj)) FazaIdleRestart(&act);
break;
}
if (SndDataPacket(act.rw.buf, j, i, typ + TOKEN_DATA_WMB) !=
SND_PACKET_OK) break;
act.rw.sector++;
}
act.rw.buf += j;
if (n -= j) continue;
while (!(n = sdCompletes[act.user](&act.rw.buf))) {
if (!act.rw.buf) {
if (!PeripheralPowerState(concatAB(PERIPH_PCSSP, nSSP_sd)))
return (FFaza)FazaIdle;
if (!typ) {
if ((uint)(act.op - act.OP_READ_1) > 1) {
WaitR1b();
SndStopTran();
} else if (SendCmd(CM_STOP_TRANSMISSION)) FazaIdleRestart(&act);
}
#ifdef SD_SAFE_WRITE
if ((uint)(act.op - act.OP_WRITE_1) <=
act.OP_WRITE_N - act.OP_WRITE_1) {
WaitR1b();
if (SendCmd(CM_SEND_STATUS)) FazaIdleRestart(&act);
}
#endif //SD_SAFE_WRITE
SDsselOff();
OffSpi();
return (FFaza)FazaIdle;
}
if (!(AtomicSwap(&sdReq, 0) & 1 << SDREQ_START)) do {
MboxPend(sdMbox, ms2tkt(300));
ILivePing(ILIVE_SD);
} while (!sdReq);
sdReq = 1 << SDREQ_BUSY;
MboxAccept(sdMbox);
}
#ifdef SD_ARG_CHK
SDassert(act.rw.buf, REGION_SDREQ_RW);
#endif
}
FazaIdleRestart(&act);
}

union SDact {
enum {
OP_NONE, //нет операции
OP_READ_1, //выполнить чтение цепочки секторов без возможности продолжения
OP_READ_N, //выполнить чтение цепочки секторов с возможностью продолжения
OP_WRITE_1, //выполнить запись цепочки секторов без возможности продолжени
OP_WRITE_N, //выполнить запись цепочки секторов с возможностью продолжения
OP_TRIM, //выполнить стирание цепочки секторов
OP_WAIT_READY, //ожидание освобождения SD-карты (снятия сигнала BUSY)
OP_n};
enum {SD_USER_TERMINAL, SD_USER_FF, SD_USER_n};
struct { //для OP_READ_.., OP_WRITE_..
u8 *buf;
u32 sector;
u16 secOfs;
} rw;
struct { //для OP_TRIM
u32 start, end;
} trim;
struct { //для всех OP_..
u32 unuse0[2];
u16 unuse1;
u8 op, user;
};
};


Данный кусок выполняет приём запросов на операции с SD от прикладных задач, их выполнение, нотификацию источников запросов о завершении
выполнения (или о возможности продолжения выполнения).
Собственно функция SndDataPacket() и выполняет отправку блока записываемых данных через SPI+DMA.
WaitR1b() - ожидание освобождения интерфейса (снятие BUSY картой).
SendCmd() - отсылка команды карте.
Функция Prepare() принимает запрос на операцю с SD от пользовательского уровня.
Собственно со строки for (typ = 0; ; ) { начинается обработка запросов чтения и записи (многоблочных и одноблочных).
Go to the top of the page
 
+Quote Post
pitt
сообщение May 8 2015, 12:30
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672



Цитата(AHTOXA @ May 8 2015, 00:18) *
Ссылка на отличные примеры по работе с SDIO: вот. Мне они очень помогли.

Thank you. I've seen that but didn't find some answers:
Цитата
//Check if the DMA is disabled (SDIO disables the DMA after it is done with it)

Could you please point me where this is in RM?
Код
  //Check if the DMA is disabled (SDIO disables the DMA after it is done with it)
  while (DMA2_Stream3->CR & DMA_SxCR_EN) {};

Very nice loop wub.gif
Код
if (DMA2->LISR & (DMA_LISR_TCIF3 | DMA_LISR_TEIF3 | DMA_LISR_DMEIF3 | DMA_LISR_FEIF3)) {
      if (!(DMA2->LISR & DMA_LISR_TCIF3)) {//A DMA error has occured. Panic!

Always have FEIF set!!! Why? How to get rid of it? Keil example doesn't look at this flag at all.

Thank you for replay though.



Цитата(jcxz @ May 8 2015, 03:44) *

Thank you.



This is the snippet from my code:
Код
void DMA2_Stream3_IRQHandler (void) {
    event_dma = true;
    *(uint8_t *)&dma_isr = DMA2->LISR>>DMA_ISR_STREAM_3;
    if (_sdio->dma_isr != NULL) (*_sdio->dma_isr)(_sdio);
    DMA2->LIFCR &= (DMA_LIFCR_CTCIF3|DMA_LIFCR_CHTIF3|DMA_LIFCR_CTEIF3|DMA_LIFCR_CDMEIF3|DMA_LIF
CR_CFEIF3);
    DMA2_Stream3->CR  &= ~(DMA_SxCR_TCIE |DMA_SxCR_TEIE);
    DMA2_Stream3->FCR &= ~DMA_SxFCR_FEIE;
}

_sdio->dma_isr is NULL
When event_dma is noticed dma_isr has only FEIF set but DMA->LISR has FEIF and TCIF even they both were cleaned in the handler...

Сообщение отредактировал pitt - May 8 2015, 13:23


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 8 2015, 18:31
Сообщение #7


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(pitt @ May 8 2015, 17:30) *
Could you please point me where this is in RM?

31.3.2 SDIO APB2 interface.
Там пример транзакции DMA. Да это и логично, ведь в случае с SDIO у нас периферийный модуль является flow controller-ом.
Цитата(pitt @ May 8 2015, 17:30) *
Very nice loop wub.gif

Ой, да ладно. Понятно же, что это в целях упрощения примера. Никто не мешает включить прерывание и взводить там какой-то флаг.
Цитата(pitt @ May 8 2015, 17:30) *
Always have FEIF set!!! Why? How to get rid of it? Keil example doesn't look at this flag at all.

Посмотрел у себя - я тоже не смотрю на этот флаг.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
pitt
сообщение May 8 2015, 19:42
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672



Цитата(AHTOXA @ May 8 2015, 14:31) *
31.3.2 SDIO APB2 interface.
Там пример транзакции DMA. Да это и логично, ведь в случае с SDIO у нас периферийный модуль является flow controller-ом.

Ой, да ладно. Понятно же, что это в целях упрощения примера. Никто не мешает включить прерывание и взводить там какой-то флаг.

Посмотрел у себя - я тоже не смотрю на этот флаг.

Try this:
Код
/* SDIO Interrupt Handler */
void SDIO_IRQHandler (void) {
  sdio_sta = SDIO->STA;
//  event_sdio = true;
event_sdio++;
//  if (_sdio->dma_isr != NULL) (*_sdio->sdio_isr)(_sdio);  // call back function
  SDIO->ICR = SDIO_ICR_CLEAR_ALL;
}


Before allowed interrupt flags
SDIO->MASK |= (SDIO_MASK_DCRCFAILIE|SDIO_MASK_DTIMEOUTIE|SDIO_MASK_TXUNDERRIE|SDIO_MASK_DATAEN
DIE|SDIO_MASK_STBITERRIE);

Look what event_sdio is? In my case it is 2 and the second time it caused by the DATAEND even as you can see it was CLEARED!!!



Цитата(AHTOXA @ May 8 2015, 14:31) *
Посмотрел у себя - я тоже не смотрю на этот флаг.


This flag is the only one indicates my problem when I'm going over 512 blocks...I was ignoring it before.


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 8 2015, 19:53
Сообщение #9


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(pitt @ May 9 2015, 00:42) *
This flag is the only one indicates my problem when I'm going over 512 blocks...I was ignoring it before.

Я не совсем понял, вы пытаетесь отправить 512 блоков по 512 байт одной транзакцией DMA? Так это не выйдет, счётчик-то (DMA_SxNDTR) 16-битный sm.gif
Как раз 512*512/4 = 0x10000. Не помещается.

Цитата(pitt @ May 9 2015, 00:42) *
Look what event_sdio is? In my case it is 2 and the second time it caused by the DATAEND even as you can see it was CLEARED!!!

Попробуйте добавить барьер после очистки флагов:
Код
SDIO->ICR = SDIO_ICR_CLEAR_ALL;
__DSB();


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
pitt
сообщение May 8 2015, 20:22
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672



Цитата(AHTOXA @ May 8 2015, 15:53) *
Я не совсем понял, вы пытаетесь отправить 512 блоков по 512 байт одной транзакцией DMA? Так это не выйдет, счётчик-то (DMA_SxNDTR) 16-битный sm.gif
Как раз 512*512/4 = 0x10000. Не помещается.


Попробуйте добавить барьер после очистки флагов:
Код
SDIO->ICR = SDIO_ICR_CLEAR_ALL;
__DSB();


Thanks for the first tip - forgot...
Wait a minute. We're using SDIO_DLEN and it is 24 bit. Please point me out where it says that DMA limits the size of transaction.

__DSB(); doesn't help the problem is a second DATAEND interrupt.

Код
/* SDIO Interrupt Handler */
void SDIO_IRQHandler (void) {
  sdio_sta = SDIO->STA;
  event_sdio = true;
  if (_sdio->dma_isr != NULL) (*_sdio->sdio_isr)(_sdio);
  SDIO->MASK &= ~SDIO_MASK_DATAENDIE;    // WTF???
  SDIO->ICR = SDIO_ICR_CLEAR_ALL;
}


That is how it works

Сообщение отредактировал pitt - May 8 2015, 20:38


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 8 2015, 20:44
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Тоже хочу делать роботов на гусенках.... даже могу сд карту осилить
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 9 2015, 06:04
Сообщение #12


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(pitt @ May 9 2015, 01:22) *
Wait a minute. We're using SDIO_DLEN and it is 24 bit. Please point me out where it says that DMA limits the size of transaction.

Явного указания не припоминаю, но с точки зрения здравого смысла - если периферийный модуль является flow controller-ом, то это не значит, что подконтрольный модуль DMA сможет передавать больше данных. Скорее всего, SDIO_DLEN просто как-то управляет значением DMA_SxNDTR.
Кстати, вы легко можете проверить эту теорию - запустите транзакцию на, скажем, 20 секторов, и в прерывании DMA Half-transfer посмотрите значение DMA_SxNDTR. Если там будет половина от начального значения SDIO_DLEN, то всё так и есть.
Цитата(pitt @ May 9 2015, 01:22) *
__DSB(); doesn't help the problem is a second DATAEND interrupt.

У меня там стоит запрещение прерывания от SDIO, так что я не вижу повторного вхождения.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 9 2015, 11:20
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Golikov A. @ May 9 2015, 02:44) *
Тоже хочу делать роботов на гусенках.... даже могу сд карту осилить

Так делайте. Кто-ж Вам мешает wink.gif
А кстати - зачем на гусенках SD???
Go to the top of the page
 
+Quote Post
pitt
сообщение May 9 2015, 12:10
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672



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

Цитата(AHTOXA @ May 9 2015, 02:04) *
Явного указания не припоминаю

У меня там стоит запрещение прерывания от SDIO, так что я не вижу повторного вхождения.

Отвратительная документация.
Вы можете разрешить и убедиться. К тому же, прерывания по DMA_SxCR_EN нет, а вот, похоже, именно оно и необходимо. Если Вы в DMA разрешите прерывание по FEIE, но тоже увидете повторное вхождение.
Код
/* DMA Interrupt Handler */
#if   defined  SDIO_DMA_STREAM3
void DMA2_Stream3_IRQHandler (void) {
//  if (DMA2_Stream3->CR & DMA_SxCR_EN) DMA2->LIFCR &= (DMA_LIFCR_CTCIF3|DMA_LIFCR_CHTIF3|DMA_LIFCR_CTEIF3|DMA_LIFCR_CDMEIF3|DMA_LIF
CR_CFEIF3);
//  else {
    event_dma = true;
    *(uint8_t *)&dma_isr = DMA2->LISR>>DMA_ISR_STREAM_3;
    if (_sdio->dma_isr != NULL) (*_sdio->dma_isr)(_sdio);
    DMA2->LIFCR &= (DMA_LIFCR_CTCIF3|DMA_LIFCR_CHTIF3|DMA_LIFCR_CTEIF3|DMA_LIFCR_CDMEIF3|DMA_LIF
CR_CFEIF3);
    DMA2_Stream3->CR  &= ~(DMA_SxCR_TCIE |DMA_SxCR_TEIE);
    DMA2_Stream3->FCR &= ~DMA_SxFCR_FEIE;
//  }
}

Раскомментируйте и полюбуйтесь.

Кристалл сложный, ошибки неизбежны, но ведь можно их хорошо задокументировать, а их errata &^%$#@!

Цитата(jcxz @ May 9 2015, 07:20) *
А кстати - зачем на гусенках SD???

DVR. А само изделие(без манипулятора) 2006-2008 года на 2-3х AT90CAN64(в зависимости от комплектации) и паре AT90PWM316 именно для привода.


Сообщение отредактировал pitt - May 9 2015, 12:06


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post
pitt
сообщение May 10 2015, 14:49
Сообщение #15


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672



Цитата(AHTOXA @ May 8 2015, 15:53) *
Я не совсем понял, вы пытаетесь отправить 512 блоков по 512 байт одной транзакцией DMA? Так это не выйдет, счётчик-то (DMA_SxNDTR) 16-битный sm.gif
Как раз 512*512/4 = 0x10000. Не помещается.

По-видимому, Вы правы, но 512*512 = 2^9 * 2^9 = 2^18 = 2^16 * 4, т.е 2 в степени 16 32-битных значений. И это получается, а вот >512 блоков не проходит и получается правдивость Вашей гипотезы.

Сообщение отредактировал pitt - May 11 2015, 02:20


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 10 2015, 14:58
Сообщение #16


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Да, конечно же я имел в виду, что больше 512 блоков не получится.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
pitt
сообщение May 11 2015, 02:21
Сообщение #17


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672



Цитата(AHTOXA @ May 10 2015, 10:58) *
Да, конечно же я имел в виду, что больше 512 блоков не получится.

Хорошо бы, если об этом упоминалось в мануале...

А что будем с FEIF делать? И с повторными вхождениями? Терпеть не могу недодокументированность... Можно, конечно, ограничить число блоков величиной 512 и тогда, вроде, можно обойтись без FEIF, но нет документированных оснований.

Скажите, а поддрежка со стороны STM в Европе такая же архипрехреновая как и в Новом Свете?

Сообщение отредактировал pitt - May 11 2015, 02:40


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 11 2015, 09:40
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



они торопятся с чипами, так что их не хватает, ошибки не успевают обслуживать, а вы неточности от них ждете)...

если поглядеть просторы интернета
FEIF - про этот флаг многие говорят, и многие сходятся к простому его игнорированию.

в описании я нашел вот что
Цитата
Caution is required when choosing the FIFO threshold (bits FTH[1:0] of the DMA_SxFCR
register) and the size of the memory burst (MBURST[1:0] of the DMA_SxCR register): The
content pointed by the FIFO threshold must exactly match to an integer number of memory
burst transfers. If this is not in the case, a FIFO error (flag FEIFx of the DMA_HISR or
DMA_LISR register) will be generated when the stream is enabled, then the stream will be
automatically disabled. The allowed and forbidden configurations are described in the
Table 48: FIFO threshold configurations.

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

Go to the top of the page
 
+Quote Post
pitt
сообщение May 11 2015, 17:02
Сообщение #19


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672



Цитата(Golikov A. @ May 11 2015, 05:40) *
...если поглядеть просторы интернета
FEIF - про этот флаг многие говорят, и многие сходятся к простому его игнорированию.

Links please.
Цитата(Golikov A. @ May 11 2015, 05:40) *
в описании я нашел вот что
дальше табличка идет запрещенных конфигураций, может с ней свериться... в ней больше запрещено чем разрешено...


The mode we're using (the last one on the page 315) is allowed, so the question still remains: why do I get stupid FEIF?!
Why STM doesn't clarify this issue? Well, one can ask many more rhetorical questions but the main one is always: Who needs rhetorical questions?!

Сообщение отредактировал pitt - May 12 2015, 01:29


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 12 2015, 04:06
Сообщение #20


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(pitt @ May 11 2015, 07:21) *
Можно, конечно, ограничить число блоков величиной 512 и тогда, вроде, можно обойтись без FEIF, но нет документированных оснований.

Вот, самое оптимальное решение. Всё равно в реальной жизни вам вряд-ли потребуется передавать более 512 блоков за раз. А попытки найти истину (документальные обоснования, ответы от техподдержки) в этом случае - просто непроизводительные потери времени. ИМХО конечно.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 12 2015, 05:01
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



ссылки...
ну типа
http://forum.easyelectronics.ru/viewtopic....69&start=75


если писать в разных вариантах сочетания
STM DMA FEIF SDIO то выпадают разные темы, в каких то люди просто не так запускали и получали ошибку, но попадаются как ваша, где концов появления не нашли...
Go to the top of the page
 
+Quote Post
pitt
сообщение May 12 2015, 10:38
Сообщение #22


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672



Проблема в том, что я не могу просимулировать ошибки. Пока только одна - запись более 512 блоков - проявляется надежно и она только выявляется через FEIF. Так как пишу прямиком с камеры JPG без проблем превышает 512 блоков... Когда и при каких обстоятельствах возникают другие ошибки...
С работы опубликую ВЕСЬ тестовый проект. Давайте вместе доведем до ума. Да, никаких их HAL или библиотек, все сам - за проблемы не им отвечать.

Сообщение отредактировал pitt - May 12 2015, 12:29
Прикрепленные файлы
Прикрепленный файл  sdio.zip ( 5.47 килобайт ) Кол-во скачиваний: 10
 


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 26th June 2025 - 01:47
Рейтинг@Mail.ru


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