Advertisement
Guest User

John O

a guest
Aug 26th, 2010
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.03 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <ctype.h>
  6. #include <ftdi.h>
  7.  
  8. #define FTDI_VID                0x0403
  9. #define FTDI_PID                0x6010
  10.  
  11. #define CLOCK_5X 0
  12. #define DIVIDE_BY 3
  13.  
  14. #define BITMODE_BITBANG_NORMAL  1
  15. #define BITMODE_BITBANG_SPI     2
  16.  
  17. #define MPSSE_CLK 12.0
  18.  
  19. //static struct ftdi_context;
  20.  
  21. static int get_buf(struct ftdi_context *, const unsigned char *, int);
  22. static int send_buf(struct ftdi_context *, const unsigned char *, int);
  23. int ft2232_spi_send_command(unsigned int, unsigned int, const unsigned char *, unsigned char *, int);
  24. int ft2232_spi_init(void);
  25.  
  26. uint8_t cs_bits = 0x08;
  27. static uint8_t pindir = 0x0b;
  28.  
  29. static struct ftdi_context ftdic_context;
  30.  
  31. int main(void) {
  32.     int ret;
  33.     unsigned int i, j;
  34.     unsigned char reg;
  35.     unsigned char command;
  36.     unsigned char *commandtwo = malloc(2);
  37.  
  38.     char registers[65] = "\x00\x60\x02\x8c\x04\x0b\x06\x13\x08\x0c\x0a\xcf\x0c\x7d\x0e\x68\x10\x46\x12\x7d\x14\x68\x16\x46\x18\x38\x1a\x00\x1c\x18\x1e\x00\x20\xa3\x22\x30\x24\x1e\x26\x07\x28\x00\x2a\x80\x2c\x69\x2e\x81\x30\x7e\x32\x96\x34\x70\x36\xbc\x38\x3f\x3a\x00\x3c\xe8\x3e\xc0";
  39. //  char registers[33] = "\x60\x8c\x0b\x13\x0c\xcf\x7d\x68\x46\x7d\x68\x46\x38\x00\x18\x00\xa3\x30\x1e\x07\x00\x80\x69\x81\x7e\x96\x70\xbc\x3f\x00\xe8\xc0";
  40.  
  41.     // Initialize SPI.
  42.     ret = ft2232_spi_init();
  43.  
  44.     // Set the registers to the correct state.
  45.     ft2232_spi_send_command(64, 0, registers, NULL, 0);
  46.  
  47.     // Read back the registers that we've written. This works, sort of, but it's answering the request sent 2 requests ago.
  48.     for (i = 0; i < 32; i++) {
  49.         j = (i << 1);
  50.         sprintf(&command, "%c", j);
  51.         ft2232_spi_send_command(1, 1, &command, &reg, 0);
  52.         printf("%u 0x%02x: 0x%02x\n", i, j, reg);
  53.     }
  54.  
  55.     // Trying to read out of the fifo here.
  56.     printf("\nNow let's try to see some data...\n");
  57.     for (i = 0; i < 80000; i++) {
  58.         ft2232_spi_send_command(0, 1, NULL, &reg, 1);
  59.         printf("%02x\n", reg);
  60.     }
  61.  
  62.     return EXIT_SUCCESS;
  63. }
  64.  
  65. static int get_buf(struct ftdi_context *ftdic, const unsigned char *buf, int size) {
  66.     int r;
  67.     r = ftdi_read_data(ftdic, (unsigned char *) buf, size);
  68.     if (r < 0) {
  69.         printf("ftdi_read_data: %d, %s\n", r,
  70.                 ftdi_get_error_string(ftdic));
  71.         return 1;
  72.     }
  73.     return 0;
  74. }
  75.  
  76. static int send_buf(struct ftdi_context *ftdic, const unsigned char *buf, int size) {
  77.     int r;
  78.     r = ftdi_write_data(ftdic, (unsigned char *) buf, size);
  79.     if (r < 0) {
  80.         printf("ftdi_write_data: %d, %s\n", r,
  81.                 ftdi_get_error_string(ftdic));
  82.         return 1;
  83.     }
  84.     return 0;
  85. }
  86.  
  87. int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr, int config_or_data) {
  88.     struct ftdi_context *ftdic = &ftdic_context;
  89.     static unsigned char *buf = NULL;
  90.     /* failed is special. We use bitwise ops, but it is essentially bool. */
  91.     int i = 0, ret = 0, failed = 0;
  92.     int bufsize;
  93.     static int oldbufsize = 0;
  94.  
  95.     if (writecnt > 65536 || readcnt > 65536)
  96.         return -1;
  97.  
  98.     /* buf is not used for the response from the chip. */
  99.     if ((writecnt + 9) > (269)) bufsize = writecnt + 9;
  100.     else bufsize = 269;
  101.     /* Never shrink. realloc() calls are expensive. */
  102.     if (bufsize > oldbufsize) {
  103.         buf = realloc(buf, bufsize);
  104.         if (!buf) {
  105.             exit(1);
  106.         }
  107.         oldbufsize = bufsize;
  108.     }
  109.  
  110.     /*
  111.      * Minimize USB transfers by packing as many commands as possible
  112.      * together. If we're not expecting to read, we can assert CS#, write,
  113.      * and deassert CS# all in one shot. If reading, we do three separate
  114.      * operations.
  115.      */
  116.     buf[i++] = SET_BITS_LOW;
  117.     buf[i++] = 0 & ~cs_bits; /* assertive */
  118.     buf[i++] = pindir;
  119.  
  120.     if (writecnt) {
  121.         buf[i++] = 0x11;
  122.         buf[i++] = (writecnt - 1) & 0xff;
  123.         buf[i++] = ((writecnt - 1) >> 8) & 0xff;
  124.         memcpy(buf + i, writearr, writecnt);
  125.         i += writecnt;
  126.     }
  127.  
  128.     /*
  129.      * Optionally terminate this batch of commands with a
  130.      * read command, then do the fetch of the results.
  131.      */
  132.     if (readcnt) {
  133.         buf[i++] = 0x20;
  134.         buf[i++] = (readcnt - 1) & 0xff;
  135.         buf[i++] = ((readcnt - 1) >> 8) & 0xff;
  136.         ret = send_buf(ftdic, buf, i);
  137.         failed = ret;
  138.         /* We can't abort here, we still have to deassert CS#. */
  139.  
  140.         i = 0;
  141.         if (ret == 0) {
  142.             /*
  143.              * FIXME: This is unreliable. There's no guarantee that
  144.              * we read the response directly after sending the read
  145.              * command. We may be scheduled out etc.
  146.              */
  147.             ret = get_buf(ftdic, readarr, readcnt);
  148.             failed |= ret;
  149.             /* We can't abort here either. */
  150.         }
  151.     }
  152.  
  153.     buf[i++] = SET_BITS_LOW;
  154.     buf[i++] = cs_bits;
  155.     buf[i++] = pindir;
  156.     ret = send_buf(ftdic, buf, i);
  157.     failed |= ret;
  158.  
  159.     return failed ? -1 : 0;
  160. }
  161.  
  162. int ft2232_spi_init(void) {
  163.     int f;
  164.     struct ftdi_context *ftdic = &ftdic_context;
  165.     unsigned char buf[512];
  166.     enum ftdi_interface ft2232_interface = INTERFACE_A;
  167.  
  168. //          cs_bits = 0x18;
  169. //          pindir = 0x1b;
  170.  
  171.     if (ftdi_init(ftdic) < 0) {
  172.         printf("ftdi_init failed\n");
  173.         return EXIT_FAILURE; // TODO
  174.     }
  175.  
  176.     f = ftdi_usb_open(ftdic, FTDI_VID, FTDI_PID);
  177.  
  178.     if (f < 0 && f != -5) {
  179.         printf("Unable to open FTDI device: %d (%s)\n", f, ftdi_get_error_string(ftdic));
  180.         exit(-1); // TODO
  181.     }
  182.  
  183.     if (ftdi_set_interface(ftdic, ft2232_interface) < 0) {
  184.         printf("Unable to select interface: %s\n", ftdic->error_str);
  185.     }
  186.  
  187.     if (ftdi_usb_reset(ftdic) < 0) {
  188.         printf("Unable to reset FTDI device\n");
  189.     }
  190.  
  191.     if (ftdi_set_latency_timer(ftdic, 2) < 0) {
  192.         printf("Unable to set latency timer\n");
  193.     }
  194.  
  195.     if (ftdi_write_data_set_chunksize(ftdic, 512)) {
  196.         printf("Unable to set chunk size\n");
  197.     }
  198.  
  199.     if (ftdi_set_bitmode(ftdic, 0x00, BITMODE_BITBANG_SPI) < 0) {
  200.         printf("Unable to set bitmode to SPI\n");
  201.     }
  202.  
  203.     buf[0] = 0x86;      /* command "set divisor" */
  204.     /* valueL/valueH are (desired_divisor - 1) */
  205.     buf[1] = (DIVIDE_BY - 1) & 0xff;
  206.     buf[2] = ((DIVIDE_BY - 1) >> 8) & 0xff;
  207.     if (send_buf(ftdic, buf, 3))
  208.         return -1;
  209.  
  210.     /* Disconnect TDI/DO to TDO/DI for loopback. */
  211.     buf[0] = 0x85;
  212.     if (send_buf(ftdic, buf, 1))
  213.         return -1;
  214.  
  215.     buf[0] = SET_BITS_LOW;
  216.     buf[1] = cs_bits;
  217.     buf[2] = pindir;
  218.     if (send_buf(ftdic, buf, 3))
  219.         return -1;
  220.  
  221.  
  222.     return 0;
  223. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement