Например TDA7294

Форум РадиоКот • Просмотр темы - STM32 новичку в ARM что к чему
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Вт апр 16, 2024 14:22:08

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 8459 ]     ... , , , 387, , , ...  
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Чт май 26, 2022 17:04:13 
Открыл глаза

Зарегистрирован: Ср сен 24, 2014 12:30:09
Сообщений: 62
Рейтинг сообщения: 0
Быть может, стоило бы прочесть Reference Manual, раздел USART? Потому что там очень доходчиво, даже с диаграммами, расписано всё. Можете через гугл-переводчик, если проблемы с английским


Читал, но я много чего там не понимаю. Не в смысле языка, а а смысле работы всего этого хозяйства. Например, мне не понятно, выставляется ли бит RXNE при срабатывании прерывания по Idle. Со временем, думаю, пойму.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Чт май 26, 2022 19:23:43 
Потрогал лапой паяльник
Аватар пользователя

Карма: -6
Рейтинг сообщений: -1
Зарегистрирован: Вс апр 03, 2022 07:01:29
Сообщений: 362
Рейтинг сообщения: 2
Но ведь это несложно и проверить на деле.
Нет, не выставляется, ведь ничего не было принято, поскольку старт-бит и стоп-бит не были обнаружены, и запуска сдвигового регистра приема не было.
Во время приема флаг RXNE выставляется в конце приема байта, а флаг IDLE будет выставлен после того, как линия RX будет оставаться свободной в течение времени, равного длительности кадра (обычно 10 бит).
Флаг ORE (overrun) будет выставляться тогда, когда был принят новый байт, а предыдущий не был прочитан.


Код:
oid USART2_IRQHandler(void)
{
   /* Линия свободна (idle frame) */
   if((USART2->ISR & USART_ISR_IDLE)&&(USART2->CR1 & USART_CR1_IDLEIE))
   {
      Start_RTOTimer();
      USART2->ICR = USART_ICR_IDLECF;
   }

   /* Предыдущий принятый символ не был прочитан */
   if(USART2->ISR & USART_ISR_ORE)
   {
      ToRXBuff(USART2->RDR);
      USART2->ICR = USART_ICR_ORECF;
   }

   /* Символ был принят */
   if((USART2->ISR & USART_ISR_RXNE)&&(USART2->CR1 & USART_CR1_RXNEIE))
   {
      Stop_RTOTimer();
      ToRXBuff(USART2->RDR);
   }

   /* Готов к передаче символа */
   if((USART2->ISR & USART_ISR_TXE)&&(USART2->CR1 & USART_CR1_TXEIE))
   {
      uint8_t ch;
      if(FromTXBuff(&ch))
         USART2->TDR = ch;
      else
         USART2->CR1 &= ~USART_CR1_TXEIE;
   }

   /* Передача символа была завершена и передающий буфер пуст */
   if((USART2->ISR & USART_ISR_TC)&&(USART2->CR1 & USART_CR1_TCIE))
   {

   }

   /* Ошибка кадра в приемнике */
   if(USART2->ISR & USART_ISR_FE)
   {
      USART2->ICR = USART_ICR_FECF;
   }
}

причем, запуск RTO-таймера можно делать или в IDLE, или в RXNE. В последнем случае таймер не останавливается, а перезапускается с начала.
Так же, я настоятельно рекомендую использовать проверку не только флага источника прерывания, но и бита разрешения этого источника. Особенно это необходимо при передаче по TXE-флагу. Этот флаг устанавливается независимо от того, включен передатчик (TE) или выключен. И попадая в прерывание по другому источнику, будет лишняя загрузка передающего регистра. Именно с помощью запрета прерывания TXEIE прекращается передача (в варианте передачи по прерываниям).
Флаг TC устанавливается по завершению передачи символа, если в передающем буфере нет загруженных байтов (TXE = 1).

Ну и не надо писать if((USART1->SR & USART_SR_RXNE) >> USART_SR_RXNE_Pos) == 1), поскольку это излишние действия. Нужно отталкиваться от того, что по правилам языка Си, выражение в if() будет истинно при любом ненулевом значении. А запись USART1->SR & USART_SR_RXNE представляет собой логическую побитовую операцию AND с содержимым регистра и значением битовой маски. То есть, например 0110 AND 0100 = 0100, это есть ненулевое значение и условие if будет истинно и выполнится. Если же 0010 AND 0100 = 0000, то условие if будет ложно и не выполнится.

& - означает побитовую операцию AND двух чисел.
&& - означает логическое AND выражений: "если (ВЫРАЖЕНИЕ_1 = истина) И (ВЫРАЖЕНИЕ_2 = истина)"


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 07:19:06 
Открыл глаза

