Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
11 / 11 / 2
Регистрация: 15.08.2011
Сообщений: 448

F407 и SDIO

13.11.2022, 21:13. Показов 725. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Проблема с микро SD, при записи данных при помощи DMA на носитель, выскакивает ошибка
FEIF3: Stream FIFO error interrupt flag
Писал на регистрах думал может у меня косяк, использовал HAL та же самая ошибка
SD карты пробовал разные тоже самое.
Может кто сталкивался?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
13.11.2022, 21:13
Ответы с готовыми решениями:

Проблема с I2S на F407
День добрый. Пробую запустить I2S на STMF407. Использую HAL. Проблема в том, что данные передаются ровно в два раза медленнее, чем это...

[РЕШЕНО]Проблемы с UART на F407 (дискавери)
Привет всем :) Вот понадобилось поработать с UART на F407. Набросал тестовую программку. Там передача байта, приём через прерывание,...

LPC43xx + SDIO
Всем привет, заранее извиняюсь, но может кто-нибудь подкинет рабочий пример для реализации SDIO на lpc43xx? В примерах вместе с CMSIS...

6
11 / 11 / 2
Регистрация: 15.08.2011
Сообщений: 448
14.11.2022, 09:18  [ТС]
И если сразу после записи, читать то зависает на
C++
1
while(!(DMA2->LISR & DMA_LISR_TCIF3));
0
61 / 186 / 31
Регистрация: 14.02.2013
Сообщений: 1,695
14.11.2022, 09:19
Может быть в не соответствии типов при обращении к адресу в памяти.
0
11 / 11 / 2
Регистрация: 15.08.2011
Сообщений: 448
14.11.2022, 11:49  [ТС]
C++
1
while(SDIO->STA & SDIO_STA_RXACT);
Вот так ушёл от проблемы, но странно всё это

Добавлено через 15 минут
может кому пригодиться
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
void Sdio::initLowLevel(void)
{
 /* Enable clock */
 RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;                                          // Port C clock
 RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;                                            // Port D clock
 RCC->APB2ENR |= RCC_APB2ENR_SDIOEN;                                           // SDIO clock
 RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;                                             // DMA2 clock
 /* Port config */
 GPIOC->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR12 | GPIO_OSPEEDER_OSPEEDR11           // Set speed, OSPEED 11 - very high speed
                   | GPIO_OSPEEDER_OSPEEDR10 | GPIO_OSPEEDER_OSPEEDR9
                   | GPIO_OSPEEDER_OSPEEDR8;
 GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR2;                                     // Set speed, OSPEED 11 - very high speed
 GPIOC->AFR[1] |= (12 << GPIO_AFRH_AFSEL12_Pos) |( 12 << GPIO_AFRH_AFSEL11_Pos)// AF12
               |    (12 << GPIO_AFRH_AFSEL10_Pos) | (12 << GPIO_AFRH_AFSEL9_Pos)
                             | (12 << GPIO_AFRH_AFSEL8_Pos); 
 GPIOD->AFR[0] |= (12 << GPIO_AFRL_AFSEL2_Pos);                                // AF12  
 GPIOC->PUPDR |= GPIO_PUPDR_PUPD11_0 | GPIO_PUPDR_PUPD10_0                     // Set pull up
               | GPIO_PUPDR_PUPD9_0 | GPIO_PUPDR_PUPD8_0;
 GPIOD->PUPDR |= GPIO_PUPDR_PUPD2_0;                                           // Set pull up
 GPIOC->MODER |= GPIO_MODER_MODE12_1 | GPIO_MODER_MODE11_1                     // Alternate function, MODER 10
                 | GPIO_MODER_MODE10_1 | GPIO_MODER_MODE9_1 
                 | GPIO_MODER_MODE8_1;        
 GPIOD->MODER |= GPIO_MODER_MODE2_1;                                           // Alternate function, MODER 10
 /* SDIO config*/ 
 SDIO->CLKCR = SDIO_CLKCR_CLKEN | 0x76;                                        // SDIO_CK is enabled, Clock = 48000 / (118+2) = 400Khz
 SDIO->POWER = SDIO_POWER_PWRCTRL;                                             // Power-on: the card is clocked
 /* DMA config */
 DMA2_Stream3->CR = DMA_SxCR_CHSEL_2 | DMA_SxCR_MBURST_0 | DMA_SxCR_PBURST_0   // Chanel 4, INCR4 (incremental burst of 4 beats)
                   | DMA_SxCR_PL | DMA_SxCR_MSIZE_1 | DMA_SxCR_PSIZE_1         // Priority level very high, size word (32-bit)
                                     | DMA_SxCR_MINC | DMA_SxCR_PFCTRL;                          // Memory increment mode, peripheral flow controller   
 DMA2_Stream3->PAR = (uint32_t)&(SDIO->FIFO);                                  // Set address periphery 
 DMA2_Stream3->FCR |= DMA_SxFCR_DMDIS | DMA_SxFCR_FTH;                         // Direct mode disable, full FIFO
}
 
 
bool Sdio::init(void)
{
 uint32_t wait = 0x0000FFFFU;
 uint16_t rca;
 uint32_t resp;
 initLowLevel();
 /* Identify card operating voltage */
 sendCmd(CMD_0, 0U, RESP_NONE);                                                // GO_IDLE_STATE
 if(sendCmd(CMD_8, 0x000001AAU, RESP_SHORT) != SDIO_STA_CMDREND) sendCmd(CMD_0, 0U, RESP_NONE); // CMD8 verify SD card interface operating condition
 while(wait--)
          {
       if(sendCmd(CMD_55, 0U, RESP_SHORT) != SDIO_STA_CMDREND) return 0;       // CMD55 APP_CMD with RCA as 0 
             if(!getResp()) return 0; 
             sendCmd(CMD_41, 0xC1100000U, RESP_SHORT);                               // CMD41
             getResp(RESP_R3, &resp);
             if((resp >> 31) == 1) break;                                            // Check if card finished power up routine
            }   
 /* Card initialization */   
 if(sendCmd(CMD_2, 0U, RESP_LONG) != SDIO_STA_CMDREND) return 0;               // CMD 2 get CID registr
 if(sendCmd(CMD_3, 0U, RESP_SHORT) != SDIO_STA_CMDREND) return 0;              // CMD 3 get RCA
 if(!getResp(RESP_R6, &resp)) return 0; 
 rca = resp >> 16;
 if(sendCmd(CMD_7, rca << 16, RESP_SHORT) != SDIO_STA_CMDREND) return 0;       // CMD 7
 if(!getResp()) return 0;
 SDIO->CLKCR = SDIO_CLKCR_CLKEN;                                               // Clock enable, full speed          
 if(sendCmd(CMD_55, rca << 16, RESP_SHORT) != SDIO_STA_CMDREND) return 0;      // CMD 55    
 if(!getResp()) return 0;   
 if(sendCmd(CMD_6, 2U, RESP_SHORT) != SDIO_STA_CMDREND) return 0;              // Send CMD6  with argument as 2 for wide bus mode, 4-wide 
 if(!getResp()) return 0;   
 SDIO->CLKCR = SDIO_CLKCR_WIDBUS_0 | SDIO_CLKCR_CLKEN;                         // 4-wide bus mode, clock enadle 
 if(sendCmd(CMD_16, BLOCKSIZE, RESP_SHORT) != SDIO_STA_CMDREND) return 0;      // CMD 16, set 512 bytes block 
 if(!getResp()) return 0;
 return 1;   
}
    
 
uint32_t Sdio::sendCmd(uint32_t cmd, uint32_t arg, uint32_t resp) 
{
 SDIO->ICR = SDIO_STATIC_FLAGS;                                                                // Clear flag    
 SDIO->ARG = arg;                                                                              // Command argument value
 SDIO->CMD = SDIO_CMD_CPSMEN | (resp << SDIO_CMD_WAITRESP_Pos) | cmd;                          // Write CMD 
 if(resp) while(!(SDIO->STA & (SDIO_STA_CTIMEOUT | SDIO_STA_CMDREND | SDIO_STA_CCRCFAIL)) || (SDIO->STA & SDIO_STA_CMDACT)); // Wait
 else while(!(SDIO->STA & (SDIO_STA_CTIMEOUT | SDIO_STA_CMDSENT)) || (SDIO->STA & SDIO_STA_CMDACT));                         // Wait 
 return SDIO->STA; 
}
 
 
bool Sdio::getResp(uint8_t respType, uint32_t *resp) 
{
 *resp = SDIO->RESP1;
 switch(respType) 
           {
          case RESP_R2:
                   resp++;
                     *resp++ = SDIO->RESP2;
                     *resp++ = SDIO->RESP3;
                     *resp   = SDIO->RESP4;
              break;
                case RESP_R3:    
                     if(SDIO->RESPCMD != 0x3F) return 0;
                break;
          case RESP_R6:
                   if(SDIO->RESPCMD != 0x03) return 0;
              break;
                case RESP_R7:
                       if(SDIO->RESPCMD != 0x08) return 0;
                break;
       }
 return 1;
}
 
 
bool Sdio::getResp(void)
{   
 return !(SDIO->RESP1 & 0xFDFFE008U);
}   
 
 
bool Sdio::readBlocks(uint8_t *data, uint32_t addr, uint32_t num) 
{
 /* DMA RX config */
 DMA2->LIFCR |= DMA_LIFCR_CTCIF3;                                              // Clear flag DMA event
 DMA2_Stream3->M0AR = (uint32_t)data;                                          // Set address buf
 DMA2_Stream3->NDTR = (BLOCKSIZE * num) / 4U;                                  // Set len
 DMA2_Stream3->CR &= ~ DMA_SxCR_DIR_0;                                         // Peripheral to memory
 DMA2_Stream3->CR |= DMA_SxCR_EN;                                                  // Enable DMA
 /* SDIO config */  
 SDIO->DLEN = BLOCKSIZE * num;                                                 // Set len
 SDIO->DTIMER = DATA_TIME_OUT;                                                 // Set time out
 SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0               // Data block size 512 bytes
               | SDIO_DCTRL_DMAEN | SDIO_DCTRL_DTDIR | SDIO_DCTRL_DTEN;          // DMA enable, direct card to controller, data transfer enabled  
 /* Send read command */
 if(num > 1) sendCmd(CMD_18, addr * BLOCKSIZE, RESP_SHORT);                    // CMD 18 send read multi block command
 else   sendCmd(CMD_17, addr * BLOCKSIZE, RESP_SHORT);                           // CMD 17 send read single block command  
 if(!getResp()) return 0;   
 while(SDIO->STA & SDIO_STA_RXACT);                                            // Wait transmit all data
 return 1;  
}
 
 
bool Sdio::writeBlocks(uint8_t *data, uint32_t addr, uint32_t num)
{
 /* Send write command */
 if(num > 1) sendCmd(CMD_25, addr * BLOCKSIZE, RESP_SHORT);                    // CMD 25 send write multi block command
 else   sendCmd(CMD_24, addr * BLOCKSIZE, RESP_SHORT);                           // CMD 24 send write single block command  
 if(!getResp()) return 0;
 /* DMA TX config */
 DMA2->LIFCR |= DMA_LIFCR_CTCIF3;                                              // Clear flag DMA event
 DMA2_Stream3->M0AR = (uint32_t)data;                                          // Set address buf
 DMA2_Stream3->NDTR = (BLOCKSIZE * num) / 4U;                                  // Set len
 DMA2_Stream3->CR |= DMA_SxCR_DIR_0;                                             // Memory to peripheral
 DMA2_Stream3->CR |= DMA_SxCR_EN;                                                  // Enable DMA 
 /* SDIO config */  
 SDIO->DLEN = BLOCKSIZE * num;                                                 // Set len
 SDIO->DTIMER = DATA_TIME_OUT;                                                 // Set time out
 SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0               // Data block size 512 bytes
               | SDIO_DCTRL_DMAEN | SDIO_DCTRL_DTEN;                               // DMA enable, direct controller to card, data transfer enabled 
 while(SDIO->STA & SDIO_STA_TXACT);                                            // Wait transmit all data
 return 1;  
}
0
11 / 11 / 2
Регистрация: 15.08.2011
Сообщений: 448
16.11.2022, 14:10  [ТС]
Странно но данные быстрее записываются, чем считываются с SD, хоть с использованием DMA или без него
Code
1
2
3
4
5
6
7
8
9
Start
INIT OK
READ:
without DMA 70
with DMA 68
WRITE:
without DMA 16
with DMA 27
END
0
61 / 186 / 31
Регистрация: 14.02.2013
Сообщений: 1,695
16.11.2022, 14:50
У STM32F память очень иедлинная.
0
75 / 66 / 12
Регистрация: 09.02.2016
Сообщений: 907
Записей в блоге: 16
16.11.2022, 18:50
Цитата Сообщение от Korbofos Посмотреть сообщение
Странно но данные быстрее записываются, чем считываются с SD
просто при записи скорее всего сначала идет запись в буфер карты, потому это так быстро происходит... а потом происходит запись (и она на самом деле очень медленная)

а чтение - чтение идет с той скоростью что можно получить с карты...и эти цифры реальные...
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
16.11.2022, 18:50
Помогаю со студенческими работами здесь

SDIO + STM32F429
Доброго времени суток всем! Столкнулся с проблемой при записи на SD карту &quot;мультиблочном&quot; режиме. Запись в &quot;одноблочном&quot;...

SDIO+bypass
Доброго времени суток всем! Освоил SDIO, но осталась одна загвоздка. Это bypass режим. Т.е. частота 48 МГц при работе с картой. Включаю...

SDIO STM32F4
Доброго времени суток, уважаемые формучане! Сразу оговорюсь, что вопрос адресован тем, кто пользуется либами и уже занимался SDIO. ...

SDIO+FAT
Добрый день! Столкнулся с непонятной проблемой. С АЦП приходят данные и складываются в циклический буфер. Из циклического буфера данные...

SDIO + SD + STM32F103
Доброго всем утра. Столкнулся с проблемой при работе с micro SD через SDIO. Вываливается ошибка SD_CMD_RSP_TIMEOUT. Теперь по порядку. У...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru