Ticket #973: mythtv_multilnb_positioner_rev5.diff
File mythtv_multilnb_positioner_rev5.diff, 40.0 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); 269 return false; 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); 213 280 return false; 214 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 } 290 215 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 if ((tuning.diseqc_type == 6) || (tuning.diseqc_type == 10)) 316 { 317 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Positioner go to stored position %1. Command: %2 %3 %4 %5") 318 .arg(tuning.diseqc_pos) 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 else 325 { 326 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Select Port # %1. Command: %2 %3 %4 %5") 327 .arg(tuning.diseqc_port) 328 .arg(cmd.msg[FRAME], 2, 16) 329 .arg(cmd.msg[ADDRESS], 2, 16) 330 .arg(cmd.msg[COMMAND], 2, 16) 331 .arg(cmd.msg[DATA_1], 2, 16)); 332 } 333 } 222 334 335 // Check to see if its a 1.1, 1.2 or 1.3 device. If so repeat the message repeats times. 336 if ((tuning.diseqc_type == 3) || (tuning.diseqc_type == 5) || 337 (tuning.diseqc_type == 6) || (tuning.diseqc_type == 7) || 338 (tuning.diseqc_type == 10) || (tuning.diseqc_type == 11)) 339 { 223 340 int repeats = repeat; 224 while (repeats--) 341 while (repeats--) 225 342 { 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; 343 usleep(DISEQC_SHORT_WAIT); 344 cmd.msg[FRAME] = CMD_REPEAT; 248 345 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 249 346 { 250 347 VERBOSE(VB_IMPORTANT, LOC_ERR + 251 " FE_DISEQC_SEND_MASTER_CMD failed" + ENO);348 "DiSEqC -> FE_DISEQC_SEND_MASTER_CMD failed" + ENO); 252 349 return false; 253 350 } 254 usleep(DISEQC_SHORT_WAIT); 255 256 cmd.msg[0] = CMD_FIRST; 257 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 351 else 258 352 { 259 VERBOSE(VB_IMPORTANT, LOC_ERR + 260 "FE_DISEQC_SEND_MASTER_CMD failed" + ENO); 261 return false; 353 if ((tuning.diseqc_type == 7) || (tuning.diseqc_type == 11)) 354 { 355 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Positioner GotoX position %1. Repeat Command: %2 %3 %4 %5 %6") 356 .arg(tuning.diseqc_pos) 357 .arg(cmd.msg[FRAME], 2, 16) 358 .arg(cmd.msg[ADDRESS], 2, 16) 359 .arg(cmd.msg[COMMAND], 2, 16) 360 .arg(cmd.msg[DATA_1], 2, 16) 361 .arg(cmd.msg[DATA_2], 2, 16)); 362 } 363 else if ((tuning.diseqc_type == 6) || (tuning.diseqc_type == 10)) 364 { 365 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Positioner go to stored position %1. Repeat Command: %2 %3 %4 %5") 366 .arg(tuning.diseqc_pos) 367 .arg(cmd.msg[FRAME], 2, 16) 368 .arg(cmd.msg[ADDRESS], 2, 16) 369 .arg(cmd.msg[COMMAND], 2, 16) 370 .arg(cmd.msg[DATA_1], 2, 16)); 371 } 372 else 373 { 374 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Select Port # %1. Repeat Command: %2 %3 %4 %5") 375 .arg(tuning.diseqc_port) 376 .arg(cmd.msg[FRAME], 2, 16) 377 .arg(cmd.msg[ADDRESS], 2, 16) 378 .arg(cmd.msg[COMMAND], 2, 16) 379 .arg(cmd.msg[DATA_1], 2, 16)); 380 } 262 381 } 263 usleep(DISEQC_SHORT_WAIT);264 382 } 265 383 } 266 384 267 if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A ) == -1) 385 usleep(DISEQC_SHORT_WAIT); 386 387 return true; 388 } 389 390 391 bool DVBDiSEqC::SendDiSEqCSetupBus(DVBTuning& tuning) 392 { 393 //Determin the Tone Burst for switches with more then 2 ports and send it 394 //This is not necessery for pure diseqc setup, but maybe required when using 395 //a simple tone switch behind a diseqc compliant switch. 396 //(This one I had hard time figuring out from the specs at eutelsat 397 //I guess the tone burst can be interpreted differently for different 398 //backward compatible diseqc switches. If backward compatible switches are present, 399 //we need to ensure they don't reset. I have yet come across a definit answer to this, 400 //but it looks like we need to use SEC_MINI_A(modulated 22khz) for all even ports(0,2,4,etc..) 401 //and SEC_MINI_B for odds. PLEASE ADVICE IF YOU KNOW FOR SURE. 402 if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST, 403 ((tuning.diseqc_port % 2) == 0 ? SEC_MINI_A : SEC_MINI_B )) < 0) 268 404 { 269 405 VERBOSE(VB_IMPORTANT, LOC_ERR + 270 " FE_DISEQC_SEND_BURST failed" + ENO);406 "DiSEqC -> FE_DISEQC_SEND_BURST failed" + ENO); 271 407 return false; 272 408 } 409 else 410 { 411 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Tone Burst set to: %1") 412 .arg((tuning.diseqc_port % 2) == 0 ? "A" : "B")); 413 } 273 414 274 415 usleep(DISEQC_SHORT_WAIT); 275 416 417 418 //finally, set the continuous tone. This is also for backward compatibility. 276 419 if (ioctl(fd_frontend, FE_SET_TONE, tuning.tone) == -1) 277 420 { 278 VERBOSE(VB_IMPORTANT, LOC_ERR + " FE_SET_TONE failed" + ENO);421 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> FE_SET_TONE failed" + ENO); 279 422 return false; 280 423 } 424 else 425 { 426 VERBOSE(VB_CHANNEL, LOC + QString("DiSEqC -> Continuous Tone set to: %1") 427 .arg(tuning.tone == SEC_TONE_ON ? "ON" : "OFF")); 428 } 281 429 282 430 return true; 283 431 } 284 432 285 286 bool DVBDiSEqC::SendDiSEqCMessage(dvb_diseqc_master_cmd &cmd) 433 /***************************************************************************** 434 Diseqc 1.x Compatible Methods 435 ****************************************************************************/ 436 bool DVBDiSEqC::Diseqc1xSwitch(DVBTuning& tuning, bool reset, bool& havetuned, uint ports) 287 437 { 288 // Turn off tone burst 289 if (ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF) == -1) 438 if ((prev_tuning.diseqc_port != tuning.diseqc_port || 439 prev_tuning.tone != tuning.tone || 440 prev_tuning.voltage != tuning.voltage ) || reset) 290 441 { 291 VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_TONE failed" + ENO);292 return false;293 }294 442 295 usleep(DISEQC_SHORT_WAIT); 443 if (tuning.diseqc_port >= ports ) 444 { 445 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Unsupported port# for specifiad DiSEqC switch."); 446 return false; 447 } 296 448 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)); 449 dvb_diseqc_master_cmd cmd = 450 {{CMD_FIRST, MASTER_TO_LSS, WRITE_N1, 0xf0, 0x00, 0x00}, 4}; 302 451 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 } 452 if ( ports == 10 ) 453 { 454 cmd.msg[COMMAND] = WRITE_N1; 455 cmd.msg[DATA_1] = 0xF0 | (tuning.diseqc_port & 0x0F); 456 } 457 else 458 { 459 cmd.msg[COMMAND] = WRITE_N0; 460 cmd.msg[DATA_1] = 461 0xF0 | 462 (((tuning.diseqc_port) * 4) & 0x0F) | 463 ((tuning.voltage == SEC_VOLTAGE_18) ? 2 : 0) | 464 ((tuning.tone == SEC_TONE_ON) ? 1 : 0); 465 } 309 466 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)); 467 if (!SendDiSEqCPrepareBus(tuning, reset)) 468 { 469 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed -> Segment I"); 470 return false; 471 } 321 472 322 cmd.msg[0] = CMD_REPEAT; 323 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 473 if (!SendDiSEqCMessage(tuning,cmd)) 324 474 { 325 VERBOSE(VB_IMPORTANT, LOC_ERR + 326 "FE_DISEQC_SEND_MASTER_CMD failed" + ENO); 475 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed. -> Segment II"); 327 476 return false; 328 477 } 329 usleep(DISEQC_SHORT_WAIT); 330 331 cmd.msg[0] = CMD_FIRST; 332 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 478 479 if (!SendDiSEqCSetupBus(tuning)) 333 480 { 334 VERBOSE(VB_IMPORTANT, LOC_ERR + 335 "FE_DISEQC_SEND_MASTER_CMD failed" + ENO); 481 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed -> Segment III"); 336 482 return false; 337 483 } 338 usleep(DISEQC_SHORT_WAIT);339 }340 484 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; 485 prev_tuning.diseqc_port = tuning.diseqc_port; 486 prev_tuning.tone = tuning.tone; 487 prev_tuning.voltage = tuning.voltage; 488 havetuned = true; 489 345 490 } 346 491 492 havetuned |= 493 (prev_tuning.diseqc_port == tuning.diseqc_port) && 494 (prev_tuning.voltage == tuning.voltage) && 495 (prev_tuning.tone == tuning.tone); 496 347 497 return true; 348 498 } 349 499 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 500 501 /***************************************************************************** 502 Diseqc Psitioner v1.2 503 ****************************************************************************/ 504 bool DVBDiSEqC::PositionerGoto(DVBTuning& tuning, bool reset, bool& havetuned) 505 { 369 506 if ((prev_tuning.diseqc_port != tuning.diseqc_port || 370 prev_tuning.tone != tuning.tone || 371 prev_tuning.voltage != tuning.voltage ) || reset) 507 prev_tuning.tone != tuning.tone || 508 prev_tuning.diseqc_pos != tuning.diseqc_pos || 509 prev_tuning.voltage != tuning.voltage ) || reset) 372 510 { 373 dvb_diseqc_master_cmd cmd =374 {{CMD_FIRST, MASTER_TO_ LSS, WRITE_N1, 0xf0, 0x00, 0x00}, 4};511 dvb_diseqc_master_cmd cmd_1 = 512 {{CMD_FIRST, MASTER_TO_POSITIONER, GOTO, tuning.diseqc_pos, 0x00, 0x00}, 4}; 375 513 376 if ( tuning.diseqc_port >= ports )514 if (!SendDiSEqCPrepareBus(tuning, reset)) 377 515 { 378 VERBOSE(VB_IMPORTANT, LOC_ERR + " Unsupported switch");516 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed -> Segment I"); 379 517 return false; 380 518 } 381 519 382 switch (ports)520 if (!SendDiSEqCMessage(tuning,cmd_1)) 383 521 { 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"); 522 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed. -> Segment II"); 523 return false; 400 524 } 401 525 402 if (!SendDiSEqCMessage(tuning,cmd)) 526 //if there is a switch behind a positioner, we send a command to it as well 527 if (tuning.diseqc_type == 10) 403 528 { 404 VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed."); 529 dvb_diseqc_master_cmd cmd_2 = 530 {{CMD_FIRST, MASTER_TO_LSS, WRITE_N0, 0xf0, 0x00, 0x00}, 4}; 531 532 cmd_2.msg[DATA_1] = 533 0xF0 | 534 (((tuning.diseqc_port) * 4) & 0x0F) | 535 ((tuning.voltage == SEC_VOLTAGE_18) ? 2 : 0) | 536 ((tuning.tone == SEC_TONE_ON) ? 1 : 0); 537 538 //set the diseqc type for the switch behind rotor. 539 tuning.diseqc_type = 5; 540 541 if (!SendDiSEqCMessage(tuning,cmd_2)) 542 { 543 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed. -> Segment II"); 544 return false; 545 } 546 547 //reset the diseqc type back to 1.2 positioner 548 tuning.diseqc_type = 10; 549 } 550 551 if (!SendDiSEqCSetupBus(tuning)) 552 { 553 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed -> Segment III"); 405 554 return false; 406 555 } 407 556 408 557 prev_tuning.diseqc_port = tuning.diseqc_port; 558 prev_tuning.diseqc_pos = tuning.diseqc_pos; 409 559 prev_tuning.tone = tuning.tone; 410 560 prev_tuning.voltage = tuning.voltage; 411 havetuned = true;412 413 561 } 414 562 415 563 havetuned |= 416 564 (prev_tuning.diseqc_port == tuning.diseqc_port) && 565 (prev_tuning.diseqc_pos == tuning.diseqc_pos) && 417 566 (prev_tuning.voltage == tuning.voltage) && 418 567 (prev_tuning.tone == tuning.tone); 419 568 420 569 return true; 421 570 } 422 571 423 bool DVBDiSEqC::DiseqcReset() 572 573 /***************************************************************************** 574 Diseqc Positioner v1.3 (Goto X) 575 ****************************************************************************/ 576 577 bool DVBDiSEqC::PositionerGotoAngular(DVBTuning& tuning, bool reset, bool& havetuned) 424 578 { 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}; 579 /* 580 // TODO: Send information here to FE saying motor is moving and 581 // to expect a longer than average tuning delay 582 if (prev_tuning.diseqc_pos != tuning.diseqc_pos) 583 VERBOSE(VB_CHANNEL, LOC + "DiSEqC Motor Moving"); 584 */ 430 585 431 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &init_cmd) <0) 586 int CMD1=0x00 , CMD2=0x00; // Bytes sent to motor 587 double USALS=0.0; 588 int DecimalLookup[10] = 589 { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E }; 590 591 // Equation lifted from VDR rotor plugin by 592 // Thomas Bergwinkl <Thomas.Bergwinkl@t-online.de> 593 594 double P = gContext->GetSetting("Latitude", "").toFloat() * TO_RADS; // Earth Station Latitude 595 double Ue = gContext->GetSetting("Longitude", "").toFloat() * TO_RADS; // Earth Station Longitude 596 double Us = tuning.diseqc_pos * TO_RADS; // Satellite Longitude 597 598 double az = M_PI + atan( tan (Us-Ue) / sin(P) ); 599 double x = acos( cos(Us-Ue) * cos(P) ); 600 double el = atan( (cos(x) - 0.1513 ) /sin(x) ); 601 double Azimuth = atan((-cos(el)*sin(az))/(sin(el)*cos(P)-cos(el)*sin(P)*cos(az)))* TO_DEC; 602 603 if (Azimuth > 0.0) 604 CMD1=0xE0; // East 605 else 606 CMD1=0xD0; // West 607 608 USALS = fabs(Azimuth); 609 610 while (USALS > 16) 432 611 { 433 VERBOSE(VB_IMPORTANT, LOC_ERR + 434 "Setup: Sending init command failed." + ENO); 435 return false; 612 CMD1++; 613 USALS -=16; 436 614 } 437 usleep(DISEQC_LONG_WAIT);438 615 439 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &reset_cmd) <0)616 while (USALS >= 1.0) 440 617 { 441 VERBOSE(VB_IMPORTANT, LOC_ERR + 442 "Setup: Sending reset command failed." + ENO); 443 return false; 618 CMD2+=0x10; 619 USALS--; 444 620 } 445 usleep(DISEQC_LONG_WAIT);446 621 447 if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &init_cmd) <0) 622 CMD2 += DecimalLookup[(int)round(USALS*10)]; 623 624 if ((prev_tuning.diseqc_port != tuning.diseqc_port || 625 prev_tuning.tone != tuning.tone || 626 prev_tuning.diseqc_pos != tuning.diseqc_pos || 627 prev_tuning.voltage != tuning.voltage ) || reset) 448 628 { 449 VERBOSE(VB_IMPORTANT, LOC_ERR + 450 "Setup: Sending init command failed." + ENO); 451 return false; 629 dvb_diseqc_master_cmd cmd_1 = 630 {{CMD_FIRST, MASTER_TO_POSITIONER, GOTO_ANGULAR, CMD1 , CMD2 , 0x00}, 5}; 631 632 if (!SendDiSEqCPrepareBus(tuning, reset)) 633 { 634 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed -> Segment I"); 635 return false; 636 } 637 638 if (!SendDiSEqCMessage(tuning,cmd_1)) 639 { 640 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed. -> Segment II"); 641 return false; 642 } 643 644 //if there is a switch behind a positioner, we send a command to it as well 645 if (tuning.diseqc_type == 11) 646 { 647 dvb_diseqc_master_cmd cmd_2 = 648 {{CMD_FIRST, MASTER_TO_LSS, WRITE_N0, 0xf0, 0x00, 0x00}, 4}; 649 650 cmd_2.msg[DATA_1] = 651 0xF0 | 652 (((tuning.diseqc_port) * 4) & 0x0F) | 653 ((tuning.voltage == SEC_VOLTAGE_18) ? 2 : 0) | 654 ((tuning.tone == SEC_TONE_ON) ? 1 : 0); 655 656 //set the diseqc type for the switch behind rotor. 657 tuning.diseqc_type = 5; 658 659 if (!SendDiSEqCMessage(tuning,cmd_2)) 660 { 661 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed. -> Segment II"); 662 return false; 663 } 664 665 //reset the diseqc type back to 1.3 positioner 666 tuning.diseqc_type = 11; 667 668 } 669 670 if (!SendDiSEqCSetupBus(tuning)) 671 { 672 VERBOSE(VB_IMPORTANT, LOC_ERR + "DiSEqC -> Setting DiSEqC failed -> Segment III"); 673 return false; 674 } 675 676 prev_tuning.diseqc_port = tuning.diseqc_port; 677 prev_tuning.diseqc_pos = tuning.diseqc_pos; 678 prev_tuning.tone = tuning.tone; 679 prev_tuning.voltage = tuning.voltage; 452 680 } 453 usleep(DISEQC_LONG_WAIT); 681 682 havetuned |= 683 (prev_tuning.diseqc_port == tuning.diseqc_port) && 684 (prev_tuning.diseqc_pos == tuning.diseqc_pos) && 685 (prev_tuning.voltage == tuning.voltage) && 686 (prev_tuning.tone == tuning.tone); 454 687 455 688 return true; 456 689 } 457 690 691 692 458 693 /***************************************************************************** 459 694 Positioner Control 460 695 *****************************************************************************/ 461 696 /* 697 // Currently not used so not needed, also will need to be modified 698 // to be used with current way of sending DiSEqC messages 462 699 bool DVBDiSEqC::PositionerDriveEast(int timestep) 463 700 { 464 701 if (!DiseqcReset()) … … 475 712 VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed."); 476 713 return false; 477 714 } 478 715 479 716 return true; 480 717 } 481 718 … … 499 736 return true; 500 737 } 501 738 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 739 bool DVBDiSEqC::PositionerStore(DVBTuning& tuning) 542 740 { 543 741 if (!DiseqcReset()) … … 649 847 650 848 return true; 651 849 } 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 } 850 */ -
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;