Зарегистрирован: Ср сен 24, 2014 12:30:09
Сообщений: 62
Рейтинг сообщения: 0
НовыйДень писал(а):
Но ведь это несложно и проверить на деле.
Нет, не выставляется, ведь ничего не было принято, поскольку старт-бит и стоп-бит не были обнаружены, и запуска сдвигового регистра приема не было.
Во время приема флаг RXNE выставляется в конце приема байта, а флаг IDLE будет выставлен после того, как линия RX будет оставаться свободной в течение времени, равного длительности кадра (обычно 10 бит).
Флаг ORE (overrun) будет выставляться тогда, когда был принят новый байт, а предыдущий не был прочитан.


"


Спасибо, ну прямо очень подробно! Сохранил себе в текстовый документ. Попробую!


Последний раз редактировалось Lum1noFor Пт май 27, 2022 09:20:08, всего редактировалось 2 раз(а).

Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 07:41:12 
Электрический кот

Карма: -4
Рейтинг сообщений: 70
Зарегистрирован: Вт ноя 19, 2019 06:10:18
Сообщений: 1054
Рейтинг сообщения: 0
Eddy_Em писал(а):
У меня UART работает через DMA: где-то только передача, где-то - и передача, и прием. И я ни разу в жизни ни IDLE, ни RTO не использовал. ЧЯДНТ?

Расскажи, как ты определяешь конец сообщения, при приёме с использованием DMA?
Возможны всего два варианта: по паузе между байтами или по коду символа.


Вернуться наверх
 
Организация питания на основе надежных литиевых аккумуляторов EVE и микросхем азиатского производства

Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 09:22:31 
Друг Кота
Аватар пользователя

Карма: 138
Рейтинг сообщений: 2712
Зарегистрирован: Чт янв 10, 2008 22:01:02
Сообщений: 21788
Откуда: Московская область, Фрязино
Рейтинг сообщения: 0
Возможны всего два варианта: по паузе между байтами или по коду символа.

Не только.
Есть еще весьма широко распространенный вариант с ФИКСИРОВАННОЙ ДЛИНОЙ пакета.
Скажем, лично я использую во всех своих проектах именно такой вариант. Он происходит из простого факта применения в коммуникациях проекта, в том числе, кастомного HID USB с пакетом в 64 байта. Вот эти пакеты у меня везде и гуляют через DMA<->RS485/RS422.


Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 09:47:00 
Собутыльник Кота
Аватар пользователя

Карма: -12
Рейтинг сообщений: -25
Зарегистрирован: Пт июл 12, 2019 22:52:01
Сообщений: 2525
Рейтинг сообщения: 0
Расскажи, как ты определяешь конец сообщения, при приёме с использованием DMA?

Элементарно: в STM32F0x2 есть прерывание по символу. Вот я по '\n' и вызываю прерывание, выключаю в нем DMA, меняю местами буферы и выставляю флаг готовности принятой строки. А DMA тем временем во второй буфер поступающие данные копит.
Там, где нет такого прерывания, я обычно прием без DMA делаю. Потому как пользователь не обязан отправлять блоки строго по одной строке: может и несколько строк отправить, а у меня логическая единица - одна строчка. Вот, чтобы не париться с промежуточным буфером, который будет на токены принятое разделять, я и заканчиваю прием строго на '\n', меняю буферы и выставляю флаг готовности.

_________________
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 09:52:21 
Электрический кот

Карма: -4
Рейтинг сообщений: 70
Зарегистрирован: Вт ноя 19, 2019 06:10:18
Сообщений: 1054
Рейтинг сообщения: 0
Возможны всего два варианта: по паузе между байтами или по коду символа.

Не только.
Есть еще весьма широко распространенный вариант с ФИКСИРОВАННОЙ ДЛИНОЙ пакета.
Скажем, лично я использую во всех своих проектах именно такой вариант. Он происходит из простого факта применения в коммуникациях проекта, в том числе, кастомного HID USB с пакетом в 64 байта. Вот эти пакеты у меня везде и гуляют через DMA<->RS485/RS422.

Ага, а если последний байт пакета не потеряется, например, с передатчика сняли питание? Тогда как? Опять звать на помощь таймер для измерения длительности паузы при приёме? Или тупо ждать следующего пакета, чтоб не заводить таймер? В итоге всё равно не получается третий вариант, однако.

Добавлено after 2 minutes 23 seconds:
Расскажи, как ты определяешь конец сообщения, при приёме с использованием DMA?

Элементарно: в STM32F0x2 есть прерывание по символу. Вот я по '\n' и вызываю прерывание, выключаю в нем DMA, меняю местами буферы и выставляю флаг готовности принятой строки. А DMA тем временем во второй буфер поступающие данные копит.
Там, где нет такого прерывания, я обычно прием без DMA делаю. Потому как пользователь не обязан отправлять блоки строго по одной строке: может и несколько строк отправить, а у меня логическая единица - одна строчка. Вот, чтобы не париться с промежуточным буфером, который будет на токены принятое разделять, я и заканчиваю прием строго на '\n', меняю буферы и выставляю флаг готовности.

