Например TDA7294

Форум РадиоКот • Просмотр темы - Вопросы по С/С++ (СИ)
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Сб июн 28, 2025 23:51:08

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


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



Начать новую тему Ответить на тему  [ Сообщений: 7669 ]     ... , , , 10, , , ...  
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Чт янв 13, 2011 15:00:42 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 21
Рейтинг сообщений: 143
Зарегистрирован: Сб фев 21, 2009 13:11:40
Сообщений: 1900
Откуда: Москва
Рейтинг сообщения: 0
asteroid7 писал(а):
Оно выводится в окно "Build". А настройки Tools->Options->Messages->Show Build стоит в All или Messages ?
:lol: везде полазил, а в Options самой среды разработки не залез))) получилось. ОГРОМНОЕ СПАСИБО, Asteroid7!!!! стояло значение "warnings", поставил "messages" - теперь сообщение выводится.
Если не затруднит, уточните, можно ли в этом сообщении выводить какие либо константы, объявленные заранее директивой #define?

_________________
Ставим плюсы: )


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Пт янв 14, 2011 20:38:57 
Опытный кот
Аватар пользователя

Зарегистрирован: Вс янв 18, 2009 21:12:49
Сообщений: 703
Рейтинг сообщения: 0
Хочу выразить благодарность avreal и ARV. Заставили меня пересмотреть отношение к реализации критических секций на микроконтроллерах. Вопрос - "Почему зная об этом ты это не использовал?" - вогнал меня в небольшой ступор ) Мдаа, много думал...

Для GCC avreal класс критических секций привёл выше, а я приведу для IAR-a не подключая никаких хиадеров. Возможно, кому пригодится:
Код:
__intrinsic unsigned char __save_interrupt( void );
__intrinsic void  __restore_interrupt( unsigned char );
__intrinsic void __enable_interrupt(void);
__intrinsic void __disable_interrupt(void);

#ifdef __cplusplus

/* Class for controlling critical blocks */
class MUTEX
{
    public:
        MUTEX ()
        {
            __state = __save_interrupt();
            __disable_interrupt();
        }

        ~MUTEX ()
        {
            __restore_interrupt( __state );
        }
       
    private:
        unsigned char __state;
};

#endif

Реализация, как обычный локальный класс:
Код:
        //---critical block---
        MUTEX m;
        ...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Пт янв 14, 2011 20:46:41 
Опытный кот
Аватар пользователя

Зарегистрирован: Вс янв 18, 2009 21:12:49
Сообщений: 703
Рейтинг сообщения: 0
avreal писал(а):
А вот пример, где логическая ошибка может быть для _любой_ архитектуры (хоть 128-битной), а предупреждения нет.
Код:
volatile char a;
volatile char b;
bool foo()
{
    char ta = a;
    return ta == b;
}


Не увидел в этом коде ошибки... Не затруднит Вас разъяснить этот момент.
Единственное, что бросается в глаза, это логическое "==" без скобок. Так это допускается стандартом.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Пт янв 14, 2011 21:02:10 
Опытный кот
Аватар пользователя

Зарегистрирован: Вс янв 18, 2009 21:12:49
Сообщений: 703
Рейтинг сообщения: 0
ibiza11 писал(а):
Если не затруднит, уточните, можно ли в этом сообщении выводить какие либо константы, объявленные заранее директивой #define?
Только текст, заключённый в скобки, выводится. В PDF файле help->AVR C/C++ Compiler Reference Guide можно это уточнить.

Мне не удалось найти применению этой #pragma message диррективы.
Есть интереснее: #error. Она компиляцию останавливает. Удобно предкомпиляционные вычисления и наличие define-ов проверять. Например:
Код:
#if !defined(PIN_SELECT)
#       error "Не задана нога выборки чего то..."
#endif

#if UART_BUFFER < 300
#       error "Буфер маленький... Нужно не менее 300 байт..."
#endif


Вернуться наверх
 
Выбираем индустриальные и медицинские источники питания MEAN WELL в открытом исполнении

Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Пт янв 14, 2011 21:39:51 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 21
Рейтинг сообщений: 143
Зарегистрирован: Сб фев 21, 2009 13:11:40
Сообщений: 1900
Откуда: Москва
Рейтинг сообщения: 0
asteroid7 писал(а):
Только текст, заключённый в скобки, выводится. В PDF файле help->AVR C/C++ Compiler Reference Guide можно это уточнить.

Спасибо, Asteroid7, за ответ. Видимо остальным было влом отвечать. Я уже всю документацию перелопатил и очень много гуглил и яндексил:) действительно, я тоже не нашел как вывести константу, определенную директивой #define. Чтобы проверить какую то промежуточную константу приходится на этапе отладки добавлять в код строчки типа
Код:
#define A ((C+D)/B-D)
...
TCCR0=A;
а потом просматривать ассемблерный листинг в этом месте. Очень неудобно. Насчет #error и #warning я тоже уже знаю) в принципе и до этого знал)))) Только там тоже нельзя выводить объявленные константы. кстати #warning не останавливает компиляцию (логично, скажете Вы :) ).
А как Вы проверяете константы, расчет которых возлагаете на препроцессор?

P.S. может кому пригодится расчет значения регистра UBRR с округлением к ближайшему значению (для 16ти семплового приема):
Код:
enum{CPU_F_MHz=16};
enum{BAUD_RATE=115200}; // скорость обмена
enum{CUR_UBRR_10x=(CPU_F_MHz*10000000/16/BAUD_RATE-10)}; //константа для записи в регистр UBRR умноженная на 10
enum{A=((CUR_UBRR_10x-5)/10),B=(CUR_UBRR_10x/10),C=B-A}; //(НАЧАЛО)округление константы для записи в регистр UBRR
#if C==0x00
#define CUR_UBRR (A+1)
#else
#define CUR_UBRR B
#endif                                                   //(КОНЕЦ) округление константы для записи в регистр UABRR
...                                                      // значение UBRR находится в CUR_UBRR
UBRR=CUR_UBRR;


В аттаче добавил расчет UBRR в Excel.


Вложения:
Комментарий к файлу: Расчет UBRR в Excel
Расчет UBRR.xls [25 KiB]
Скачиваний: 233

_________________
Ставим плюсы: )
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Пт янв 14, 2011 22:48:33 
Опытный кот
Аватар пользователя

Карма: 7
Рейтинг сообщений: 52
Зарегистрирован: Чт дек 31, 2009 19:27:45
Сообщений: 842
Откуда: Бровари, Україна
Рейтинг сообщения: 0
asteroid7 писал(а):
Для GCC avreal класс критических секций привёл выше, а я приведу для IAR-a не подключая никаких хиадеров.
Собственно, я привёл класс критической секции из AVR/GCC порта операционной системы scmRTOS, написанной на С++.
Ваш пример можно сделать "несколько С++-нее", сделав сохранение состояния прерываний не присваиванием, а инициализацией.
Код:
MUTEX () :  __state( __save_interrupt() )
        {
            __disable_interrupt();
        }
Тогда он станет ещё более похожим на соответствующий класс AVR/IAR порта scmRTOS.

scmRTOS wiki http://scmrtos.sourceforge.net/ScmRTOS
Немного о ней у меня на сайте http://real.kiev.ua/scmRTOS — ссылки и подробное объяснение одного из примеров.

_________________
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.


Вернуться наверх
 
Распродажа паяльного оборудования ATTEN!
Паяльные станции, паяльники и аксессуары по самой выгодной цене.

По промокоду radiokot скидка 10%
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Пт янв 14, 2011 23:06:37 
Опытный кот
Аватар пользователя

Карма: 7
Рейтинг сообщений: 52
Зарегистрирован: Чт дек 31, 2009 19:27:45
Сообщений: 842
Откуда: Бровари, Україна
Рейтинг сообщения: 0
asteroid7 писал(а):
Не увидел в этом коде ошибки... Не затруднит Вас разъяснить этот момент.
Единственное, что бросается в глаза, это логическое "==" без скобок. Так это допускается стандартом.
А её и компилятор не видит :-)
Я ж говорю, он не догадывается ни о чём.
Тут может быть логическая ошибка, в точности та же, что и в Вашем примере про 8-битный контроллер и 16-битные данные.
Если переменные a и b меняются в прерывании вместе и должны обрабатываться согласованно (я привёл сравнение просто в качестве примера примитивной обработки), то их надо читать обязательно в общей критической секции в две временные переменные и только потом обрабатывать. Но компилятор об этом не знает, поэтому и не предупреждает. В отличие от прямого сравнения a == b, где он ворчит о возможной зависимости от порядка чтения.

Кстати, не всегда даже 16-битную переменную (имеются ввиду 8-битники, конечно), изменяемую в прерывании, обязательно читать в крит. секции. Пусть у нас есть таймаут, декрементируемый в прерывании до 0.
Код:
volatile uint16_t timeout;

some_ISR()
{
    if( timeout ) --timeout;
}

bool is_timeout_expired()
{
    return HIGH_BYTE( timeout ) == 0 && LOW_BYTE( timeout ) == 0;
}
Тут немного условно показано. И ISR без привязки к компилятору, и не показано само чтение. Можно timeout сделать объединением { uint16_t u; uint8_t b[2]; } и в макросах читать из байтовой части, можно в макросах обращаться по приведённому к (volatile uint8_t *) указателю со смещениями, не важно.
Важно то, что прерывание только декрементирует переменную и 0 уже не трогает.
СС++ для встроенного оператора &&) гарантирует, что вычисление операндов идёт слева направо с прекращением вычислений, когда результат уже ясен. Поэтому чтение сначала старшей части безопасно.
Старшая часть если уже стала 0, то при анализе младшей уже не поменяется.
А если ещё не 0, то младшая и не зачитывается.
Если за время сравнения с 0 старшей части младшая меняется — ну и ладно. Если к тому времени сама станет нулём — тем лучше, раньше узнаем об окончании таймаута :-)

_________________
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Сб янв 15, 2011 01:11:27 
Опытный кот
Аватар пользователя

Карма: 7
Рейтинг сообщений: 52
Зарегистрирован: Чт дек 31, 2009 19:27:45
Сообщений: 842
Откуда: Бровари, Україна
Рейтинг сообщения: 0
ibiza11 писал(а):
А как Вы проверяете константы, расчет которых возлагаете на препроцессор?
P.S. может кому пригодится расчет значения регистра UBRR с округлением к ближайшему значению (для 16ти семплового приема):
Я не смотрю глазами на сами константы. Если мне нужно проверить отклонение, то тогда из CURR_UBRR назад рассчитывается REAL_BAUD, потом
Код:
#define BAUD_THOUSANDTH   15 /* Отклонение 15 тысячных, 1.5% */
#define BAUD_LIMIT (BAUD_RATE * BAUD_THOUSANDTH / 1000)
#if (REAL_BAUD - BAUD_RATE) > BAUD_LIMIT || (REAL_BAUD - BAUD_RATE) < -BAUD_LIMIT
#error "Baudrate is out of range"
#endif
А округлять проще так:
Код:
#define DIV_ROUND(dividend, divider) ( (dividend + divider/2) / divider )
#define CUR_UBRR  DIV_ROUND( CPU_F_MHz*1000000/16, BAUD_RATE)

_________________
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Сб янв 15, 2011 02:20:50 
Вымогатель припоя

Карма: 2
Рейтинг сообщений: 2
Зарегистрирован: Пн мар 23, 2009 04:03:45
Сообщений: 557
Рейтинг сообщения: 0
ibiza11 писал(а):

P.S. может кому пригодится расчет значения регистра UBRR с округлением к ближайшему значению (для 16ти семплового приема):


У меня адаптивная настройка "аналога" UBRR (в пиках он обзывается SPBRG) реализована так:

Код:
#define BAUDRATE            19200U
unsigned int      oscMeasuredValue = 31250;   //fosc = 128 * oscMeasuredValue; 31250*128=4000000
//....
unsigned int Get_Osc_Freq (void);
//....
oscMeasuredValue = Get_Osc_Freq();   //Измерение частоты
SPBRG   = ((oscMeasuredValue + (BAUDRATE/16)) / (BAUDRATE/8) - 1);

Сперва в программе измеряется тактовая частота внутреннего RC-генератора (в попугаях, дабы уложиться в двухбайтовую переменную), потом вычисляется нужное значение регистра c округлением.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Сб янв 15, 2011 09:07:50 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 21
Рейтинг сообщений: 143
Зарегистрирован: Сб фев 21, 2009 13:11:40
Сообщений: 1900
Откуда: Москва
Рейтинг сообщения: 0
Спасибо за формулу округления:) что-то я совсем по сложному пути пошел)))) Вроде в школьном курсе алгебры была подобная формула? 8)

_________________
Ставим плюсы: )


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс янв 16, 2011 16:31:29 
Опытный кот
Аватар пользователя

Зарегистрирован: Вс янв 18, 2009 21:12:49
Сообщений: 703
Рейтинг сообщения: 0
ibiza11 писал(а):
Видимо остальным было влом отвечать.
На этом форуме единицы, кто использует IAR. Но, последние полгода интерес к нему увеличился )

ibiza11 писал(а):
А как Вы проверяете константы, расчет которых возлагаете на препроцессор?
Например, проверка переполнения регистра OCR (8 бит) в качестве генерации меандра для разной частоты. Приведу утрированно, но смысл думаю будет понятен.
Код:
#define VAL_OCR( del, freq_hz ) ( ( QUARZ_FREQUENCY / ( del * freq_hz ) >> 1 ) - 1 )

//меандр для 1000 Hz
#define VAL_OCR_1000    VAL_OCR( 128ul, 1000ul )
//меандр для 2000 Hz
#define VAL_OCR_2000    VAL_OCR( 1ul, 2000ul )

#if VAL_OCR_1000 > 255
#error "1000 Hz - не влазит в байт. Нужно увеличить делитель"
#endif

#if VAL_OCR_2000 > 255
#error "2000 Hz - не влазит в байт. Нужно увеличить делитель"
#endif


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс янв 16, 2011 16:47:25 
Опытный кот
Аватар пользователя

Зарегистрирован: Вс янв 18, 2009 21:12:49
Сообщений: 703
Рейтинг сообщения: 0
avreal писал(а):
Ваш пример можно сделать "несколько С++-нее", сделав сохранение состояния прерываний не присваиванием, а инициализацией.
Согласен, Ваш вариант красивее.
Не то чтобы не доверяю, но навсякий случай перепроверил генерируемый код. Один в один.

avreal писал(а):
А её и компилятор не видит Я ж говорю, он не догадывается ни о чём.Тут может быть логическая ошибка, в точности та же, что и в Вашем примере про 8-битный контроллер и 16-битные данные.Если переменные a и b меняются в прерывании вместе...
Так я и думал - затупил. Не проанализировал при обоюдном изменении. )


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс янв 16, 2011 23:37:12 
Мудрый кот
Аватар пользователя

Карма: 25
Рейтинг сообщений: 79
Зарегистрирован: Вт окт 05, 2010 01:08:57
Сообщений: 1800
Рейтинг сообщения: 0
Знаю что элементарно, и даже как то делал раньше, но забыл как. :roll: Мне нужно 4 младших бита переменной типа unsigned int занести в 11,12,13,14 бит другой переменной типа unsigned long int (естественно не меняя остальных). Подскажите как.

_________________
KIT


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс янв 16, 2011 23:53:27 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 21
Рейтинг сообщений: 143
Зарегистрирован: Сб фев 21, 2009 13:11:40
Сообщений: 1900
Откуда: Москва
Рейтинг сообщения: 0
Код:
unsigned int a,b,c;
...
c=a&(0x000F); //копируем 4 младших бита из числа а, остальные обнуляем
c=(c<<11);//сдвигаем их до 14-11 битов
b=b&~(0x7800);//сбрасываем 14-11 биты в числе b (здесь ошибка была, забыл проинвертировать, сейчас поправил)
b=b|c;//копируем биты из числа с в число b

_________________
Ставим плюсы: )


Последний раз редактировалось ibiza11 Пн янв 17, 2011 01:00:15, всего редактировалось 2 раз(а).

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Пн янв 17, 2011 00:40:11 
Мудрый кот
Аватар пользователя

Карма: 25
Рейтинг сообщений: 79
Зарегистрирован: Вт окт 05, 2010 01:08:57
Сообщений: 1800
Рейтинг сообщения: 0
ibiza11 Спасибо.
Точно, меня же интересуют 11-14 биты, а они входят в int переменную, значит можно просто с помощью двоичного ИЛИ сложит int и long int (предварительно сдвинув int) и получить желаемое.

_________________
KIT


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вт янв 18, 2011 17:34:41 
Прорезались зубы

Карма: 5
Рейтинг сообщений: 7
Зарегистрирован: Вс дек 10, 2006 19:26:13
Сообщений: 205
Рейтинг сообщения: 0
Есть массив символов
Код:
unsigned char mass[]={"123456789"};
,как перекинуть символы на другой массив, чтобы было так-
Код:
unsigned char mass[]={"987654321"};
?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вт янв 18, 2011 18:39:46 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 21
Рейтинг сообщений: 143
Зарегистрирован: Сб фев 21, 2009 13:11:40
Сообщений: 1900
Откуда: Москва
Рейтинг сообщения: 0
Код:
unsigned char a[9]={1,2,3,4,5,6,7,8,9};
unsigned char b[9];
unsigned char i=0;
unsigned char j=8;
...
while (i<9)
{
   b[j]=a[i];
   i++;
   j--;
}

_________________
Ставим плюсы: )


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вт янв 18, 2011 19:06:55 
Прорезались зубы

Карма: 5
Рейтинг сообщений: 7
Зарегистрирован: Вс дек 10, 2006 19:26:13
Сообщений: 205
Рейтинг сообщения: 0
ibiza11 , спасибо, проверил-работает.


Вернуться наверх
 
В сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Ср янв 19, 2011 10:07:00 
Друг Кота
Аватар пользователя

Карма: 67
Рейтинг сообщений: 1060
Зарегистрирован: Чт сен 18, 2008 12:27:21
Сообщений: 19675
Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
dm211 писал(а):
проверил-работает.

Гы, ещё бы оно не работало :)))

_________________
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Измерить нннада?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Чт янв 20, 2011 21:39:34 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 2
Рейтинг сообщений: 23
Зарегистрирован: Чт апр 08, 2010 18:50:01
Сообщений: 2095
Откуда: Краснодар
Рейтинг сообщения: 0
кхе кхе.. может кто поделится кодом работы с LPT ( линухоподобный ) ?
в сети нашел только странный пример

Код:
#include <stdio.h>
#include <pthread.h>
#include <fcntl.h>

int main(int argc,char* argv[])
{
int val,port;
int fd;

if(argc<3){fprintf(stderr,"usage: %s port value\n",argv[0]); exit(1);}
if(sscanf(argv[1],"0x%x",&port) && sscanf(argv[2],"0x%x",&val))
{
fd=open("/dev/io",O_RDWR);
if(fd==-1){perror("open");exit(1);}
outb(port,val);
close(fd);
}
else
{fprintf(stderr,"port and value must be in hex format with 0x prefix\n"); exit(1);}

}


ругается на outb.

я опять затеял переписывать программу с паскаля )) я бы и так ею пользовался, но она не работает в wine

_________________
RETI ;рети-рети интеррапт, через шины данных тракт, через память, через порт, возвращайся в главный код
@hobbyelectronics


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

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


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

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


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

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


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