Communication over the SD Interface

The C0-microSD is designed to communicate with host devices over the SD interface. When connected to a host computer, the device presents itself as a 20.2 MB (19.3 MiB) unformatted block storage device. All communication is achieved with block read and write operations which are initiated by the host. This is true whether the device is in Bootloader mode, or in Signaloid Core mode.

The communication over the SD interface is done using block read and write operations, and not an SDIO extension of the SD interface.

Bootloader communication example

In this example, the C0-microSD is in Bootloader mode, and connected to a host computer that runs MacOS. To flash a new bitstream to the Custom User Bitstream section of the device you can use the dd command. Here, we assume that the device is located in /dev/disk4/, and that the bitstream file is bitstream.bin.

% sudo dd if=bitstream.bin of=/dev/disk4 seek=3072 bs=512

203+1 records in
203+1 records out
104090 bytes transferred in 1.904253 secs (54662 bytes/sec)

In the example above, the seek argument is calculated by taking the decimal representation of the USER_BITSTREAM_OFFSET (see /hardware-overview/bootloader-addresssing.html), and dividing it by the block size (bs = 512). All of the bootloader operations can be done using the C0_microSD_toolkit.py script that you can find here.

Signaloid Core communication example

In this example, the C0-microSD is in Signaloid Core mode, and connected to a host computer that runs MacOS. We assume that the device is located in /dev/disk4/. Here, we communicate with the C0-microSD using a C host application to set the command register to 0x00000001.

#include <stdio.h>
#include <errno.h>
#include <stdint.h>

main(void)
{
	char*		devicePath = "/dev/disk4";
	uint32_t	command = 0x00000001;
	uint32_t	commandRegisterOffset = 0x00010000;
	
	/*
	 *	Open the C0-microSD device
	 */
	fd = open(devicePath, O_WRONLY | O_SYNC | O_DSYNC);
	if (fd == -1)
	{
		perror("Error opening device");
		return -1;
	}

	/*
	 *	Seek to offset for command register
	 */
	seek_offset = lseek(fd, commandRegisterOffset, SEEK_SET);
	if (seek_offset == (off_t)-1)
	{
		perror("Error seeking to target offset");
		close(fd);
		return -1;
	}

	/*
	 *	Write command register data
	 */
	result = write(fd, &command, sizeof(uint32_t));
	if (result != bufferSize)
	{
		perror("Error writing data to the device");
	}
	
	/*
	 *	Close the C0-microSD device
	 */
	close(fd);
}

The commandRegisterOffset is determined based on the Signaloid Core communication scheme specifications. You can find header files and helper functions for building your own C and Python based host applications here.