Ticket #973: mythtv_multilnb_positioner_rev3.diff
File mythtv_multilnb_positioner_rev3.diff, 39.3 KB (added by , 20 years ago) |
---|
-
libs/libmythtv/dvbdiseqc.cpp
diff -Naur mythtv/libs/libmythtv/dvbdiseqc.cpp mythtv-diseqc/libs/libmythtv/dvbdiseqc.cpp
old new 13 13 * - DiSEqC 1.0 - 1.1. 14 14 * Kenneth Aafloy (ke-aa at frisurf.no) 15 15 * - Initial framework. 16 * Zdzislaw Gorlicki (zdzisekg at yahoo.com) 17 * - DiSEqC 1.2/1.3 + switch 16 18 * 17 19 * This program is free software; you can redistribute it and/or modify 18 20 * it under the terms of the GNU General Public License as published by … … 73 75 return false; 74 76 break; 75 77 case 2: // v1.0 2 Way 78 if (!Diseqc1xSwitch(tuning, reset, havetuned, 2)) 79 return false; 80 break; 76 81 case 3: // v1.1 2 Way 77 82 if (!Diseqc1xSwitch(tuning, reset, havetuned, 2)) 78 83 return false; 79 84 break; 80 85 case 4: // v1.0 4 Way 86 if (!Diseqc1xSwitch(tuning, reset, havetuned, 4)) 87 return false; 88 break; 81 89 case 5: // v1.1 4 Way 82 90 if (!Diseqc1xSwitch(tuning, reset, havetuned, 4)) 83 91 return false; 84 92 break; 85 93 case 6: // 1.2 Positioner (HH Motor) 86 94 if (!PositionerGoto(tuning,reset,havetuned)) 87 95 return false; 88 96 break; 89 97 case 7: // 1.3 Positioner (HH Motor with USALS) 90 98 if (!PositionerGotoAngular(tuning,reset,havetuned)) 91 99 return false; 92 100 break; 93 101 case 8: // v1.1 10 Way 94 102 if (!Diseqc1xSwitch(tuning, reset, havetuned, 10)) 95 103 return false; 96 104 break; 97 105 case 10: // 1.2 Positioner (HH Motor with a switch behind it) 106 if (!PositionerGoto(tuning,reset,havetuned)) 107 return false; 108 break; 109 case 11: // 1.3 Positioner (HH Motor with USALS and with a switch behind it) 110 if (!PositionerGotoAngular(tuning, reset, havetuned)) 111 return false; 112 break; 98 113 default: 99 114 VERBOSE(VB_IMPORTANT, LOC_ERR + "Unsupported DiSEqC type(" 100 115 <<tuning.diseqc_type<<")"); 101 116 } 102 117 103 118 return true; 104 119 } 105 120 … … 156 171 VERBOSE(VB_IMPORTANT, LOC_ERR + 157 172 "Tone Switches only support two ports."); 158 173 174 // I think SEC_MINI_A is 0 in DB so we should compare against that. right? 159 175 if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST, 160 (tuning.diseqc_port == 1? SEC_MINI_A : SEC_MINI_B )) < 0)176 (tuning.diseqc_port == 0 ? SEC_MINI_A : SEC_MINI_B )) < 0) 161 177 { 162 178 VERBOSE(VB_IMPORTANT, LOC_ERR + 163 179 "Setting Tone Switch failed." + ENO); … … 173 189 } 174 190 175 191 /***************************************************************************** 176 Diseqc 1.x Compatible Methods 177 ****************************************************************************/ 192 Legend: 193 {}=Segment 194 T=Set Tone 195 V=Set Voltage 196 w=Wait 197 []=Diseqc Message 198 TB=Set Tone Burst 199 T=Set Tone 200 201 A typical diseqc messages should look like this: 202 T V w [XX XX XX XX] w TB T 203 204 I split this into three functions: 205 1) SendDiSEqCPrepareBus => {T V} 206 2) SenDiSEqCMessage => {w [XX XX XX XX ] w} 207 3) SendDiSEqCSetupBus => {TB T} 208 209 This way we can make the SenDiSEqCMessage as long as we want, for ex. when we 210 use cascaded switches or a switch behind a positioner. 211 ex. T V w [XX XX XX XX] w [XX XX XX XX] w TB T 178 212 179 bool DVBDiSEqC::SendDiSEqCMessage(DVBTuning& tuning, dvb_diseqc_master_cmd &cmd) 213 /****************************************************************************/ 214 //Resets switches and LNBS 215 bool DVBDiSEqC::DiseqcReset() 180 216 { 181 // Turn off tone burst 182 if (ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF) == -1) 217 struct dvb_diseqc_master_cmd reset_cmd = 218 {{CMD_FIRST, MASTER_TO_LSS, RESET, 0x00, 0x00}, 3}; 219 220 struct dvb_diseqc_master_cmd init_cmd = 221 {{CMD_FIRST, MASTER_TO_LSS, POWERON, 0x00, 0x00}, 3}; 222 223 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &init_cmd) <0) 183 224 { 184 VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_TONE failed" + ENO); 225 VERBOSE(VB_IMPORTANT, LOC_ERR + 226 "DiSEqC -> Sending init command failed." + ENO); 185 227 return false; 186 228 } 229 usleep(DISEQC_LONG_WAIT); 187 230 188 /* 189 Old version of the code set the voltage to 13V everytime. 190 After looking at the EutelSat specs I saw no reason that 191 this was done. I have tested this with my DiSEqC switch 192 and all is fine. 193 */ 231 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &reset_cmd) <0) 232 { 233 VERBOSE(VB_IMPORTANT, LOC_ERR + 234 "DiSEqC -> Sending reset command failed." + ENO); 235 return false; 236 } 237 usleep(DISEQC_LONG_WAIT); 194 238 195 if (ioctl(fd_frontend, FE_ SET_VOLTAGE, tuning.voltage) == -1)239 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &init_cmd) <0) 196 240 { 197 VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_VOLTAGE failed" + ENO); 241 VERBOSE(VB_IMPORTANT, LOC_ERR + 242 "DiSEqC -> Sending init command failed." + ENO); 198 243 return false; 199 } 244 } 245 usleep(DISEQC_LONG_WAIT); 200 246 201 usleep(DISEQC_SHORT_WAIT); 247 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Reset completed. Ready to send commands.")); 248 249 return true; 250 } 202 251 203 VERBOSE(VB_CHANNEL, LOC + QString("Sending 1.0 Command: %1 %2 %3 %4")204 .arg(cmd.msg[0], 2, 16)205 .arg(cmd.msg[1], 2, 16)206 .arg(cmd.msg[2], 2, 16)207 .arg(cmd.msg[3], 2, 16));208 252 209 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 253 bool DVBDiSEqC::SendDiSEqCPrepareBus(DVBTuning& tuning, bool reset) 254 { 255 // Reset "visible" DiSEqC switches or LNBs 256 if (reset) 210 257 { 211 VERBOSE(VB_IMPORTANT, LOC_ERR + 212 "FE_DISEQC_SEND_MASTER_CMD failed" + ENO); 258 if (!DiseqcReset()) 259 { 260 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> DiseqcReset() failed"); 261 return false; 262 } 263 } 264 265 // Turn off Continuous tone 266 if (ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF) == -1) 267 { 268 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> FE_SET_TONE failed" + ENO); 213 269 return false; 214 270 } 271 else 272 { 273 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Continuous Tone set to: OFF")); 274 } 275 276 // Set Voltage 277 if (ioctl(fd_frontend, FE_SET_VOLTAGE, tuning.voltage) == -1) 278 { 279 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> FE_SET_VOLTAGE failed" + ENO); 280 return false; 281 } 282 else 283 { 284 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Voltage set to: %1") 285 .arg(tuning.voltage==SEC_VOLTAGE_13?"13V":"18V")); 286 } 287 288 return true; 289 } 215 290 291 292 bool DVBDiSEqC::SendDiSEqCMessage(DVBTuning& tuning, dvb_diseqc_master_cmd &cmd) 293 { 294 // Send the DiSEqC command 216 295 usleep(DISEQC_SHORT_WAIT); 217 296 218 // Check to see if its a 1.1 or 1.2 device. If so repeat the message repeats times. 219 if ((tuning.diseqc_type == 3) || (tuning.diseqc_type == 5) || 220 (tuning.diseqc_type == 6) || (tuning.diseqc_type == 7)) 297 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 298 { 299 VERBOSE(VB_IMPORTANT, LOC_ERR + 300 "DiSEqC -> FE_DISEQC_SEND_MASTER_CMD failed" + ENO); 301 return false; 302 } 303 else 221 304 { 305 if ((tuning.diseqc_type == 7) || (tuning.diseqc_type == 11)) 306 { 307 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Positioner GotoX position %1. Command: %2 %3 %4 %5 %6") 308 .arg(tuning.diseqc_pos) 309 .arg(cmd.msg[FRAME], 2, 16) 310 .arg(cmd.msg[ADDRESS], 2, 16) 311 .arg(cmd.msg[COMMAND], 2, 16) 312 .arg(cmd.msg[DATA_1], 2, 16) 313 .arg(cmd.msg[DATA_2], 2, 16)); 314 } 315 else 316 { 317 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Select Port # %1. Command: %2 %3 %4 %5") 318 .arg(tuning.diseqc_port) 319 .arg(cmd.msg[FRAME], 2, 16) 320 .arg(cmd.msg[ADDRESS], 2, 16) 321 .arg(cmd.msg[COMMAND], 2, 16) 322 .arg(cmd.msg[DATA_1], 2, 16)); 323 } 324 } 222 325 326 // Check to see if its a 1.1, 1.2 or 1.3 device. If so repeat the message repeats times. 327 if ((tuning.diseqc_type == 3) || (tuning.diseqc_type == 5) || 328 (tuning.diseqc_type == 6) || (tuning.diseqc_type == 7) || 329 (tuning.diseqc_type == 10) || (tuning.diseqc_type == 11)) 330 { 223 331 int repeats = repeat; 224 while (repeats--) 332 while (repeats--) 225 333 { 226 227 if (tuning.diseqc_type == 7) 228 { 229 VERBOSE(VB_CHANNEL, LOC + 230 QString("Sending 1.3 Repeat Command: %1 %2 %3 %4 %5") 231 .arg(cmd.msg[0],2,16) 232 .arg(cmd.msg[1],2,16) 233 .arg(cmd.msg[2],2,16) 234 .arg(cmd.msg[3],2,16) 235 .arg(cmd.msg[4],2,16)); 236 } 237 else 238 { 239 VERBOSE(VB_CHANNEL, LOC + 240 QString("Sending 1.1/1.2 Repeat Command: %1 %2 %3 %4") 241 .arg(cmd.msg[0],2,16) 242 .arg(cmd.msg[1],2,16) 243 .arg(cmd.msg[2],2,16) 244 .arg(cmd.msg[3],2,16)); 245 } 246 247 cmd.msg[0] = CMD_REPEAT; 334 usleep(DISEQC_SHORT_WAIT); 335 cmd.msg[FRAME] = CMD_REPEAT; 248 336 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 249 337 { 250 338 VERBOSE(VB_IMPORTANT, LOC_ERR + 251 " FE_DISEQC_SEND_MASTER_CMD failed" + ENO);339 "DiSEqC -> FE_DISEQC_SEND_MASTER_CMD failed" + ENO); 252 340 return false; 253 341 } 254 usleep(DISEQC_SHORT_WAIT); 255 256 cmd.msg[0] = CMD_FIRST; 257 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 342 else 258 343 { 259 VERBOSE(VB_IMPORTANT, LOC_ERR + 260 "FE_DISEQC_SEND_MASTER_CMD failed" + ENO); 261 return false; 344 if ((tuning.diseqc_type == 7) || (tuning.diseqc_type == 11)) 345 { 346 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Positioner GotoX position %1. Repeat Command: %2 %3 %4 %5 %6") 347 .arg(tuning.diseqc_pos) 348 .arg(cmd.msg[FRAME], 2, 16) 349 .arg(cmd.msg[ADDRESS], 2, 16) 350 .arg(cmd.msg[COMMAND], 2, 16) 351 .arg(cmd.msg[DATA_1], 2, 16) 352 .arg(cmd.msg[DATA_2], 2, 16)); 353 } 354 else 355 { 356 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Select Port # %1. Repeat Command: %2 %3 %4 %5") 357 .arg(tuning.diseqc_port) 358 .arg(cmd.msg[FRAME], 2, 16) 359 .arg(cmd.msg[ADDRESS], 2, 16) 360 .arg(cmd.msg[COMMAND], 2, 16) 361 .arg(cmd.msg[DATA_1], 2, 16)); 362 } 262 363 } 263 usleep(DISEQC_SHORT_WAIT);264 364 } 265 365 } 266 366 267 if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A ) == -1) 367 usleep(DISEQC_SHORT_WAIT); 368 369 return true; 370 } 371 372 373 bool DVBDiSEqC::SendDiSEqCSetupBus(DVBTuning& tuning) 374 { 375 //Determin the Tone Burst for switches with more then 2 ports and send it 376 //This is not necessery for pure diseqc setup, but maybe required when using 377 //a simple tone switch behind a diseqc compliant switch. 378 //(This one I had hard time figuring out from the specs at eutelsat 379 //I guess the tone burst can be interpreted differently for different 380 //backward compatible diseqc switches. If backward compatible switches are present, 381 //we need to ensure they don't reset. I have yet come across a definit answer to this, 382 //but it looks like we need to use SEC_MINI_A(modulated 22khz) for all even ports(0,2,4,etc..) 383 //and SEC_MINI_B for odds. PLEASE ADVICE IF YOU KNOW FOR SURE. 384 if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST, 385 ((tuning.diseqc_port % 2) == 0 ? SEC_MINI_A : SEC_MINI_B )) < 0) 268 386 { 269 387 VERBOSE(VB_IMPORTANT, LOC_ERR + 270 " FE_DISEQC_SEND_BURST failed" + ENO);388 "DiSEqC -> FE_DISEQC_SEND_BURST failed" + ENO); 271 389 return false; 272 390 } 391 else 392 { 393 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Tone Burst set to: %1") 394 .arg((tuning.diseqc_port % 2) == 0 ? "A" : "B")); 395 } 273 396 274 397 usleep(DISEQC_SHORT_WAIT); 275 398 399 400 //finally, set the continuous tone. This is also for backward compatibility. 401 //(Not sure why, but looking at the log, 402 //this is always set to ON. Any ideas here? I thought this is used to 403 //select between the High and Low LOF. In my setup LOFSwith=99999000 and 404 //LOFlo=LOFhi=10750000. In this case it should always select LOFlo, right?) 276 405 if (ioctl(fd_frontend, FE_SET_TONE, tuning.tone) == -1) 277 406 { 278 VERBOSE(VB_IMPORTANT, LOC_ERR + " FE_SET_TONE failed" + ENO);407 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> FE_SET_TONE failed" + ENO); 279 408 return false; 280 409 } 410 else 411 { 412 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Continuous Tone set to: %1") 413 .arg(tuning.tone == 0 ? "OFF" : "ON")); 414 } 281 415 282 416 return true; 283 417 } 284 418 285 286 bool DVBDiSEqC::SendDiSEqCMessage(dvb_diseqc_master_cmd &cmd) 419 /***************************************************************************** 420 Diseqc 1.x Compatible Methods 421 ****************************************************************************/ 422 bool DVBDiSEqC::Diseqc1xSwitch(DVBTuning& tuning, bool reset, bool& havetuned, uint ports) 287 423 { 288 // Turn off tone burst 289 if (ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF) == -1) 424 if ((prev_tuning.diseqc_port != tuning.diseqc_port || 425 prev_tuning.tone != tuning.tone || 426 prev_tuning.voltage != tuning.voltage ) || reset) 290 427 { 291 VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_TONE failed" + ENO);292 return false;293 }294 428 295 usleep(DISEQC_SHORT_WAIT); 429 if (tuning.diseqc_port >= ports ) 430 { 431 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Unsupported port# for specifiad DiSEqC switch."); 432 return false; 433 } 296 434 297 VERBOSE(VB_CHANNEL, LOC + QString("Sending 1.0 Command: %1 %2 %3 %4") 298 .arg(cmd.msg[0], 2, 16) 299 .arg(cmd.msg[1], 2, 16) 300 .arg(cmd.msg[2], 2, 16) 301 .arg(cmd.msg[3], 2, 16)); 435 dvb_diseqc_master_cmd cmd = 436 {{CMD_FIRST, MASTER_TO_LSS, WRITE_N1, 0xf0, 0x00, 0x00}, 4}; 302 437 303 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 304 { 305 VERBOSE(VB_IMPORTANT, LOC_ERR + 306 "FE_DISEQC_SEND_MASTER_CMD failed" + ENO); 307 return false; 308 } 438 if ( ports == 10 ) 439 { 440 cmd.msg[COMMAND] = WRITE_N1; 441 cmd.msg[DATA_1] = 0xF0 | (tuning.diseqc_port & 0x0F); 442 } 443 else 444 { 445 cmd.msg[COMMAND] = WRITE_N0; 446 cmd.msg[DATA_1] = 447 0xF0 | 448 (((tuning.diseqc_port) * 4) & 0x0F) | 449 ((tuning.voltage == SEC_VOLTAGE_18) ? 2 : 0) | 450 ((tuning.tone == SEC_TONE_ON) ? 1 : 0); 451 } 309 452 310 usleep(DISEQC_SHORT_WAIT); 311 312 int repeats = repeat; 313 while (repeats--) 314 { 315 VERBOSE(VB_CHANNEL, LOC + 316 QString("Sending 1.1/1.2/1.3 Repeat Command: %1 %2 %3 %4") 317 .arg(cmd.msg[0], 2, 16) 318 .arg(cmd.msg[1], 2, 16) 319 .arg(cmd.msg[2], 2, 16) 320 .arg(cmd.msg[3], 2, 16)); 453 if (!SendDiSEqCPrepareBus(tuning, reset)) 454 { 455 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed -> Segment I"); 456 return false; 457 } 321 458 322 cmd.msg[0] = CMD_REPEAT; 323 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 459 if (!SendDiSEqCMessage(tuning,cmd)) 324 460 { 325 VERBOSE(VB_IMPORTANT, LOC_ERR + 326 "FE_DISEQC_SEND_MASTER_CMD failed" + ENO); 461 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed. -> Segment II"); 327 462 return false; 328 463 } 329 usleep(DISEQC_SHORT_WAIT); 330 331 cmd.msg[0] = CMD_FIRST; 332 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 464 465 if (!SendDiSEqCSetupBus(tuning)) 333 466 { 334 VERBOSE(VB_IMPORTANT, LOC_ERR + 335 "FE_DISEQC_SEND_MASTER_CMD failed" + ENO); 467 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed -> Segment III"); 336 468 return false; 337 469 } 338 usleep(DISEQC_SHORT_WAIT);339 }340 470 341 if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A ) == -1) 342 { 343 VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_DISEQC_SEND_BURST failed" + ENO); 344 return false; 471 prev_tuning.diseqc_port = tuning.diseqc_port; 472 prev_tuning.tone = tuning.tone; 473 prev_tuning.voltage = tuning.voltage; 474 havetuned = true; 475 345 476 } 346 477 478 havetuned |= 479 (prev_tuning.diseqc_port == tuning.diseqc_port) && 480 (prev_tuning.voltage == tuning.voltage) && 481 (prev_tuning.tone == tuning.tone); 482 347 483 return true; 348 484 } 349 485 350 bool DVBDiSEqC::Diseqc1xSwitch(DVBTuning& tuning, bool reset,351 bool& havetuned, uint ports)352 {353 if (reset)354 {355 if (!DiseqcReset())356 {357 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");358 return false;359 }360 }361 362 VERBOSE(VB_CHANNEL, LOC +363 QString("1.1 Switch (%1 ports) - Port %2 - %3 %4")364 .arg(ports)365 .arg(tuning.diseqc_port)366 .arg(tuning.tone==SEC_TONE_ON?"Tone ON":"Tone OFF")367 .arg(tuning.voltage==SEC_VOLTAGE_13?"13V":"18V"));368 486 487 /***************************************************************************** 488 Diseqc Psitioner v1.2 489 ****************************************************************************/ 490 bool DVBDiSEqC::PositionerGoto(DVBTuning& tuning, bool reset, bool& havetuned) 491 { 369 492 if ((prev_tuning.diseqc_port != tuning.diseqc_port || 370 prev_tuning.tone != tuning.tone || 371 prev_tuning.voltage != tuning.voltage ) || reset) 493 prev_tuning.tone != tuning.tone || 494 prev_tuning.diseqc_pos != tuning.diseqc_pos || 495 prev_tuning.voltage != tuning.voltage ) || reset) 372 496 { 373 dvb_diseqc_master_cmd cmd =374 {{CMD_FIRST, MASTER_TO_ LSS, WRITE_N1, 0xf0, 0x00, 0x00}, 4};497 dvb_diseqc_master_cmd cmd_1 = 498 {{CMD_FIRST, MASTER_TO_POSITIONER, GOTO, tuning.diseqc_pos, 0x00, 0x00}, 4}; 375 499 376 if ( tuning.diseqc_port >= ports )500 if (!SendDiSEqCPrepareBus(tuning, reset)) 377 501 { 378 VERBOSE(VB_IMPORTANT, LOC_ERR + " Unsupported switch");502 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed -> Segment I"); 379 503 return false; 380 504 } 381 505 382 switch (ports)506 if (!SendDiSEqCMessage(tuning,cmd_1)) 383 507 { 384 case 10: 385 cmd.msg[COMMAND] = WRITE_N1; 386 cmd.msg[DATA_1] = 0xF0 | (tuning.diseqc_port & 0x0F); 387 break; 388 case 4: 389 case 2: 390 cmd.msg[COMMAND] = WRITE_N0; 391 cmd.msg[DATA_1] = 392 0xF0 | 393 (((tuning.diseqc_port) * 4) & 0x0F) | 394 ((tuning.voltage == SEC_VOLTAGE_18) ? 2 : 0) | 395 ((tuning.tone == SEC_TONE_ON) ? 1 : 0); 396 break; 397 default: 398 VERBOSE(VB_IMPORTANT, LOC_ERR + 399 "Unsupported number of ports for DiSEqC 1.1 Switch"); 508 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed. -> Segment II"); 509 return false; 400 510 } 401 511 402 if (!SendDiSEqCMessage(tuning,cmd)) 512 //if there is a switch behind a positioner, we send a command to it as well 513 if (tuning.diseqc_type == 10) 403 514 { 404 VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed."); 515 dvb_diseqc_master_cmd cmd_2 = 516 {{CMD_FIRST, MASTER_TO_LSS, WRITE_N0, 0xf0, 0x00, 0x00}, 4}; 517 518 cmd_2.msg[DATA_1] = 519 0xF0 | 520 (((tuning.diseqc_port) * 4) & 0x0F) | 521 ((tuning.voltage == SEC_VOLTAGE_18) ? 2 : 0) | 522 ((tuning.tone == SEC_TONE_ON) ? 1 : 0); 523 524 //set the diseqc type for the switch behind rotor. 525 tuning.diseqc_type = 5; 526 527 if (!SendDiSEqCMessage(tuning,cmd_2)) 528 { 529 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed. -> Segment II"); 530 return false; 531 } 532 533 //reset the diseqc type back to 1.2 positioner 534 tuning.diseqc_type = 10; 535 } 536 537 if (!SendDiSEqCSetupBus(tuning)) 538 { 539 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed -> Segment III"); 405 540 return false; 406 541 } 407 542 408 543 prev_tuning.diseqc_port = tuning.diseqc_port; 544 prev_tuning.diseqc_pos = tuning.diseqc_pos; 409 545 prev_tuning.tone = tuning.tone; 410 546 prev_tuning.voltage = tuning.voltage; 411 havetuned = true;412 413 547 } 414 548 415 549 havetuned |= 416 550 (prev_tuning.diseqc_port == tuning.diseqc_port) && 551 (prev_tuning.diseqc_pos == tuning.diseqc_pos) && 417 552 (prev_tuning.voltage == tuning.voltage) && 418 553 (prev_tuning.tone == tuning.tone); 419 554 420 555 return true; 421 556 } 422 557 423 bool DVBDiSEqC::DiseqcReset() 558 559 /***************************************************************************** 560 Diseqc Positioner v1.3 (Goto X) 561 ****************************************************************************/ 562 563 bool DVBDiSEqC::PositionerGotoAngular(DVBTuning& tuning, bool reset, bool& havetuned) 424 564 { 425 struct dvb_diseqc_master_cmd reset_cmd = 426 {{CMD_FIRST, MASTER_TO_LSS, RESET, 0x00, 0x00}, 3}; 427 428 struct dvb_diseqc_master_cmd init_cmd = 429 {{CMD_FIRST, MASTER_TO_LSS, POWERON, 0x00, 0x00}, 3}; 565 /* 566 // TODO: Send information here to FE saying motor is moving and 567 // to expect a longer than average tuning delay 568 if (prev_tuning.diseqc_pos != tuning.diseqc_pos) 569 VERBOSE(VB_CHANNEL, LOC + "DiSEqC Motor Moving"); 570 */ 430 571 431 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &init_cmd) <0) 572 int CMD1=0x00 , CMD2=0x00; // Bytes sent to motor 573 double USALS=0.0; 574 int DecimalLookup[10] = 575 { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E }; 576 577 // Equation lifted from VDR rotor plugin by 578 // Thomas Bergwinkl <Thomas.Bergwinkl@t-online.de> 579 580 double P = gContext->GetSetting("Latitude", "").toFloat() * TO_RADS; // Earth Station Latitude 581 double Ue = gContext->GetSetting("Longitude", "").toFloat() * TO_RADS; // Earth Station Longitude 582 double Us = tuning.diseqc_pos * TO_RADS; // Satellite Longitude 583 584 double az = M_PI + atan( tan (Us-Ue) / sin(P) ); 585 double x = acos( cos(Us-Ue) * cos(P) ); 586 double el = atan( (cos(x) - 0.1513 ) /sin(x) ); 587 double Azimuth = atan((-cos(el)*sin(az))/(sin(el)*cos(P)-cos(el)*sin(P)*cos(az)))* TO_DEC; 588 589 if (Azimuth > 0.0) 590 CMD1=0xE0; // East 591 else 592 CMD1=0xD0; // West 593 594 USALS = fabs(Azimuth); 595 596 while (USALS > 16) 432 597 { 433 VERBOSE(VB_IMPORTANT, LOC_ERR + 434 "Setup: Sending init command failed." + ENO); 435 return false; 598 CMD1++; 599 USALS -=16; 436 600 } 437 usleep(DISEQC_LONG_WAIT);438 601 439 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &reset_cmd) <0)602 while (USALS >= 1.0) 440 603 { 441 VERBOSE(VB_IMPORTANT, LOC_ERR + 442 "Setup: Sending reset command failed." + ENO); 443 return false; 604 CMD2+=0x10; 605 USALS--; 444 606 } 445 usleep(DISEQC_LONG_WAIT);446 607 447 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &init_cmd) <0) 608 CMD2 += DecimalLookup[(int)round(USALS*10)]; 609 610 if ((prev_tuning.diseqc_port != tuning.diseqc_port || 611 prev_tuning.tone != tuning.tone || 612 prev_tuning.diseqc_pos != tuning.diseqc_pos || 613 prev_tuning.voltage != tuning.voltage ) || reset) 448 614 { 449 VERBOSE(VB_IMPORTANT, LOC_ERR + 450 "Setup: Sending init command failed." + ENO); 451 return false; 615 dvb_diseqc_master_cmd cmd_1 = 616 {{CMD_FIRST, MASTER_TO_POSITIONER, GOTO_ANGULAR, CMD1 , CMD2 , 0x00}, 5}; 617 618 if (!SendDiSEqCPrepareBus(tuning, reset)) 619 { 620 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed -> Segment I"); 621 return false; 622 } 623 624 if (!SendDiSEqCMessage(tuning,cmd_1)) 625 { 626 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed. -> Segment II"); 627 return false; 628 } 629 630 //if there is a switch behind a positioner, we send a command to it as well 631 if (tuning.diseqc_type == 11) 632 { 633 dvb_diseqc_master_cmd cmd_2 = 634 {{CMD_FIRST, MASTER_TO_LSS, WRITE_N0, 0xf0, 0x00, 0x00}, 4}; 635 636 cmd_2.msg[DATA_1] = 637 0xF0 | 638 (((tuning.diseqc_port) * 4) & 0x0F) | 639 ((tuning.voltage == SEC_VOLTAGE_18) ? 2 : 0) | 640 ((tuning.tone == SEC_TONE_ON) ? 1 : 0); 641 642 //set the diseqc type for the switch behind rotor. 643 tuning.diseqc_type = 5; 644 645 if (!SendDiSEqCMessage(tuning,cmd_2)) 646 { 647 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed. -> Segment II"); 648 return false; 649 } 650 651 //reset the diseqc type back to 1.3 positioner 652 tuning.diseqc_type = 11; 653 654 } 655 656 if (!SendDiSEqCSetupBus(tuning)) 657 { 658 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed -> Segment III"); 659 return false; 660 } 661 662 prev_tuning.diseqc_port = tuning.diseqc_port; 663 prev_tuning.diseqc_pos = tuning.diseqc_pos; 664 prev_tuning.tone = tuning.tone; 665 prev_tuning.voltage = tuning.voltage; 452 666 } 453 usleep(DISEQC_LONG_WAIT); 667 668 havetuned |= 669 (prev_tuning.diseqc_port == tuning.diseqc_port) && 670 (prev_tuning.diseqc_pos == tuning.diseqc_pos) && 671 (prev_tuning.voltage == tuning.voltage) && 672 (prev_tuning.tone == tuning.tone); 454 673 455 674 return true; 456 675 } 457 676 677 678 458 679 /***************************************************************************** 459 680 Positioner Control 460 681 *****************************************************************************/ 461 682 /* 683 // Currently not used so not needed, also will need to be modified 684 // to be used with current way of sending DiSEqC messages 462 685 bool DVBDiSEqC::PositionerDriveEast(int timestep) 463 686 { 464 687 if (!DiseqcReset()) … … 475 698 VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed."); 476 699 return false; 477 700 } 478 701 479 702 return true; 480 703 } 481 704 … … 499 722 return true; 500 723 } 501 724 502 bool DVBDiSEqC::PositionerGoto(DVBTuning& tuning, bool reset, bool& havetuned)503 {504 // A reset seems to be required for my positioner to work consistently505 VERBOSE(VB_CHANNEL, LOC + QString("1.2 Motor - Goto Stored Position %1")506 .arg(tuning.diseqc_port));507 508 if ((prev_tuning.diseqc_port != tuning.diseqc_port ||509 prev_tuning.tone != tuning.tone ||510 prev_tuning.voltage != tuning.voltage) || reset)511 {512 if (!DiseqcReset())513 {514 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");515 return false;516 }517 518 dvb_diseqc_master_cmd cmd =519 {{CMD_FIRST, MASTER_TO_POSITIONER, GOTO, tuning.diseqc_port,520 0x00, 0x00}, 4};521 522 if (!SendDiSEqCMessage(tuning,cmd))523 {524 VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");525 return false;526 }527 528 prev_tuning.diseqc_port = tuning.diseqc_port;529 prev_tuning.tone = tuning.tone;530 prev_tuning.voltage = tuning.voltage;531 }532 533 havetuned |=534 (prev_tuning.diseqc_port == tuning.diseqc_port) &&535 (prev_tuning.voltage == tuning.voltage) &&536 (prev_tuning.tone == tuning.tone);537 538 return true;539 }540 541 725 bool DVBDiSEqC::PositionerStore(DVBTuning& tuning) 542 726 { 543 727 if (!DiseqcReset()) … … 649 833 650 834 return true; 651 835 } 652 653 /***************************************************************************** 654 Diseqc v1.3 (Goto X) 655 ****************************************************************************/ 656 657 bool DVBDiSEqC::PositionerGotoAngular(DVBTuning& tuning, bool reset, 658 bool& havetuned) 659 { 660 // TODO: Send information here to FE saying motor is moving and 661 // to expect a longer than average tuning delay 662 if (prev_tuning.diseqc_pos != tuning.diseqc_pos) 663 VERBOSE(VB_CHANNEL, LOC + "DiSEqC Motor Moving"); 664 665 int CMD1=0x00 , CMD2=0x00; // Bytes sent to motor 666 double USALS=0.0; 667 int DecimalLookup[10] = 668 { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E }; 669 670 // Equation lifted from VDR rotor plugin by 671 // Thomas Bergwinkl <Thomas.Bergwinkl@t-online.de> 672 673 double P = gContext->GetSetting("Latitude", "").toFloat() * TO_RADS; // Earth Station Latitude 674 double Ue = gContext->GetSetting("Longitude", "").toFloat() * TO_RADS; // Earth Station Longitude 675 double Us = tuning.diseqc_pos * TO_RADS; // Satellite Longitude 676 677 double az = M_PI + atan( tan (Us-Ue) / sin(P) ); 678 double x = acos( cos(Us-Ue) * cos(P) ); 679 double el = atan( (cos(x) - 0.1513 ) /sin(x) ); 680 double Azimuth = atan((-cos(el)*sin(az))/(sin(el)*cos(P)-cos(el)*sin(P)*cos(az)))* TO_DEC; 681 682 // printf("Offset = %f\n",Azimuth); 683 684 if (Azimuth > 0.0) 685 CMD1=0xE0; // East 686 else 687 CMD1=0xD0; // West 688 689 USALS = fabs(Azimuth); 690 691 while (USALS > 16) 692 { 693 CMD1++; 694 USALS -=16; 695 } 696 697 while (USALS >= 1.0) 698 { 699 CMD2+=0x10; 700 USALS--; 701 } 702 703 CMD2 += DecimalLookup[(int)round(USALS*10)]; 704 705 if (!DiseqcReset()) 706 { 707 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed"); 708 return false; 709 } 710 711 // required db changes - get lat and lon for ground station location in db 712 // and added to tuning 713 // sat_pos be passed into tuning, and be a float not an int./ 714 715 VERBOSE(VB_CHANNEL, LOC + QString("1.3 Motor - Goto Angular Position %1") 716 .arg(tuning.diseqc_pos)); 717 718 if ((prev_tuning.diseqc_port != tuning.diseqc_port || 719 prev_tuning.tone != tuning.tone || 720 prev_tuning.diseqc_pos != tuning.diseqc_pos || 721 prev_tuning.voltage != tuning.voltage ) || reset) 722 { 723 724 dvb_diseqc_master_cmd cmd = 725 {{CMD_FIRST, MASTER_TO_POSITIONER, GOTO_ANGULAR, CMD1 , CMD2 , 726 0x00}, 5}; 727 728 if (!SendDiSEqCMessage(tuning,cmd)) 729 { 730 VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed."); 731 return false; 732 } 733 734 prev_tuning.diseqc_port = tuning.diseqc_port; 735 prev_tuning.diseqc_pos = tuning.diseqc_pos; 736 prev_tuning.tone = tuning.tone; 737 prev_tuning.voltage = tuning.voltage; 738 } 739 740 havetuned |= 741 (prev_tuning.diseqc_port == tuning.diseqc_port) && 742 (prev_tuning.diseqc_pos == tuning.diseqc_pos) && 743 (prev_tuning.voltage == tuning.voltage) && 744 (prev_tuning.tone == tuning.tone); 745 746 return true; 747 } 836 */ -
libs/libmythtv/dvbdiseqc.h
diff -Naur mythtv/libs/libmythtv/dvbdiseqc.h mythtv-diseqc/libs/libmythtv/dvbdiseqc.h
old new 31 31 DVBTuning prev_tuning; 32 32 int repeat; 33 33 34 35 bool SendDiSEqCMessage(DVBTuning& tuning, dvb_diseqc_master_cmd &cmd);36 bool SendDiSEqCMessage(dvb_diseqc_master_cmd &cmd);37 38 34 bool ToneVoltageLnb(DVBTuning& tuning, bool reset, bool& havetuned); 39 35 bool ToneSwitch(DVBTuning& tuning, bool reset, bool& havetuned); 40 bool Diseqc1xSwitch(DVBTuning& tuning, bool reset, bool& havetuned, 41 uint ports); 36 37 bool SendDiSEqCPrepareBus(DVBTuning& tuning, bool reset); 38 bool SendDiSEqCMessage(DVBTuning& tuning, dvb_diseqc_master_cmd &cmd); 39 bool SendDiSEqCSetupBus(DVBTuning& tuning); 40 41 bool Diseqc1xSwitch(DVBTuning& tuning, bool reset, bool& havetuned, uint ports); 42 42 bool PositionerGoto(DVBTuning& tuning, bool reset, bool& havetuned); 43 bool PositionerGotoAngular(DVBTuning& tuning, bool reset, bool& havetuned); 44 /* 45 //currently not used 43 46 bool PositionerStore(DVBTuning& tuning); 44 47 bool PositionerStopMovement(); 45 48 bool PositionerStoreEastLimit(); 46 49 bool PositionerStoreWestLimit(); 47 bool PositionerDisableLimits(); 50 bool PositionerDisableLimits(); 48 51 bool PositionerDriveEast(int timestep); 49 52 bool PositionerDriveWest(int timestep); 50 bool PositionerGotoAngular(DVBTuning& tuning, bool reset,51 bool& havetuned);52 53 53 // Still need to be written 54 54 bool Positioner_Status(); 55 */ 55 56 56 57 enum diseqc_cmd_bytes { 57 58 FRAME = 0x0, … … 72 73 REPLY_CRCERR_RPT = 0xe6, 73 74 REPLY_CMDERR_RPT = 0xe7 74 75 }; 75 76 76 77 enum diseqc_address { 77 78 MASTER_TO_ALL = 0x00, 78 79 MASTER_TO_LSS = 0x10, -
libs/libmythtv/videosource.cpp
diff -Naur mythtv/libs/libmythtv/videosource.cpp mythtv-diseqc/libs/libmythtv/videosource.cpp
old new 1242 1242 addSelection("DiSEqC v1.2 Positioner","6"); 1243 1243 addSelection("DiSEqC v1.3 Positioner (Goto X)","7"); 1244 1244 addSelection("DiSEqC v1.1 or 2.1 (10-way method2)","8"); 1245 addSelection("DiSEqC v1.2 Positioner + DiSEqC switch.","10"); 1246 addSelection("DiSEqC v1.3 Positioner (Goto X) + DiSEqC switch.","11"); 1245 1247 setHelpText(QObject::tr("Select the input type for DVB-S cards. " 1246 1248 "Leave as Single LNB/Input for DVB-C or DVB-T. " 1247 1249 "The inputs are mapped from Input Connections option " … … 1687 1689 { 1688 1690 setLabel(QObject::tr("DiSEqC Satellite Location")); 1689 1691 setValue("0.0"); 1690 setHelpText(QObject::tr(" The longitude of the satellite"1691 " you are aiming at. For western hemisphere use "1692 " a negative value. Value is in decimal."));1692 setHelpText(QObject::tr("For 1.2 positioner enter the number as it is stored in the positioner for this satellite" 1693 "or for the GotoX (DiSEqC 1.3/USALS) positioner, this is a longitude of the satellite " 1694 "you are aiming at. For western hemisphere use a negative value. Value is in decimal.")); 1693 1695 // setVisible(false); 1694 1696 }; 1695 1697 // void fillSelections(const QString& pos) { … … 1698 1700 }; 1699 1701 1700 1702 1701 class DiSEqCPort: public L abelSetting, public CISetting1703 class DiSEqCPort: public LineEditSetting, public CISetting 1702 1704 { 1703 1705 public: 1704 1706 DiSEqCPort(const CardInput& parent) 1705 1707 : CISetting(parent, "diseqc_port") 1706 1708 { 1707 set Visible(false);1708 };1709 void fillSelections(const QString& port) {1710 setValue(port);1709 setLabel(QObject::tr("DiSEqC Port")); 1710 setValue("0"); 1711 setHelpText(QObject::tr("Port number of a DiSEqC switch. " 1712 "For 2 Port switches set to 0 or 1. For 4 port switches, 0 to 3.")); 1711 1713 }; 1712 1714 }; 1713 1715 … … 1994 1996 { 1995 1997 if (dvbType == CardUtil::QPSK) 1996 1998 { 1997 //Check for DiSEqC type 1998 diseqcpos->setVisible(true); 1999 lnblofswitch->setVisible(true); 2000 lnbloflo->setVisible(true); 2001 lnblofhi->setVisible(true); 2002 if (CardUtil::GetDISEqCType(_cardid) == CardUtil::POSITIONER_X) 2003 diseqcpos->setEnabled(true); 2004 else 2005 diseqcpos->setEnabled(false); 2006 } 2007 else 2008 { 2009 diseqcpos->setVisible(false); 2010 lnblofswitch->setVisible(false); 2011 lnbloflo->setVisible(false); 2012 lnblofhi->setVisible(false); 1999 //Check for DiSEqC type 2000 diseqcpos->setVisible(true); 2001 diseqcport->setVisible(true); 2002 lnblofswitch->setVisible(true); 2003 lnbloflo->setVisible(true); 2004 lnblofhi->setVisible(true); 2005 if (CardUtil::GetDISEqCType(_cardid) == CardUtil::POSITIONER_1_2 || 2006 CardUtil::GetDISEqCType(_cardid) == CardUtil::POSITIONER_X) 2007 { 2008 diseqcpos->setEnabled(true); 2009 diseqcport->setEnabled(false); 2010 } 2011 else if (CardUtil::GetDISEqCType(_cardid) == CardUtil::POSITIONER_1_2_SWITCH || 2012 CardUtil::GetDISEqCType(_cardid) == CardUtil::POSITIONER_X_SWITCH) 2013 { 2014 diseqcpos->setEnabled(true); 2015 diseqcport->setEnabled(true); 2016 } 2017 else 2018 { 2019 diseqcpos->setEnabled(false); 2020 diseqcport->setEnabled(false); 2021 } 2022 } 2023 else 2024 { 2025 diseqcpos->setVisible(false); 2026 lnblofswitch->setVisible(false); 2027 lnbloflo->setVisible(false); 2028 lnblofhi->setVisible(false); 2013 2029 } 2014 2030 } 2015 2031 } … … 2433 2449 list.append(DVBDiSEqCInputList( 2434 2450 stxt.arg(i+1,2), QString::number(i), "")); 2435 2451 break; 2452 case 10: 2453 for (i = 1; i < 50; ++i) 2454 list.append(DVBDiSEqCInputList( 2455 mtxt.arg(i), "", QString::number(i))); 2456 break; 2457 case 11: 2458 for (i = 1; i < 100; ++i) 2459 list.append(DVBDiSEqCInputList( 2460 itxt.arg(i), "", QString::number(i))); 2461 break; 2462 2436 2463 default: 2437 2464 list.append(DVBDiSEqCInputList( 2438 2465 QString("DVBInput"), QString(""), QString(""))); -
libs/libmythtv/videosource.h
diff -Naur mythtv/libs/libmythtv/videosource.h mythtv-diseqc/libs/libmythtv/videosource.h
old new 53 53 POSITIONER_X, 54 54 POSITIONER_1_2_SWITCH_2, 55 55 POSITIONER_X_SWITCH_2, 56 POSITIONER_1_2_SWITCH, 57 POSITIONER_X_SWITCH, 56 58 }; 57 59 /// \brief dvb card type 58 60 static const QString DVB;