14. Griffin Hardware
The griffin knob is a secondary core peripharal used in Monolith that is used alongside the Monome. It is controlled using the hidapi wrapper.
14.1. hidapi system include
The hidapi uses a system include hidapi/hidapi.h
#ifndef MONOLITH_SIMPLE
#include "hidapi/hidapi.h"
#endif
14.2. Griffin Hardware Data
Griffin is stored in an hidapi handle of type hid_device
called griffin_handle
.
#ifndef MONOLITH_SIMPLE
hid_device *griffin_handle;
#endif
#ifndef MONOLITH_SIMPLE
m->griffin_handle = NULL;
#endif
It is closed with hid_close
.
#ifndef MONOLITH_SIMPLE
if(m->griffin_handle != NULL) hid_close(m->griffin_handle);
#endif
14.3. Griffin Setup and Cleanup
The Griffin knob is started and initialized with the
function monolith_griffin_setup
.
void monolith_griffin_setup(monolith_d *m);
The nice thing about the hidapi wrapper is that is loads devices using Vendor and Product ID numbers, which are cross-platform. No os-dependent code needed with this layer, which is nice.
We want pulling to be non-blocking, so this must be
explicitely set using hid_set_nonblocking
.
void monolith_griffin_setup(monolith_d *m)
{
#ifndef MONOLITH_SIMPLE
monolith_griffin_d *g;
g = &m->vgriffin;
if(m->griffin_handle != NULL) return;
m->griffin_handle = hid_open(0x077d, 0x0410, NULL);
if(m->griffin_handle == NULL) {
fprintf(stderr, "Could not open Griffin knob\n");
return;
}
hid_set_nonblocking(m->griffin_handle, 1);
<<set_griffin_callbacks>>
#endif
}
Griffin setup is implemented as a function called
monolith:griffin-setup
.
{"monolith:griffin-setup", pp_griffin_setup, 0, 0, {CHR,___,___}},
static cell pp_griffin_setup(cell x) {
monolith_griffin_setup(monolith_data_get());
return UNSPECIFIC;
}
At the end of the program, the griffin is closed with the
function monolith_griffin_cleanup
.
void monolith_griffin_cleanup(monolith_d *m);
void monolith_griffin_cleanup(monolith_d *m)
{
<<close_griffin_handle>>
}
This gets called at cleanup.
monolith_griffin_cleanup(m);
14.4. Polling the Griffin
Griffin events are pulled with the function
monolith_griffin_poll
.
This is code directly lifted from monomer.
void monolith_griffin_poll(monolith_d *m);
void monolith_griffin_poll(monolith_d *m)
{
#ifndef MONOLITH_SIMPLE
static unsigned char buf[16];
int res;
if(m->griffin_handle == NULL) return;
res = hid_read(m->griffin_handle, buf, 16);
if(res > 0) {
if(buf[1] == 0) {
monolith_griffin_push(&m->vgriffin, buf[0]);
} else if(buf[1] > 0) {
monolith_griffin_turn(&m->vgriffin,
(signed char)buf[1]);
}
}
#endif
}
The poll function is called inside of the main poll callback.
#ifndef MONOLITH_SIMPLE
monolith_griffin_poll(m);
#endif
14.5. Set Griffin Callbacks
14.5.1. Set Default Turn Callback
#ifndef MONOLITH_SIMPLE
static void griffin_turn(monolith_griffin_d *g, int state);
#endif
#ifndef MONOLITH_SIMPLE
static void griffin_turn(monolith_griffin_d *g, int state)
{
if(g->md->curpage != NULL) {
monolith_page_turn(g->md->curpage, state);
}
}
#endif
monolith_griffin_turn_set(g, griffin_turn);
14.5.2. Set Default Push Callback
#ifndef MONOLITH_SIMPLE
static void griffin_push(monolith_griffin_d *g, int state);
#endif
#ifndef MONOLITH_SIMPLE
static void griffin_push(monolith_griffin_d *g, int state)
{
if(g->md->curpage != NULL) {
monolith_page_push(g->md->curpage, state);
}
}
#endif
monolith_griffin_push_set(g, griffin_push);
prev | home | next