Так ведь я тебя и спрашивал, по паузе или коду символа? То есть по коду символа, как и ожидалось. Ибо по-другому никак.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 09:59:00 
Друг Кота
Аватар пользователя

Карма: 138
Рейтинг сообщений: 2712
Зарегистрирован: Чт янв 10, 2008 22:01:02
Сообщений: 21788
Откуда: Московская область, Фрязино
Рейтинг сообщения: 0
а если последний байт пакета не потеряется, например, с передатчика сняли питание? Тогда как?

Ну сняли и сняли. Пропадет последний незавершенный и первый пакет после включения. Первый после включения завершит сессию DMA и перезапустит ожидание адресного байта.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 10:02:08 
Электрический кот

Карма: -4
Рейтинг сообщений: 70
Зарегистрирован: Вт ноя 19, 2019 06:10:18
Сообщений: 1054
Рейтинг сообщения: 0
а если последний байт пакета не потеряется, например, с передатчика сняли питание? Тогда как?

Ну сняли и сняли. Пропадет последний незавершенный и первый пакет после включения. Первый после включения завершит сессию DMA и перезапустит ожидание адресного байта.

Хм, то есть факт потери связи зафиксирован не будет.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 10:04:27 
Собутыльник Кота
Аватар пользователя

Карма: -12
Рейтинг сообщений: -25
Зарегистрирован: Пт июл 12, 2019 22:52:01
Сообщений: 2525
Рейтинг сообщения: 0
tonyk, почему же по-другому - никак? Можно и по таймауту. Только придется городить промежуточную буферизацию (кольцевой буфер) с построчной выдачей.
Я вот баловался с передачей по USB, используя кольцевой буфер — чтобы максимально увеличить скорость выдачи данных и избавиться от блокирующих операций.

_________________
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 10:21:12 
Друг Кота
Аватар пользователя

Карма: 138
Рейтинг сообщений: 2712
Зарегистрирован: Чт янв 10, 2008 22:01:02
Сообщений: 21788
Откуда: Московская область, Фрязино
Рейтинг сообщения: 0
Хм, то есть факт потери связи зафиксирован не будет.

Почему не будет? Будет. Это делает хост (сиречь программа в винде). А девайсу болт положить на связь. Его функционирование никак с наличием обмена не связано. Через обмен идет управление и мониторинг. Все это не обязательно.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 10:47:53 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Eddy_Em писал(а):
Элементарно: в STM32F0x2 есть прерывание по символу. Вот я по '\n' и вызываю прерывание, выключаю в нем DMA, меняю местами буферы и выставляю флаг готовности принятой строки.
а контроль переполнения буфера как реализован? а то ведь это классическая дыра...

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 11:02:36 
Друг Кота
Аватар пользователя

Карма: 138
Рейтинг сообщений: 2712
Зарегистрирован: Чт янв 10, 2008 22:01:02
Сообщений: 21788
Откуда: Московская область, Фрязино
Рейтинг сообщения: 0
контроль переполнения буфера как реализован?

Очевидно, что по прерыванию от ДМА. Только не переполнение, а заполненный буфер.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 11:31:28 
Электрический кот

Карма: -4
Рейтинг сообщений: 70
Зарегистрирован: Вт ноя 19, 2019 06:10:18
Сообщений: 1054
Рейтинг сообщения: 0
Eddy_Em писал(а):
Можно и по таймауту. Только придется городить промежуточную буферизацию (кольцевой буфер) с построчной выдачей.

А можно ничего не городить, а использовать уже имеющийся во всех STM32 IDLE или, что лучше, RTO. :)))


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 11:40:03 
Собутыльник Кота
Аватар пользователя

Карма: -12
Рейтинг сообщений: -25
Зарегистрирован: Пт июл 12, 2019 22:52:01
Сообщений: 2525
Рейтинг сообщения: 0
использовать уже имеющийся во всех STM32 IDLE или, что лучше, RTO. :)))

А кто сказал, что байты должны идти "ноздря в ноздрю"? Может, между ними по 2-4 свободных фрейма? И окончанием передачи считать, скажем, паузу дольше 100мс после последнего байта…
Я таймауты вообще на терминале тестировал, у меня был выставлен таймаут в 3 секунды (уж за три-то секунды я успею следующий символ набрать =D)

Что до переполнения буфера: а как он переполнится, когда прием идет посредством DMA? По заполнению буфера идет прерывание, и коль не было '\n' в процессе, считаем строку бажной и сбрасываем нафиг с выставлением флага ошибки (т.е. следующий пакет тоже нужно будет выбросить).

