реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Как вы работаете с регистрами GPIOx_AFR?
allsettingsdone
сообщение Oct 20 2015, 08:11
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 22-01-13
Пользователь №: 75 284



Как вы настраиваете альтернативные функции у GPIO с помощью регистров GPIOx_AFR (например при настройке USART1 на PA9, PA10 на STM32F407VG) ? В стандартном файле описания периферии (stm32f4xx.h) - нет информации и масок для работы с этим регистром. Просто высчитываете сами битовую маску и записываете в этот регистр готовое число?
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 20 2015, 08:15
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Некоторые пользуются для этого кубом, но путь настоящего джедая читать описание, по нему находить что надо записать в регистр и писать это туда!

битики в макросах объявлены, комбинацию вычисляете по описанию
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 20 2015, 08:29
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Golikov A. @ Oct 20 2015, 11:15) *
путь настоящего джедая читать описание, по нему находить что надо записать в регистр и писать это туда!

А что, можно как-то по-другому? biggrin.gif
Там даже раскладка регистра очень удобно на шестнадцатеричные константы ложится yeah.gif
Go to the top of the page
 
+Quote Post
smalcom
сообщение Oct 20 2015, 08:41
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 292
Регистрация: 26-06-07
Пользователь №: 28 718



SPL )
Go to the top of the page
 
+Quote Post
allsettingsdone
сообщение Oct 20 2015, 08:51
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 22-01-13
Пользователь №: 75 284



Как узнать число, которое нужно записать в AFRH9 и AFRH10, что бы включить альтернативную функцию USART1 на PA9, PA10 на STM32F407? (это число состоит из 4-ёх бит согласно стр. 287 RM0090)

Сообщение отредактировал allsettingsdone - Oct 20 2015, 08:52
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Oct 20 2015, 08:53
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Или так...

Код
        #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)

Прикрепленные файлы
Прикрепленный файл  pio.zip ( 11.78 килобайт ) Кол-во скачиваний: 11
 
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 20 2015, 08:56
Сообщение #7


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Типа того. Раньше для альтернативных функций конкретно перечисления создавал (typedef enum { AF_SYSTEM, AF_TIM1, AF_TIM2 = 1, AF_TIM3...), потом перестал.
CODE
/*! GPIO Mode Type */
typedef enum {
MD_IN, //!< Input *
MD_GO, //!< General purpose output
MD_AF, //!< Alternate function
MD_AN //!< Analog
} GPIO_MODE_t;

/*! GPIO Output Type */
typedef enum {
OT_PP, //!< Output push-pull*
OT_OD //!< Output open-drain
} GPIO_OTYPE_t;

/*! GPIO Output Speed Type */
typedef enum {
SP_LO, //!< 2 MHz Low speed *
SP_ME, //!< 10 MHz Medium speed
// 2 MHz
SP_HI = 3 //!< 50 MHz High speed
} GPIO_OSPEED_t;

/*! GPIO Pull-Up_Pull-Down Type */
typedef enum {
PL_NP, //!< No pull-up, pull-down *
PL_PU, //!< Pull-up
PL_PD //!< Pull-down
// Reserved
} GPIO_PUPD_t;

/*! GPIO Alternate Functions
The specific alternate function assignments for each pin are detailed in
the device datasheet */
typedef enum {
AF_00, //!< AF0 *
AF_01, //!< AF1
AF_02, //!< AF2
AF_03, //!< AF3
AF_04, //!< AF4
AF_05, //!< AF5
AF_06, //!< AF6
AF_07, //!< AF7
AF_08, //!< AF8
AF_09, //!< AF9
AF_10, //!< AF10
AF_11, //!< AF11
AF_12, //!< AF12
AF_13, //!< AF13
AF_14, //!< AF14
AF_15 //!< AF15
} GPIO_AFLH_t;

#define GPIO_CONF(PORT, \
MD00, OT00, SP00, PL00, AF00, \
MD01, OT01, SP01, PL01, AF01, \
MD02, OT02, SP02, PL02, AF02, \
MD03, OT03, SP03, PL03, AF03, \
MD04, OT04, SP04, PL04, AF04, \
MD05, OT05, SP05, PL05, AF05, \
MD06, OT06, SP06, PL06, AF06, \
MD07, OT07, SP07, PL07, AF07, \
MD08, OT08, SP08, PL08, AF08, \
MD09, OT09, SP09, PL09, AF09, \
MD10, OT10, SP10, PL10, AF10, \
MD11, OT11, SP11, PL11, AF11, \
MD12, OT12, SP12, PL12, AF12, \
MD13, OT13, SP13, PL13, AF13, \
MD14, OT14, SP14, PL14, AF14, \
MD15, OT15, SP15, PL15, AF15); \
GPIO##PORT->MODER = ( \
MD00 << 0 | MD01 << 2 | MD02 << 4 | MD03 << 6 | \
MD04 << 8 | MD05 << 10 | MD06 << 12 | MD07 << 14 | \
MD08 << 16 | MD09 << 18 | MD10 << 20 | MD11 << 22 | \
MD12 << 24 | MD13 << 26 | MD14 << 28 | (uint32_t)MD15 << 30); \
GPIO##PORT->OTYPER = ( \
OT00 << 0 | OT01 << 1 | OT02 << 2 | OT03 << 3 | \
OT04 << 4 | OT05 << 5 | OT06 << 6 | OT07 << 7 | \
OT08 << 8 | OT09 << 9 | OT10 << 10 | OT11 << 11 | \
OT12 << 12 | OT13 << 13 | OT14 << 14 | (uint32_t)OT15 << 15); \
GPIO##PORT->OSPEEDR = ( \
SP00 << 0 | SP01 << 2 | SP02 << 4 | SP03 << 6 | \
SP04 << 8 | SP05 << 10 | SP06 << 12 | SP07 << 14 | \
SP08 << 16 | SP09 << 18 | SP10 << 20 | SP11 << 22 | \
SP12 << 24 | SP13 << 26 | SP14 << 28 | (uint32_t)SP15 << 30); \
GPIO##PORT->PUPDR = ( \
PL00 << 0 | PL01 << 2 | PL02 << 4 | PL03 << 6 | \
PL04 << 8 | PL05 << 10 | PL06 << 12 | PL07 << 14 | \
PL08 << 16 | PL09 << 18 | PL10 << 20 | PL11 << 22 | \
PL12 << 24 | PL13 << 26 | PL14 << 28 | (uint32_t)PL15 << 30); \
GPIO##PORT->AFR[0] = ( \
AF00 << 0 | AF01 << 4 | AF02 << 8 | AF03 << 12 | \
AF04 << 16 | AF05 << 20 | AF06 << 24 | (uint32_t)AF07 << 28); \
GPIO##PORT->AFR[1] = ( \
AF08 << 0 | AF09 << 4 | AF10 << 8 | AF11 << 12 | \
AF12 << 16 | AF13 << 20 | AF14 << 24 | (uint32_t)AF15 << 28);
Go to the top of the page
 
+Quote Post
RadiatoR
сообщение Oct 20 2015, 09:24
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 270
Регистрация: 8-08-15
Из: Москва
Пользователь №: 87 901



Цитата(allsettingsdone @ Oct 20 2015, 11:51) *
Как узнать число, которое нужно записать в AFRH9 и AFRH10, что бы включить альтернативную функцию USART1 на PA9, PA10 на STM32F407? (это число состоит из 4-ёх бит согласно стр. 287 RM0090)


В вашем случае так:
GPIOA->AFR[1]|=0x770;

Если представить вышеуказанное число в двоичном виде, то у нас получится следующее:
0111 0111 0000.
Как вы и писали на каждую ножку настройка функций идет по 4 битам. Здесь последние 4 бита идут нули, а следующие 8 имеют значение 0х77, что соответствует 7 альтернативной функции (USART1) для вашего контроллера на ножках 9 и 10. Сами назначения функций (зависимость функции от числа) можно посмотреть в таблице альтернативных функций в даташите на контроллер
http://www.st.com/web/en/resource/technica.../DM00037051.pdf
Стр. 61

Сообщение отредактировал ЯadiatoR - Oct 20 2015, 09:29
Go to the top of the page
 
+Quote Post
AlanDrakes
сообщение Oct 20 2015, 10:17
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 101
Регистрация: 2-05-15
Из: Россия, Омск
Пользователь №: 86 474



ИМХО, в Datasheet на STM32F407, страница 61, описаны альтернативные функции по каждому пину в виде таблицы. Соответственно, AF0 == 0000 (0), AF15 == 1111 (F), etc.
А уже в Reference manual'е описаны сами регистры.
Так что, пример выбора альтертанивной функции #10 для пина #7 будет выглядеть так:
Код
GPIOn->AFRL &= ~(0xF0000000); // Сброс битов альтертанивных функций для пина
GPIOn->AFRL |= (0xA0000000); // Выставляем биты регистра

Либо
Код
GPIOn->AFRL &= ~(0x0F << 28); // То же, но с предварительными сдвигами.
GPIOn->AFRL |= (0x0A << 28); // То же, но со сдвигом.


Сообщение отредактировал AlanDrakes - Oct 20 2015, 10:18
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 20 2015, 11:23
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



ну и есть дефайн AF0-AF15, его надо использовать вместо явной константы
Go to the top of the page
 
+Quote Post
Эдди
сообщение Oct 20 2015, 11:24
Сообщение #11


Знающий
****

Группа: Участник
Сообщений: 825
Регистрация: 16-04-15
Из: КЧР, Нижний Архыз
Пользователь №: 86 250



В opencm3 нужные макросы есть. И даже функции вроде
Код
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_OFF, AFIO_MAPR_SPI1_REMAP);

(это я SPI на более удобные ноги переносил) или так:
Код
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_OFF, AFIO_MAPR_TIM2_REMAP_PARTIAL_REMAP2);

(а это - переносил таймер на 5-tolerant ноги).
Ну и, естественно, везде в main() до конфигурирования ног делаю
Код
AFIO_MAPR = AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_OFF;

(по какой-то глупой причине это приходится явно делать)
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Oct 21 2015, 11:44
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(allsettingsdone @ Oct 20 2015, 11:11) *
Как вы настраиваете альтернативные функции у GPIO с помощью регистров GPIOx_AFR (например при настройке USART1 на PA9, PA10 на STM32F407VG) ?


Странно, что никто не сказал, что единственный правильный путь - это STM32Tpl.

Код
Pin<'A',9>::Alternate (ALT_FUNC_USART1);
Pin<'A',10>::Alternate (ALT_FUNC_USART1);


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 21 2015, 13:12
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



а как этот правильный путь поможет задать альтернативные функции LPC? или право делать процы с альтернативными функциями пинов на арм ядре только у СТМsm.gif?

Правильный путь для любого проца, настроить регистры согласно описанию!
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 21 2015, 14:46
Сообщение #14


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Golikov A. @ Oct 21 2015, 18:12) *
а как этот правильный путь поможет задать альтернативные функции LPC?

Название темы хронически не читаем? Где у LPC регистр GPIOx_AFR?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 21 2015, 14:47
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



ну это так докопаться....
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Oct 22 2015, 06:22
Сообщение #16


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(Golikov A. @ Oct 21 2015, 16:12) *
а как этот правильный путь поможет задать альтернативные функции LPC? или право делать процы с альтернативными функциями пинов на арм ядре только у СТМsm.gif?


Если мне придётся снова работать с LPC'хами, буду делать библиотеку по образу и подобию.
Когда-то у меня был набор макросов (в принципе, то же самое - задавался порт, пин, режим пина), но эти хитрые шаблоны удобнее.

Варианты ЯadiatoR и AlanDrakes, которые прочитали даташит, явно неудобные. Пусть компилятор нужные смещения считает, он железный.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
adnega
сообщение Oct 22 2015, 07:15
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Инициализирую все выводы в одном месте init_GPIO()
CODE
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);
Go to the top of the page
 
+Quote Post
Alechek
сообщение Oct 26 2015, 08:52
Сообщение #18


Профессионал
*****

Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882



Инициалиация в одном месте хорошо. Но иногда не прокатывает: при работе с встраиваемыми модулями (GSM и прочие) сразу инициализировать ноги нельзя, вначале надо подать на модуль питание. И, соотвественно, иницалиировать в третье состяоние при снятии питания.
Таким образом, инциализация ног происходит не разово, а постоянно в работе.
Для LPC и STM создан "drv_gpio"

Все регистры для установки ног вычиляются внутри функции IO_SetupPin(..)
С одной стороны, лишние накладные расходы, с другой - код намного читабельнее и понятнее.
Единстенное, что никак не стандартизируешь - вариант альтернативной конфиграции ноги. Тут уж придется лезть в даташит.

CODE
#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
Go to the top of the page
 
+Quote Post
den_po
сообщение Oct 27 2015, 08:03
Сообщение #19


Частый гость
**

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Цитата(esaulenka @ Oct 22 2015, 09:22) *
Если мне придётся снова работать с 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;

Естественно, пины можно и в рантайме перенастроить.
Сейчас выкладывать библиотеку стыдновато, я уже тогда хотел всё переделать =)
Для тех камней, на которых сейчас сижу, такого не делал - у иаровского оптимизатора глюки наблюдались, а без оптимизации результат очень печальный. Но может и сделаю когда-нибудь.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 27 2015, 08:57
Сообщение #20


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Дам ссылку на уже упомянутую в этой теме мою библиотеку для stm32: stm32tpl.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 22:02
Рейтинг@Mail.ru


Страница сгенерированна за 0.01591 секунд с 7
ELECTRONIX ©2004-2016