void setup_switch (int frontend_fd, fe_sec_voltage_t voltage, fe_sec_tone_mode_t tone, int committed, int uncommitted, int servo) { if (tone) printf("22khz OFF\n"); else printf("22khz ON\n"); if (ioctl(frontend_fd, FE_SET_TONE, SEC_TONE_OFF) == -1) perror("FE_SET_TONE ERROR!"); usleep(20000); if (ioctl(frontend_fd, FE_SET_VOLTAGE, voltage) == -1) perror("FE_SET_VOLTAGE ERROR!"); usleep(servo*1000); if (uncommitted) diseqc_send_msg(frontend_fd, uncommitted_switch_cmds[uncommitted-1]); if (committed) diseqc_send_msg(frontend_fd, committed_switch_cmds[committed-1]); if (ioctl(frontend_fd, FE_SET_TONE, tone) == -1) perror("FE_SET_TONE ERROR!"); usleep(20000); }
static int diseqc_setup(int fd, struct sec_params *params) { int pos = params->pos; int band = params->tone; fe_sec_voltage_t voltage = params->voltage; int ret; struct diseqc_cmd cmd = {{{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 }; /* * param: high nibble: reset bits, low nibble set bits, * bits are: option, position, polarization, band */ cmd.cmd.msg[3] = 0xf0 | (((pos * 4) & 0x0f) | (band ? 1 : 0) | (voltage ? 0 : 2)); ret = diseqc_send_msg(fd, params, &cmd); if (ret < 0) { fprintf(stderr, "SEC message send failed, err=%d", ret); return -EIO; } return 0; }
/* digital satellite equipment control, * specification is available from http://www.eutelsat.com/ */ static void diseqc (int secfd, int sat_no, int voltage, int tone) { struct diseqc_cmd cmd = { {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 }; /* param: high nibble: reset bits, low nibble set bits, * bits are: option, position, polarizaion, band */ cmd.cmd.msg[3] = 0xf0 | (((sat_no * 4) & 0x0f) | (tone == SEC_TONE_ON ? 1 : 0) | (voltage == SEC_VOLTAGE_13 ? 0 : 2)); /* send twice because some diseqc switches do not respond correctly the * first time */ diseqc_send_msg (secfd, voltage, &cmd, tone, sat_no % 2 ? SEC_MINI_B : SEC_MINI_A); diseqc_send_msg (secfd, voltage, &cmd, tone, sat_no % 2 ? SEC_MINI_B : SEC_MINI_A); }
int main(int argc, char **argv) { struct diseqc_cmd *cmd[2] = { NULL, NULL }; char *fedev = "/dev/dvb/adapter0/frontend0"; int fd; if (getenv("FRONTEND")) fedev = getenv("FRONTEND"); printf("diseqc test: using '%s'\n", fedev); if ((fd = open(fedev, O_RDWR)) < 0) { perror("open"); return -1; } if (argc > 1) { int i = atol(argv[1]); cmd[0] = &switch_cmds[i]; diseqc_send_msg(fd, i % 2 ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13, cmd, (i/2) % 2 ? SEC_TONE_ON : SEC_TONE_OFF, (i/4) % 2 ? SEC_MINI_B : SEC_MINI_A); } else { unsigned int j; for (j=0; j<sizeof(switch_cmds)/sizeof(struct diseqc_cmd); j++) { cmd[0] = &switch_cmds[j]; diseqc_send_msg(fd, j % 2 ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13, cmd, (j/2) % 2 ? SEC_TONE_ON : SEC_TONE_OFF, (j/4) % 2 ? SEC_MINI_B : SEC_MINI_A); msleep (1000); } } close(fd); return 0; }
/* digital satellite equipment control, * specification is available from http://www.eutelsat.com/ */ static int do_diseqc(int secfd, int sat_no, int polv, int hi_lo) { struct diseqc_cmd cmd = { {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 }; /* param: high nibble: reset bits, low nibble set bits, * bits are: option, position, polarizaion, band */ cmd.cmd.msg[3] = 0xf0 | (((sat_no * 4) & 0x0f) | (hi_lo ? 1 : 0) | (polv ? 0 : 2)); return diseqc_send_msg(secfd, polv ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18, &cmd, hi_lo ? SEC_TONE_ON : SEC_TONE_OFF, (sat_no / 4) % 2 ? SEC_MINI_B : SEC_MINI_A); }
int setup_switch (int frontend_fd, int switch_pos, int voltage_18, int hiband, int uncommitted_switch_pos) { int i; int err; struct diseqc_cmd *cmd[2] = { NULL, NULL }; i = uncommitted_switch_pos; // fprintf(stderr,"DiSEqC: uncommitted switch pos %i\n", uncommitted_switch_pos); if (i < 0 || i >= (int) (sizeof(uncommitted_switch_cmds)/sizeof(struct diseqc_cmd))) return -EINVAL; cmd[0] = &uncommitted_switch_cmds[i]; diseqc_send_msg (frontend_fd, voltage_18 ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13, cmd, hiband ? SEC_TONE_ON : SEC_TONE_OFF, switch_pos % 2 ? SEC_MINI_B : SEC_MINI_A); i = 4 * switch_pos + 2 * hiband + (voltage_18 ? 1 : 0); // fprintf(stderr,"DiSEqC: switch pos %i, %sV, %sband (index %d)\n", // switch_pos, voltage_18 ? "18" : "13", hiband ? "hi" : "lo", i); if (i < 0 || i >= (int) (sizeof(committed_switch_cmds)/sizeof(struct diseqc_cmd))) return -EINVAL; cmd[0] = &committed_switch_cmds[i]; err = diseqc_send_msg (frontend_fd, voltage_18 ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13, cmd, hiband ? SEC_TONE_ON : SEC_TONE_OFF, switch_pos % 2 ? SEC_MINI_B : SEC_MINI_A); return err; }
void motor_usals(int frontend_fd, double site_lat, double site_long, double sat_long) { if (ioctl(frontend_fd, FE_SET_TONE, SEC_TONE_OFF) == -1) perror("FE_SET_TONE ERROR!"); usleep(20000); if (ioctl(frontend_fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18) == -1) perror("FE_SET_VOLTAGE ERROR!"); usleep(20000); double r_eq = 6378.14; // Earth radius double r_sat = 42164.57; // Distance from earth centre to satellite site_lat = radian(site_lat); site_long = radian(site_long); sat_long = radian(sat_long); double declination = degree( atan( r_eq * sin(site_lat) / ( (r_sat - r_eq) + (r_eq * (1 - cos(site_lat))) ) ) ); // x = [0], y = [1], z = [2] double dishVector[3] = { r_eq * cos(site_lat), 0, r_eq * sin(site_lat) }; double satVector[3] = { r_sat * cos(site_long - sat_long), r_sat * sin(site_long - sat_long), 0 }; double satPointing[3] = { satVector[0] - dishVector[0], satVector[1] - dishVector[1], satVector[2] - dishVector[2] } ; double motor_angle = degree( atan( satPointing[1]/satPointing[0] ) ); int sixteenths = fabs(motor_angle) * 16.0 + 0.5; int angle_1, angle_2; angle_1 = motor_angle > 0.0 ? 0xd0 : 0xe0; angle_1 |= sixteenths >> 8; angle_2 = sixteenths & 0xff; printf("Long: %.2f, Lat: %.2f, Orbital Pos: %.2f, RotorCmd: %02x %02x, motor_angle: %.2f declination: %.2f\n", degree(site_long), degree(site_lat), degree(sat_long), angle_1, angle_2, motor_angle, declination); struct dvb_diseqc_master_cmd usals_cmd = { { 0xe0, 0x31, 0x6e, angle_1, angle_2, 0x00 }, 5 }; diseqc_send_msg(frontend_fd, usals_cmd); printf("Waiting for motor to move, either wait 45sec or hit 's' to skip\n"); int c; int sec = time(NULL); set_conio_terminal_mode(); do { sleep(1); if ( kbhit() ) c = kbgetchar(); /* consume the character */ } while( (char)c != 's' && sec+45 > time(NULL) ); reset_terminal_mode(); }
void motor_gotox(int frontend_fd, int pmem) { struct dvb_diseqc_master_cmd gotox_cmd = { { 0xe0, 0x31, 0x6B, pmem, 0x00, 0x00 }, 4 }; diseqc_send_msg(frontend_fd, gotox_cmd); printf("Waiting for motor to move, either wait 45sec or hit 's' to skip\n"); int c; int sec = time(NULL); set_conio_terminal_mode(); do { sleep(1); if ( kbhit() ) c = kbgetchar(); /* consume the character */ } while( (char)c != 's' && sec+45 > time(NULL) ); reset_terminal_mode(); }
int setup_switch(int frontend_fd, int switch_pos, int voltage_18, int hiband) { struct diseqc_cmd *cmd[2] = { NULL, NULL }; int i = 4 * switch_pos + 2 * hiband + (voltage_18 ? 1 : 0); if (i < 0 || i >= (int) (sizeof(switch_cmds)/sizeof(struct diseqc_cmd))) return -EINVAL; cmd[0] = &switch_cmds[i]; return diseqc_send_msg (frontend_fd, i % 2 ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13, cmd, (i/2) % 2 ? SEC_TONE_ON : SEC_TONE_OFF, (i/4) % 2 ? SEC_MINI_B : SEC_MINI_A); }
static int do_diseqc(int fd, unsigned char sat_no, int polv, int hi_lo) { struct diseqc_cmd cmd = { {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 }; if(sat_no != 0) { unsigned char d = sat_no; /* param: high nibble: reset bits, low nibble set bits, * bits are: option, position, polarizaion, band */ sat_no--; cmd.cmd.msg[3] = 0xf0 | (((sat_no * 4) & 0x0f) | (polv ? 0 : 2) | (hi_lo ? 1 : 0)); return diseqc_send_msg(fd, polv ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18, &cmd, hi_lo ? SEC_TONE_ON : SEC_TONE_OFF, d); } else //only tone and voltage { fe_sec_voltage_t voltage; fprintf(stderr, "Setting only tone %s and voltage %dV\n", (hi_lo ? "ON" : "OFF"), (polv ? 13 : 18)); if(ioctl(fd, FE_SET_VOLTAGE, (polv ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18)) < 0) return -1; if(ioctl(fd, FE_SET_TONE, (hi_lo ? SEC_TONE_ON : SEC_TONE_OFF)) < 0) return -1; usleep(15 * 1000); return 0; } }
int diseqc_setup(int fe_fd, int lnb_num, int voltage, int band, uint32_t version, uint32_t repeats) { int i = (lnb_num % 4) * 4 + voltage * 2 + (band ? 1 : 0); int j = lnb_num / 4; int k, err; tvhtrace("diseqc", "fe_fd=%i, lnb_num=%i, voltage=%i, band=%i, version=%i, repeats=%i", fe_fd, lnb_num, voltage, band, version, repeats); /* verify lnb number and diseqc data */ if(lnb_num < 0 || lnb_num >=64 || i < 0 || i >= 16 || j < 0 || j >= 16) return -1; /* turn off continuous tone */ tvhtrace("diseqc", "disabling continuous tone"); if ((err = ioctl(fe_fd, FE_SET_TONE, SEC_TONE_OFF))) { tvhlog(LOG_ERR, "diseqc", "error trying to turn off continuous tone"); return err; } /* set lnb voltage */ tvhtrace("diseqc", "setting lnb voltage to %iV", (i/2) % 2 ? 18 : 13); if ((err = ioctl(fe_fd, FE_SET_VOLTAGE, (i/2) % 2 ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13))) { tvhlog(LOG_ERR, "diseqc", "error setting lnb voltage"); return err; } msleep(15); if (repeats == 0) { /* uncommited msg, wait 15ms, commited msg */ if ((err = diseqc_send_msg(fe_fd, 0xE0, 0x10, 0x39, 0xF0 | j, 0, 0, 4))) return err; msleep(15); if ((err = diseqc_send_msg(fe_fd, 0xE0, 0x10, 0x38, 0xF0 | i, 0, 0, 4))) return err; } else { /* commited msg, 25ms, uncommited msg, 25ms, commited msg, etc */ if ((err = diseqc_send_msg(fe_fd, 0xE0, 0x10, 0x38, 0xF0 | i, 0, 0, 4))) return err; for (k = 0; k < repeats; k++) { msleep(25); if ((err = diseqc_send_msg(fe_fd, 0xE0, 0x10, 0x39, 0xF0 | j, 0, 0, 4))) return err; msleep(25); if ((err = diseqc_send_msg(fe_fd, 0xE1, 0x10, 0x38, 0xF0 | i, 0, 0, 4))) return err; } } msleep(15); /* set toneburst */ tvhtrace("diseqc", (i/4) % 2 ? "sending mini diseqc B" : "sending mini diseqc A"); if ((err = ioctl(fe_fd, FE_DISEQC_SEND_BURST, (i/4) % 2 ? SEC_MINI_B : SEC_MINI_A))) { tvhlog(LOG_ERR, "diseqc", "error sending mini diseqc command"); return err; } msleep(15); /* set continuous tone */ tvhtrace("diseqc", i % 2 ? "enabling continous tone" : "disabling continuous tone"); if ((err = ioctl(fe_fd, FE_SET_TONE, i % 2 ? SEC_TONE_ON : SEC_TONE_OFF))) { tvhlog(LOG_ERR, "diseqc", "error setting continuous tone"); return err; } return 0; }
void motor_gotox_save(int frontend_fd, int pmem) { struct dvb_diseqc_master_cmd gotox_save_cmd = { { 0xe0, 0x31, 0x6A, pmem, 0x00, 0x00 }, 4 }; diseqc_send_msg(frontend_fd, gotox_save_cmd); usleep(20000); }
void motor_west(int frontend_fd, int dir) { diseqc_send_msg(frontend_fd, step_west[dir]); usleep(20000); }
void motor_dir(int frontend_fd, int dir) { diseqc_send_msg(frontend_fd, dir_cmd[dir]); usleep(20000); }
/** @brief generate and sent the digital satellite equipment control "message", * specification is available from http://www.eutelsat.com/ * * This function will set the LNB voltage and the 22kHz tone. If a satellite switching is asked * it will send a diseqc message * * @param fd : the file descriptor of the frontend * @param sat_no : the satellite number (0 for non diseqc compliant hardware, 1 to 4 for diseqc compliant) * @param switch_type the switch type (commited or uncommited) * @param pol_v_r : 1 : vertical or circular right, 0 : horizontal or circular left * @param hi_lo : the band for a dual band lnb * @param lnb_voltage_off : if one, force the 13/18V voltage to be 0 independantly of polarization */ static int do_diseqc(int fd, unsigned char sat_no, char switch_type, int pol_v_r, int hi_lo, int lnb_voltage_off) { fe_sec_voltage_t lnb_voltage; struct diseqc_cmd *cmd[2] = { NULL, NULL }; int ret; //Compute the lnb voltage : 0 if we asked, of 13V for vertical and circular right, 18 for horizontal and circular left if (lnb_voltage_off) { lnb_voltage=SEC_VOLTAGE_OFF; log_message( log_module, MSG_INFO, "LNB voltage 0V\n"); } else if(pol_v_r) { lnb_voltage=SEC_VOLTAGE_13; log_message( log_module, MSG_INFO, "LNB voltage 13V\n"); } else { lnb_voltage=SEC_VOLTAGE_18; log_message( log_module, MSG_INFO, "LNB voltage 18V\n"); } //Diseqc compliant hardware if(sat_no != 0) { cmd[0]=malloc(sizeof(struct diseqc_cmd)); if(cmd[0]==NULL) { log_message( log_module, MSG_ERROR,"Problem with malloc : %s file : %s line %d\n",strerror(errno),__FILE__,__LINE__); Interrupted=ERROR_MEMORY<<8; return -1; } cmd[0]->wait=0; //Framing byte : Command from master, no reply required, first transmission : 0xe0 cmd[0]->cmd.msg[0] = 0xe0; //Address byte : Any LNB, switcher or SMATV cmd[0]->cmd.msg[1] = 0x10; //Command byte : Write to port group 1 (Uncommited switches) //Command byte : Write to port group 0 (Committed switches) 0x38 if(switch_type=='U') cmd[0]->cmd.msg[2] = 0x39; else cmd[0]->cmd.msg[2] = 0x38; /* param: high nibble: reset bits, low nibble set bits, * bits are: option, position, polarization, band */ cmd[0]->cmd.msg[3] = 0xf0 | ((((sat_no-1) * 4) & 0x0f) | (pol_v_r ? 0 : 2) | (hi_lo ? 1 : 0)); // cmd[0]->cmd.msg[4] = 0x00; cmd[0]->cmd.msg[5] = 0x00; cmd[0]->cmd.msg_len=4; log_message( log_module, MSG_DETAIL ,"Test Diseqc message %02x %02x %02x %02x %02x len %d\n", cmd[0]->cmd.msg[0],cmd[0]->cmd.msg[1],cmd[0]->cmd.msg[2],cmd[0]->cmd.msg[3],cmd[0]->cmd.msg[4],cmd[0]->cmd.msg[5], cmd[0]->cmd.msg_len); ret = diseqc_send_msg(fd, lnb_voltage, cmd, hi_lo ? SEC_TONE_ON : SEC_TONE_OFF, (sat_no) % 2 ? SEC_MINI_B : SEC_MINI_A); if(ret) { log_message( log_module, MSG_WARN, "problem sending the DiseqC message or setting tone/voltage\n"); } free(cmd[0]); return ret; } else //only tone and voltage { if(ioctl(fd, FE_SET_VOLTAGE, lnb_voltage) < 0) { log_message( log_module, MSG_WARN, "problem to set the LNB voltage\n"); return -1; } if(ioctl(fd, FE_SET_TONE, (hi_lo ? SEC_TONE_ON : SEC_TONE_OFF)) < 0) { log_message( log_module, MSG_WARN, "problem to set the 22kHz tone\n"); return -1; } msleep(15); return 0; } }