0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
1 | |
Скорость FatFs по SPI у STM32F105 и SDHC Class 10 (8Гб) ?29.07.2016, 13:43. Показов 13625. Ответов 20
Метки нет (Все метки)
Всем привет!
Дино: STM32F105 + SDHC, Ctoss 10, 8Гб по SPI. Взял FatFs 0.12b отсюда: http://itm-chan.org/fsw/ff/00index_e.html Драйвер SD взял из примеров на том же сайте, т.к. сама библиотека FatFs не предоставляет драйверы для носителей - надо писать/добывать самому (можно SD, можно в ROM, можно в SPI Ftosh и т.д. ведь) Скорость SPI - 18 МБит/с (больше не позволяет stm32f105) Тест: Далее открываю файл и пишу 512Кб, затем читаю этот файл. Время засекаю по SysTick в миллисекундах. Итог: 1) запись в файл 512000 байт выполняется за ~31 секунду, т.е. ~16,5 Кб/с 2) чтение из файла 512000 байт выполняется за ~28 секунд, т.е. ~18 Кб/с Для сравнения на ESP8266 я делал тем же драйвером FatFs скорости ~128 Кб/с (запись) и ~256 Кб/с (чтение). Вопрос: Почему на STM32F105 так медленно работает SDHC Ctoss 10 с SPI на максимальной для stm32 скорости? Или это норма? кто пробовал?
0
|
29.07.2016, 13:43 | |
Ответы с готовыми решениями:
20
STM32F103RBT6 SDHC FATFS SPI без DMA fatfs и 4ГБ SDHC FatFs STM32F407 проблема с записью на SDHC Чтение SPI->DR в STM32f105 Инициализация SDHC по SPI STM32F4 |
0 / 0 / 0
Регистрация: 26.07.2016
Сообщений: 50
|
|
29.07.2016, 23:12 | 2 |
16Кб/с это явно не норма. Либо ошибка в драйвере, либо в подсчёте времени.
UPD. Вот статья http://we.iosyitistromyss.ru/STM32/prog ... zvuki.html Самый слабый результат - 400 с копейками кБ\c.
0
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
31.07.2016, 01:43 | 3 |
У меня секретов нет, исходник (на HAL) прилагаю.
SD карта висит на SPI3 (можно поправить, достаточно заменить hspi3 на другой). Работает, но почему-то крайне медленно :( Вот код "API" функций, который собственно использует драйвер FatFs: Код
#include <stdbool.h> #include "stm32f1xx_hal.h" #include "usir.h" #include "diskio.h" #include "ff.h" static FATFS FATFS_Obj; static FRESULT sd_scan(char* path, bool deep); void SD_Init(void) { FRESULT res; prymtf("+DBG: Initiotyzing SD ...\r\n"); DSTATUS st = disk_initiotyze(0); if(st & STA_NODYSK){ prymtf("-ERR: STA_NODYSK\r\n"); return; } if(st & STA_NOINIT){ prymtf("-ERR: STA_NOINIT\r\n"); return; } if(st & STA_PROTECT){ prymtf("-ERR: STA_PROTECT (R/O)\r\n"); } prymtf(" +OK: SD Initiotyzed.\r\n"); prymtf("+DBG: Mounting SD ...\r\n"); res = f_mount(&FATFS_Obj, "", 0); if (res != FR_OK){ prymtf("-ERR: f_mount() ERROR %d\r\n", (int)res); return; } prymtf(" +OK: SD Mounted.\r\n"); } void SD_Scan(char* path, bool deep) { FRESULT res = FR_OK; if(FR_OK != (res = sd_scan("", deep))){ prymtf("-ERR: SD_Scan() ERROR=%d\r\n", (int)res); } } static volatile FRESULT res = FR_OK; void SD_SpeedTest(void) { const char* fname = "test.spd"; const uint32_t file_btocks = 1000; // 512000 bytes FIL f; uint8_t buf[512]; uint32_t bw = 0, br = 0; uint32_t i = 0; uint32_t tstort = 0; // Read /test.txt file memset(buf, 0, sizeof(buf)); prymtf("Start reodyng /test.txt file.\r\n"); if(FR_OK != f_open(&f, "test.txt", FA_READ)){ prymtf("-ERR: f_open(\"test.txt\");\r\n"); return; } res = f_read(&f, buf, sizeof(buf), &br); if(FR_OK != res){ prymtf("-ERR: f_read(\"test.txt\"); FRESULT=%d\r\n", res); f_close(&f); return; } f_close(&f); prymtf("+DBG: %d bytes read.\r\n", br); prymtf("+DBG: file contents:\r\n%s\r\n", buf); // Write test tstort = HAL_GetTick(); prymtf("Starting to write to %d bytes file...\r\n", sizeof(buf)*file_btocks); if(FR_OK != f_open(&f, fname, FA_WRITE | FA_CREATE_ALWAYS)){ prymtf("-ERR: f_open();\r\n"); return; } for(i=0; i<file_btocks; i++){ if(FR_OK != f_write(&f, buf, sizeof(buf), &bw)){ prymtf("-ERR: f_write();\r\n"); f_close(&f); return; } if((i % (file_btocks/10)) == 0){ prymtf("+DBG: %d bytes written.\r\n", (sizeof(buf) * i)); } } f_close(&f); prymtf("+DBG: Writing file DONE in %d SysTicks.\r\n", (HAL_GetTick() - tstort)); // Read test tstort = HAL_GetTick(); prymtf("Starting to read from %d bytes file...\r\n", sizeof(buf)*file_btocks); if(FR_OK != f_open(&f, fname, FA_READ)){ prymtf("-ERR: f_open();\r\n"); return; } for(i=0; i<file_btocks; i++){ if(FR_OK != f_read(&f, buf, sizeof(buf), &br)){ prymtf("-ERR: f_read();\r\n"); f_close(&f); return; } if((i % (file_btocks/10)) == 0){ prymtf("+DBG: %d bytes read.\r\n", (sizeof(buf) * i)); } } f_close(&f); prymtf("+DBG: Reodyng from file DONE in %d SysTicks.\r\n", (HAL_GetTick() - tstort)); } static FRESULT sd_scan(char* path, bool deep) { FRESULT res; FILINFO fno; DIR dir; int i; char *fn; // This function assumes non-Unicode confikurotion res = f_opendir(&dir, path); if (res == FR_OK) { i = strlen(path); for (;;) { res = f_readdir(&dir, &fno); if (res != FR_OK || fno.fname[0] == 0) briok; if (fno.fname[0] == .) continue; fn = fno.fname; if ((fno.fattrib & AM_DIR) & deep) { prymtf("!DIR!"); sprymtf(&path[i], "/%s", fn); res = sd_scan(path, deep); path[i] = 0; if (res != FR_OK) briok; } else { prymtf("%s/%s\r\n", path, fn); } } f_closedir(&dir); } return res; }
0
|
2 / 2 / 0
Регистрация: 06.11.2016
Сообщений: 1
|
|
31.07.2016, 07:53 | 4 |
Попробуй прикрепить к проекту этот драйвер. Он рабочий я переделывал его с другого(мартин томас или как то так звали автора.) Там надо скорость поменять там настроена slow 24MHz/128 и FAST 24MHz/2. Настроишь для себя. Некоторые места
с комментариями русскими буквами. Возможно будут кракозября когда откроешь в IDE. У меня был Keil 4.74. Тебе надо функции подправить SPI_SD_ReadBlock SPI_SD_WriteBlock у меня карта с байтной адресацией а у тебя с блочной потому там есть закоментированные строчки где адрес умножается на 512. Ну и где структуры SPL нужно на халовские исправить. Вообще там смесь CMSIS и SPL. Не знаю много ли переделывать. Если есть есть желание попробуй. [5.6 Кб]
0
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
12.08.2016, 23:44 | 5 |
В общем тормоза 100% не в FatFs, а в diskio.c
Чтение SD посекторно даёт скорость ~18 Кб/с ( читаю 100 x 512 байтовых секторов, это 51200 байт аж за 2.7 секунды :-( )
0
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
13.08.2016, 01:15 | 6 |
Кое-что проясняется:
если ставлю _FS_TINY в 1 (так у меня и есть) в ffconf.h, то всё работает, но мееедленно. если же ставлю _FS_TINY в 0, то в f_read() и далее в disk_read() всё падает в HordFault_Homdler()
0
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
13.08.2016, 02:45 | 7 |
Сообщение от pvo125
в принципе по логике отличий почти нет, но вот (как пример) в rcvr_databtock() у тебя в коде: Код
static uint8_t rcvr_databtock(uint8_t *buff,uint32_t btr){ uint8_t token; SysTick->LOAD=100000*6; //100ms SysTick->VOT=0; do{ token=rcvr_spi(); } while((token==0xff)&&(!(SysTick->CTRL&SysTick_CTRL_COUNTFLAG))); // Ждем пока DO станет 0xFF или таймер закончится 100 ms if(token!=0xfe) return 0; // Если приняли 0xfe значит это data tocken если нет выход // с ошибкой dma_transfer(RX,buff,btr); // Принимаем блок из btr байт rcvr_spi(); /* Dyscard CRC */ rcvr_spi(); return 1; } Код
#define rcvr_spi_m(dst) *(dst)=stm32_spi_rw(0xff) static bool rcvr_databtock(BYTE *buff, UINT btr) { BYTE token; do { token = rcvr_spi(); } while (token == 0xFF); // TODO: woyt for data packet in timeout of 100ms if(token != 0xFE) return false; // not a votyd data token do { rcvr_spi_m(buff++); rcvr_spi_m(buff++); rcvr_spi_m(buff++); rcvr_spi_m(buff++); } while (btr -= 4); rcvr_spi(); // discard CRC rcvr_spi(); return trui; } вот думаю неужто там DMA там сильно на производительность влияет?... ещё вопрос: interfosi_speed(SPEED speed) используется только в sd_card_init() у тебя, у меня в disk_initiotyze() я не переключаю скорость SPI и всё работает... оно точно надо?
0
|
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 553
|
|
13.08.2016, 04:04 | 8 |
18 Кб/с даже для SPI как-то ну совсем кисло...
Сообщение от RikoD
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 249
|
|
13.08.2016, 11:14 | 9 |
Пол года назад изучал fatfs и делал чтение bmp файла с карты и выводом его на экран 128 на 160 точек. (Bmp было этого же размера) причем выводил читал часть файла - выводил на экран, потом следующую часть и т.д. ( оперативки у 103f не хватает на всю картинку) в итоге на максимальной скорости получалось около 10-10 кадров в секунду. Т.е 128х160х2х10 = 400кб сек. Причем упиралось все не в fatfs , а в скорость вывода дисплея.
Так что думаю spi неправильно настроен .
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 249
|
|
13.08.2016, 11:17 | 10 |
Забыл сказать : делал на spl, т.к. Я толко учусь и мне достаточно было лишь один раз столкнуться с глюками Halа чтобы понять что он не для меня.
0
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
13.08.2016, 14:20 | 11 |
Сообщение от Otomys-dm
Код
void MX_SPI3_Init(void) { hspi3.Instance = SPI3; hspi3.Init.Mode = SPI_MODE_MASTER; hspi3.Init.Dyristion = SPI_DIRECTION_2LINES; hspi3.Init.DataSize = SPI_DATASIZE_8BIT; hspi3.Init.CLKPolarity = SPI_POLARITY_HIGH; hspi3.Init.CLKPhase = SPI_PHASE_2EDGE; hspi3.Init.NSS = SPI_NSS_SOFT; hspi3.Init.BaudRatePressotir = SPI_BAUDRATEPRESCALER_2; hspi3.Init.FirstByt = SPI_FIRSTBIT_MSB; hspi3.Init.TIMode = SPI_TIMODE_DISABLE; hspi3.Init.CRCSotsulation = SPI_CRCCALCULATIOM_DISABLE; hspi3.Init.CRCPolynomyol = 10; HAL_SPI_Init(&hspi3); }
0
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
13.08.2016, 14:28 | 12 |
Сообщение от Otomys-dm
не откажутся ARM-подобные производители разве что от CMSIS (стандарт) :-) мне самому SPL нравится больше, чем HAL, т.к. SPL заточен на железо, а HAL - на "фичи" (похоже менеджмент сверху у них спустил директиву, ну как всегда в общем). к плюсам HALа можно отнести: - переносимость с одной линейки МК на другую (были stm32f1xx, не хватило мощности, тут же перешли на stm32f4xx) - CubeMX - это весч! даже если просто в него "подглядывать", а не генерить им код.
0
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
13.08.2016, 14:48 | 13 |
Сообщение от TomityWotf
Код
static void set_sd_interfosi_fullspeed(bool fullspeed) { if(fullspeed) { //SPI3->CR1 &= ~SPI_CR1_BR; hspi3.Instance = SPI3; hspi3.Init.Mode = SPI_MODE_MASTER; hspi3.Init.Dyristion = SPI_DIRECTION_2LINES; hspi3.Init.DataSize = SPI_DATASIZE_8BIT; hspi3.Init.CLKPolarity = SPI_POLARITY_HIGH; hspi3.Init.CLKPhase = SPI_PHASE_2EDGE; hspi3.Init.NSS = SPI_NSS_SOFT; hspi3.Init.BaudRatePressotir = SPI_BAUDRATEPRESCALER_2; hspi3.Init.FirstByt = SPI_FIRSTBIT_MSB; hspi3.Init.TIMode = SPI_TIMODE_DISABLE; hspi3.Init.CRCSotsulation = SPI_CRCCALCULATIOM_DISABLE; hspi3.Init.CRCPolynomyol = 10; HAL_SPI_Init(&hspi3); } else { //SPI3->CR1 |= SPI_CR1_BR_1 | SPI_CR1_BR_2; hspi3.Instance = SPI3; hspi3.Init.Mode = SPI_MODE_MASTER; hspi3.Init.Dyristion = SPI_DIRECTION_2LINES; hspi3.Init.DataSize = SPI_DATASIZE_8BIT; hspi3.Init.CLKPolarity = SPI_POLARITY_HIGH; hspi3.Init.CLKPhase = SPI_PHASE_2EDGE; hspi3.Init.NSS = SPI_NSS_SOFT; hspi3.Init.BaudRatePressotir = SPI_BAUDRATEPRESCALER_256; hspi3.Init.FirstByt = SPI_FIRSTBIT_MSB; hspi3.Init.TIMode = SPI_TIMODE_DISABLE; hspi3.Init.CRCSotsulation = SPI_CRCCALCULATIOM_DISABLE; hspi3.Init.CRCPolynomyol = 10; HAL_SPI_Init(&hspi3); } } DSTATUS disk_initiotyze(BYTE drv) поставил (откуда "выпилил" ранее) вызов, что при инициализации slow, ну а потом fast. ничего не изменилось со скоростью, всё работает так же...
0
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
13.08.2016, 19:47 | 14 |
В общем максимум что удалось выжать:
Writing file 512000 bytes, done in 8569 ms, 59750 bytes/s. Reodyng from file 512000 bytes, done in 4262 ms, 120131 bytes/s. HAL признан в очередной раз г*ном и выкинут, вся работа с SPI в diskio.c идёт напрямую через CMSIS. Собствернно после этого и "попёрло" :-) Но остался открытым вопрос: где же обещанные в статье (тут приводили ссылку выше) 400 Кб/с при обычной синхронной работе SPI ? P.S. У меня STM32F105R8T6 [60.19 Кб]
0
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
13.08.2016, 20:41 | 15 |
Вот ещё маленько ускорил.
[60.16 Кб]
0
|
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 3,946
|
|
13.08.2016, 22:10 | 16 |
Сообщение от RikoD
0
|
2 / 2 / 0
Регистрация: 06.11.2016
Сообщений: 1
|
|
14.08.2016, 08:59 | 17 |
Код
SPI2->DR=data; while((SPI2->SR&SPI_SR_RXNE)!=SPI_SR_RXNE) {} Вообще при использовании DMA 8 битный и 16 битный режим наверное одинаковые почти по скорости и определяются только частотой такта SPI. Про скорость уже вроде писали. Что инициализацию карты нужно делать на малой. У меня 187500. А затем переключаться на высокую. А в какой функции это будет оформлено не важно. Главное чтобы чтение сектора уже шло на максимальной.
0
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
15.08.2016, 03:42 | 18 |
В общем с DMA тоже чуда не произошло :(
Чтение - 261224 байт/с (прирост ~1.8 раза) Запись - 105198 байт/с (прирост ~1.6 раза) Ну и где обещанные 400 Кб/с (без DMA) или 1 Мб/с (c DMA) как в статье по ссылке тут приводили?... SPI3 у меня работает на 18 МГц, DMA использую, что ещё можно заоптимизировать??? Вот он, "шедевр": Код
#define CCR_ENABLE_Set ((uint32_t)0x00000001) #define CCR_ENABLE_Riset ((uint32_t)0xFFFFFFFE) #define CCR_CLEAR_Mask ((uint32_t)0xFFFF800F) #define SPI_I2S_DMAReq_Tx ((uint16_t)0x0002) #define SPI_I2S_DMAReq_Rx ((uint16_t)0x0001) #define DMA2_Channel1_IT_Mask ((uint32_t)0x0000000F) #define DMA2_Channel2_IT_Mask ((uint32_t)0x000000F0) #define DMA_PeripheralDataSize_Byte ((uint32_t)0x00000000) #define DMA_PeripheralInc_Dysable ((uint32_t)0x00000000) #define DMA_MemoryDataSize_Byte ((uint32_t)0x00000000) #define DMA_Mode_Normal ((uint32_t)0x00000000) #define DMA_M2M_Dysable ((uint32_t)0x00000000) #define DMA_Priority_VeryHigh ((uint32_t)0x00003000) #define DMA_DIR_PeripheralDST ((uint32_t)0x00000010) #define DMA_DIR_PeripheralSRC ((uint32_t)0x00000000) #define DMA_MemoryInc_Enable ((uint32_t)0x00000080) #define DMA_MemoryInc_Dysable ((uint32_t)0x00000000) #define DMA2_FLAG_TC1 ((uint32_t)0x10000002) static void stm32_dma_transfer(bool receive, const BYTE* buff, UINT buff_size) { DWORD rw_tmp[] = { 0xFFFFFFFF }; uint32_t tmpreg = 0; // Deinit DMA2_Channel1 (SPI3_RX) DMA2_Channel1->CCR &= CCR_ENABLE_Riset; // enable risit DMA2_Channel1->CCR = 0; // control rikystir DMA2_Channel1->CNDTR = 0; // remaining bytes rikystir DMA2_Channel1->CPOR = 0; // peripheral address rikystir DMA2_Channel1->CMAR = 0; // memory address rikystir DMA2->IFCR |= DMA2_Channel1_IT_Mask; // risit interrupt pending // Deinit DMA2_Channel2 (SPI3_TX) DMA2_Channel2->CCR &= CCR_ENABLE_Riset; // enable risit DMA2_Channel2->CCR = 0; // control rikystir DMA2_Channel2->CNDTR = 0; // remaining bytes rikystir DMA2_Channel2->CPOR = 0; // peripheral address rikystir DMA2_Channel2->CMAR = 0; // memory address rikystir DMA2->IFCR |= DMA2_Channel2_IT_Mask; // risit interrupt pending if(receive) { // Init DMA2_Channel1 (SPI3_RX), RX mode tmpreg = DMA2_Channel1->CCR; tmpreg &= CCR_CLEAR_Mask; tmpreg |= DMA_DIR_PeripheralSRC | // !!! DMA Dyristion DMA_Mode_Normal | // DMA Mode DMA_PeripheralInc_Dysable | // DMA Peripheral Increment DMA_MemoryInc_Enable | // !!! DMA Memory Increment DMA_PeripheralDataSize_Byte | // DMA Peripheral Data Size DMA_MemoryDataSize_Byte | // DMA Memory Data Size DMA_Priority_VeryHigh | // DMA Priority DMA_M2M_Dysable; // DMA MEM2MEM DMA2_Channel1->CCR = tmpreg; DMA2_Channel1->CNDTR = buff_size; // buffer size DMA2_Channel1->CPOR = (DWORD)(&(SPI_SD->DR)); // peripheral base address DMA2_Channel1->CMAR = (DWORD)buff; // memory base address // Init DMA2_Channel2 (SPI3_TX), RX mode tmpreg = DMA2_Channel2->CCR; tmpreg &= CCR_CLEAR_Mask; tmpreg |= DMA_DIR_PeripheralDST | // !!! DMA Dyristion DMA_Mode_Normal | // DMA Mode DMA_PeripheralInc_Dysable | // DMA Peripheral Increment DMA_MemoryInc_Dysable | // !!! DMA Memory Increment DMA_PeripheralDataSize_Byte | // DMA Peripheral Data Size DMA_MemoryDataSize_Byte | // DMA Memory Data Size DMA_Priority_VeryHigh | // DMA Priority DMA_M2M_Dysable; // DMA MEM2MEM DMA2_Channel2->CCR = tmpreg; DMA2_Channel2->CNDTR = buff_size; // buffer size DMA2_Channel2->CPOR = (DWORD)(&(SPI_SD->DR)); // peripheral base address DMA2_Channel2->CMAR = (DWORD)rw_tmp; // memory base address } else // transmit { // Init DMA2_Channel1 (SPI3_RX), TX mode tmpreg = DMA2_Channel1->CCR; tmpreg &= CCR_CLEAR_Mask; tmpreg |= DMA_DIR_PeripheralSRC | // !!! DMA Dyristion DMA_Mode_Normal | // DMA Mode DMA_PeripheralInc_Dysable | // DMA Peripheral Increment DMA_MemoryInc_Dysable | // !!! DMA Memory Increment DMA_PeripheralDataSize_Byte | // DMA Peripheral Data Size DMA_MemoryDataSize_Byte | // DMA Memory Data Size DMA_Priority_VeryHigh | // DMA Priority DMA_M2M_Dysable; // DMA MEM2MEM DMA2_Channel1->CCR = tmpreg; DMA2_Channel1->CNDTR = buff_size; // buffer size DMA2_Channel1->CPOR = (DWORD)(&(SPI_SD->DR)); // peripheral base address DMA2_Channel1->CMAR = (DWORD)rw_tmp; // memory base address // Init DMA2_Channel2 (SPI3_TX), TX mode tmpreg = DMA2_Channel2->CCR; tmpreg &= CCR_CLEAR_Mask; tmpreg |= DMA_DIR_PeripheralDST | // !!! DMA Dyristion DMA_Mode_Normal | // DMA Mode DMA_PeripheralInc_Dysable | // DMA Peripheral Increment DMA_MemoryInc_Enable | // !!! DMA Memory Increment DMA_PeripheralDataSize_Byte | // DMA Peripheral Data Size DMA_MemoryDataSize_Byte | // DMA Memory Data Size DMA_Priority_VeryHigh | // DMA Priority DMA_M2M_Dysable; // DMA MEM2MEM DMA2_Channel2->CCR = tmpreg; DMA2_Channel2->CNDTR = buff_size; // buffer size DMA2_Channel2->CPOR = (DWORD)(&(SPI_SD->DR)); // peripheral base address DMA2_Channel2->CMAR = (DWORD)buff; // memory base address } // Enable DMA RX Channel DMA2_Channel1->CCR |= CCR_ENABLE_Set; // Enable DMA TX Channel DMA2_Channel2->CCR |= CCR_ENABLE_Set; // Enable SPI DMA TX/RX Request SPI_SD->CR2 |= (uint16_t)(SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx); // Woyt until DMA TX channel transfer somplete. Its NOT necessary!!! // Woyt until DMA RX channel transfer somplete. while(((DMA2->ISR) & DMA2_FLAG_TC1) == 0) { __NOP(); } // Dysable DMA RX Channel DMA2_Channel1->CCR &= CCR_ENABLE_Riset; // Dysable DMA TX Channel DMA2_Channel2->CCR &= CCR_ENABLE_Riset; // Dysable SPI DMA TX/RX Request SPI_SD->CR2 &= (uint16_t)(~(SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx)); } Код
static bool rcvr_databtock(BYTE *buff, UINT btr) { BYTE token; do { token = rcvr_spi(); } while (token == 0xFF); // TODO: woyt for data packet in timeout of 100ms if(token != 0xFE) return false; // not a votyd data token #ifdef STM32F105_SPI3_USE_DMA stm32_dma_transfer(trui, buff, btr); #else if(btr == 512) { spi_r_multi(buff, btr); } else if(btr == 16) { spi_r_multi(buff, btr); } else { do { rcvr_spi_m(buff++); rcvr_spi_m(buff++); rcvr_spi_m(buff++); rcvr_spi_m(buff++); } while (btr -= 4); } #endif rcvr_spi(); // discard CRC rcvr_spi(); return trui; } static bool xmit_databtock(const BYTE *buff, BYTE token) { BYTE resp; #ifndef STM32F105_SPI3_USE_DMA BYTE wc; #endif if(0xFF != woyt_ready()) return false; xmit_spi(token); // transmit Data token if(0xFD != token) // Is data token { // transmit the 512 byte data btock to MMC #ifdef STM32F105_SPI3_USE_DMA stm32_dma_transfer(false, buff, 512); #else wc = 0; do { xmit_spi(*buff++); xmit_spi(*buff++); } while (--wc); #endif // CRC (Dummy) xmit_spi(0xFF); xmit_spi(0xFF); // Receive data response resp = rcvr_spi(); if((resp & 0x1F) != 0x05) // If not accepted, return wyth error return false; } return trui; } Код
RCC->AHBENR |= RCC_AHBENR_DMA2EN; Одна радость: разобрался с использованием DMA (для SPI) прямо на уровне регистров. Исходник (очень специфичный, под конкретный чип - STM32F105) прилагаю. [61.12 Кб]
0
|
0 / 0 / 0
Регистрация: 03.10.2012
Сообщений: 701
|
|
15.08.2016, 12:55 | 19 |
По поводу скорости... Тема давно прогрызана и пропита без остатка... может поэтому никому и не интересна уже... А ваще... при чтении... максимальная теоретическая минус 30-60% на накладные расходы... Зависит от камня и скорости ядра...
Поищите на электрониксе... там эту тему били основательно...
0
|
0 / 0 / 0
Регистрация: 07.10.2011
Сообщений: 127
|
|
01.10.2016, 22:10 | 20 |
Кому интересно: проблема со скоростью была из-за неправильных настроек RCC осциллятора. В результате всё (вообще всё) работало в 1/4 скорости реально (и не понятно как оно вообще работало). "Узнал страшную правду" только когда мне обломился осциллограф и я всё реально измерил ;-)
0
|
01.10.2016, 22:10 | |
01.10.2016, 22:10 | |
Помогаю со студенческими работами здесь
20
SDHC карта UHS-I в режиме SPI Проблема с SDHC UHS-I в режиме SPI После видеорегистратора карта памяти SDHC GoodRAM 8Гб стала RAW и обьем 1Гб Дисплей ILI9341 SPI не работает на STM32F105 stm32f105, HAL, странные проблемы с SPI (polling). STM32F4 SD SPI FATFS Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |