Управляем чем угодно откуда угодно

виртурилка и часы

Виртурилка, 3G/4G, WiFi, моторчики, датчики, GPS и прочее - питание, драйвера, совместимость и т.д.

виртурилка и часы

Сообщение phoenix367 » 21 ноя 2013, 00:01

Думаю ни для кого из пользователей сего девайса не секрет, что в виртурилке нет энергонезависимых часов. Соответственно после каждого включения время сбрасывается в 0 и его надо устанавливать заново. Это неудобно, поскольку требуется либо сетевое соединение с сервером NTP, либо каждый раз делать это ручками. Соответственно был куплен отдельный модуль аппаратных энергонезависимых часов. Вот такой примерно http://amperka.ru/collection/boards/product/real-time-clock. И все бы хорошо, вот только этот модуль основывается на микросхеме DS1307 и вешается на шину I2C. Микросхема эта имеет адрес на шине 0x68 и изменить его нельзя. И тут возникает проблема с платой датчиков (у меня используется вот такая http://www.electronshik.ru/card/akselerometr-giroskop-magnitometr-barometr-118516). Дело в том, что у гироскопа ITG3200 тот же самый адрес. Теоретически его можно поменять, но учитывая размер выводов уже впаянной микросхемы подключиться к ней не так-то просто. Напоминаю, что шина I2C в виртурилке только одна. Поэтому я пошел другим путем, а именно решил сделать мультиплексирование, поскольку к часам нужно обращаться только при старте виртурилки и установке времени. Путем гугления выяснилось, что есть специальные микросхемы-мультиплексоры типа вот таких http://www.ti.com/product/pca9543a. Однако в нашей деревне таких отродясь не водилось, а переплачивать в чип-и-дипе тройную стоимость и еще ждать чуть не месяц мне не захотелось. Стал гуглить дальше и нагуглил, что поскольку все устройства на шине работают как slave, то можно мультиплексировать в одну сторону только линию I2C_CLK (CON71 на гребенке выиртурилки). Порывшись в коробке с барахлом с удивлением обнаружил, что у меня оказывается есть теплая ламповая микросхема К155ЛИ5 (два элемента И с открытым коллектором) уже впаянная в плату вместе с подтягивающими резисторами. Плату видимо делал еще в школе, и уже не помню зачем. Кто знаком с электроникой уже, наверное, догадались, как из этой микросхемы сделать мультиплексор (точнее демультиплексор). Ниже приведена схема включения:

Изображение

Выход I2C_CLK_A подключаем ко входу CLK платы датчиков, а выход I2C_CLK_B подключаем ко входу CLK модуля часов. Входы SDA обеих плат соединяем вместе и подключаем к контакту I2C_DATA виртурилки. Остальные контакты мультиплексора подключаем к одноименным контактам вирутрилки (см. вики). Недостатков у вышеприведенной схемы два. Первый состоит в том, что отключенная в текущий момент времени линия находится в состоянии 0, а должна быть в 1. Лечится заменой элемента И на ИЛИ. Второй недостаток - это подтяжка к +5В платы с датчиками, которая работает от +3,3В. Поэтому резистор R2 лучше подключить к источнику +3,3В. Мне было лень переделывать уже готовую плату, поэтому оставил как есть. Собственно на этом по железной части все.

В сборе все выглядит примерно так
Изображение

Теперь о том, как этим хозяйством управлять. А управлять им очень просто. Если хотим работать с датчиками, то подаем 0 на GPIO79 и 1 на GPIO82. Если хотим работать с часами, то подаем 1 на GPIO79 и 0 на GPIO82. Подав 0 на GPIO79 и GPIO82 выключаем шину. Кроме того, чтобы работать с часами на DS1307 нужно еще собрать соответствующий модуль в ядре (находится в Device drivers->Real Time Clock). Ниже приведены скрипты, которые позволяют управлять шиной I2C через описанный мультиплексор.

multiplexer_state.sh - выдает на стандартный вывод информацию о том, какая шина включена
Код: Выделить всё
#!/bin/sh

GPIO_STATES=`head -c 83 /dev/v2r_gpio`
if ([ $? -ne 0 ])
then
echo "Error occured during read GPIO state"
    exit 1
fi

A_BUS_BIT=${GPIO_STATES:82:1}
B_BUS_BIT=${GPIO_STATES:79:1}

if [ "$A_BUS_BIT" = "1" ] && [ "$B_BUS_BIT" = "0" ]
then
echo "A"
elif [ "$A_BUS_BIT" = "0" ] && [ "$B_BUS_BIT" = "1" ]
then
echo "B"
elif [ "$A_BUS_BIT" = "0" ] && [ "$B_BUS_BIT" = "0" ]
then
echo "off"
else
echo "Invalid multiplexer state"
fi


switch_i2c.sh - переключает шину (A, B или off для полного отключения)
Код: Выделить всё
#!/bin/sh

if ([ $# -ne 1 ])
then
echo "Invalid arguments. Usage: switch_i2c.sh <bus index>"
    exit 1
fi

BUS_INDEX=$1

case "$BUS_INDEX" in
"A")
    echo "set gpio79 output:0" > /dev/v2r_gpio
    echo "set gpio82 output:1" > /dev/v2r_gpio
    if ([ $? -eq 0 ])
    then
echo "Select bus A"
    else
echo "Error occured during bus switching"
    fi
    ;;
"B")
    echo "set gpio79 output:1" > /dev/v2r_gpio
    echo "set gpio82 output:0" > /dev/v2r_gpio
    if ([ $? -eq 0 ])
    then
echo "Select bus B"
    else
echo "Error occured during bus switching"
    fi
    ;;
"off")
    echo "set gpio79 output:0" > /dev/v2r_gpio
    echo "set gpio82 output:0" > /dev/v2r_gpio
    if ([ $? -eq 0 ])
    then
echo "I2C bus multiplexor is off"
    else
echo "Error occured during bus shutting down"
    fi
    ;;
*)
    echo "Incorrect multiplexing bus index $BUS_INDEX"
    exit 1
    ;;
esac


set_sys_clock.sh - синхронизирует системное время со временем модуля энергонезависимых часов
Код: Выделить всё
#!/bin/sh

echo "Restore Virt2real system time from DS1307 module..."

I2C_CREATE_DEVICE_FILE="/sys/class/i2c-adapter/i2c-1/new_device"
I2C_DELETE_DEVICE_FILE="/sys/class/i2c-adapter/i2c-1/delete_device"

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

eval "${SCRIPT_DIR}/switch_i2c.sh B"

echo "Attach to clock device..."
echo ds1307 0x68 > $I2C_CREATE_DEVICE_FILE

echo "Setup system clock..."
hwclock -s -f /dev/rtc1

echo "Detach clock device"
echo 0x68 > $I2C_DELETE_DEVICE_FILE


save_sys_clock.sh - сохраняет текущее системное время в энергонезависимые часы на DS1307
Код: Выделить всё
#!/bin/sh

echo "Save Virt2real system time to DS1307 module..."

I2C_CREATE_DEVICE_FILE="/sys/class/i2c-adapter/i2c-1/new_device"
I2C_DELETE_DEVICE_FILE="/sys/class/i2c-adapter/i2c-1/delete_device"

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

eval "${SCRIPT_DIR}/switch_i2c.sh B"

echo "Attach to clock device..."
echo ds1307 0x68 > $I2C_CREATE_DEVICE_FILE

echo "Save system clock..."
hwclock -w -f /dev/rtc1

echo "Detach clock device"
echo 0x68 > $I2C_DELETE_DEVICE_FILE


Собственно скрипты можно взять отсюда https://github.com/phoenix367/v2rpins_sdk/tree/master/cherokey-robot/scripts
Если вы хотите, чтобы виртурилка автоматически синхронизировала свои системные часы при запуске, то в файл /etc/virt2real/autostart.sh надо добавить следующие строчки:

Код: Выделить всё
#Loading system time and switch to main I2C bus
modprobe rtc_ds1307
<путь к скриптам>/set_sys_clock.sh
<путь к скриптам>/switch_i2c.sh A
hwclock -w -f /dev/rtc0


<путь к скриптам> - это путь к папке, в которую установлены рассмотренные выше скрипты.

Вместо К155ЛИ5 можно использовать более современные аналоги (эта микросхема судя по дате выпуска на месяц старше меня и немного нагревается при работе, думаю что из-за ламп внутри :mrgreen: ). Если вы не будете использовать часы на DS1307 совместно с ITG3200, то весь этот огород вам нафиг не нужен. Вот такие пироги с котятами.

ЗЫ: Мораль сей басни такова: Граждане, не выкидывайте старое барахло, через много лет оно вам обязательно пригодится!
phoenix367
 
Сообщения: 193
Зарегистрирован: 09 сен 2013, 00:19

Вернуться в Железо - заставляем работать

Кто сейчас на конференции

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

cron