libedt_timing.c

Go to the documentation of this file.
00001 /* #pragma ident "@(#)libedt_timing.c   1.28 04/22/11 EDT" */
00002 
00048 #include <time.h>
00049 //#include "libedt_timing.h"
00050 #include "edtinc.h"
00051 
00052 /* Timing register offsets: */
00053 /*      Time Dist. Board:       0x60 (default) */
00054 /*      MSDV:                   0xa4 */
00055 /*      Net10G:                 0xac */
00056 /*      SRXL-2:                 0x5c */
00057 /*      CLINK:                  0x31 */
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)   /* edt_interface is "pcd" or "pdv" or "pe53b", etc. */
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) /* Master clears this bit. */
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);                                  /* Each character takes about 8 usec */
00172     }
00173     ch = edt_spi_reg_read(edt_p, SPI_DATA);
00174     edt_spi_reg_write(edt_p, SPI_STROBE, 0x00); /* SPI fifo must be strobed after each read */
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);                                  /* Each character takes about 8 usec */
00186     }
00187     ch = edt_spi_reg_read(edt_p, SPI_DATA);
00188     edt_spi_reg_write(edt_p, SPI_STROBE, 0x00); /* SPI fifo must be strobed after each read */
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 == '\\')             /* Translate \\ to '\' and \z to zero */
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);             /* Write byte to SPI fifo */
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);        /* Reset SPI fifo */
00292     edt_spi_reg_write(edt_p, SPI_STAT_CTRL, 0x00);
00293 }
00294 
00295 static int
00296 spi_pkt_crc_fails(u_char *pkt)                                  /* Check packet CRC.  Return 0 for success, nonzero for failure. */
00297 {
00298     int i;
00299     u_char len = pkt[1], ckl, ckh;                              /* Second byte is data length. */
00300 
00301     len += 2;                                                   /* Include cmd and len bytes in CRC computation. */
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)                 /* Get Packet command byte */
00334         return -1;
00335     pkt[0] = byte;
00336 
00337     if (edt_spi_get_binary(edt_p, &byte) == -1)                 /* Get Packet data length byte */
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     /* Capture the packet data and CRC bytes and check the packet against the CRC. */
00352     for (i = 2; i < len + 4; ++i)                               /* command byte + length byte + data bytes + two CRC bytes */
00353     {
00354         if (edt_spi_get_binary(edt_p, &byte) == -1)             /* Get Packet data or CRC byte */
00355             return -1;
00356         pkt[i] = byte;
00357     }
00358 
00359     if (spi_pkt_crc_fails(pkt))                                 /* Check packet CRC.  Return -1 if failure. */
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)                           /* command byte + length byte + data bytes + two CRC bytes */
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};                  /* Single char NULL terminated string */
00433     uint64_t irigb_lltime;                      /* irigb time in 64-bit unix-based time format */
00434     unsigned int irigb_time;    /* CPU word-size irigb and computer unix time format */
00435     time_t timevar, computer_time;
00436     u_char stat;                                /* SPI stat register */
00437     int new_timestamp_format = 0;                               /* New SPI interface from msp430? */
00438 
00439     for (loop = 0; !done && (loop < loops || loops == 0); /* loop incremented only upon timestamp input */ ) {
00440         /* Wait for SPI input fifo to become non-empty */
00441         if ((((stat = edt_spi_get_stat(edt_p)) & 0x02)) != 0x02) {
00442             irigb_lltime = 0;
00443             
00444             for (i = 0; i < 16; ++i) {          /* Capture 16 ascii-hex bytes */
00445                 inchar[0] = edt_spi_get_byte(edt_p);
00446 
00447                 if (inchar[0] == 0) {           /* If user had hit Control-C, break out of loop back to prompt */
00448                     done = 1;
00449                     break;
00450                 }
00451                 else if (inchar[0] == SPI_PKT_START) {  /* Forward compatibility (after July '08 V3.0 firmware) */
00452                     irigb_lltime = edt_spi_get_time_pkt(edt_p);
00453                     if (irigb_lltime == 0)                      /* packet reception error */
00454                     {
00455                         puts("Searching for timestamp packet version...");
00456                         retry = 1;
00457                     }
00458 
00459                     new_timestamp_format = 1;
00460                     break;
00461                 }
00462                 else {                                  /* Backward compatibility (before July '08 V3.0 firmware) */
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);                   /* Send flash-loader escape */
00554         edt_msleep(100);
00555 
00556         edt_spi_flush_fifo(edt_p);
00557         edt_msleep(100);
00558 
00559         /* Empty the FIFO of any leftover bytes */
00560         /*while ( !edt_spi_fifo_empty(edt_p) ) */
00561         /*{ */
00562             /*ch = edt_spi_get_byte(edt_p); */
00563         /*} */
00564 
00565         edt_spi_put_byte(edt_p, 0x80);                   /* Verify that flash-loader is running */
00566         edt_msleep(100);
00567 
00568         ch = edt_spi_get_byte(edt_p);
00569 
00570         ++ tries;                                       /* Retry 20 times */
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     /* Empty the FIFO of any leftover bytes */
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)         /* TODO: change this when almost-full flag is available */
00621             edt_usec_busywait(10);                                      /* Each character takes about 8 usec */
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)                 /* Create 16-bit CRC low byte */
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)                        /* Create 16-bit CRC high byte */
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)                          /* Send binary data to SPI; escape zeros and escape character. */
00659 {
00660     u_char esc_char = 0;
00661 
00662     if (val == '\0')                                            /* Translate zero bytes to '\' + 'z' */
00663     {
00664         val = '\\';
00665         esc_char = 'z';
00666     }
00667     else if (val == '\\')                                       /* Translate '\' bytes to '\' + '\' */
00668         esc_char = '\\';
00669 
00670     while ((edt_spi_get_stat(edt_p) & FIFO_OUT_FULL))           /* Wait for room in SPI output fifo      */
00671         edt_usec_busywait(9);                                   /* Each character takes about 8 usec */
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))       /* Wait for room in SPI output fifo */
00678             edt_usec_busywait(9);                               /* Each character takes about 8 usec */
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);                                   /* Start of packet */
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));       /* 16-bit CRC low byte */
00743     edt_spi_send_binary(edt_p, edt_crc16_highbyte(cmdbuf,len+2));       /* 16-bit CRC high byte */
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;                              /* length = 1 data byte. */
00796     cmdbuf[2] = enable;                         /* Enable timestamp. */
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;                              /* length = 1 data byte. */
00840     cmdbuf[2] = enable;                         /* Enable timestamp. */
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;                              /* length = 1 data byte. */
00876     cmdbuf[2] = seconds;                        /* Seconds to offset timestamp */
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;                                      /* Length: 5 data bytes:  byte(1) clock select value; bytes[2-5] integer32 clock hz value */
00920     cmdbuf[2] = clock_sel;                              /* Select internal or external clock */
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);                  /* Disable 1 Hz timecode */
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);                  /* Enable 1 Hz timecode */
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;                              /* length = 2 data bytes. */
00982     cmdbuf[2] = year & 0xff;                    /* LSByte of year */
00983     cmdbuf[3] = (year >> 8) & 0xff;             /* MSByte of year */
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;                              /* No data */
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 }

Generated on 19 Jun 2015 by  doxygen 1.4.7