00001
00002 static char sccsid[] = "@(#) pmac.c 1.32@(#)";
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #ifndef rtlinux
00047 #include "rcs.hh"
00048 #else
00049
00050 #include "physmem.hh"
00051
00052
00053 #endif
00054
00055
00056
00057
00058
00059 #include "pmac.h"
00060
00061 #ifdef lynxosPC
00062 extern "C" {
00063 #include "pcioDrv.h"
00064 }
00065 #endif
00066
00067 #ifdef linux
00068 #include <asm/io.h>
00069 #endif
00070
00071
00072
00073 #ifndef PMAC_PROM_V1_13
00074 #define PMAC_MSG_BASE 0x600
00075 #endif
00076
00077 static unsigned int PMAC_BASE_ADDR = 0xD0000;
00078 static unsigned int PMAC_IO_ADDR = 0x210;
00079
00080
00081
00082 #define PMAC_NAME "pmac"
00083 #define PMAC_DPRAM_SIZE ((long) 0x4000)
00084 #define PMAC_IO_SIZE ((long) 0x8)
00085 #define PMAC_RESERVED 0x800
00086
00087 #define PMAC_IO_SPEED 9
00088
00089
00090 #define PMAC_LAST_CHAR (PMAC_SIZE - PMAC_RESERVED - PMAC_MSG_LEN - 4 - 1)
00091 #define PMAC_LAST_SHORT ((PMAC_SIZE - PMAC_RESERVED - PMAC_MSG_LEN - 4) / sizeof(short) - 1)
00092 #define PMAC_LAST_INT ((PMAC_SIZE - PMAC_RESERVED - PMAC_MSG_LEN - 4) / sizeof(int) - 1)
00093 #define PMAC_LAST_FLOAT ((PMAC_SIZE - PMAC_RESERVED - PMAC_MSG_LEN - 4) / sizeof(float) - 1)
00094
00095 #if !defined(lynxosPC) && !defined(WIN32)
00096 #define DEBUG_PMAC
00097
00098 #endif
00099
00100 #ifdef DEBUG_PMAC
00101
00102 #include <stdio.h>
00103 #include <errno.h>
00104
00105 #endif
00106
00107 PHYSMEM_HANDLE *pmac_dpram_handle=NULL;
00108 PHYSMEM_HANDLE *pmac_io_handle=NULL;
00109
00110 #define TIMEOUT 100*PMAC_IO_SPEED*100
00111
00112
00113 static int sendchar(char c, int timeout);
00114 static PMAC_RETURN_VAL getline(char *, int);
00115 static PMAC_RETURN_VAL sendline(const char *line, int timeout);
00116
00117 #define ACK 6
00118 #define BELL 7
00119 #define LF 10
00120 #define CR 13
00121 #define CTRL_X 24
00122
00123 #define PMAC_DATA_BASE_OFFSET (0x800 + 4 + PMAC_MSG_LEN)
00124
00125
00126 void pmac_outportb(unsigned long port, char byte)
00127 {
00128 #if defined(lynxosPC)
00129 outportb(port, byte);
00130 #else
00131 #if defined(linux)
00132 outb(byte, port);
00133 #else
00134 if(NULL != pmac_io_handle)
00135 {
00136 pmac_io_handle->offset = port - PMAC_IO_ADDR;
00137 pmac_io_handle->write(&byte, 1);
00138 }
00139 #endif
00140 #endif
00141 }
00142
00143 char pmac_inportb(unsigned long port)
00144 {
00145 char byte;
00146 #if defined(lynxosPC)
00147 byte = inportb(port);
00148 #else
00149 #if defined(linux)
00150 byte = inb(port);
00151 #else
00152 if(NULL != pmac_io_handle)
00153 {
00154 pmac_io_handle->offset = port - PMAC_IO_ADDR;
00155 pmac_io_handle->read(&byte, 1);
00156 }
00157 #endif
00158 #endif
00159 return byte;
00160 }
00161
00162 static int pmac_initialized = 0;
00163
00164 void pmac_init()
00165 {
00166 #ifndef DEBUG_PMAC
00167 char reply[PMAC_MSG_LEN];
00168
00169 if(pmac_initialized)
00170 {
00171 return;
00172 }
00173
00174 if(NULL == pmac_io_handle)
00175 {
00176 pmac_io_handle = new PHYSMEM_HANDLE(PMAC_IO_ADDR, NT_ISA_IO_ADDRESS, PMAC_IO_SIZE);
00177 if(NULL == pmac_io_handle)
00178 {
00179 #ifndef rtlinux
00180 rcs_print_error( "can't get PMAC IO\n");
00181 #endif
00182 return;
00183 }
00184 if(!pmac_io_handle->valid())
00185 {
00186 #ifndef rtlinux
00187 rcs_print_error( "can't get PMAC IO\n");
00188 #endif
00189 return;
00190 }
00191 }
00192
00193 pmac_outportb(PMAC_IO_ADDR+5, 0);
00194 pmac_outportb(PMAC_IO_ADDR+6, 0);
00195
00196
00197
00198 #ifndef WIN32
00199 getline(reply, TIMEOUT);
00200 #else
00201 getline(reply, TIMEOUT/10);
00202 #endif
00203
00204 if(NULL == pmac_dpram_handle)
00205 {
00206 pmac_dpram_handle = new PHYSMEM_HANDLE(PMAC_BASE_ADDR, NT_ISA_MEM_ADDRESS, PMAC_DPRAM_SIZE);
00207 if(NULL == pmac_dpram_handle)
00208 {
00209 #ifndef rtlinux
00210 rcs_print_error( "can't get PMAC DP RAM\n");
00211 #endif
00212 return;
00213 }
00214 if(!pmac_dpram_handle->valid())
00215 {
00216 #ifndef rtlinux
00217 rcs_print_error( "can't get PMAC DP RAM\n");
00218 #endif
00219 return;
00220 }
00221 }
00222
00223
00224 (void) pmac_online();
00225 pmac_initialized = 1;
00226 #endif
00227 }
00228
00229 void pmac_exit()
00230 {
00231 #ifndef DEBUG_PMAC
00232 pmac_initialized = 0;
00233 if(NULL != pmac_dpram_handle)
00234 {
00235 delete pmac_dpram_handle;
00236 pmac_dpram_handle = NULL;
00237 }
00238 if(NULL != pmac_io_handle)
00239 {
00240 delete pmac_io_handle;
00241 pmac_io_handle = NULL;
00242 }
00243
00244 #endif
00245 }
00246
00247 static int pmac_dpram_error_message_sent = 0;
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 PMAC_UINT8 read_pmac_uint8(int index)
00259 {
00260 #ifdef DEBUG_PMAC
00261 return 0;
00262 #else
00263 PMAC_UINT8 byte;
00264 if(NULL == pmac_dpram_handle)
00265 {
00266 pmac_init();
00267 }
00268 if(NULL == pmac_dpram_handle)
00269 {
00270 if(!pmac_dpram_error_message_sent)
00271 {
00272 #ifndef rtlinux
00273 rcs_print_error("Can't read from PMAC's dual-ported RAM.\n");
00274 #endif
00275 }
00276 pmac_dpram_error_message_sent=1;
00277 return 0;
00278 }
00279 pmac_dpram_handle->offset = PMAC_DATA_BASE_OFFSET + index;
00280 pmac_dpram_handle->read(&byte, 1);
00281 return byte;
00282 #endif
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 void write_pmac_uint8(int index, PMAC_UINT8 val)
00294 {
00295 #ifdef DEBUG_PMAC
00296 return;
00297 #else
00298 if(NULL == pmac_dpram_handle)
00299 {
00300 pmac_init();
00301 }
00302 if(NULL == pmac_dpram_handle)
00303 {
00304 if(!pmac_dpram_error_message_sent)
00305 {
00306 #ifndef rtlinux
00307 rcs_print_error("Can't write to PMAC's dual-ported RAM.\n");
00308 #endif
00309 }
00310 pmac_dpram_error_message_sent=1;
00311 return;
00312 }
00313 pmac_dpram_handle->offset = PMAC_DATA_BASE_OFFSET + index;
00314 pmac_dpram_handle->write(&val, 1);
00315 #endif
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 PMAC_UINT16 read_pmac_uint16(int index)
00328 {
00329 #ifdef DEBUG_PMAC
00330 return 0;
00331 #else
00332 PMAC_UINT16 retval;
00333 if(NULL == pmac_dpram_handle)
00334 {
00335 pmac_init();
00336 }
00337 if(NULL == pmac_dpram_handle)
00338 {
00339 if(!pmac_dpram_error_message_sent)
00340 {
00341 #ifndef rtlinux
00342 rcs_print_error("Can't read from PMAC's dual-ported RAM.\n");
00343 #endif
00344 }
00345 pmac_dpram_error_message_sent=1;
00346 return 0;
00347 }
00348 pmac_dpram_handle->offset = PMAC_DATA_BASE_OFFSET + index*2;
00349 pmac_dpram_handle->read(&retval, 2);
00350 return retval;
00351 #endif
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 void write_pmac_uint16(int index, PMAC_UINT16 val)
00363 {
00364 #ifdef DEBUG_PMAC
00365 return;
00366 #else
00367 if(NULL == pmac_dpram_handle)
00368 {
00369 pmac_init();
00370 }
00371 if(NULL == pmac_dpram_handle)
00372 {
00373 if(!pmac_dpram_error_message_sent)
00374 {
00375 #ifndef rtlinux
00376 rcs_print_error("Can't write to PMAC's dual-ported RAM.\n");
00377 #endif
00378 }
00379 pmac_dpram_error_message_sent=1;
00380 return;
00381 }
00382 pmac_dpram_handle->offset = PMAC_DATA_BASE_OFFSET + index*2;
00383 pmac_dpram_handle->write(&val, 2);
00384 #endif
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 PMAC_UINT32 read_pmac_uint32(int index)
00397 {
00398 #ifdef DEBUG_PMAC
00399 return 0;
00400 #else
00401 PMAC_UINT16 lo, hi;
00402 PMAC_UINT32 retval;
00403
00404 lo = read_pmac_uint16(index*2);
00405 hi = read_pmac_uint16(index*2+1);
00406 retval = ((PMAC_UINT32)hi << 16) + lo;
00407 return retval;
00408 #endif
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 void pmac_writeint(int index, unsigned int val)
00420 {
00421 #ifdef DEBUG_PMAC
00422 return;
00423 #else
00424 PMAC_UINT16 lo, hi;
00425
00426
00427 lo = (unsigned short) (val & 0x0000FFFF);
00428 hi = (unsigned short) ((val & 0xFFFF0000) >> 16);
00429
00430 write_pmac_uint16( index*2, lo);
00431 write_pmac_uint16( index*2+1, hi);
00432 #endif
00433 }
00434
00435 void write_pmac_uint32(int index, PMAC_UINT32 val)
00436 {
00437 pmac_writeint(index, (unsigned int) val);
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 float pmac_readfloat(int index)
00450 {
00451 #ifdef DEBUG_PMAC
00452 return 0;
00453 #else
00454 PMAC_UINT16 lo, hi;
00455 PMAC_UINT32 temp32;
00456
00457
00458 lo = read_pmac_uint16(2*index);
00459 hi = read_pmac_uint16(2*index+1);
00460
00461 temp32 = (hi << 16) + lo;
00462 return *((float *) &temp32);
00463 #endif
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 void pmac_writefloat(int index, float val)
00475 {
00476 #ifdef DEBUG_PMAC
00477 return;
00478 #else
00479 PMAC_UINT16 lo, hi;
00480
00481 lo = (unsigned short) (*((unsigned int *) &val) & 0x0000FFFF);
00482 hi = (unsigned short) ((*((unsigned int *) &val) & 0xFFFF0000) >> 16);
00483
00484 write_pmac_uint16(index*2,lo);
00485 write_pmac_uint16(index*2+1,hi);
00486 #endif
00487 }
00488
00489
00490
00491
00492 static int write_ready()
00493 {
00494 #ifndef DEBUG_PMAC
00495
00496 return pmac_inportb(PMAC_IO_ADDR+2) & 2 ? 1 : 0;
00497 #else
00498 return 1;
00499 #endif
00500 }
00501
00502 static int read_ready()
00503 {
00504 #ifndef DEBUG_PMAC
00505
00506 return pmac_inportb(PMAC_IO_ADDR+2) & 1 ? 1 : 0;
00507 #else
00508 return 1;
00509 #endif
00510 }
00511
00512 static int sendchar(char outchar, int timeout)
00513 {
00514 #ifndef DEBUG_PMAC
00515 int i = 0;
00516
00517 while (i++ < timeout && !write_ready())
00518 ;
00519 if (i < timeout)
00520 {
00521 pmac_outportb(PMAC_IO_ADDR+7, outchar);
00522 return 0;
00523 }
00524 return -1;
00525 #else
00526 return 0;
00527 #endif
00528 }
00529
00530 static PMAC_RETURN_VAL sendline(const char *line, int timeout)
00531 {
00532 #ifndef PMAC_DEBUG
00533 int i = 0;
00534
00535 while (line[i] != 0)
00536 {
00537 if (-1 == sendchar(line[i++], timeout))
00538 return PMAC_WRITE_TIMEOUT;
00539 }
00540 if (-1 == sendchar(13, timeout))
00541 return PMAC_WRITE_TIMEOUT;
00542
00543 return PMAC_ACK;
00544 #else
00545 return PMAC_ACK;
00546 #endif
00547 }
00548
00549
00550
00551
00552
00553 static PMAC_RETURN_VAL getline(char *linebuf, int timeout)
00554 {
00555 #ifdef DEBUG_PMAC
00556 return PMAC_ACK;
00557 #else
00558
00559 char ic;
00560 int timer, nc;
00561 PMAC_RETURN_VAL retval = PMAC_ACK;
00562
00563 ic = nc = timer = 0;
00564 for (;;)
00565 {
00566 if (read_ready())
00567 {
00568 ic = pmac_inportb(PMAC_IO_ADDR+7);
00569 timer = 0;
00570
00571
00572 if (ic == -1)
00573 {
00574 retval = PMAC_INVALID_COMM_PARAMS;
00575 break;
00576 }
00577
00578
00579 if (ic == ACK)
00580 {
00581
00582
00583
00584
00585 break;
00586 }
00587
00588
00589
00590 if (ic == LF)
00591 {
00592 retval = PMAC_INVALID_COMM_PARAMS;
00593 break;
00594 }
00595
00596
00597
00598 if (ic == BELL)
00599 {
00600
00601 retval = PMAC_ERR;
00602 continue;
00603 }
00604
00605
00606
00607
00608 if (ic == CR && retval == PMAC_ERR)
00609 {
00610
00611 break;
00612 }
00613
00614
00615 if (nc >= PMAC_MSG_LEN-1)
00616 {
00617 retval = PMAC_BUF_TOO_SMALL;
00618 continue;
00619 }
00620
00621
00622 linebuf[nc++] = ic;
00623 continue;
00624 }
00625 else
00626 {
00627
00628 if (timer++ >= timeout)
00629 {
00630 retval = PMAC_TIMEOUT;
00631 break;
00632 }
00633 }
00634 }
00635
00636
00637 linebuf[nc++] = 0;
00638
00639 return retval;
00640
00641 #endif
00642 }
00643
00644 static PMAC_RETURN_VAL pmac_writemsg_bus(const char *msg, char *reply, int len)
00645 {
00646 #ifndef DEBUG_PMAC
00647
00648 int timeout = 10*700*PMAC_IO_SPEED;
00649 PMAC_RETURN_VAL retval;
00650
00651
00652 if ((retval = sendline(msg, timeout)) != PMAC_ACK)
00653 return retval;
00654
00655
00656 return getline(reply, timeout);
00657 #else
00658 return PMAC_ACK;
00659
00660 #endif
00661 }
00662
00663
00664
00665
00666
00667
00668 PMAC_RETURN_VAL pmac_writemsg(const char *msg, char *reply, int len)
00669 {
00670 #ifdef DEBUG_PMAC
00671 printf("%s\n", msg);
00672 return PMAC_ACK;
00673 #else
00674 return pmac_writemsg_bus(msg, reply, len);
00675 #endif
00676 }
00677
00678
00679 PMAC_RETURN_VAL pmac_reset()
00680 {
00681 int timeout = 10*700*PMAC_IO_SPEED;
00682
00683 #if defined(lynxosPC) || defined(linux)
00684 if (NULL == pmac_io_handle)
00685 return PMAC_ERR;
00686 #endif
00687
00688
00689 return sendline("$$$", timeout);
00690 }
00691
00692
00693 int pmac_sendstring(const char *string)
00694 {
00695 #ifdef DEBUG_PMAC
00696 printf("%s\n", string);
00697 return 0;
00698 #else
00699 int dperr;
00700 char reply[PMAC_MSG_LEN];
00701
00702 #if defined(lynxosPC) || defined(linux)
00703
00704 if (NULL == pmac_io_handle)
00705 {
00706
00707 pmac_init();
00708 }
00709 #endif
00710
00711
00712 if ((dperr = pmac_writemsg(string, reply, PMAC_MSG_LEN)) != PMAC_ACK)
00713 {
00714
00715 pmac_print_error(dperr, reply);
00716 #ifndef rtlinux
00717 rcs_print_error( "command is %s\n", string);
00718 #endif
00719 return -1;
00720 }
00721 else
00722 {
00723
00724 return 0;
00725 }
00726 #endif
00727 }
00728
00729 #ifdef DEBUG_PMAC
00730
00731 static int pmac_online_state;
00732 #endif
00733
00734
00735 int pmac_online()
00736 {
00737
00738 if (-1 == pmac_sendstring("A"))
00739 return -1;
00740
00741 if (-1 == pmac_sendstring("CLOSE"))
00742 return -1;
00743
00744 if (-1 == pmac_sendstring("DELETE ROT"))
00745 return -1;
00746
00747 return 0;
00748 }
00749
00750
00751 int pmac_program()
00752 {
00753
00754 if (-1 == pmac_sendstring("A"))
00755 return -1;
00756
00757 if (-1 == pmac_sendstring("CLOSE"))
00758 return -1;
00759
00760 if (-1 == pmac_sendstring("DELETE ROT"))
00761 return -1;
00762
00763 if (-1 == pmac_sendstring("DEFINE TBUF 1"))
00764 return -1;
00765
00766 if (-1 == pmac_sendstring("DEFINE ROT 8192"))
00767 return -1;
00768
00769 if (-1 == pmac_sendstring("B0"))
00770 return -1;
00771 if (-1 == pmac_sendstring("OPEN ROT"))
00772 return -1;
00773 if (-1 == pmac_sendstring("R"))
00774 return -1;
00775
00776 if (-1 == pmac_sendstring("TSEL 1"))
00777 return -1;
00778
00779 if (-1 == pmac_sendstring("TINIT"))
00780 return -1;
00781 if (-1 == pmac_sendstring("ADIS 1"))
00782 return -1;
00783
00784 return 0;
00785 }
00786
00787
00788
00789 int pmac_in_position(int axis)
00790 {
00791 #ifdef DEBUG_PMAC
00792 return 1;
00793 #else
00794 int ipos;
00795
00796
00797 switch (axis) {
00798 case 1:
00799 ipos = IPOS_1;
00800 break;
00801 case 2:
00802 ipos = IPOS_2;
00803 break;
00804 case 3:
00805 ipos = IPOS_3;
00806 break;
00807 case 4:
00808 ipos = IPOS_4;
00809 break;
00810 default:
00811 return 1;
00812 }
00813
00814 if (read_pmac_uint32(ipos) == 1)
00815 return 1;
00816 return 0;
00817 #endif
00818 }
00819
00820
00821
00822 int pmac_at_home(int axis)
00823 {
00824 #ifdef DEBUG_PMAC
00825 return 1;
00826 #else
00827 int homed;
00828
00829
00830 switch (axis) {
00831 case 1:
00832 homed = HOMED_1;
00833 break;
00834 case 2:
00835 homed = HOMED_2;
00836 break;
00837 case 3:
00838 homed = HOMED_3;
00839 break;
00840 default:
00841 return -1;
00842 }
00843
00844 if (read_pmac_uint32(homed) == 1)
00845 return 1;
00846 return 0;
00847 #endif
00848 }
00849
00850
00851 int pmac_at_limit(int axis)
00852 {
00853 #ifdef DEBUG_PMAC
00854 return 0;
00855 #else
00856 int limit;
00857
00858 switch (axis)
00859 {
00860 case 1:
00861 limit = read_pmac_uint32(NEG_LIM_1) == 1 ? -1 :
00862 read_pmac_uint32(POS_LIM_1) == 1 ? 1 : 0;
00863 break;
00864 case 2:
00865 limit = read_pmac_uint32(NEG_LIM_2) == 1 ? -1 :
00866 read_pmac_uint32(POS_LIM_2) == 1 ? 1 : 0;
00867 break;
00868 case 3:
00869 limit = read_pmac_uint32(NEG_LIM_3) == 1 ? -1 :
00870 read_pmac_uint32(POS_LIM_3) == 1 ? 1 : 0;
00871 break;
00872 default:
00873 return -1;
00874 }
00875
00876 return limit;
00877 #endif
00878 }
00879
00880
00881 int pmac_at_sw_limit(int axis)
00882 {
00883 #ifdef DEBUG_PMAC
00884 return 0;
00885 #else
00886 int limit;
00887
00888 switch (axis)
00889 {
00890 case 1:
00891 limit = read_pmac_uint32(SW_NEG_LIM_1) == 1 ? -1 :
00892 read_pmac_uint32(SW_POS_LIM_1) == 1 ? 1 : 0;
00893 break;
00894 case 2:
00895 limit = read_pmac_uint32(SW_NEG_LIM_2) == 1 ? -1 :
00896 read_pmac_uint32(SW_POS_LIM_2) == 1 ? 1 : 0;
00897 break;
00898 case 3:
00899 limit = read_pmac_uint32(SW_NEG_LIM_3) == 1 ? -1 :
00900 read_pmac_uint32(SW_POS_LIM_3) == 1 ? 1 : 0;
00901 break;
00902 case 4:
00903 limit = read_pmac_uint32(SW_NEG_LIM_4) == 1 ? -1 :
00904 read_pmac_uint32(SW_POS_LIM_4) == 1 ? 1 : 0;
00905 break;
00906 default:
00907 return -1;
00908 }
00909
00910 return limit;
00911 #endif
00912 }
00913
00914
00915
00916
00917
00918 int pmac_prog_running()
00919 {
00920 #ifdef DEBUG_PMAC
00921 return !pmac_online_state;
00922 #else
00923 return read_pmac_uint32(CS_PROG_RUNNING);
00924 #endif
00925 }
00926
00927 #ifdef DEBUG_PMAC
00928 static double _pos[AXIS_MAX];
00929 #endif
00930
00931
00932 double pmac_pos(int axis)
00933 {
00934 #ifdef DEBUG_PMAC
00935 return 0.0;
00936
00937
00938 #else
00939 int index;
00940 int pos;
00941
00942
00943 switch (axis) {
00944 case 1:
00945 index = ACT_POS_1;
00946 break;
00947 case 2:
00948 index = ACT_POS_2;
00949 break;
00950 case 3:
00951 index = ACT_POS_3;
00952 break;
00953 case 4:
00954 index = ACT_POS_4;
00955 break;
00956 default:
00957 return -1;
00958 }
00959
00960 pos = (int) read_pmac_uint32(index);
00961 return pos;
00962 #endif
00963 }
00964
00965
00966 double pmac_target_pos(int axis)
00967 {
00968 #ifdef DEBUG_PMAC
00969 return 0.0;
00970 #else
00971 int index;
00972 int target;
00973
00974
00975 switch (axis) {
00976 case 1:
00977 index = TARGET_POS_1;
00978 break;
00979 case 2:
00980 index = TARGET_POS_2;
00981 break;
00982 case 3:
00983 index = TARGET_POS_3;
00984 break;
00985 case 4:
00986 index = TARGET_POS_4;
00987 break;
00988 default:
00989 return -1;
00990 }
00991
00992 target = (int) read_pmac_uint32(index);
00993 return target;
00994 #endif
00995 }
00996
00997
00998
00999
01000 void pmac_print_error(int dperr, const char *reply)
01001 {
01002 int error_number;
01003
01004 switch (dperr)
01005 {
01006 case PMAC_ACK:
01007 return;
01008
01009 case PMAC_BUF_TOO_SMALL:
01010 #ifndef rtlinux
01011 rcs_print_error( "buffer too small to hold reply\n");
01012 #endif
01013 return;
01014
01015 case PMAC_BAD_PARAMS:
01016 #ifndef rtlinux
01017 rcs_print_error( "bad parameters to call to pmac_writemsg()\n");
01018 #endif
01019 return;
01020
01021 case PMAC_TIMEOUT:
01022 #ifndef rtlinux
01023 rcs_print_error( "timeout on read from PMAC\n");
01024 #endif
01025 return;
01026
01027 case PMAC_WRITE_TIMEOUT:
01028 #ifndef rtlinux
01029 rcs_print_error( "timeout on write to PMAC\n");
01030 #endif
01031 return;
01032
01033 case PMAC_INVALID_COMM_PARAMS:
01034 #ifndef rtlinux
01035 rcs_print_error( "invalid PMAC comm params\n");
01036 #endif
01037 return;
01038
01039 case PMAC_ERR:
01040
01041
01042 if (1 != sscanf(&reply[3], "%d", &error_number))
01043 {
01044 #ifndef rtlinux
01045 rcs_print_error( "invalid error string: %s\n", reply);
01046 #endif
01047 return;
01048 }
01049
01050
01051 switch (error_number)
01052 {
01053 case 1:
01054 #ifndef rtlinux
01055 rcs_print_error( "command not allowed during program execution\n");
01056 #endif
01057 break;
01058
01059 case 3:
01060 #ifndef rtlinux
01061 rcs_print_error( "data error or unrecognized command\n");
01062 #endif
01063 break;
01064
01065 case 5:
01066 #ifndef rtlinux
01067 rcs_print_error( "command not allowed unless buffer is open\n");
01068 #endif
01069 break;
01070
01071 case 6:
01072 #ifndef rtlinux
01073 rcs_print_error( "no room in buffer for command\n");
01074 #endif
01075 break;
01076
01077 case 7:
01078 #ifndef rtlinux
01079 rcs_print_error( "buffer already in use\n");
01080 #endif
01081 break;
01082
01083 case 9:
01084 #ifndef rtlinux
01085 rcs_print_error( "program structural error (e.g., ENDIF without IF)\n");
01086 #endif
01087 break;
01088
01089 case 10:
01090 #ifndef rtlinux
01091 rcs_print_error( "both overtravel limits set for a motor in the C.S.\n");
01092 #endif
01093 break;
01094
01095 case 11:
01096 #ifndef rtlinux
01097 rcs_print_error( "previous move not completed\n");
01098 #endif
01099 break;
01100
01101 case 12:
01102 #ifndef rtlinux
01103 rcs_print_error( "a motor in the coordinate system is open-loop\n");
01104 #endif
01105 break;
01106
01107 case 13:
01108 #ifndef rtlinux
01109 rcs_print_error( "a motor in the coordinate system is not activated\n");
01110 #endif
01111 break;
01112
01113 case 14:
01114 #ifndef rtlinux
01115 rcs_print_error( "no motors in the coordinate system\n");
01116 #endif
01117 break;
01118
01119 case 15:
01120 #ifndef rtlinux
01121 rcs_print_error( "not pointing to a valid program buffer\n");
01122 #endif
01123 break;
01124
01125 case 16:
01126 #ifndef rtlinux
01127 rcs_print_error( "running improperly structured program (e.g., missing ENDWHILE)\n");
01128 #endif
01129 break;
01130
01131 default:
01132 break;
01133 }
01134
01135 default:
01136 return;
01137 }
01138 }
01139
01140
01141
01142 #ifdef DEBUG_PMAC
01143
01144 static int _spindle_enabled = 0;
01145 static double _spindle_speed = 0.0;
01146
01147 #endif
01148
01149
01150
01151 #define GEAR_1_A 39.4
01152 #define GEAR_1_B 0.0
01153
01154 #define GEAR_2_A 12.1
01155 #define GEAR_2_B 0.0
01156
01157 #define GEAR_3_A 3.66
01158 #define GEAR_3_B 0.0
01159
01160 static int rpms_to_counts(double rpms, int gear)
01161 {
01162 switch (gear)
01163 {
01164 case 1:
01165 case 4:
01166 return GEAR_1_A * rpms + GEAR_1_B;
01167 case 2:
01168 return GEAR_2_A * rpms + GEAR_2_B;
01169 case 3:
01170 return GEAR_3_A * rpms + GEAR_3_B;
01171 default:
01172 return 0;
01173 }
01174 }
01175
01176 static double clip_rpms(double speed_factor, int gear)
01177 {
01178
01179
01180
01181
01182
01183 switch (gear)
01184 {
01185 case 1:
01186 case 4:
01187 if (speed_factor > 336)
01188 speed_factor = 336;
01189 else if (speed_factor < -336)
01190 speed_factor = -336;
01191 break;
01192 case 2:
01193 if (speed_factor > 1086)
01194 speed_factor = 1086;
01195 else if (speed_factor < -1086)
01196 speed_factor = -1086;
01197 break;
01198 case 3:
01199 if (speed_factor > 3000)
01200 speed_factor = 3000;
01201 else if (speed_factor < -3000)
01202 speed_factor = -3000;
01203 break;
01204 default:
01205
01206 break;
01207 }
01208
01209 return speed_factor;
01210 }
01211
01212 #define MAX_COUNTS 12000
01213
01214
01215 void pmac_spindle_speed(double rpms, int gear)
01216 {
01217 int val;
01218
01219
01220 rpms = clip_rpms(rpms, gear);
01221
01222
01223 val = rpms_to_counts(rpms, gear);
01224
01225
01226 if (val < -MAX_COUNTS)
01227 {
01228 val = -MAX_COUNTS;
01229 }
01230 else if (val > MAX_COUNTS)
01231 {
01232 val = MAX_COUNTS;
01233 }
01234
01235 val = -val;
01236
01237
01238 pmac_writeint(SPINDLE_SPEED, val);
01239 #ifdef DEBUG_PMAC
01240 printf("setting pmac spindle speed to %d\n", val);
01241 _spindle_speed = rpms;
01242 #endif
01243 }
01244
01245
01246
01247 int pmac_enable_spindle()
01248 {
01249
01250
01251 if (pmac_prog_running())
01252 {
01253
01254
01255
01256 if (-1 == pmac_online())
01257 return -1;
01258 }
01259
01260
01261 if (-1 == pmac_sendstring("#4K"))
01262 return -1;
01263
01264
01265 if (-1 == pmac_sendstring("I400=0"))
01266 return -1;
01267
01268 #ifdef DEBUG_PMAC
01269 _spindle_enabled = 1;
01270 #endif
01271
01272 return 0;
01273 }
01274
01275
01276
01277 int pmac_disable_spindle()
01278 {
01279
01280 pmac_spindle_speed(0.0, 1);
01281
01282
01283 if (pmac_prog_running())
01284 {
01285 if (-1 == pmac_online())
01286 return -1;
01287 }
01288
01289
01290 if (-1 == pmac_sendstring("I400=1"))
01291 return -1;
01292 if (-1 == pmac_sendstring("#4J/"))
01293 return -1;
01294
01295
01296 #ifdef DEBUG_PMAC
01297 _spindle_enabled = 0;
01298 #endif
01299
01300 return 0;
01301 }
01302
01303 int pmac_spindle_is_open_loop()
01304 {
01305
01306
01307
01308
01309 return read_pmac_uint32(OPEN_LOOP_4);
01310 }
01311
01312
01313
01314
01315
01316
01317 int pmac_probe_on()
01318 {
01319
01320 if (pmac_prog_running())
01321 {
01322 if (-1 == pmac_online())
01323 {
01324 return -1;
01325 }
01326 }
01327
01328
01329 pmac_sendstring("I902=2");
01330 pmac_sendstring("I907=2");
01331 pmac_sendstring("I912=2");
01332
01333
01334 pmac_sendstring("I903=3");
01335 pmac_sendstring("I908=3");
01336 pmac_sendstring("I913=3");
01337
01338 return 0;
01339 }
01340
01341
01342
01343
01344 int pmac_probe_off()
01345 {
01346
01347 if (pmac_prog_running())
01348 {
01349 if (-1 == pmac_online())
01350 {
01351 return -1;
01352 }
01353 }
01354
01355
01356 pmac_sendstring("I902=P902");
01357 pmac_sendstring("I907=P907");
01358 pmac_sendstring("I912=P912");
01359
01360
01361 pmac_sendstring("I903=0");
01362 pmac_sendstring("I908=0");
01363 pmac_sendstring("I913=0");
01364
01365 return 0;
01366 }
01367
01368 int pmac_probe_clear(int axis)
01369 {
01370 switch (axis)
01371 {
01372 case 1:
01373 pmac_writeint(CAPTURE_READY_1, 0);
01374 break;
01375 case 2:
01376 pmac_writeint(CAPTURE_READY_2, 0);
01377 break;
01378 case 3:
01379 pmac_writeint(CAPTURE_READY_3, 0);
01380 break;
01381 default:
01382 return -1;
01383 }
01384 return 0;
01385 }
01386
01387
01388
01389 int pmac_probe_tripped(int axis)
01390 {
01391 switch (axis)
01392 {
01393 case 1:
01394 return read_pmac_uint32(CAPTURE_READY_1);
01395 case 2:
01396 return read_pmac_uint32(CAPTURE_READY_2);
01397 case 3:
01398 return read_pmac_uint32(CAPTURE_READY_3);
01399 default:
01400 return 0;
01401 }
01402 }
01403
01404
01405 int pmac_probe_value(int axis)
01406 {
01407 int value;
01408 int offset;
01409
01410
01411 if (axis < 1 || axis > 3)
01412 {
01413 return 0;
01414 }
01415
01416
01417 switch (axis)
01418 {
01419 case 1:
01420 value = read_pmac_uint32(CAPTURED_1);
01421 offset = read_pmac_uint32(HOME_OFFSET_1);
01422 break;
01423 case 2:
01424 value = read_pmac_uint32(CAPTURED_2);
01425 offset = read_pmac_uint32(HOME_OFFSET_2);
01426 break;
01427 case 3:
01428 value = read_pmac_uint32(CAPTURED_3);
01429 offset = read_pmac_uint32(HOME_OFFSET_3);
01430 break;
01431 }
01432
01433
01434 return (value - offset);
01435 }