Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- This is my first attempt at making the SX1211 USB radio do anything.
- */
- #include <stdio.h>
- #include <stdint.h>
- #include <string.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <ftdi.h>
- #define FTDI_VID 0x0403
- #define FTDI_PID 0x6010
- #define CLOCK_5X 1
- #define DIVIDE_BY 3
- #define BITMODE_BITBANG_NORMAL 1
- #define BITMODE_BITBANG_SPI 2
- uint8_t cs_bits = 0x08;
- static uint8_t pindir = 0x0b;
- static struct ftdi_context ftdic_context;
- int main(void)
- {
- int ret;
- unsigned char reg;
- 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";
- ret = ft2232_spi_init();
- ft2232_spi_send_command(64, 0, registers, NULL, 0);
- ft2232_spi_send_command(1, 1, "\x40", ®, 0);
- printf("This is what we got: x%02x\n", reg);
- sleep(2);
- ft2232_spi_send_command(64, 0, registers, NULL, 0);
- ft2232_spi_send_command(1, 1, "\x40", ®, 0);
- printf("This is what we got: x%02x\n", reg);
- return EXIT_SUCCESS;
- }
- static int get_buf(struct ftdi_context *ftdic, const unsigned char *buf, int size)
- {
- int r;
- r = ftdi_read_data(ftdic, (unsigned char *) buf, size);
- if (r < 0) {
- printf("ftdi_read_data: %d, %s\n", r,
- ftdi_get_error_string(ftdic));
- return 1;
- }
- return 0;
- }
- static int send_buf(struct ftdi_context *ftdic, const unsigned char *buf, int size)
- {
- int r;
- r = ftdi_write_data(ftdic, (unsigned char *) buf, size);
- if (r < 0) {
- printf("ftdi_write_data: %d, %s\n", r,
- ftdi_get_error_string(ftdic));
- return 1;
- }
- return 0;
- }
- int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt,
- const unsigned char *writearr, unsigned char *readarr, int config_or_data)
- {
- struct ftdi_context *ftdic = &ftdic_context;
- static unsigned char *buf = NULL;
- /* failed is special. We use bitwise ops, but it is essentially bool. */
- int i = 0, ret = 0, failed = 0;
- int bufsize;
- static int oldbufsize = 0;
- if (config_or_data) cs_bits = 16;
- else cs_bits = 8;
- if (writecnt > 65536 || readcnt > 65536)
- return -1;
- /* buf is not used for the response from the chip. */
- if ((writecnt + 9) > (269)) bufsize = writecnt + 9;
- else bufsize = 269;
- /* Never shrink. realloc() calls are expensive. */
- if (bufsize > oldbufsize) {
- buf = realloc(buf, bufsize);
- if (!buf) {
- printf("Out of memory!\n");
- exit(1);
- }
- oldbufsize = bufsize;
- }
- /*
- * Minimize USB transfers by packing as many commands as possible
- * together. If we're not expecting to read, we can assert CS#, write,
- * and deassert CS# all in one shot. If reading, we do three separate
- * operations.
- */
- printf("Assert CS#\n");
- buf[i++] = SET_BITS_LOW;
- buf[i++] = 0 & ~cs_bits; /* assertive */
- buf[i++] = pindir;
- if (writecnt) {
- buf[i++] = 0x11;
- buf[i++] = (writecnt - 1) & 0xff;
- buf[i++] = ((writecnt - 1) >> 8) & 0xff;
- memcpy(buf + i, writearr, writecnt);
- i += writecnt;
- }
- /*
- * Optionally terminate this batch of commands with a
- * read command, then do the fetch of the results.
- */
- if (readcnt) {
- buf[i++] = 0x20;
- buf[i++] = (readcnt - 1) & 0xff;
- buf[i++] = ((readcnt - 1) >> 8) & 0xff;
- ret = send_buf(ftdic, buf, i);
- failed = ret;
- /* We can't abort here, we still have to deassert CS#. */
- if (ret)
- printf("send_buf failed before read: %i\n",
- ret);
- i = 0;
- if (ret == 0) {
- /*
- * FIXME: This is unreliable. There's no guarantee that
- * we read the response directly after sending the read
- * command. We may be scheduled out etc.
- */
- ret = get_buf(ftdic, readarr, readcnt);
- failed |= ret;
- /* We can't abort here either. */
- if (ret)
- printf("get_buf failed: %i\n", ret);
- }
- }
- printf("De-assert CS#\n");
- buf[i++] = SET_BITS_LOW;
- buf[i++] = cs_bits;
- buf[i++] = pindir;
- ret = send_buf(ftdic, buf, i);
- failed |= ret;
- if (ret)
- printf("send_buf failed at end: %i\n", ret);
- return failed ? -1 : 0;
- }
- int ft2232_spi_init(void)
- {
- int f;
- struct ftdi_context *ftdic = &ftdic_context;
- unsigned char buf[512];
- int ft2232_vid = FTDI_VID;
- int ft2232_type = FTDI_PID;
- enum ftdi_interface ft2232_interface = INTERFACE_B;
- char *arg;
- ft2232_interface = INTERFACE_A;
- if (ftdi_init(ftdic) < 0) {
- printf("ftdi_init failed\n");
- return EXIT_FAILURE; // TODO
- }
- f = ftdi_usb_open(ftdic, FTDI_VID, ft2232_type);
- if (f < 0 && f != -5) {
- printf("Unable to open FTDI device: %d (%s)\n", f,
- ftdi_get_error_string(ftdic));
- exit(-1); // TODO
- }
- if (ftdi_set_interface(ftdic, ft2232_interface) < 0) {
- printf("Unable to select interface: %s\n",
- ftdic->error_str);
- }
- if (ftdi_usb_reset(ftdic) < 0) {
- printf("Unable to reset FTDI device\n");
- }
- if (ftdi_set_latency_timer(ftdic, 2) < 0) {
- printf("Unable to set latency timer\n");
- }
- if (ftdi_write_data_set_chunksize(ftdic, 512)) {
- printf("Unable to set chunk size\n");
- }
- if (ftdi_set_bitmode(ftdic, 0x00, BITMODE_BITBANG_SPI) < 0) {
- printf("Unable to set bitmode to SPI\n");
- }
- #if CLOCK_5X
- printf("Disable divide-by-5 front stage\n");
- buf[0] = 0x8a; /* Disable divide-by-5. */
- if (send_buf(ftdic, buf, 1))
- return -1;
- #define MPSSE_CLK 60.0
- #else
- #define MPSSE_CLK 12.0
- #endif
- printf("Set clock divisor\n");
- buf[0] = 0x86; /* command "set divisor" */
- /* valueL/valueH are (desired_divisor - 1) */
- buf[1] = (DIVIDE_BY - 1) & 0xff;
- buf[2] = ((DIVIDE_BY - 1) >> 8) & 0xff;
- if (send_buf(ftdic, buf, 3))
- return -1;
- printf("SPI clock is %fMHz\n",
- (double)(MPSSE_CLK / (((DIVIDE_BY - 1) + 1) * 2)));
- /* Disconnect TDI/DO to TDO/DI for loopback. */
- printf("No loopback of TDI/DO TDO/DI\n");
- buf[0] = 0x85;
- if (send_buf(ftdic, buf, 1))
- return -1;
- printf("Set data bits\n");
- buf[0] = SET_BITS_LOW;
- buf[1] = cs_bits;
- buf[2] = pindir;
- if (send_buf(ftdic, buf, 3))
- return -1;
- //buses_supported = CHIP_BUSTYPE_SPI;
- //spi_controller = SPI_CONTROLLER_FT2232;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement