Guest User

John O

a guest
Aug 23rd, 2010
71
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  
  3.    This is my first attempt at making the SX1211 USB radio do anything.
  4.  
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <stdint.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include <ctype.h>
  12. #include <ftdi.h>
  13.  
  14.  
  15. #define FTDI_VID                0x0403
  16. #define FTDI_PID                0x6010
  17.  
  18. #define CLOCK_5X 1
  19. #define DIVIDE_BY 3
  20.  
  21. #define BITMODE_BITBANG_NORMAL  1
  22. #define BITMODE_BITBANG_SPI 2
  23.  
  24. uint8_t cs_bits = 0x08;
  25. static uint8_t pindir = 0x0b;
  26. static struct ftdi_context ftdic_context;
  27.  
  28. int main(void)
  29. {
  30.     int ret;
  31.     unsigned char reg;
  32.     char registers[64] = "\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";
  33.  
  34.     ret = ft2232_spi_init();
  35.  
  36.     ft2232_spi_send_command(64, 0, registers, NULL, 0);
  37.     ft2232_spi_send_command(1, 1, "\x40", &reg, 0);
  38.  
  39.     printf("This is what we got: x%02x\n", reg);
  40.     sleep(2);
  41.  
  42.     ft2232_spi_send_command(64, 0, registers, NULL, 0);
  43.     ft2232_spi_send_command(1, 1, "\x40", &reg, 0);
  44.  
  45.     printf("This is what we got: x%02x\n", reg);
  46.     return EXIT_SUCCESS;
  47. }
  48.  
  49. static int get_buf(struct ftdi_context *ftdic, const unsigned char *buf, int size)
  50. {
  51.     int r;
  52.     r = ftdi_read_data(ftdic, (unsigned char *) buf, size);
  53.     if (r < 0) {
  54.         printf("ftdi_read_data: %d, %s\n", r,
  55.                 ftdi_get_error_string(ftdic));
  56.         return 1;
  57.     }
  58.     return 0;
  59. }
  60.  
  61. static int send_buf(struct ftdi_context *ftdic, const unsigned char *buf, int size)
  62. {
  63.     int r;
  64.     r = ftdi_write_data(ftdic, (unsigned char *) buf, size);
  65.     if (r < 0) {
  66.         printf("ftdi_write_data: %d, %s\n", r,
  67.                 ftdi_get_error_string(ftdic));
  68.         return 1;
  69.     }
  70.     return 0;
  71. }
  72.  
  73. int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt,
  74.         const unsigned char *writearr, unsigned char *readarr, int config_or_data)
  75. {
  76.     struct ftdi_context *ftdic = &ftdic_context;
  77.     static unsigned char *buf = NULL;
  78.     /* failed is special. We use bitwise ops, but it is essentially bool. */
  79.     int i = 0, ret = 0, failed = 0;
  80.     int bufsize;
  81.     static int oldbufsize = 0;
  82.  
  83.     if (config_or_data) cs_bits = 16;
  84.     else cs_bits = 8;
  85.  
  86.     if (writecnt > 65536 || readcnt > 65536)
  87.         return -1;
  88.  
  89.     /* buf is not used for the response from the chip. */
  90.     if ((writecnt + 9) > (269)) bufsize = writecnt + 9;
  91.     else bufsize = 269;
  92.     /* Never shrink. realloc() calls are expensive. */
  93.     if (bufsize > oldbufsize) {
  94.         buf = realloc(buf, bufsize);
  95.         if (!buf) {
  96.             printf("Out of memory!\n");
  97.             exit(1);
  98.         }
  99.         oldbufsize = bufsize;
  100.     }
  101.  
  102.     /*
  103.      * Minimize USB transfers by packing as many commands as possible
  104.      * together. If we're not expecting to read, we can assert CS#, write,
  105.      * and deassert CS# all in one shot. If reading, we do three separate
  106.      * operations.
  107.      */
  108.     printf("Assert CS#\n");
  109.     buf[i++] = SET_BITS_LOW;
  110.     buf[i++] = 0 & ~cs_bits; /* assertive */
  111.     buf[i++] = pindir;
  112.  
  113.     if (writecnt) {
  114.         buf[i++] = 0x11;
  115.         buf[i++] = (writecnt - 1) & 0xff;
  116.         buf[i++] = ((writecnt - 1) >> 8) & 0xff;
  117.         memcpy(buf + i, writearr, writecnt);
  118.         i += writecnt;
  119.     }
  120.  
  121.     /*
  122.      * Optionally terminate this batch of commands with a
  123.      * read command, then do the fetch of the results.
  124.      */
  125.     if (readcnt) {
  126.         buf[i++] = 0x20;
  127.         buf[i++] = (readcnt - 1) & 0xff;
  128.         buf[i++] = ((readcnt - 1) >> 8) & 0xff;
  129.         ret = send_buf(ftdic, buf, i);
  130.         failed = ret;
  131.         /* We can't abort here, we still have to deassert CS#. */
  132.         if (ret)
  133.             printf("send_buf failed before read: %i\n",
  134.                 ret);
  135.         i = 0;
  136.         if (ret == 0) {
  137.             /*
  138.              * FIXME: This is unreliable. There's no guarantee that
  139.              * we read the response directly after sending the read
  140.              * command. We may be scheduled out etc.
  141.              */
  142.             ret = get_buf(ftdic, readarr, readcnt);
  143.             failed |= ret;
  144.             /* We can't abort here either. */
  145.             if (ret)
  146.                 printf("get_buf failed: %i\n", ret);
  147.         }
  148.     }
  149.  
  150.     printf("De-assert CS#\n");
  151.     buf[i++] = SET_BITS_LOW;
  152.     buf[i++] = cs_bits;
  153.     buf[i++] = pindir;
  154.     ret = send_buf(ftdic, buf, i);
  155.     failed |= ret;
  156.     if (ret)
  157.         printf("send_buf failed at end: %i\n", ret);
  158.  
  159.     return failed ? -1 : 0;
  160. }
  161.  
  162. int ft2232_spi_init(void)
  163. {
  164.     int f;
  165.     struct ftdi_context *ftdic = &ftdic_context;
  166.     unsigned char buf[512];
  167.     int ft2232_vid = FTDI_VID;
  168.     int ft2232_type = FTDI_PID;
  169.     enum ftdi_interface ft2232_interface = INTERFACE_B;
  170.     char *arg;
  171.  
  172.     ft2232_interface = INTERFACE_A;
  173.  
  174.     if (ftdi_init(ftdic) < 0) {
  175.         printf("ftdi_init failed\n");
  176.         return EXIT_FAILURE; // TODO
  177.     }
  178.  
  179.     f = ftdi_usb_open(ftdic, FTDI_VID, ft2232_type);
  180.  
  181.     if (f < 0 && f != -5) {
  182.         printf("Unable to open FTDI device: %d (%s)\n", f,
  183.                 ftdi_get_error_string(ftdic));
  184.         exit(-1); // TODO
  185.     }
  186.  
  187.     if (ftdi_set_interface(ftdic, ft2232_interface) < 0) {
  188.         printf("Unable to select interface: %s\n",
  189.                 ftdic->error_str);
  190.     }
  191.  
  192.     if (ftdi_usb_reset(ftdic) < 0) {
  193.         printf("Unable to reset FTDI device\n");
  194.     }
  195.  
  196.     if (ftdi_set_latency_timer(ftdic, 2) < 0) {
  197.         printf("Unable to set latency timer\n");
  198.     }
  199.  
  200.     if (ftdi_write_data_set_chunksize(ftdic, 512)) {
  201.         printf("Unable to set chunk size\n");
  202.     }
  203.  
  204.     if (ftdi_set_bitmode(ftdic, 0x00, BITMODE_BITBANG_SPI) < 0) {
  205.         printf("Unable to set bitmode to SPI\n");
  206.     }
  207.  
  208. #if CLOCK_5X
  209.     printf("Disable divide-by-5 front stage\n");
  210.     buf[0] = 0x8a;      /* Disable divide-by-5. */
  211.     if (send_buf(ftdic, buf, 1))
  212.         return -1;
  213. #define MPSSE_CLK 60.0
  214.  
  215. #else
  216.  
  217. #define MPSSE_CLK 12.0
  218.  
  219. #endif
  220.     printf("Set clock divisor\n");
  221.     buf[0] = 0x86;      /* command "set divisor" */
  222.     /* valueL/valueH are (desired_divisor - 1) */
  223.     buf[1] = (DIVIDE_BY - 1) & 0xff;
  224.     buf[2] = ((DIVIDE_BY - 1) >> 8) & 0xff;
  225.     if (send_buf(ftdic, buf, 3))
  226.         return -1;
  227.  
  228.     printf("SPI clock is %fMHz\n",
  229.          (double)(MPSSE_CLK / (((DIVIDE_BY - 1) + 1) * 2)));
  230.  
  231.     /* Disconnect TDI/DO to TDO/DI for loopback. */
  232.     printf("No loopback of TDI/DO TDO/DI\n");
  233.     buf[0] = 0x85;
  234.     if (send_buf(ftdic, buf, 1))
  235.         return -1;
  236.  
  237.     printf("Set data bits\n");
  238.     buf[0] = SET_BITS_LOW;
  239.     buf[1] = cs_bits;
  240.     buf[2] = pindir;
  241.     if (send_buf(ftdic, buf, 3))
  242.         return -1;
  243.  
  244.     //buses_supported = CHIP_BUSTYPE_SPI;
  245.     //spi_controller = SPI_CONTROLLER_FT2232;
  246.  
  247.     return 0;
  248. }
RAW Paste Data