MiklPolikov 0 25 октября, 2014 Опубликовано 25 октября, 2014 (изменено) · Жалоба Кто-нибудь разобрался с настройкой SDIO ? У меня , при попытке передать cmd команду, на линиях CMD и CK тишина. Процессор STM32L151RDT Мысли такие: 1)Не совсем уверен, что номер периферии, которую надо включить на ногах, на самом деле 12. В документации не очень понятно написано. 2) Не понятно, какая именно последовательность действий нужна для передачи CMD. Записать что-то в регистр ARG , записать что-тов регистр CMD , и команда сразу должна начать передаваться ? Или ещё есть какой-нибудь бит запуска передачи ? ////// //настраиваем порт RCC->AHBENR |= RCC_AHBENR_GPIOCEN; RCC->AHBENR |= RCC_AHBENR_GPIODEN; GPIOC->OSPEEDR|= GPIO_OSPEEDER_OSPEEDR8|GPIO_OSPEEDER_OSPEEDR9|GPIO_OSPEEDER_OSPEEDR10|GPIO_OSPEE DER_OSPEEDR11| GPIO_OSPEEDER_OSPEEDR11; GPIOD->OSPEEDR|= GPIO_OSPEEDER_OSPEEDR2; GPIOC->MODER &= ~GPIO_MODER_MODER8; GPIOC->MODER |= GPIO_MODER_MODER8_1; GPIOC->MODER &= ~GPIO_MODER_MODER9; GPIOC->MODER |= GPIO_MODER_MODER9_1; GPIOC->MODER &= ~GPIO_MODER_MODER10; GPIOC->MODER |= GPIO_MODER_MODER10_1; GPIOC->MODER &= ~GPIO_MODER_MODER11; GPIOC->MODER |= GPIO_MODER_MODER11_1; GPIOC->MODER &= ~GPIO_MODER_MODER12; GPIOC->MODER |= GPIO_MODER_MODER12_1; GPIOD->MODER &= ~GPIO_MODER_MODER2; GPIOD->MODER |= GPIO_MODER_MODER2_1; GPIOC->AFR[1]|=(12<<0); GPIOC->AFR[1]|=(12<<4); GPIOC->AFR[1]|=(12<<8); GPIOC->AFR[1]|=(12<<12); GPIOC->AFR[1]|=(12<<16); GPIOD->AFR[0]|=(12<<8); ///////Настраиваем SDIO RCC->APB2ENR|=RCC_APB2ENR_SDIOEN; // включаем тактирование RCC->APB2RSTR|=RCC_APB2RSTR_SDIORST; RCC->APB2RSTR&=~RCC_APB2RSTR_SDIORST; //сброс настроек SDIO->CLKCR|=SDIO_CLKCR_HWFC_EN; //HW Flow Control is enabled SDIO->CLKCR|=SDIO_CLKCR_WIDBUS_0; // 4-wide bus mode: SDIO_D[3:0] used SDIO->CLKCR|=SDIO_CLKCR_PWRSAV; //SDIO_CK is only enabled when the bus is active SDIO->CLKCR|=SDIO_CLKCR_CLKEN; //SDIO_CK is enabled SDIO->CLKCR|=SDIO_CMD_CPSMEN; //Command path state machine (CPSM) Enable bit SDIO->CLKCR|=SDIO_CMD_WAITPEND; //CPSM Waits for ends of data transfer SDIO->DTIMER=400000; //Data timeout period SDIO->DLEN=512; //Data length value SDIO->DCTRL|=SDIO_DCTRL_SDIOEN; SDIO->DCTRL|=SDIO_DCTRL_DTMODE; //SDIOEN=1 and DTMODE=1, the peripheral enables an SDIO multibyte transfer. //Непонятно, что это SDIO->DCTRL|=SDIO_DCTRL_RWMOD; //Read Wait control using SDIO_CK ///Непонятно, что это SDIO->DCTRL|=SDIO_DCTRL_DBLOCKSIZE_0 | SDIO_DCTRL_DBLOCKSIZE_3; // размер блока 512 ///Пытаемся передать команту char cmd=CMD0 while(1) { SDIO->CLKCR|=SDIO_CMD_WAITRESP_0; //Short response, expect CMDREND or CCRCFAIL flag SDIO->CLKCR &=~ SDIO_CMD_WAITRESP_1; SDIO->CLKCR|=SDIO_CMD_CPSMEN; //Command path state machine (CPSM) Enable bit SDIO->CLKCR &=~ SDIO_CMD_CMDINDEX; SDIO->CLKCR |=(cmd & SDIO_CMD_CMDINDEX); SDIO->ARG=0; } Изменено 25 октября, 2014 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 25 октября, 2014 Опубликовано 25 октября, 2014 · Жалоба Кто-нибудь разобрался с настройкой SDIO ? 12 - правильно, по крайней мере для F4 так; Сначала включайте тактирование SDIO, а уже потом - подключайте ножки к альтернативным функциям; В настройке ног у вас два раза GPIO_OSPEEDER_OSPEEDR11 (и нет GPIO_OSPEEDER_OSPEEDR12); После включения тактирования добавьте __DSB(); SDIO->CLKCR нужно обнулить перед тем как делать ему SDIO->CLKCR |= ...; Для инициализации используется однобитная шина и медленная скорость (не более 400 КГц); Пока хватит:) ЗЫ. Чтобы не раскапывать всё это самостоятельно, посмотрите вот эти примеры. Там всё сделано не в пример проще, чем в примерах от ST. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MiklPolikov 0 26 октября, 2014 Опубликовано 26 октября, 2014 · Жалоба АНТОХА, спасибо, примеры очень хорошие, у меня всё заработало. Напишу осмысленный код, и выложу тут. [*] Сначала включайте тактирование SDIO, а уже потом - подключайте ножки к альтернативным функциям; Так сказано где-то в документации ? Мне всегда казалось, что порт и периферия ни как не связаны в плане тактирования, и их можно включать и настраивать в любой последовательности. Всегда сначала включал тактирование порта и настраивал его, потом то же самое с периферией. Сейчас с SDIO так же сделал и работает. [*] После включения тактирования добавьте __DSB(); Здравая мысль. Но каким-то образом у меня всё всегда работало без этого __dsb(); [*] SDIO->CLKCR нужно обнулить перед тем как делать ему SDIO->CLKCR |= ...; Зачем ? Там после ресета и так 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 26 октября, 2014 Опубликовано 26 октября, 2014 · Жалоба Так сказано где-то в документации ? у NXP в доках перед каждым мдулем процедура его включения именно с такой последовательностью. включение модуля, клоки, порты, прерывания наверное хороший тон, вряд ли есть зависимость от последовательности, вернее от места настройки портов... Здравая мысль. Но каким-то образом у меня всё всегда работало без этого __dsb(); не очень понятно зачем оно тут, мне кажется это все для случаев переключения контекстов (прерывания, операционки и подобное), я не прав? Зачем ? Там после ресета и так 0. хороший тон, чтоб не рвать волосы когда появиться бутлоадер, или чужие модули, которые тоже что-то понастраивают.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 26 октября, 2014 Опубликовано 26 октября, 2014 · Жалоба Так сказано где-то в документации ? Мне всегда казалось, что порт и периферия ни как не связаны в плане тактирования, и их можно включать и настраивать в любой последовательности. Всегда сначала включал тактирование порта и настраивал его, потом то же самое с периферией. Сейчас с SDIO так же сделал и работает. Я не помню, откуда я это взял. Возможно, мне подсознательно кажется, что нельзя подключать ноги к неработающему модулю. (И, вроде бы, на F1xx при попытке включить remap до включения тактирования происходило зависание, но не уверен). В общем, если заработало в ином порядке - хорошо, замечание снимается:) Здравая мысль. Но каким-то образом у меня всё всегда работало без этого __dsb(); В 99% случаев сработает и без __DSB(), но в 1% - зависнет. Такие глюки тяжелее всего ловить. Объясню, отчего так происходит. Может случиться так, что матрица шин загружена, запись в AHBENR задержится, и следующая после включения тактирования команда выполнится раньше, чем собственно включится тактирование. И если эта следующая команда обратится к периферии модуля, то произойдёт сбой. Команда __DSB() приостанавливает выполнение кода до тех пор, пока все записи по всем шинам не завершатся. (В либах от ST из-за их "многословности" такое практически исключено, там между включением тактирования и обращением к модулю гарантированно выполнится ещё десяток команд). Зачем ? Там после ресета и так 0. Ну, может быть, вы захотите вызывать свою процедуру инициализации не только после резета. Вы же точно знаете, что в начале вашей процедуры инициализации SDIO->CLKCR должен быть 0. Вот и задаёте его значение явно, это придаст вашему коду дополнительную надёжность. (И к тому же сократит код:) ( "=" вместо "|=") ). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MiklPolikov 0 26 октября, 2014 Опубликовано 26 октября, 2014 · Жалоба В 99% случаев сработает и без __DSB(), но в 1% - зависнет. Такие глюки тяжелее всего ловить. Объясню, отчего так происходит. Может случиться так, что матрица шин загружена, запись в AHBENR задержится, и следующая после включения тактирования команда выполнится раньше, чем собственно включится тактирование. И если эта следующая команда обратится к периферии модуля, то произойдёт сбой. Команда __DSB() приостанавливает выполнение кода до тех пор, пока все записи по всем шинам не завершатся. (В либах от ST из-за их "многословности" такое практически исключено, там между включением тактирования и обращением к модулю гарантированно выполнится ещё десяток команд). Ну, может быть, вы захотите вызывать свою процедуру инициализации не только после резета. Вы же точно знаете, что в начале вашей процедуры инициализации SDIO->CLKCR должен быть 0. Вот и задаёте его значение явно, это придаст вашему коду дополнительную надёжность. (И к тому же сократит код:) ( "=" вместо "|=") ). В STM32L обращение к регистрам включенной периферии не вызывает зависание, просто в регистры не пишется. Перед настройкой периферии я всегда делаю ресет этой периферии. И вот это-хороший тон. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 26 октября, 2014 Опубликовано 26 октября, 2014 · Жалоба В STM32L обращение к регистрам включенной периферии не вызывает зависание, просто в регистры не пишется. И что, это пустяки, не страшно? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 26 октября, 2014 Опубликовано 26 октября, 2014 · Жалоба у NXP в доках перед каждым мдулем процедура его включения именно с такой последовательностью. включение модуля, клоки, порты, прерывания Цитату можете привести? Видел что-то вроде этого The UART pins must be configured in the IOCON block before the UART clock can be enabled in the in the SYSAHBCLKCTRL register (Table xx) for parts LPCxxxx.... The sequence of configuring the UART pins and the UART clock has no effect for parts LPCxxxx/01 and .... Описание периферийного модуля XXX: 2. Power: In the SYSAHBCLKCTRL register, set bit xx (Table xx). 3. Peripheral clock: Enable the UART peripheral clock by writing to the UARTCLKDIV register (Table xx). Удивила только взаимосвязь Power и SYSAHBCLKCTRL, который, судя по названию, отвечает за клок. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 27 октября, 2014 Опубликовано 27 октября, 2014 · Жалоба Цитату можете привести? LPC1768 UM10360 в начале главы про любую периферию The UART1 peripheral is configured using the following registers: 1. Power: In the PCONP register (Table 46), set bits PCUART1. Remark: On reset, UART1 is enabled (PCUART1 = 1). 2. Peripheral clock: In the PCLKSEL0 register (Table 40), select PCLK_UART1. 3. Baud rate: In register U1LCR (Table 298), set bit DLAB =1. This enables access to registers DLL (Table 292) and DLM (Table 293) for setting the baud rate. Also, if needed, set the fractional baud rate in the fractional divider register (Table 305). 4. UART FIFO: Use bit FIFO enable (bit 0) in register U0FCR (Table 297) to enable FIFO. 5. Pins: Select UART pins through PINSEL registers and pin modes through the PINMODE registers (Section 8.5). Remark: UART receive pins should not have pull-down resistors enabled. 6. Interrupts: To enable UART interrupts set bit DLAB =0 in register U1LCR (Table 298). This enables access to U1IER (Table 294). Interrupts are enabled in the NVIC using the appropriate Interrupt Set Enable register. 7. DMA: UART1 transmit and receive functions can operated with the GPDMA controller (see Table 543). или The Timer 0, 1, 2, and 3 peripherals are configured using the following registers: 1. Power: In the PCONP register (Table 46), set bits PCTIM0/1/2/3. Remark: On reset, Timer0/1 are enabled (PCTIM0/1 = 1), and Timer2/3 are disabled (PCTIM2/3 = 0). 2. Peripheral clock: In the PCLKSEL0 register (Table 40), select PCLK_TIMER0/1; in the PCLKSEL1 register (Table 41), select PCLK_TIMER2/3. 3. Pins: Select timer pins through the PINSEL registers. Select the pin modes for the port pins with timer functions through the PINMODE registers (Section 8.5). 4. Interrupts: See register T0/1/2/3MCR (Table 429) and T0/1/2/3CCR (Table 430) for match and capture events. Interrupts are enabled in the NVIC using the appropriate Interrupt Set Enable register. 5. DMA: Up to two match conditions can be used to generate timed DMA requests, see Table 543. понятно что это список регистров, но последовательность во всех модулях единая. А главное что когда я писал функции их конфигурации я просто по пунктам настраивал то что надо, и у меня возникла именно такая последовательность Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 28 октября, 2014 Опубликовано 28 октября, 2014 · Жалоба LPC1768 UM10360 в начале главы про любую периферию Зря обобщаете. Во всех (мелких) процах (LPC11xx, LPC12xx, LPC13xx), в которых пины настраиваются через регистры IOCON написано выделенным шрифтом - Remark: The XXX pins must be configured in the corresponding IOCON registers before the XXX clocks are enabled. Хотя я проверял и так и эдак, т.к. поздно заметил эту ремарку. В обоих случаях работает. Но долговременной гарантии конечно же нет. Например в новых ревизиях чипов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 28 октября, 2014 Опубликовано 28 октября, 2014 · Жалоба ну наверное это верно. Надо читать мануал и делать как написано для каждого конкретного случая... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MiklPolikov 0 29 октября, 2014 Опубликовано 29 октября, 2014 · Жалоба ну наверное это верно. Надо читать мануал и делать как написано для каждого конкретного случая... Может кто подскажет : 1) Карта проходит инициальзацию. Отвечает на CMD2, CMD3 . Но после этого не хочет отвечать на CMD17 , CMD18 . Выставляется бит SDIO_STA_CTIMEOUT. В примерах https://github.com/yigiter/Sample-STM32F4-c...OLib/src/SDIO.c после посылки CMD17 почему-то нет проверки получен ответ или нет. В чём может быть причина ? 2) Почему флаг SDIO_STA_CTIMEOUT выставляется мгновенно ? Казалось бы, если в регистре SDIO_DTIMER значение 0xFFFFFFFF , а частота шины 400КГц , то тайм-аут должен случится через 0xffffffff / 400КГц = 10737 секунд Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 29 октября, 2014 Опубликовано 29 октября, 2014 · Жалоба а не по этой команде определяется тип карты? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hd44780 0 29 октября, 2014 Опубликовано 29 октября, 2014 · Жалоба Таймаут на CMD17 и у меня регулярно вылетает на F439. На F407 (дискавери) всё идеально. Карта одна и та же. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MiklPolikov 0 29 октября, 2014 Опубликовано 29 октября, 2014 · Жалоба Таймаут на CMD17 и у меня регулярно вылетает на F439. На F407 (дискавери) всё идеально. Карта одна и та же. Глюк можно списать на нехорошую разводку. Вопрос в другом : почему вообще происходит тайм-аут, если значение в регистре SDIO_DTIMER = 0xffffffff и частота клока 400КГц должны давать время тайм-аута 10000 секунд ? Можно было бы предположить, что процессор принимает что-то совсем несуразное, что даже нельзя интерпретировать как ответ с неправильным CRC , но вот только при отсутствии карты тайм-аут происходит так же быстро. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться