SPI Slave wants to send data from multiple threads

Technical questions regarding the XTC tools and programming with XMOS.
jmag99
Active Member
Posts: 35
Joined: Tue Jul 20, 2010 9:45 pm

SPI Slave wants to send data from multiple threads

Post by jmag99 »

I have a spi slave added to the USB Audio reference design. I want to use this to allow another processor to read back a few parameters I gather while running the program. Everything works, except I have some get/set functions that other threads call into to notify the spi slave of new settings. The compiler is telling me that I am violating parallel thread rules. I understand why this is, but I don't know what the proper workaround is. How is this handled in a typical application?


User avatar
rp181
Respected Member
Posts: 395
Joined: Tue May 18, 2010 12:25 am

Post by rp181 »

Not sure if i'm interpreting what you're saying, but it sounds like you were trying to access the SPI ports from different threads, which violates the parallel rules.

The proper way to approach this is to just route all of your communications through 1 thread, and that thread can connect to others via channels. So thread A, which is connected to the SPI ports, listens to threads [B,C...], receives data from another thread, and then outputs it on the SPI lines.
jmag99
Active Member
Posts: 35
Joined: Tue Jul 20, 2010 9:45 pm

Post by jmag99 »

Thanks, this is exactly what I need to do. Are there any simple examples of this around?
User avatar
rp181
Respected Member
Posts: 395
Joined: Tue May 18, 2010 12:25 am

Post by rp181 »

More or less this:

Code: Select all

on tile[0] : SPI spi = . . . ;  //something something something

void spiController(chanend c, SPI &spi);
void threadB(chanend c);

int main(){
	chan channel; //using a streaming chan if speed is important
	par{
		on tile[0] : spiController(channel, spi);
		on tile[0] : threadB(channel);
	}
}

//have more chanend params if you want more than one thread to be able to write to the SPI, add case statements
void spiController(chanend c, SPI &spi){
	unsigned int input;
	
	initSPI();

	while(1){
		select{
			case c :> input:
				//Read data into a buffer
				break;
			default:
				//Do stuff, write buffered data to spi
		}
	}
}
Note, there's probably stuff wrong with this, but that's the basic structure.
jmag99
Active Member
Posts: 35
Joined: Tue Jul 20, 2010 9:45 pm

Post by jmag99 »

Thanks, this is a big help!