Cannot send 1-byte transfers using linux-omap-2.6.32. Bug/limitation of SPI driver?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,
       I'm using a TI OMAP 3503 as SPI master and a Freescale MC1322x zigbee module, as SPI slave. 

I find that I cannot perform perform 1 byte transfers. However, I can perform 2 byte, 4 byte and 16 byte transfers.

Is this a bug/limitation of the spi driver in linux-omap-2.6.32 kernel (latest arago TI PSP baseline for OMAP3)?

I modified the spidev_test.c program and I find that when sending data, I have to specific a minimum transfer length of 2, for a message. 

If I specify an array size of 1, no transfer takes place.

I need 1 byte transfers to implement a firmware update program over SPI bus for the Freescale MC1322x zigbee module. 

Would anyone have a code snippet or example that shows how to perform exactly 1 byte transfers using the spi bus on linux-2.6.32 kernel? 

In the following example, if I set the firmware update file tranmit buffer size to 1, it doesnt work. 

It works for 2, 4 and 16 byte transfers.

#define FIRMWARE_UPDATE_FILE_TRANSMIT_BUFFER_SIZE   16

static const char *device = "/dev/spidev3.0";
static const char *filename = "";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 4000000;
static uint16_t delay;

static void transfer_firmware_update_file(int fd)
{
	FILE *file                        =  NULL;                       // Pointer to a file descriptor.
	unsigned long fileLength          =  0;                          // Length of the file.
	uint8_t tx        [FIRMWARE_UPDATE_FILE_TRANSMIT_BUFFER_SIZE];   // SPI transmit buffer for firmware update file.
	uint8_t rx        [ARRAY_SIZE(tx)];                              // SPI receive buffer for firmware update file.
	int ret                           = -1;                          // Return result.
	int count                         =  0;                          // Counter variable use for loops.

	// Open the firmware update file in binary mode.
	file = fopen(filename, "rb");
	if(!file) {
		fprintf(stderr, "Unable to open file %s\nPlease try again.\n", filename);
		return;
	}

	// Get the length of the firmware update file.
	fseek(file, 0, SEEK_END);
	fileLength = ftell(file);
	rewind(file);

#if (DEBUG)
	// Display the size of the firmware update file
	fprintf(stdout, "Size of the firmware update file = %ld bytes\n", fileLength);

	// Display the size of the transmit buffer.
	fprintf(stdout, "Size of the array for the firmware update file transmit buffer = %d\n", ARRAY_SIZE(tx));

	// Display the size of the receive buffer.
	fprintf(stdout, "Size of the array for the firmware update file receive buffer = %d\n", ARRAY_SIZE(rx));
#endif

	// Initialize the SPI message transfer object
	struct spi_ioc_transfer tr = {
		.tx_buf = (unsigned long)tx,
		.rx_buf = (unsigned long)rx,
		.len = 0,
		.delay_usecs = delay,
		.speed_hz = speed,
		.bits_per_word = bits,
	};

	// Initialize firmware update file transmit and receive buffers.
	memset(tx, 0, sizeof(tx));             // Initialize all elements of the firmware update file transmit buffer to zero.
	memset(rx, 0, sizeof(rx));             // Initialize all elements of the firmware update file receive buffer to zero.

	// Message Sequence 02: Read the contents of the firmware update file in blocks and transmit it over the SPI bus.
	while (ret != 0) {
		// Read contents of the firmware update file into the transmit buffer. For binary file I/O, use fread and fwrite.
		ret = fread(tx, 1, ARRAY_SIZE(tx), file);

		// If we have no more bytes to read, exit the loop.
		if (ret == 0) break;

		// Update the SPI message transfer length.
		tr.len = ret;

#if (DEBUG)
		// Debug: Print out the contents of the transmit buffer array.
		fprintf(stdout, "Number of elements read from the firmware update file into the transmit buffer = %d\n", ret);
		fprintf(stdout, "\nDisplaying the contents of the transmit buffer\n");
		for (count = 0; count < ret; count++) {
			if (!(count % ret))
				puts("");
			printf("%.2X ", tx[count]);
		}
#endif

		// Send the SPI message payload.
		if (ioctl(fd, SPI_IOC_MESSAGE(1), &tr) == 1)
			pabort("Error: Cannot send spi message containing the firmware update file payload");
	
#if (DEBUG)
		// Debug: Print out the contents of the receive buffer array.
		fprintf(stdout, "\n\nDisplaying the contents of the receive buffer\n");
		for (count = 0; count < ret; count++) {
			if (!(count % ret))
				puts("");
			printf("%.2X ", rx[count]);
		}
		puts("");
		fprintf(stdout, "\nNumber of bytes received = %d bytes\n\n", ret);
#endif
	}; // end-of-while-loop

	// Close the file handle.
	if(file) {
		fclose(file);
		file = NULL;
		fileLength = 0;
	}
}


Best regards,

Elvis Dowson

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux