00001
00002
00048 #include <time.h>
00049
00050 #include "edtinc.h"
00051
00052
00053
00054
00055
00056
00057
00058
00059
00069 u_int
00070 edt_spi_reg_read(EdtDev *edt_p, u_int desc)
00071 {
00072 u_int adj_desc = desc;
00073 u_int retval;
00074
00075 if (edt_p->spi_reg_base)
00076 {
00077 adj_desc &= ~0x000000ff;
00078 adj_desc |= edt_p->spi_reg_base + (desc & 0x0f);
00079 }
00080 retval= edt_reg_read(edt_p, adj_desc);
00081 return retval;
00082 }
00083
00092 void
00093 edt_spi_reg_write(EdtDev *edt_p, u_int desc, u_int val)
00094 {
00095 u_int adj_desc = desc;
00096
00097 if (edt_p->spi_reg_base)
00098 {
00099 adj_desc &= ~0x000000ff;
00100 adj_desc |= edt_p->spi_reg_base + (desc & 0x0f);
00101 }
00102 edt_reg_write(edt_p, adj_desc, val);
00103 }
00104
00120 EdtDev *
00121 edt_spi_open(char *edt_interface, int unit, u_int spi_reg_base)
00122 {
00123 EdtDev *edt_p = NULL;
00124
00125 printf("Trying PCD unit %d\n", unit);
00126 edt_p = edt_open(edt_interface, unit);
00127
00128 if (edt_p != NULL)
00129 {
00130 edt_p->spi_reg_base = spi_reg_base;
00131 if ((edt_spi_reg_read(edt_p, SPI_STAT_CTRL) & 0x80) != 0)
00132 {
00133 fputs("Warning: SPI unit is not master device; may be read-only\n", stderr);
00134 fflush(stderr);
00135 }
00136
00137 }
00138
00139 return edt_p;
00140 }
00141
00150 int
00151 edt_spi_close(EdtDev *edt_p)
00152 {
00153 return edt_close(edt_p);
00154 }
00155
00164 u_char
00165 edt_spi_get_byte(EdtDev *edt_p)
00166 {
00167 u_char ch;
00168
00169 while (edt_spi_get_stat(edt_p) & FIFO_IN_EMPTY)
00170 {
00171 edt_usec_busywait(10);
00172 }
00173 ch = edt_spi_reg_read(edt_p, SPI_DATA);
00174 edt_spi_reg_write(edt_p, SPI_STROBE, 0x00);
00175 return ch;
00176 }
00177
00178 u_char
00179 edt_spi_get_byte_nointr(EdtDev *edt_p)
00180 {
00181 u_char ch;
00182
00183 while (edt_spi_get_stat(edt_p) & FIFO_IN_EMPTY)
00184 {
00185 edt_usec_busywait(10);
00186 }
00187 ch = edt_spi_reg_read(edt_p, SPI_DATA);
00188 edt_spi_reg_write(edt_p, SPI_STROBE, 0x00);
00189 return ch;
00190 }
00191
00201 int
00202 edt_spi_get_binary(EdtDev *edt_p, unsigned char *byte)
00203 {
00204 u_char ch;
00205
00206 if ((ch = edt_spi_get_byte(edt_p)) == 0)
00207 return -1;
00208
00209 if (ch == '\\')
00210 {
00211 if ((ch = edt_spi_get_byte(edt_p)) == 0)
00212 return -1;
00213
00214 if (ch == '\\')
00215 {
00216 *byte = ch;
00217 }
00218 else if (ch == 'z')
00219 {
00220 *byte = 0;
00221 }
00222 else
00223 return -1;
00224 }
00225 else
00226 *byte = ch;
00227
00228 return 0;
00229 }
00230
00231
00240 int
00241 edt_spi_fifo_empty(EdtDev *edt_p)
00242 {
00243 if (edt_spi_get_stat(edt_p) & FIFO_IN_EMPTY)
00244 return 1;
00245 else
00246 return 0;
00247 }
00248
00259 u_char
00260 edt_spi_put_byte(EdtDev *edt_p, u_char ch)
00261 {
00262 edt_spi_reg_write(edt_p, SPI_DATA, ch);
00263 return ch;
00264 }
00265
00274 u_char
00275 edt_spi_get_stat(EdtDev *edt_p)
00276 {
00277 return edt_spi_reg_read(edt_p, SPI_STAT_CTRL);
00278 }
00279
00288 void
00289 edt_spi_flush_fifo(EdtDev *edt_p)
00290 {
00291 edt_spi_reg_write(edt_p, SPI_STAT_CTRL, FIFO_RESET);
00292 edt_spi_reg_write(edt_p, SPI_STAT_CTRL, 0x00);
00293 }
00294
00295 static int
00296 spi_pkt_crc_fails(u_char *pkt)
00297 {
00298 int i;
00299 u_char len = pkt[1], ckl, ckh;
00300
00301 len += 2;
00302
00303 ckl = pkt[0];
00304 ckh = pkt[1];
00305
00306 for (i = 2; i < len; i += 2)
00307 {
00308 ckl ^= pkt[i];
00309 ckh ^= pkt[i+1];
00310 }
00311
00312 ckl = ~ckl;
00313 ckh = ~ckh;
00314
00315 return ((ckl ^ pkt[len]) | (ckh ^ pkt[len+1]));
00316 }
00317
00327 int
00328 edt_spi_get_pkt(EdtDev *edt_p, u_char *pkt)
00329 {
00330 int i, len;
00331 u_char byte;
00332
00333 if (edt_spi_get_binary(edt_p, &byte) == -1)
00334 return -1;
00335 pkt[0] = byte;
00336
00337 if (edt_spi_get_binary(edt_p, &byte) == -1)
00338 return -1;
00339 len = pkt[1] = byte;
00340
00341 if (len > 60)
00342 {
00343 puts("Packet length check failed");
00344 puts("\nPacket dump:");
00345 printf(" cmd 0x%x len %d ", pkt[0], pkt[1]);
00346 puts("\n");
00347
00348 return -1;
00349 }
00350
00351
00352 for (i = 2; i < len + 4; ++i)
00353 {
00354 if (edt_spi_get_binary(edt_p, &byte) == -1)
00355 return -1;
00356 pkt[i] = byte;
00357 }
00358
00359 if (spi_pkt_crc_fails(pkt))
00360 {
00361 puts("crc check failed");
00362 puts("\nPacket dump:");
00363 printf(" cmd 0x%x len %d ", pkt[0], len);
00364 for (i = 2; i < len + 4; ++i)
00365 printf(" pkt[%d] 0x%x ", i, pkt[i]);
00366 puts("\n");
00367
00368 return -1;
00369 }
00370 else
00371 {
00372 return len;
00373 }
00374 }
00375
00384 uint64_t
00385 edt_spi_get_time_pkt(EdtDev *edt_p)
00386 {
00387 u_char command, len;
00388 uint64_t tval = 0;
00389 static u_char pkt[64];
00390 int i, retval;
00391
00392 if ((retval = edt_spi_get_pkt(edt_p, pkt)) == -1)
00393 return 0;
00394
00395 command = pkt[0];
00396 len = pkt[1];
00397
00398 switch (command)
00399 {
00400 case SPI_TIMECODE_PKT:
00401 case SPI_TIMECODE_PKT_RAW:
00402 {
00403 for (i = 0; i < len; ++i)
00404 tval |= pkt[i+2] << (8 * i);
00405
00406 tval |= (uint64_t) command << 56;
00407 break;
00408 }
00409 }
00410
00411 return tval;
00412 }
00413
00428 void
00429 edt_spi_display_time(EdtDev *edt_p, int loops)
00430 {
00431 int loop, i, done = 0, retry = 0;
00432 u_char inchar[2] = {0, 0};
00433 uint64_t irigb_lltime;
00434 unsigned int irigb_time;
00435 time_t timevar, computer_time;
00436 u_char stat;
00437 int new_timestamp_format = 0;
00438
00439 for (loop = 0; !done && (loop < loops || loops == 0); ) {
00440
00441 if ((((stat = edt_spi_get_stat(edt_p)) & 0x02)) != 0x02) {
00442 irigb_lltime = 0;
00443
00444 for (i = 0; i < 16; ++i) {
00445 inchar[0] = edt_spi_get_byte(edt_p);
00446
00447 if (inchar[0] == 0) {
00448 done = 1;
00449 break;
00450 }
00451 else if (inchar[0] == SPI_PKT_START) {
00452 irigb_lltime = edt_spi_get_time_pkt(edt_p);
00453 if (irigb_lltime == 0)
00454 {
00455 puts("Searching for timestamp packet version...");
00456 retry = 1;
00457 }
00458
00459 new_timestamp_format = 1;
00460 break;
00461 }
00462 else {
00463 irigb_lltime |= (uint64_t) (strtoul((const char *)inchar, NULL, 16) << (i*4));
00464 new_timestamp_format = 0;
00465 }
00466 }
00467
00468 if (retry)
00469 {
00470 retry = 0;
00471 continue;
00472 }
00473 else
00474 {
00475
00476 ++loop;
00477
00478 irigb_time = (unsigned int) irigb_lltime;
00479 timevar = irigb_time;
00480 computer_time = time(NULL);
00481
00482 if (irigb_time)
00483 {
00484 char *p;
00485 static char computer_str[32];
00486 static char irigb_str[32];
00487 int timecode_format = (int) (irigb_lltime >> 56) & 0xff;
00488
00489 p = ctime((const time_t *) &computer_time);
00490 strcpy(computer_str, p);
00491
00492 if ((p = ctime((const time_t *) &timevar)) == NULL)
00493 {
00494 puts("Flushing SPI fifo...");
00495 edt_spi_flush_fifo(edt_p);
00496 }
00497 else
00498 {
00499 strcpy(irigb_str, p);
00500
00501 printf("\n\nPolling loop %d (%s spi format; press Control-C to end loop)\n\n", loop, (new_timestamp_format) ? "new" : "old");
00502 if (timecode_format == SPI_TIMECODE_PKT_RAW)
00503 {
00504 ts_raw_t *raw_p = (ts_raw_t *) & irigb_time;
00505
00506 printf("IRIG-B BCD values: seconds %d minutes %d hours %d day-of-year %d year %d\n",
00507 raw_p->seconds,
00508 raw_p->minutes,
00509 raw_p->hours,
00510 raw_p->days,
00511 raw_p->years);
00512 }
00513 else
00514 {
00515 printf("IRIG-B seconds: %010d; TZ corrected: ", (int) irigb_time);
00516 fputs(irigb_str, stdout);
00517 }
00518 printf("Computer seconds: %010d; TZ corrected: ", (int) computer_time);
00519 fputs(computer_str, stdout);
00520 fflush(stdout);
00521 }
00522 }
00523 }
00524
00525 if (new_timestamp_format == 0)
00526 edt_spi_flush_fifo(edt_p);
00527 }
00528 }
00529 }
00530
00531
00545 int
00546 edt_spi_invoke_flash_loader(EdtDev *edt_p)
00547 {
00548 int ch, ret = 0, tries = 0;
00549
00550 do
00551 {
00552 puts("Attention msp430:");
00553 edt_spi_put_byte(edt_p, 0x80);
00554 edt_msleep(100);
00555
00556 edt_spi_flush_fifo(edt_p);
00557 edt_msleep(100);
00558
00559
00560
00561
00562
00563
00564
00565 edt_spi_put_byte(edt_p, 0x80);
00566 edt_msleep(100);
00567
00568 ch = edt_spi_get_byte(edt_p);
00569
00570 ++ tries;
00571 if (ch != 0x90)
00572 {
00573 if (ch == 0xa0)
00574 printf("Expected ACK (0x90) got NAK (0x%x)\n", ch);
00575 else
00576 printf("Expected ACK (0x90) got 0x%x\n", ch);
00577 }
00578
00579 } while (ch != 0x90 && ch != 0xa0 && tries < 20);
00580
00581 if (ch == 0x90)
00582 {
00583 puts("Flash programming mode started.\n");
00584 }
00585 else
00586 {
00587 puts("Flash programming mode faulted. Insure that firmware is properly loaded.\n");
00588 ret = -1;
00589 }
00590
00591
00592 while ( !edt_spi_fifo_empty(edt_p) )
00593 {
00594 volatile int dummy = edt_spi_get_byte(edt_p);
00595 printf("Flushing SPI FIFO (0x%x left in fifo)\n", dummy);
00596 edt_spi_flush_fifo(edt_p);
00597 }
00598
00599
00600 return ret;
00601 }
00602
00613 char *
00614 edt_spi_putstr(EdtDev *edt_p, char *str)
00615 {
00616 char *p;
00617
00618 for (p = str; *p != '\0'; ++p)
00619 {
00620 while ((edt_spi_get_stat(edt_p) & FIFO_OUT_EMPTY) == 0)
00621 edt_usec_busywait(10);
00622
00623 edt_spi_put_byte(edt_p, *p);
00624 }
00625
00626 return str;
00627 }
00628
00629 u_char
00630 edt_crc16_lowbyte(u_char *buf, int len)
00631 {
00632 int i;
00633 u_char result;
00634
00635 result = buf[0];
00636
00637 for (i = 2; i < len; i += 2)
00638 result ^= buf[i];
00639
00640 return ~result;
00641 }
00642
00643 u_char
00644 edt_crc16_highbyte(u_char *buf, int len)
00645 {
00646 int i;
00647 u_char result;
00648
00649 result = buf[1];
00650
00651 for (i = 2; i < len; i += 2)
00652 result ^= buf[i+1];
00653
00654 return ~result;
00655 }
00656
00657 void
00658 edt_spi_send_binary(EdtDev *edt_p, u_char val)
00659 {
00660 u_char esc_char = 0;
00661
00662 if (val == '\0')
00663 {
00664 val = '\\';
00665 esc_char = 'z';
00666 }
00667 else if (val == '\\')
00668 esc_char = '\\';
00669
00670 while ((edt_spi_get_stat(edt_p) & FIFO_OUT_FULL))
00671 edt_usec_busywait(9);
00672
00673 edt_spi_put_byte(edt_p, val);
00674
00675 if (esc_char)
00676 {
00677 while ((edt_spi_get_stat(edt_p) & FIFO_OUT_FULL))
00678 edt_usec_busywait(9);
00679
00680 edt_spi_put_byte(edt_p, esc_char);
00681 }
00682 }
00683
00727 void
00728 edt_spi_send_packet(EdtDev *edt_p, u_char *cmdbuf)
00729 {
00730 int i;
00731
00732 u_char cmd = cmdbuf[0];
00733 u_char len = cmdbuf[1];
00734
00735 edt_spi_send_binary(edt_p, 0x82);
00736 edt_spi_send_binary(edt_p, cmd);
00737 edt_spi_send_binary(edt_p, len);
00738
00739 for (i = 0; i < len; ++i)
00740 edt_spi_send_binary(edt_p, cmdbuf[i+2]);
00741
00742 edt_spi_send_binary(edt_p, edt_crc16_lowbyte(cmdbuf, len+2));
00743 edt_spi_send_binary(edt_p, edt_crc16_highbyte(cmdbuf,len+2));
00744 }
00745
00757 int
00758 edt_get_timecode_version(EdtDev *edt_p)
00759 {
00760 int retval;
00761
00762 edt_set_timecode_enable(edt_p, 0);
00763 edt_msleep(2000);
00764 edt_spi_flush_fifo(edt_p);
00765
00766 edt_spi_put_byte(edt_p, 0x81);
00767 retval = edt_spi_get_byte(edt_p);
00768
00769 edt_set_timecode_enable(edt_p, 1);
00770
00771 return retval & 0x7f;
00772 }
00773
00788 int
00789 edt_set_timecode_enable(EdtDev *edt_p, int enable)
00790 {
00791 u_char cmdbuf[16];
00792 int loopcount = 0;
00793
00794 cmdbuf[0] = SPI_TIMECODE_EN;
00795 cmdbuf[1] = 1;
00796 cmdbuf[2] = enable;
00797 edt_spi_send_packet(edt_p, cmdbuf);
00798
00799 while ((cmdbuf[0] = edt_spi_get_byte(edt_p)) != ACK && cmdbuf[0] != NAK)
00800 {
00801 if (++loopcount > 1000)
00802 {
00803 fprintf(stderr, "timeout waiting for ACK or NAK; edt_set_timecode_enable %d failed\n", enable);
00804 return -1;
00805 }
00806 }
00807
00808
00809 if (cmdbuf[0] != ACK)
00810 {
00811 fprintf(stderr, "edt_set_timecode_enable %d failed on NAK\n", enable);
00812 return -1;
00813 }
00814 else
00815 return 0;
00816 }
00817
00833 void
00834 edt_set_timecode_raw(EdtDev *edt_p, int enable)
00835 {
00836 u_char cmdbuf[16];
00837
00838 cmdbuf[0] = SPI_TIMECODE_RAW;
00839 cmdbuf[1] = 1;
00840 cmdbuf[2] = enable;
00841 edt_spi_send_packet(edt_p, cmdbuf);
00842
00843 while ((cmdbuf[0] = edt_spi_get_byte(edt_p)) != ACK && cmdbuf[0] != NAK)
00844 ;
00845
00846 if (cmdbuf[0] != ACK)
00847 puts("Got NAK; command fault.\n");
00848 else
00849 puts("Got ACK; command succeeded.\n");
00850
00851 edt_set_timecode_seconds_offset(edt_p, (enable) ? 0 : 1);
00852 }
00853
00869 void
00870 edt_set_timecode_seconds_offset(EdtDev *edt_p, u_int seconds)
00871 {
00872 u_char cmdbuf[16];
00873
00874 cmdbuf[0] = SPI_TIMECODE_ADD_SECONDS;
00875 cmdbuf[1] = 1;
00876 cmdbuf[2] = seconds;
00877 edt_spi_send_packet(edt_p, cmdbuf);
00878
00879 while ((cmdbuf[0] = edt_spi_get_byte(edt_p)) != ACK && cmdbuf[0] != NAK)
00880 ;
00881
00882 if (cmdbuf[0] != ACK)
00883 puts("Got NAK; command fault.\n");
00884 }
00885
00905 void
00906 edt_set_msp430_clock(EdtDev *edt_p, int clock_sel, int clock_hz)
00907 {
00908 u_char cmdbuf[16];
00909
00910 printf("\nSet msp430 clock source to %d and hz rate to %d:\n\n", clock_sel, clock_hz);
00911
00912 if (clock_sel != 0 && clock_sel != 1)
00913 {
00914 puts("Illegal clock_sel value: must be 0 for internal or 1 for external clock.\n");
00915 return;
00916 }
00917
00918 cmdbuf[0] = SPI_CLK_SELECT;
00919 cmdbuf[1] = 5;
00920 cmdbuf[2] = clock_sel;
00921
00922 if (clock_sel == 0 && clock_hz != 1000000 && clock_hz != 8000000
00923 && clock_hz != 12000000 && clock_hz != 16000000)
00924 {
00925 puts("Illegal internal clock_hz value. Must be one of:");
00926 puts("1000000, 8000000, 12000000 or 16000000.\n");
00927 return;
00928
00929 }
00930
00931 cmdbuf[3] = clock_hz & 0xff;
00932 cmdbuf[4] = (clock_hz >> 8) & 0xff;
00933 cmdbuf[5] = (clock_hz >> 16) & 0xff;
00934 cmdbuf[6] = (clock_hz >> 24) & 0xff;
00935
00936 edt_set_timecode_enable(edt_p, 0);
00937 edt_spi_send_packet(edt_p, cmdbuf);
00938
00939 while ((cmdbuf[0] = edt_spi_get_byte(edt_p)) != ACK && cmdbuf[0] != NAK)
00940 printf("Waiting for ACK/NAK got %x\n", cmdbuf[0]);
00941
00942 if (cmdbuf[0] != ACK)
00943 puts("Got NAK; command fault.\n");
00944 else
00945 puts("Got ACK; command succeeded.\n");
00946
00947 edt_set_timecode_enable(edt_p, 1);
00948
00949 edt_spi_flush_fifo(edt_p);
00950 }
00951
00975 void
00976 edt_enable_timecode_programmable_year(EdtDev *edt_p, u_short year)
00977 {
00978 u_char cmdbuf[16];
00979
00980 cmdbuf[0] = SPI_ENABLE_PROGRAMMED_YEAR;
00981 cmdbuf[1] = 2;
00982 cmdbuf[2] = year & 0xff;
00983 cmdbuf[3] = (year >> 8) & 0xff;
00984 edt_spi_send_packet(edt_p, cmdbuf);
00985
00986 while ((cmdbuf[0] = edt_spi_get_byte(edt_p)) != ACK && cmdbuf[0] != NAK)
00987 ;
00988
00989 if (cmdbuf[0] != ACK)
00990 puts("Got NAK; command fault.\n");
00991 }
00992
01006 void
01007 edt_disable_timecode_programmable_year(EdtDev *edt_p)
01008 {
01009 u_char cmdbuf[16];
01010
01011 cmdbuf[0] = SPI_DISABLE_PROGRAMMED_YEAR;
01012 cmdbuf[1] = 0;
01013 edt_spi_send_packet(edt_p, cmdbuf);
01014
01015 while ((cmdbuf[0] = edt_spi_get_byte(edt_p)) != ACK && cmdbuf[0] != NAK)
01016 ;
01017
01018 if (cmdbuf[0] != ACK)
01019 puts("Got NAK; command fault.\n");
01020 }