esaulenka 7 22 октября, 2015 Опубликовано 22 октября, 2015 · Жалоба а как этот правильный путь поможет задать альтернативные функции LPC? или право делать процы с альтернативными функциями пинов на арм ядре только у СТМ:)? Если мне придётся снова работать с LPC'хами, буду делать библиотеку по образу и подобию. Когда-то у меня был набор макросов (в принципе, то же самое - задавался порт, пин, режим пина), но эти хитрые шаблоны удобнее. Варианты ЯadiatoR и AlanDrakes, которые прочитали даташит, явно неудобные. Пусть компилятор нужные смещения считает, он железный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 22 октября, 2015 Опубликовано 22 октября, 2015 · Жалоба Инициализирую все выводы в одном месте init_GPIO() GPIOA->MODER = 0 | (GPIO_MODE_OUTPUT << GPIO_MODER_PIN0) // ( 6) free | (GPIO_MODE_OUTPUT << GPIO_MODER_PIN1) // ( 7) free | (GPIO_MODE_ALTERNATE << GPIO_MODER_PIN2) // ( 8) USART1_TX (console) | (GPIO_MODE_ALTERNATE << GPIO_MODER_PIN3) // ( 9) USART1_RX (console) | (GPIO_MODE_OUTPUT << GPIO_MODER_PIN4) // (10) WORKLED | (GPIO_MODE_OUTPUT << GPIO_MODER_PIN5) // (11) free | (GPIO_MODE_ALTERNATE << GPIO_MODER_PIN6) // (12) TIM3_CH1 | (GPIO_MODE_OUTPUT << GPIO_MODER_PIN7) // (13) free | (GPIO_MODE_ALTERNATE << GPIO_MODER_PIN9) // (17) TIM1_CH2 | (GPIO_MODE_OUTPUT << GPIO_MODER_PIN10) // (18) free | (GPIO_MODE_ALTERNATE << GPIO_MODER_PIN13) // (19) SWDIO (debug) | (GPIO_MODE_ALTERNATE << GPIO_MODER_PIN14); // (20) SWCLK (debug) GPIOA->AFR[0] = 0 | (AF_PA2_USART1_TX << GPIO_AFR0_PIN2) | (AF_PA3_USART1_RX << GPIO_AFR0_PIN3) | (AF_PA6_TIM3_CH1 << GPIO_AFR0_PIN6); GPIOA->AFR[1] = 0 | (AF_PA9_TIM1_CH2 << GPIO_AFR1_PIN9) | (AF_PA13_SWDIO << GPIO_AFR1_PIN13) | (AF_PA14_SWCLK << GPIO_AFR1_PIN14); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alechek 0 26 октября, 2015 Опубликовано 26 октября, 2015 · Жалоба Инициалиация в одном месте хорошо. Но иногда не прокатывает: при работе с встраиваемыми модулями (GSM и прочие) сразу инициализировать ноги нельзя, вначале надо подать на модуль питание. И, соотвественно, иницалиировать в третье состяоние при снятии питания. Таким образом, инциализация ног происходит не разово, а постоянно в работе. Для LPC и STM создан "drv_gpio" Все регистры для установки ног вычиляются внутри функции IO_SetupPin(..) С одной стороны, лишние накладные расходы, с другой - код намного читабельнее и понятнее. Единстенное, что никак не стандартизируешь - вариант альтернативной конфиграции ноги. Тут уж придется лезть в даташит. #ifndef __DRV_IOPORTS_H #define __DRV_IOPORTS_H enum __pindirection { PIN_IN, PIN_OUT, PIN_ALTOUT }; enum __pullupmode { ppullINACTIVE = 0, ppullDOWN, ppullUP, ppullREPEATER }; enum __pinslew { pslewENABLED = 0, pslewDISABLED = 1 }; enum __pinmode { pinNORMAL = 0, pinOPENDRAIN = 1, pinANALOG = 2, }; enum __pinfilter { pglfENABLED = 0, pglfDISABLED = 1 }; enum __pinntest_res { PIN_OK, PIN_SHORTLOW, PIN_SHORTHIGH }; #define pmANALOG 0 #define pmDIGITAL 1 #define PORTA A #define PORTB B #define PORTC C #define PORTD D #define PORTE E #define PORTF F #define PORTABASE ((void*)&GPIOA_CRL) #define PORTBBASE ((void*)&GPIOB_CRL) #define PORTCBASE ((void*)&GPIOC_CRL) #define PORTDBASE ((void*)&GPIOD_CRL) #define PORTEBASE ((void*)&GPIOE_CRL) #define _PORTBASE(port) ((void*)&(GPIO ## port ## _CRL)) #define _PORTSET(port) GPIO ## port ## _BSRR #define _PORTCLR(port) GPIO ## port ## _BRR #define _PORTPIN(port) GPIO ## port ## _IDR #define PORTSET(port) _PORTSET(port) #define PORTCLR(port) _PORTCLR(port) #define PORTPIN(port) _PORTPIN(port) #define PINSET(port, pin) _PORTSET(port) = BIT(pin) #define PINCLR(port, pin) _PORTCLR(port) = BIT(pin) #define PINREAD(port, pin) (!!(_PORTPIN(port) & BIT(pin))) #define PINSETUP(port, pin, dir, pu, pm, s, f) \ IO_SetupPin(_PORTBASE(port), pin, dir, pu, pm, s, f) #define PINMODE(port, pin, mode) #define PINDIR(dir, port, pin) IO_PinDir(dir, port, (1UL << pin)) #ifdef __cplusplus extern "C" { #endif void IO_Init(void); void IO_SetupPin(void * portbase, int pin, enum __pindirection dir, enum __pullupmode pumode, enum __pinmode pinmode, enum __pinslew slewrate, enum __pinfilter filter); enum __pinntest_res IO_PinTest(int port, int pin); void IO_PinDir(enum __pindirection dir, int port, unsigned long pinmask); #ifdef __cplusplus } #endif #endif //__DRV_IOPORTS_H Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
den_po 0 27 октября, 2015 Опубликовано 27 октября, 2015 · Жалоба Если мне придётся снова работать с LPC'хами, буду делать библиотеку по образу и подобию. Когда-то у меня был набор макросов (в принципе, то же самое - задавался порт, пин, режим пина), но эти хитрые шаблоны удобнее. Года 3 назад делал библиотеку шаблонов для LPC 2119/2368/2468. Кому-то такие объявления могут показаться избыточными, но мне самому пользоваться очень нравилось. CPU::WATCHDOGTIMER<> wdt( CPU::PLL::PeriodToTicks(10), CPU::WATCHDOGTIMER<>::DEBUG ); CPU::TIMER<0> ustimer( CPU::PLL::FreqToTicks(1000000) ); CPU::CALLBACKTIMER<1, MEASURETIMERCB, IRQP_MEASURETIMER> measuretimer( CPU::PLL::FreqToTicks(FADC) ); CPU::GPIO0::PINGROUP<0,2> _uartusb_rx_tx(1); USBQUEYECLASS usbq(115200); CPU::GPIO0::PINGROUP<8,2> _uartrs485_rx_tx(1); CPU::GPIO0::PIN<10> uartrs485_txen(0, CPU::GPIO0::OUTPUT); RS485QUEYECLASS rs485q(19200, 8, RS485QUEYECLASS::EVEN, 1); CPU::GPIO1::PIN<23> disp_d7_busy(0, CPU::GPIO1::OUTPUT); CPU::GPIO0::PIN<13> disp_rs(0, CPU::GPIO0::OUTPUT); CPU::GPIO0::PIN<BUTTON1PIN, CPU::GPIO0::PININVERTED> button1_pressed(0, CPU::GPIO0::INPUT); CPU::GPIO0::PIN<17> spi_sck(2); CPU::GPIO0::PIN<18> spi_miso(2); CPU::GPIO0::PIN<19> spi_mosi(2); CPU::SPI<1> spi(2000000, CPU::SPI<1>::MASTER, CPU::SPI<1>::MSB, 16); AD7656< CPU::SPI<1>, spi, CPU::GPIO0::PIN<5>, adc_st, CPU::GPIO0::PIN<20>, adc_cs1, CPU::GPIO0::PIN<3>, adc_busy1> adc_gen_out; AD7656< CPU::SPI<1>, spi, CPU::GPIO0::PIN<5>, adc_st, CPU::GPIO0::PIN<4>, adc_cs2, CPU::GPIO0::PIN<7>, adc_busy2> adc_gen_excitation; Естественно, пины можно и в рантайме перенастроить. Сейчас выкладывать библиотеку стыдновато, я уже тогда хотел всё переделать =) Для тех камней, на которых сейчас сижу, такого не делал - у иаровского оптимизатора глюки наблюдались, а без оптимизации результат очень печальный. Но может и сделаю когда-нибудь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 27 октября, 2015 Опубликовано 27 октября, 2015 · Жалоба Дам ссылку на уже упомянутую в этой теме мою библиотеку для stm32: stm32tpl. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Shalfey 0 6 ноября, 2021 Опубликовано 6 ноября, 2021 · Жалоба GPIOB->AFR[1]|=0x0003; А вот так просто нельзя, просто глянуть в таблицу. Или нужно выпендросы с "простынями" кода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 24 6 ноября, 2021 Опубликовано 6 ноября, 2021 · Жалоба #define GPIO_CAN_RX XGPIO_DEF4('B', 8, 0, 9) #define GPIO_CAN_TX XGPIO_DEF4('B', 9, 0, 9) ... GPIO_set_mode_FUNCTION(GPIO_CAN_RX); GPIO_set_mode_FUNCTION(GPIO_CAN_TX); ... #define XGPIO_DECODE(xGPIO) \ GPIO_TypeDef *GPIO = (GPIO_TypeDef *) (GPIOA_BASE + 0x0400 * XGPIO_GET_PORT(xGPIO)); \ int N = XGPIO_GET_N(xGPIO); void GPIO_set_mode_FUNCTION(int xGPIO) { XGPIO_DECODE(xGPIO); MODIFY_REG(GPIO->AFR[(N > 7) ? 1 : 0], 15UL << ((N & 7) * 4), (XGPIO_GET_FUNC(xGPIO) & 0xF) << ((N & 7) * 4)); MODIFY_REG(GPIO->MODER, 3UL << (N * 2), 2UL << (N * 2)); } Для номеров функций (в параметрах XGPIO_DEF4) можно объявить названия, но у меня не было такой цели, смотрю в документацию когда нужно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MDD 0 7 ноября, 2021 Опубликовано 7 ноября, 2021 · Жалоба 16 hours ago, Shalfey said: GPIOB->AFR[1]|=0x0003; А вот так просто нельзя, просто глянуть в таблицу. Или нужно выпендросы с "простынями" кода. Практиковал такое. Но пришел к выводу, что настройки Куба именно для пинов для меня более комфортны. GPIO_InitStruct.Pin = LL_GPIO_PIN_10; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_6; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); PS.Сейчас досмотрелся. Первый пост через 11 лет после регистрации в тему шестилетней давности! Однако... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SDFV 0 26 августа, 2022 Опубликовано 26 августа, 2022 · Жалоба On 10/20/2015 at 9:24 AM, RadiatoR said: В вашем случае так: GPIOA->AFR[1]|=0x770; Объясните пожалуйста, как сопоставляется этот код, а именно AFR[1] с тем что написано в RM (в частности на STM32F411(сопоставимо с STM32F405/STM32F407); информацию надо смотреть в двух документах?) По Datasheet(?) смотрим маппинг на выводах PA9/PA10 для USART1. Это AF07. По RM0090 смотрим биты для AF7 => 0111. Но в даташите указан регистр GPIOA_AFRH, а у нас GPIOA->AFR[1]. Я так понимаю, что нехватает еще какогото документа Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 26 августа, 2022 Опубликовано 26 августа, 2022 · Жалоба 1 minute ago, SDFV said: GPIOA_AFRH, а у нас GPIOA->AFR[1] Очевидно, GPIOA_AFRL соответствует GPIOA->AFR[0] 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SDFV 0 26 августа, 2022 Опубликовано 26 августа, 2022 · Жалоба Что-то аналогичное в голове крутится). Но хотелось бы прочитать первоисточник. Полгода назад разбирался с этим регистром на STM32F103, в каком то блоге. Тогда более менее стало понятно. Теперь вот с STM32F4 опять возник данный вопрос... У Cortex-M4 регистры только AFR[0] и AFR[1] ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 26 августа, 2022 Опубликовано 26 августа, 2022 · Жалоба 4 минуты назад, SDFV сказал: У Cortex-M4 регистры только AFR[0] и AFR[1] ? Это косяк STM. В документации эти регистры называются AFRL и AFRH, а в поставляемом заголовочном файле описаны как массив из двух регистров. Примите это как есть и не создавайте проблему там где её нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 26 августа, 2022 Опубликовано 26 августа, 2022 · Жалоба Да обозвали всего лишь по-другому, не вижу проблем. С индексом массива код писать проще. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 1 октября, 2022 Опубликовано 1 октября, 2022 · Жалоба On 10/20/2015 at 10:53 AM, GenaSPB said: Или так... #define arm_stm32f30x_hardware_pio_altfn(gpio, opins, afn) \ { \ const portholder_t lo = power4((opins) >> 0); \ const portholder_t hi = power4((opins) >> 8); \ (gpio)->AFR [0] = ((gpio)->AFR [0] & ~ (lo * 0x0f)) | (lo * (afn)); \ (gpio)->AFR [1] = ((gpio)->AFR [1] & ~ (hi * 0x0f)) | (hi * (afn)); \ } while (0) У меня такой вопрос "back to roots": в чём глубинный смысл { ... } while (0) вместо просто { ... } ? У меня и второй вариант всегда работал... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 1 октября, 2022 Опубликовано 1 октября, 2022 · Жалоба 5 minutes ago, KnightIgor said: в чём глубинный смысл { ... } while (0) вместо просто { ... } У меня и второй вариант всегда работал... Так не будет работать: #define f() { ... } if (cond) f(); else ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться