Ноя 01

AVR упрощаем TWI (I2C)

Давно уже написал, а выложить все как-то влом было. Но если вдруг, кому потребуется, простенькая библиотечка для работы с Two-Wire Interface (TWI, он же I2C) на AVR вообще и ATMega328p (та самая, которая в arduino nano v3 стоит) в частности.

Пользоваться проще некуда, подглядеть в libtwi.h всегда можно.

Скачать на гитхабе github.com/bevice/libtwi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "main.h"
#include "libtwi.h"
#include <util/delay.h>
void setup() {
    twi_init();
    DDRB |= _BV(PB5); // включим PB5 на выход, на Arduino Nano там светодиодик
 
}
 
#define DATA_SIZE 10
static uint8_t data[DATA_SIZE] ={0};
 
void twi_cb(uint8_t status){
    if(status!= TWI_STATUS_ERROR) // если все прочиталось - перевернем светодиод
        DDRB ^= _BV(PB5);
}
 
int main() {
    setup();
 
    while (1) {
        // для 24CXX при записи передается адрес и следом данные.
        uint8_t buff[] = {0x10,1,2,3,4,5}; 
        // передаем buff в железку с адресом  0xA0, 
        // как закончим передавать - дергаем twi_cb
        twi_transmit_data(0xA0, sizeof(buff), buff, &twi_cb);
 
        _delay_ms(1000);
 
        // читаем  DATA_SIZE байт из железки 
        // с адресом 0xA0 начиная с регистра 0x10
        // как в буффер data, как дочитаем
        //  - попадем в коллбек twi_cb с соответствующим статусом
    twi_receive_data_adr8(0xA0, 0x10, DATA_SIZE, data, &twi_cb);
 
    _delay_ms(1000);
    }
}
Июл 08

Такие дела..


Сижу отлаживаю железку на китайской arduino-nano-v3, тыкаю анализатором на RX ногу, а там пусто, иголки одни. Хотя AVR-ка точно с уарта читает и отвечает как надо.
А на самом деле-то не должна, полтора вольта за логический 0 это вообще как?

Июн 08

Asterisk, Lua и MySQL. Добавляем номер в черный список

Табличка немного отличается от предыдущего поста, поле number уникальное.

Пишем макрос:

extensions['macro-ban'] = {
        s = function()
                cid = channel.CALLERID("num"):get()
                query = "INSERT INTO blacklist (number, expires) VALUES ('" .. cid .. "', date_add(NOW(), INTERVAL 1 DAY)) on duplicate key update expires = date_add(NOW() INTERVAL 1 DAY);"
                local con = assert (env:connect(DB_NAME,DB_USER,DB_PASSWORD))
                assert (con:execute(query))
                con:close()
        end
};

Добалвяем макрос в features.conf:

[applicationmap]
ban => *5,peer/callee,macro(ban)

и не забываем включить в __DYNAMIC_FEATURES в диалплане:

extensions = {
    ["incoming"] = {
        ["DID"] = function()
            channel.__DYNAMIC_FEATURES = "ban"
            app.dial("SIP/100")
        end;
    }
}

Теперь ответивший нажатием *5 может добавить номер звонящего в черный список.

Июн 06

Asterisk, LUA и MySQL. Черный Список.

С помощью LUA делается элементарно:

В MySQL делаем табличку blacklist:

CREATE TABLE blacklist (
  NUMBER VARCHAR(20) NOT NULL,
  expires datetime DEFAULT NULL
)

Подключаем к LUA библиотеку luaSQL и luasql.mysql для работы с базой данных

 
-- расскажем, где искать
package.cpath = package.cpath .. ";/usr/lib/i386-linux-gnu/lua/5.1/?.so" 
-- и подключем
local luasql = require "luasql.mysql"
local mysql = assert (luasql.mysql())
 
-- данные для подключения к базе MySQL
local DB_HOST = "localhost"
local DB_NAME = "db_name"
local DB_USER = "db_user"
local DB_PASSWORD = "db_passwod"
 
-- и пишем функцию проверки: 
function is_banned(cid_number)
        local con = assert (env:connect(DB_NAME,DB_USER,DB_PASSWORD))
        local cur = assert (con:execute("SELECT * FROM blacklist where '".. cid_number.."' like number and (expires>now() or expires is NULL);"))
        c = cur:numrows()
        cur:close()
        con:close()
        return c>0
end
 
 
-- а дальше и начинаем использовать:
 
extensions = {
    ["incoming"] = {
        ["DID"] = function() 
            if is_banned(channel.CALLERID["number"]:get()) then
                -- Номер в черном списке, что-то с ним делаем
                app.answer()
                app.wait(1)
                app.hangup()
            end;
        end;
    }
}

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

Июн 05

Asterisk и Lua. Очень быстрый старт

Астериск из коробки может исползовать язык программирования LUA для написания диалплана. И это прекрасно! В диалплане можно подключить любую установленную lua-библиотеку и получить доступ к базе данных (SQLite, MySQL, PostgreSQL), работать с сетью, читать-записывать файлики. Причем, делается это все довольно просто.
Зная любой язык программирования и вооружившись справочником по синтаксису LUA, а так же прочитав пару абзацев ниже можно без проблем начать использовать всю мощь этой связки.
Continue reading

Апр 27

AVR CMake

Clion & AVRВот уже несколько лет пользуюсь CMake-ом, чтобы собирать проекты под AVR. Сподвиг на этом конечно же вышедший осенью 2014 Jetbrains CLion, который как оказалось идеально подходит для написания кода под Atmel AVR. Короче, рекомендую.
Возможно, для корректной работы нужно будет установить переменную среды AVR_FIND_ROOT_PATH – на папку с avr (содержащую lib и include), а так же папка с avr-gcc, avr-g++, avr-objcopy, avr-size должны находиться в PATH. Ну или доработать напильником generic-gcc-avr.cmake

В общем, шаблон тут: https://github.com/bevice/avr_cmake_template
Continue reading

Июн 15

UART размер экрана

Для общения через UART с железками (avr, stm32 и прочими) в основном использую GNU screen:

$ screen /dev/tty.ubserial 9600

А вот что-то дернуло, раскрасить вывод микроконтроллера и раскрасил (не мудрено, печатаем что-то вроде \033[31m и вперед, ну только цвета меняем). А потом поехало: захотелось печатать в разных местах экрана (\033[y;xH), а вот как напечатать в центре? Надо же знать размер экрана, а он у меня (да и у всех) каждый раз разный.
Долго возился, выяснил, что screen отдавать размер окна (\033[18t) не умеет. Зато DCS передает напрямую терминалу из которого запущен: вот и нашелся грязный хак: оборачиваем запрос размера в ESC-P последовательность, и вот уже знаем размер экрана.
Печатаем хитрую строку:

\033P\033[18t033\

и получаем ответ:

\[8;31;163t

31 строка, 163 колонки, а 8 – это номер CSI-репорта. Он всегда такой.

вот тут большой список похоже что вообще всех ESC-последовательностей которые терминалы поддерживают: ttssh2.osdn.jp

P.S.
Ну а бонусом – таким же способом можно поставить заголовок окна который screen ставить умеет только через жопу.

\033P\033]0;New Window Title\a\033\\