/* $Id: board.c,v 1.12 2004/04/01 05:33:53 jmuelmen Exp $ */ /* board-wise operations go in here */ #include "libsurf.h" #include "surf_int.h" #include "surf_drv.h" #include #include #define BUFSIZE 64 static pthread_mutex_t _mut; int surf_board_init () { int ret = pthread_mutex_init(&_mut, NULL); if (ret) perror("Initializing surf board mutex"); return ret; } static int surf_board_lock () { int ret = pthread_mutex_lock(&_mut); if (ret) perror("Locking surf board mutex"); return ret; } static int surf_board_unlock () { int ret = pthread_mutex_unlock(&_mut); if (ret) perror("Unlocking surf board mutex"); return ret; } static double _adctov (int adc) { const double conv = 2.048 / (double)(1 << 12); return adc * conv; } static void phex (const char *buf, int count) { int i; for (i = 0; i < count; ++i) printf("%x ", buf[i]); printf("\n"); } static int _get_status (const char *brd, int chn, char *buf, int count) { int ret; char _buf[BUFSIZE]; surf_board_lock(); _buf[0] = SURF_MOD_STATUS; if ((ret = surf_write_board(brd, chn + 1, _buf, 1)) < 0) { surf_board_unlock(); return ret; } ret = surf_read_board(brd, chn + 1, buf, count); if (ret < 0) { surf_board_unlock(); return ret; } /* phex(buf, 13); */ surf_board_unlock(); return ret; } #if 0 /* !!!!!!!!!!!!! READ NEXT LINE BEFORE REMOVING #if !!!!!!!!!!!!!!! */ /* fix us! we're not thread-safe. */ int surf_brd_raw_write (const char *board, int ep, char *buf, int count) { /* simplest function ever. Just a wrapper around surf_write_board. */ return surf_write_board(board, ep, buf, count); } int surf_brd_raw_read (const char *board, int ep, char *buf, int count) { /* co-simplest function ever. Just a wrapper around surf_read_board. */ return surf_read_board(board, ep, buf, count); } #endif /* These functions are more interesting. They actually require us sticking something into the buffer */ int surf_brd_ena (const char *brd, int chn, int ena) { int ret; char buf[BUFSIZE]; surf_board_lock(); buf[0] = SURF_MOD_ENA; buf[1] = ena ? 1 : 0; ret = surf_write_board(brd, chn + 1, buf, 2); surf_board_unlock(); return ret; } int surf_brd_end (const char *brd, int chn, int ena) { int ret; char buf[BUFSIZE]; surf_board_lock(); buf[0] = SURF_MOD_END; buf[1] = ena ? 1 : 0; ret = surf_write_board(brd, chn + 1, buf, 2); surf_board_unlock(); return ret; } int surf_brd_sel_rd (const char *brd, int chn) { int ret; char buf[BUFSIZE]; surf_board_lock(); buf[0] = SURF_MOD_SEL_RD; ret = surf_write_board(brd, chn + 1, buf, 1); surf_board_unlock(); return ret; } int surf_brd_sel_wr (const char *brd, int chn) { int ret; char buf[BUFSIZE]; surf_board_lock(); buf[0] = SURF_MOD_SEL_WR; ret = surf_write_board(brd, chn + 1, buf, 1); surf_board_unlock(); return ret; } int surf_brd_sel_wr_glob (const char *brd) { int ret; char buf[BUFSIZE]; surf_board_lock(); buf[0] = SURF_GLOB_WRITE; ret = surf_write_board(brd, 1, buf, 1); surf_board_unlock(); return ret; } int surf_brd_set_anl_v (const char *brd, int chn, double v) { int ret; int _v; char buf[BUFSIZE]; unsigned char _v_l, _v_h; /* first convert the double into a 16-bit integer */ _v = (int)(2000 * v); _v_h = (unsigned char)(_v >> 8); _v_l = (unsigned char)(_v & 0xff); surf_board_lock(); buf[0] = SURF_MOD_SET_ANAL; buf[1] = _v_h; buf[2] = _v_l; /* printf("Sending %x %x", _v_h, _v_l); */ ret = surf_write_board(brd, chn + 1, buf, 3); surf_board_unlock(); return ret; } int surf_brd_set_dig_v (const char *brd, int chn, double v) { int ret; int _v; char buf[BUFSIZE]; unsigned char _v_l, _v_h; /* first convert the double into a 16-bit integer */ _v = (int)(2000 * v); _v_h = (unsigned char)(_v >> 8); _v_l = (unsigned char)(_v & 0xff); surf_board_lock(); buf[0] = SURF_MOD_SET_DIG; buf[1] = _v_h; buf[2] = _v_l; /* printf("Sending %x %x", _v_h, _v_l); */ ret = surf_write_board(brd, chn + 1, buf, 3); surf_board_unlock(); return ret; } int surf_brd_set_anl_tol (const char *brd, int chn, double v) { int ret; int _v; char buf[BUFSIZE]; unsigned char _v_l; if (v > 0.128) /* can't allow higher tolerance than 0xff / 2000 */ return -1; /* first convert the double into a 16-bit integer */ _v = (int)(2000 * v); _v_l = (unsigned char)(_v & 0xff); surf_board_lock(); buf[0] = SURF_MOD_TOL_ANL; buf[1] = _v_l; ret = surf_write_board(brd, chn + 1, buf, 2); surf_board_unlock(); return ret; } int surf_brd_set_dig_tol (const char *brd, int chn, double v) { int ret; int _v; char buf[BUFSIZE]; unsigned char _v_l; if (v > 0.128) /* can't allow higher tolerance than 0xff / 2000 */ return -1; /* first convert the double into a 16-bit integer */ _v = (int)(2000 * v); _v_l = (unsigned char)(_v & 0xff); surf_board_lock(); buf[0] = SURF_MOD_TOL_DIG; buf[1] = _v_l; ret = surf_write_board(brd, chn + 1, buf, 2); surf_board_unlock(); return ret; } int surf_brd_set_anl_comp (const char *brd, int chn, int c) { int ret; char buf[BUFSIZE]; surf_board_lock(); buf[0] = SURF_MOD_COMP_ANL; buf[1] = c != 0; /* because c is an int */ ret = surf_write_board(brd, chn + 1, buf, 2); surf_board_unlock(); return ret; } int surf_brd_set_dig_comp (const char *brd, int chn, int c) { int ret; char buf[BUFSIZE]; surf_board_lock(); buf[0] = SURF_MOD_COMP_DIG; buf[1] = c != 0; /* because c is an int */ ret = surf_write_board(brd, chn + 1, buf, 2); surf_board_unlock(); return ret; } int surf_brd_set_anl_dac (const char *brd, int chn, char dac) { int ret; char buf[BUFSIZE]; /* fix me! this gentleman is going to need a different command. */ surf_board_lock(); buf[0] = SURF_MOD_SET_ANAL; buf[1] = dac; ret = surf_write_board(brd, chn + 1, buf, 2); surf_board_unlock(); return ret; } int surf_brd_set_dig_dac (const char *brd, int chn, char _v) { int ret; char buf[BUFSIZE]; surf_board_lock(); buf[0] = SURF_MOD_SET_DIG; buf[1] = _v; ret = surf_write_board(brd, chn + 1, buf, 2); surf_board_unlock(); return ret; } int surf_brd_get_anl_i_adc (const char *brd, int chn) { int ret; char buf[BUFSIZE]; unsigned char ah, al; /* adc high, adc low byte */ /* don't need to lock; _get_status does. */ if ((ret = _get_status(brd, chn, buf, sizeof(buf))) < 0) return ret; ah = buf[7]; al = buf[8]; return ((ah & 0x0f) << 8) + al; } int surf_brd_get_dig_i_adc (const char *brd, int chn) { int ret; char buf[BUFSIZE]; unsigned char ah, al; /* adc high, adc low byte */ /* don't need to lock; _get_status does. */ if ((ret = _get_status(brd, chn, buf, sizeof(buf))) < 0) return ret; ah = buf[9]; al = buf[10]; return ((ah & 0x0f) << 8) + al; } int surf_brd_get_anl_v_adc (const char *brd, int chn) { int ret; char buf[BUFSIZE]; unsigned char ah, al; /* adc high, adc low byte */ /* don't need to lock; _get_status does. */ if ((ret = _get_status(brd, chn, buf, sizeof(buf))) < 0) return ret; ah = buf[1]; al = buf[2]; return ((ah & 0x0f) << 8) + al; } int surf_brd_get_dig_v_adc (const char *brd, int chn) { int ret; char buf[BUFSIZE]; unsigned char ah, al; /* adc high, adc low byte */ /* don't need to lock; _get_status does. */ if ((ret = _get_status(brd, chn, buf, sizeof(buf))) < 0) return ret; ah = buf[3]; al = buf[4]; return ((ah & 0x0f) << 8) + al; } int surf_brd_get_temp_adc (const char *brd, int chn) { int ret; char buf[BUFSIZE]; unsigned char ah, al; /* adc high, adc low byte */ /* don't need to lock; _get_status does. */ if ((ret = _get_status(brd, chn, buf, sizeof(buf))) < 0) return ret; ah = buf[11]; al = buf[12]; return ((ah & 0x0f) << 8) + al; } int surf_brd_get_gnd_v_adc (const char *brd, int chn) { int ret; char buf[BUFSIZE]; unsigned char ah, al; /* adc high, adc low byte */ /* don't need to lock; _get_status does. */ if ((ret = _get_status(brd, chn, buf, sizeof(buf))) < 0) return ret; ah = buf[5]; al = buf[6]; return ((ah & 0x0f) << 8) + al; } double surf_brd_get_anl_v (const char *brd, int chn) { /* don't need to lock; surf_brd_get_... does. */ int v_adc = surf_brd_get_anl_v_adc(brd, chn); int v_gnd = surf_brd_get_gnd_v_adc(brd, chn); if (v_adc < 0) return v_adc; if (v_gnd < 0) return v_gnd; /* return 2 * _adctov(v_adc) - _adctov(v_gnd); */ return 2 * v_adc / 2e3 - v_gnd / 1.97e3; } double surf_brd_get_dig_v (const char *brd, int chn) { /* don't need to lock; surf_brd_get_... does. */ int v_adc = surf_brd_get_dig_v_adc(brd, chn); int v_gnd = surf_brd_get_gnd_v_adc(brd, chn); if (v_adc < 0) return v_adc; if (v_gnd < 0) return v_gnd; /* return 2 * _adctov(v_adc) - _adctov(v_gnd); */ return 2 * v_adc / 2e3 - v_gnd / 1.97e3; } double surf_brd_get_anl_i (const char *brd, int chn) { /* static const double rs = 39e-3; */ int i_adc = surf_brd_get_anl_i_adc(brd, chn); if (i_adc < 0) return i_adc; return i_adc / 2000.0; } double surf_brd_get_dig_i (const char *brd, int chn) { /* don't need to lock; surf_brd_get_... does. */ /* const double rs = 47e-3; */ int i_adc = surf_brd_get_dig_i_adc(brd, chn); if (i_adc < 0) return i_adc; return i_adc / 2400.0; } double surf_brd_get_temp (const char *brd, int chn) { int t_adc; double v_adc, r_ntc; /* first convert adc count into resistance */ /* don't need to lock; surf_brd_get_... does. */ t_adc = surf_brd_get_temp_adc(brd, chn); if (t_adc < 0) return t_adc; v_adc = _adctov(t_adc); r_ntc = 3.3 / v_adc * 20 * 237 - 237 - 10e3; /* then convert resistance into temperature */ return 1.0 / (7.79417e-4 + (2.72053e-4 * log(r_ntc)) + (8.83526e-8 * pow(log(r_ntc), 3.0))); } int surf_brd_temp_reset (const char *brd) { int ret; char buf[BUFSIZE]; surf_board_lock(); buf[0] = SURF_GLOB_RESET; ret = surf_write_board(brd, 1, buf, 1); surf_board_unlock(); return ret; } /* fix me! Implement these! remember to lock properly. */ int surf_brd_get_sel_rd (const char *brd, int chn) { return -1; } int surf_brd_get_sel_wr (const char *brd, int chn) { return -1; } int surf_brd_get_ena (const char *brd, int chn) { return -1; } int surf_brd_get_end (const char *brd, int chn) { return -1; } #if 0 /* these functions are outmoded. */ /* these functions don't need to lock the board system, since they call other functions that will lock. */ int surf_brd_set_anl_v (const char *brd, int chn, double v) { int adc = (int)rint(250 / 1.5 * (2.8 - v)); if (adc < 0 || adc > 255) return -1; return surf_brd_set_anl_dac(brd, chn, (unsigned char)adc); } int surf_brd_set_dig_v (const char *brd, int chn, double v) { int adc = (int)rint(250 / 1.5 * (2.8 - v)); if (adc < 0 || adc > 255) return -1; return surf_brd_set_dig_dac(brd, chn, (unsigned char)adc); } #endif