_________________
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 12:29:40 
Первый раз сказал Мяу!

Карма: -1
Рейтинг сообщений: 1
Зарегистрирован: Вт май 17, 2022 09:49:48
Сообщений: 26
Рейтинг сообщения: 0
Спойлер
Код:
oid USART2_IRQHandler(void)
{
   /* Линия свободна (idle frame) */
   if((USART2->ISR & USART_ISR_IDLE)&&(USART2->CR1 & USART_CR1_IDLEIE))
   {
      Start_RTOTimer();
      USART2->ICR = USART_ICR_IDLECF;
   }

   /* Предыдущий принятый символ не был прочитан */
   if(USART2->ISR & USART_ISR_ORE)
   {
      ToRXBuff(USART2->RDR);
      USART2->ICR = USART_ICR_ORECF;
   }

   /* Символ был принят */
   if((USART2->ISR & USART_ISR_RXNE)&&(USART2->CR1 & USART_CR1_RXNEIE))
   {
      Stop_RTOTimer();
      ToRXBuff(USART2->RDR);
   }

   /* Готов к передаче символа */
   if((USART2->ISR & USART_ISR_TXE)&&(USART2->CR1 & USART_CR1_TXEIE))
   {
      uint8_t ch;
      if(FromTXBuff(&ch))
         USART2->TDR = ch;
      else
         USART2->CR1 &= ~USART_CR1_TXEIE;
   }

   /* Передача символа была завершена и передающий буфер пуст */
   if((USART2->ISR & USART_ISR_TC)&&(USART2->CR1 & USART_CR1_TCIE))
   {

   }

   /* Ошибка кадра в приемнике */
   if(USART2->ISR & USART_ISR_FE)
   {
      USART2->ICR = USART_ICR_FECF;
   }
}

ухты как классно сделано! взял себе


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 12:32:30 
Электрический кот

Карма: -4
Рейтинг сообщений: 70
Зарегистрирован: Вт ноя 19, 2019 06:10:18
Сообщений: 1054
Рейтинг сообщения: 0
Eddy_Em писал(а):
А кто сказал, что байты должны идти "ноздря в ноздрю"? Может, между ними по 2-4 свободных фрейма?

А ты поставь в настройках терминала, чтоб он отправлял сразу всю строку по нажатию "Enter", вот твои байты и пойдут ноздря-в-ноздрю.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Пт май 27, 2022 17:05:58 
Потрогал лапой паяльник
Аватар пользователя

Карма: -6
Рейтинг сообщений: -1
Зарегистрирован: Вс апр 03, 2022 07:01:29
Сообщений: 362
Рейтинг сообщения: 0
Одного универсального способа нет, всегда пишется под конкретную задачу. Где-то пакеты все одинаковой длины, где-то разной длины, но начинаются/заканчиваются определенными символами, где-то инфа в нетекстовом виде и нет определенного завершающего символа, где-то разрозненные символы с произвольными промежутками, где-то минимальные промежутки между пакетами регламентированы, а где-то есть контроль четности. Где-то очень высокая скорость порта и нужен DMA на прием/отправку, а где-то скорость низкая по отношению к частоте МК, да еще и занят нужный канал DMA.
Вобщем, ты владеешь несколькими методами работы и выбираешь в конкретном случае наиболее подходящий. Так и везде, в принципе то. Поэтому спорить, что дескать только DMA форева или стопудово только прерывания - не имеет смысла.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Вт июн 14, 2022 10:01:26 
Опытный кот

Карма: 16
Рейтинг сообщений: 177
Зарегистрирован: Сб апр 14, 2012 16:11:35
Сообщений: 718
Рейтинг сообщения: 0
Уважаемые знатоки, подскажите в решении проблемы. Использовал STM32F051 совместно с отладчиком BlackMagik. Сначала всё работало как часы, прошивало, отлаживало. Но в один момент чип перестал видиться отладчиком. Достал ST-Link. С ним теперь возможна только запись прошивки из-под ресета через родную прогу, без отладки. Пин BOOT0 сидит на земле, то есть используется запуск из прошивки флеш, пины SWD в проекте вообще не заняты и нигде не переназначаются. Куда копать для восстановления нормальной работы SWD?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 новичку в ARM что к чему
СообщениеДобавлено: Вт июн 14, 2022 10:21:40 
Первый раз сказал Мяу!

Карма: -1
Рейтинг сообщений: 1
Зарегистрирован: Вт май 17, 2022 09:49:48
Сообщений: 26
Рейтинг сообщения: 0
наверно отключили swd в настройках cubeide


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 8459 ]     ... , , , 387, , , ...  

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 13


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y