MementoMori
Свой-
Постов
1 340 -
Зарегистрирован
-
Посещение
Весь контент MementoMori
-
Очень долго инициализируется SD-карта.
MementoMori ответил MementoMori тема в ARM
Может с DMA что не так? Хотя врядли... -
Очень долго инициализируется SD-карта.
MementoMori ответил MementoMori тема в ARM
Так и есть - во время инициализации на клоке 400 кгц, потом включается 24 МГЦ (почему-то, мож где делитель). Поставил в OD - инициализируется так же долго, а после инициализации ничего не читает. Кстати в Кубе при настройке SDMMC вообще нет варианта включить эту ногу в OD -
Очень долго инициализируется SD-карта.
MementoMori ответил MementoMori тема в ARM
Проверю, конечно. Отмечу только, что такой же проект, сгенерированный тем же Кубом для платы Discovery работает нормально. Там, правда, резисторы есть.... Но частоты не переключаются. По крайней мере пользователем, может быть HAL в своих недрах дает какие-то команды....Единственное - инициализация идет в однобитном режиме. -
Очень долго инициализируется SD-карта.
MementoMori ответил MementoMori тема в ARM
Есть конденсатор. P.S. Ну вы мою простынку почитали? Понятно, что что-то с определением вольтажа не так? -
Очень долго инициализируется SD-карта.
MementoMori ответил MementoMori тема в ARM
На всякиий случай - осциллограмма с CMD во время ожидания Клок аналогичного качества На остальных линиях лог.1, шумов нет. -
Очень долго инициализируется SD-карта.
MementoMori ответил MementoMori тема в ARM
Итак, схема Настройка портов Только не подумайте, что я настолько окалокубился, что даже не умею вручную настраивать ножки, я картинку из куба выложил для наглядности. Тактирование Трассировка (интуитивно понятно, где TOP, а где BOTTOM) Плата со слотом И вот CallStack до зависания Пройдемся по этому списку static void MX_SDMMC1_SD_Init(void) { /* USER CODE BEGIN SDMMC1_Init 0 */ /* USER CODE END SDMMC1_Init 0 */ /* USER CODE BEGIN SDMMC1_Init 1 */ /* USER CODE END SDMMC1_Init 1 */ hsd1.Instance = SDMMC1; hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; hsd1.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE; hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B; hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; hsd1.Init.ClockDiv = 0; /* USER CODE BEGIN SDMMC1_Init 2 */ BSP_SD_Init(); // ЭТУ ФУНКЦИЮ ПРИВЕДУ НИЖЕ /* USER CODE END SDMMC1_Init 2 */ } __weak uint8_t BSP_SD_Init(void) { uint8_t sd_state = MSD_OK; /* Check if the SD card is plugged in the slot */ if (BSP_SD_IsDetected() != SD_PRESENT) { return MSD_ERROR_SD_NOT_PRESENT; } /* HAL SD initialization */ sd_state = HAL_SD_Init(&hsd1); // ПОДВИСАЕТ В ВЫШЕУКАЗАННОЙ ФУНКЦИИ, ВСЕ ЧТО НИЖЕ ВЫПОЛНЯЕТСЯ ПОТОМ /* Configure SD Bus width (4 bits mode selected) */ if (sd_state == MSD_OK) { /* Enable wide operation */ if (HAL_SD_ConfigWideBusOperation(&hsd1, SDMMC_BUS_WIDE_4B) != HAL_OK) { sd_state = MSD_ERROR; } } return sd_state; } void HAL_SD_MspInit(SD_HandleTypeDef* hsd) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(hsd->Instance==SDMMC1) { /* USER CODE BEGIN SDMMC1_MspInit 0 */ /* USER CODE END SDMMC1_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_SDMMC1_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); /**SDMMC1 GPIO Configuration PC8 ------> SDMMC1_D0 PC9 ------> SDMMC1_D1 PC10 ------> SDMMC1_D2 PC11 ------> SDMMC1_D3 PC12 ------> SDMMC1_CK PD2 ------> SDMMC1_CMD */ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); /* SDMMC1 DMA Init */ /* SDMMC1_RX Init */ hdma_sdmmc1_rx.Instance = DMA2_Stream3; hdma_sdmmc1_rx.Init.Channel = DMA_CHANNEL_4; hdma_sdmmc1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_sdmmc1_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_sdmmc1_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_sdmmc1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_sdmmc1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_sdmmc1_rx.Init.Mode = DMA_PFCTRL; hdma_sdmmc1_rx.Init.Priority = DMA_PRIORITY_LOW; hdma_sdmmc1_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE; hdma_sdmmc1_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; hdma_sdmmc1_rx.Init.MemBurst = DMA_MBURST_INC4; hdma_sdmmc1_rx.Init.PeriphBurst = DMA_PBURST_INC4; if (HAL_DMA_Init(&hdma_sdmmc1_rx) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(hsd,hdmarx,hdma_sdmmc1_rx); /* SDMMC1_TX Init */ hdma_sdmmc1_tx.Instance = DMA2_Stream6; hdma_sdmmc1_tx.Init.Channel = DMA_CHANNEL_4; hdma_sdmmc1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_sdmmc1_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_sdmmc1_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_sdmmc1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_sdmmc1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_sdmmc1_tx.Init.Mode = DMA_PFCTRL; hdma_sdmmc1_tx.Init.Priority = DMA_PRIORITY_LOW; hdma_sdmmc1_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE; hdma_sdmmc1_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; hdma_sdmmc1_tx.Init.MemBurst = DMA_MBURST_INC4; hdma_sdmmc1_tx.Init.PeriphBurst = DMA_PBURST_INC4; if (HAL_DMA_Init(&hdma_sdmmc1_tx) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(hsd,hdmatx,hdma_sdmmc1_tx); /* SDMMC1 interrupt Init */ HAL_NVIC_SetPriority(SDMMC1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(SDMMC1_IRQn); /* USER CODE BEGIN SDMMC1_MspInit 1 */ /* USER CODE END SDMMC1_MspInit 1 */ } } ВЫШЕУКАЗАННАЯ ФУНКЦИЯ ВЫПОЛНЯЕТСЯ ОТ И ДО HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd) { uint32_t errorstate; HAL_StatusTypeDef status; SD_InitTypeDef Init; /* Default SDMMC peripheral configuration for SD card initialization */ Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE; Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; Init.BusWide = SDMMC_BUS_WIDE_1B; Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; Init.ClockDiv = SDMMC_INIT_CLK_DIV; /* Initialize SDMMC peripheral interface with default configuration */ status = SDMMC_Init(hsd->Instance, Init); if(status != HAL_OK) { return HAL_ERROR; } /* Disable SDMMC Clock */ __HAL_SD_DISABLE(hsd); /* Set Power State to ON */ (void)SDMMC_PowerState_ON(hsd->Instance); /* Enable SDMMC Clock */ __HAL_SD_ENABLE(hsd); /* Identify card operating voltage */ errorstate = SD_PowerON(hsd); // ПОДВИСАЕТ В ВЫШЕУКАЗАННОЙ ФУНКЦИИ, ВСЕ ЧТО НИЖЕ ВЫПОЛНЯЕТСЯ ПОТОМ if(errorstate != HAL_SD_ERROR_NONE) { hsd->State = HAL_SD_STATE_READY; hsd->ErrorCode |= errorstate; return HAL_ERROR; } /* Card initialization */ errorstate = SD_InitCard(hsd); if(errorstate != HAL_SD_ERROR_NONE) { hsd->State = HAL_SD_STATE_READY; hsd->ErrorCode |= errorstate; return HAL_ERROR; } return HAL_OK; } А вот функция, в которой происходит подвисание static uint32_t SD_PowerON(SD_HandleTypeDef *hsd) { __IO uint32_t count = 0U; uint32_t response = 0U, validvoltage = 0U; uint32_t errorstate; /* CMD0: GO_IDLE_STATE */ errorstate = SDMMC_CmdGoIdleState(hsd->Instance); if(errorstate != HAL_SD_ERROR_NONE) { return errorstate; } /* CMD8: SEND_IF_COND: Command available only on V2.0 cards */ errorstate = SDMMC_CmdOperCond(hsd->Instance); if(errorstate != HAL_SD_ERROR_NONE) { hsd->SdCard.CardVersion = CARD_V1_X; /* CMD0: GO_IDLE_STATE */ errorstate = SDMMC_CmdGoIdleState(hsd->Instance); if(errorstate != HAL_SD_ERROR_NONE) { return errorstate; } } else { hsd->SdCard.CardVersion = CARD_V2_X; } if( hsd->SdCard.CardVersion == CARD_V2_X) { /* SEND CMD55 APP_CMD with RCA as 0 */ errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); if(errorstate != HAL_SD_ERROR_NONE) { return HAL_SD_ERROR_UNSUPPORTED_FEATURE; } } /* SD CARD */ /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */ // ЭТОТ ЦИКЛ КРУТИТСЯ ОЧЕНЬ ДОЛГО, ПОЧЕМУ - ОБЪЯСНЮ НИЖЕ while((count < SDMMC_MAX_VOLT_TRIAL) && (validvoltage == 0U)) { /* SEND CMD55 APP_CMD with RCA as 0 */ errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); if(errorstate != HAL_SD_ERROR_NONE) { return errorstate; } /* Send CMD41 */ errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_VOLTAGE_WINDOW_SD | SDMMC_HIGH_CAPACITY | SD_SWITCH_1_8V_CAPACITY); if(errorstate != HAL_SD_ERROR_NONE) { return HAL_SD_ERROR_UNSUPPORTED_FEATURE; } /* Get command response */ response = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); /* Get operating voltage*/ validvoltage = (((response >> 31U) == 1U) ? 1U : 0U); count++; } if(count >= SDMMC_MAX_VOLT_TRIAL) { return HAL_SD_ERROR_INVALID_VOLTRANGE; } if((response & SDMMC_HIGH_CAPACITY) == SDMMC_HIGH_CAPACITY) /* (response &= SD_HIGH_CAPACITY) */ { hsd->SdCard.CardType = CARD_SDHC_SDXC; } else { hsd->SdCard.CardType = CARD_SDSC; } return HAL_SD_ERROR_NONE; } Засада кроется вот где while((count < SDMMC_MAX_VOLT_TRIAL) && (validvoltage == 0U)) { /* SEND CMD55 APP_CMD with RCA as 0 */ errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); if(errorstate != HAL_SD_ERROR_NONE) { return errorstate; } /* Send CMD41 */ errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_VOLTAGE_WINDOW_SD | SDMMC_HIGH_CAPACITY | SD_SWITCH_1_8V_CAPACITY); if(errorstate != HAL_SD_ERROR_NONE) { return HAL_SD_ERROR_UNSUPPORTED_FEATURE; } /* Get command response */ response = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); /* Get operating voltage*/ validvoltage = (((response >> 31U) == 1U) ? 1U : 0U); count++; } Если посмотреть на условие while, то этот цикл крутится пока не произойдет одно из событий - либо validvoltage не станет неравным нулю, либо пока count не дотикает до 0xFF Как только он дотикает, программа идет дальше. response всегда равен 0xFF8000, validvoltage=0; -
Очень долго инициализируется SD-карта.
MementoMori ответил MementoMori тема в ARM
Друзья, спасибо за советы, но хочу напомнить - проблема именно с инициализацией. Чтение идёт нормально. Как мне кажется, если бы были проблемы с железом, то это отражалось бы на всех этапах работы. Если я не прав - поправьте. -
Очень долго инициализируется SD-карта.
MementoMori ответил MementoMori тема в ARM
Спасибо. Вечером доберусь до дома. Приведу схему, трассировку, даже кабель и плату разъёма сфоткаю. Нет. А эта линия наиболее критична? У меня платка китайская для 3д принтера, на ней 4 линии, конденсатор, резисторов нет. Подключеная к контроллеру 3д принтера она работает. Ладно, остальная информация вечером. -
Очень долго инициализируется SD-карта.
MementoMori ответил MementoMori тема в ARM
Я бы в дополнение еще отметил интересный факт. Если включать на "холодную", то это происходит всегда. Если же подключаться отладчиком, то первый раз - долго, а потом можно долго ресетить контроллер, прежде чем такая ситуация возникнет вновь. Кстати.... у меня нет резисторов на линиях, но есть внутренние подтяжки, а кабель короткий - 7 см. Так можно делать? -
Очень долго инициализируется SD-карта.
MementoMori ответил MementoMori тема в ARM
Пробовал, все то же самое. -
Очень долго инициализируется SD-карта.
MementoMori опубликовал тема в ARM
STM32F746, Код сгенерирован калокубом. Есть такая функция в нем SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_CMD, SDMMC_CMDTIMEOUT); Так вот когда в теле этой функции проверяется регистр SDMMCx->STA, то проверка идет очень долго, так как бит CMDACT в единице. Спустя 20-30 секунд бит сбрасывается и карта работает идеально. Что характерно, время инициализации может быть и меньшим, иногда все сразу проходит. режим 4 битный, частота 48 МГц. Куда копать? -
FatFS и русские буквы.
MementoMori ответил MementoMori тема в В помощь начинающему
Как выяснилось, читает с карты. -
FatFS и русские буквы.
MementoMori ответил MementoMori тема в В помощь начинающему
Задолбался отлавливать один глюк, возникающий при обновлении списка файлов. Есть один вопрос, ответ на который приблизить меня к пониманию причины этого глюка. Скажите, функция f_readdir() читает данные обращаясь к карте, или же из находящегося в оперативной памяти некоего массива? -
FatFS и русские буквы.
MementoMori ответил MementoMori тема в В помощь начинающему
Еще один вопрос. Когда-то я писал просмотрщик папок, это было еще под DOS. Был там удобный способ переходить из директории в директорию, с помощью добавления в путь двух точек. Например если задать путь "\.." - то попадешь в предыдущую директорию. А если написать "С:\FOLDER\.." то попадешь в "С:\". И в списке файлов первая запись это "..". Удобно - парсить строку не надо. А можно ли как-то так же с FatFS? -
FatFS и русские буквы.
MementoMori ответил MementoMori тема в В помощь начинающему
Хорошо телепатируете. Не только на прием, но и на передачу - я ведь сделал именно так, как вы сейчас написали, но до прочтения вашего поста (и чуть позже после того, как он был оставлен) Угадайте мою следующую проблему и ее решение) -
FatFS и русские буквы.
MementoMori ответил MementoMori тема в В помощь начинающему
Вопрос следующий. Получил я текст, читаемый в cp1251, записанный в переменную fn, представляющую собой массив uint8_t. Хочу вывести его в виджет библиотеки TouchGFX рукописной функцией SetItemFName(fn); Но загвоздка в том, что нужен юникод, для этого, как я понял из таблицы кодировок, нужно прибавить к символу число 848. Соответственно нужно преобразовать в uint16_t пытаюсь это сделать. У меня строка "абвгд", то есть последовательость 0xE0, 0xE1, 0xE2, 0xE3, 0xE4. Преобразовываю SetItemFName((uint16_t*)fn) Получаю массив не из 0x00E0,0x00E1,0x00E2,0x00E3, а нечто иное - 0xE1E0, 0xE3E2,0xE5E4. Я конечно уже сделал все ручками, побайтово заполнив массив в цикле, но что-то мне подсказывает, что есть более изящное решение. Есть ли оно и каково оно? -
Поддерживаю идею о работе по частям. Правда у меня свои причины. Я пытаюсь читать SD карту при помощи интерфейса touchgfx. А в случае отображения информации на экране, память в любом случае будет забита - в scrolllist, если будет 5000 файлов, все 5 тысяч и загрузится и займут память. Зачем дублировать эти данные массивом, необходимым только для передачи информации из системной области в интерфейсу. Я полагаю, создатели touchgfx озаботились обработкой scrollist, количество элементов которого заранее неизвестно Правда, я поступил коряво - не стал транспортировать данные, а тупо подключил Fatfs.h к файлу, описыващему конкретный экран и вызываю функции работы с файловой системой прямо из интерфейса. Чем разрушаю идею создателей о разделении интерфейса и системы. Но работает без глюков. Хочу, правда, переделать - подавать команды из интерфейса в системную область программы, читать по одному имени файла и передавать его куда следует.
-
FatFS и русские буквы.
MementoMori ответил MementoMori тема в В помощь начинающему
Так если бы этой кодировки не было вообще, а то ж ведь до 0.12С была, а потом пропала. Так русский Иван набросал функцию перекодирования, но все же недоумевает, почему китайский Хунь так кастрировал свое творение. -
FatFS и русские буквы.
MementoMori ответил MementoMori тема в В помощь начинающему
Вот товарищ http://forum.easyelectronics.ru/viewtopic.php?f=35&t=33457 (вроде бы его ник видел и на этом форуме) пишет Раньше я решал эту проблему подсовыванием нужных макросов/таблиц из каких-то старых версий FatFS, где Win1251 ещё была. Но оказалось, что в R0.13 (может одной-двух предыдущих - не знаю) сильно изменилась система перекодировок и просто подсунуть нужные таблицы не получается. -
FatFS и русские буквы.
MementoMori ответил MementoMori тема в В помощь начинающему
Спас вот такой костыль for(uint8_t i=0; i<strlen(fn);i++) { if ((fn[i]>=128) && (fn[i]<=175)) fn[i]+=64; //A...Я,а..п else if ((fn[i]>=224) && (fn[i]<=239)) fn[i]+=16; //р..я else if (fn[i]==240) fn[i]=168; // Ё else if (fn[i]==241) fn[i]=184;// ё } -
FatFS и русские буквы.
MementoMori ответил MementoMori тема в В помощь начинающему
Вывожу через uart. Вот как выглядит файл "абвгдеж.txt" Это наверное и правда win1251 161->193 162->194 163->195 и дальше по тексту. Я когда искал решение своей проблемы, наткнулся на тему, где товарищ сетовал, что у него русские буквы читаются только если указать cp1251, но это в версии FatFS 0.12b, а он хочет Fat 0.13. Китайцы ему ответитили, что 0.12b- последняя версия, которая поддерживает cp1251. У меня версия 0.12c (то есть уже не b) Я создавал файлы ручками, из под винды. Так же может сделать и пользователь. Что же это получается, последняя версия принципиально не годится для русского Ивана? -
FatFS и русские буквы.
MementoMori опубликовал тема в В помощь начинающему
Добрый вечер. Ковыряю FatFS R0.12c Не получается читать русские буквы. Настраиваю так #define FF_CODE_PAGE 866#define FF_USE_LFN 2#define FF_LFN_UNICODE 0 Ну или #define FF_CODE_PAGE 855 Вместо русских букв белеберда. Хотя в библиотеке есть не просто кириллица (855), но и "Russian" - 866. Что я делаю не так? -
SMD-TAXI опыт 6 лет использования
MementoMori ответил Михаил Баранов тема в Пайка и монтаж
Да ваще, свои пацаны, чиста. -
SMD-TAXI опыт 6 лет использования
MementoMori ответил Михаил Баранов тема в Пайка и монтаж
Михаил, у вас первый рабочий день промоутером у производителя SDM-TAXI? Ну хоть бы ссылку дали, а то лень искать. -
Перегретый чип?
MementoMori ответил MementoMori тема в Ремонт и отладка
В F746 все немного по-другому. Вот как оказывается надо было: DWT->LAR = 0xC5ACCE55; // ВОТ ЭТОГО НЕ ХВАТАЛО /* Disable clock cycle counter */ DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; //~0x00000001; /* Enable clock cycle counter */ DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; //0x00000001; /* Reset the clock cycle counter value */ DWT->CYCCNT = 0;