//dmx-i2c.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2013 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #include #include #include #define DEFAULT_DEVICE "/dev/i2c-1" #define DEFAULT_SLAVE 0x58 #define ADDR_COMMAND 2 #define ADDR_BANK 4 #define ADDR_DATA 5 #define COMMAND_DMX 0x3f struct state { size_t startaddr; size_t len; uint8_t slave; struct roar_vio_calls * vio; }; static struct state * g_state; static struct state g_state_init = { .startaddr = 0, .len = 16, .slave = DEFAULT_SLAVE, .vio = NULL }; static inline int __i2c_set_slave(void) { struct roar_vio_sysio_ioctl ctl = {.cmd = I2C_SLAVE, .argp = (void*)(int)g_state->slave}; return roar_vio_ctl(g_state->vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl); } static inline int __i2c_write(size_t off, const uint8_t value) { union i2c_smbus_data data = {.byte = value}; struct i2c_smbus_ioctl_data args = {.read_write = I2C_SMBUS_WRITE, .command = off, .size = I2C_SMBUS_BYTE_DATA, .data = &data}; struct roar_vio_sysio_ioctl ctl = {.cmd = I2C_SMBUS, .argp = &args}; return roar_vio_ctl(g_state->vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl); } static inline int __i2c_command(uint8_t command) { return __i2c_write(ADDR_COMMAND, command); } static inline int __i2c_start_dmx(void) { return __i2c_command(COMMAND_DMX); } static inline int __i2c_set_channel(size_t channel, uint8_t value) { size_t bank, offset; bank = channel/32; offset = bank*32; if ( __i2c_write(ADDR_BANK, bank) == -1 ) return -1; return __i2c_write(ADDR_DATA+channel-offset, value); } static int _init (struct roar_dl_librarypara * para) { struct roar_keyval * p; const char * dev = DEFAULT_DEVICE; p = roar_keyval_lookup(para->argv, "startaddr", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->startaddr = atoi(p->value); p = roar_keyval_lookup(para->argv, "len", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->len = atoi(p->value); p = roar_keyval_lookup(para->argv, "slave", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->slave = atoi(p->value); p = roar_keyval_lookup(para->argv, "device", para->argc, 1); if ( p != NULL && p->value != NULL ) dev = p->value; g_state->vio = roar_vio_open_dstr_simple_new(dev, ROAR_VIOF_READWRITE); if ( g_state->vio == NULL ) { ROAR_ERR("_init(para=%p): Can not open device: %s: %s", para, dev, roar_errorstring); return -1; } __i2c_set_slave(); return 0; } static int _free (struct roar_dl_librarypara * para) { (void)para; roar_vio_close(g_state->vio); g_state->vio = NULL; return 0; } static int _update (struct roar_dl_librarypara * para) { size_t i; int val; (void)para; __i2c_start_dmx(); for (i = 0; i < g_state->len; i++) { val = light_dmxchannel_get(g_state->startaddr + i); if ( val < 0 ) continue; __i2c_set_channel(i, val); } return 0; } static struct roar_dl_appsched sched = { .init = _init, .free = _free, .update = _update, .tick = NULL, .wait = NULL }; ROAR_DL_PLUGIN_START(dmx_waveform) { ROARD_DL_CHECK_VERSIONS(); ROAR_DL_PLUGIN_META_PRODUCT_NIV("dmx-i2c", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("This plugin sends DMX data to RoarAudio DMX Transmitters using I²C"); ROAR_DL_PLUGIN_REG_GLOBAL_DATA(g_state, g_state_init); ROAR_DL_PLUGIN_REG_APPSCHED(&sched); } ROAR_DL_PLUGIN_END //ll