Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Spi Sspbuf

Status
Not open for further replies.
I know you know how to make SPI periperals do their thing...
So what does

Blueteeth said:
...the 'CS' line is only used for single byte transfers.

mean? This was the part that confused me.
 
Papabravo said:
I know you know how to make SPI periperals do their thing...
So what does mean? This was the part that confused me.

Oops I have madee a booboo :( I *assumed* that the PIC automatically provides the CS line in master mode, and in doing , would only stay low for a byte transfer, then move back up to idle high. The reason I didn't know the PIC doesn't implement the CS automatically in master mode is that I never used it, I just control it manually anyway. After going through the datasheet it seems its only needed by the hardware when in slave mode, in master mode, one has to produce their own CS line.

Sorry, didn't mean to cause confusion, but hey, I learn something new every day :D

To the OP, this relaly has nothing to do with your problem because you implement the CS in software anyway. Did you go to the link I provided, lots of nice C examples of using the SSP module in SPI, for both sending and recieving (stores recieveddummy bit) and it worked on my compiler.

Blueteeth
 
No problem Blue. I believe this is the forum's great strength. Subjecting ideas and explanations to the crucible of vigorous debate benefits everyone.
 
Exactly mate, exchanging idea's an opinions to help people learn (at all levels) and solve project problems. A great resource for any electronic/electrical enigneer :D
 
Hey guys, thanks very much for your help

Unfortunately I am still very much stuck on this problem, I've looked at the C and ASM solutions but they still do not seem to solve this problem.

I have read through the datasheets many times, but I think it's a misunderstand on my part of the MAX3100.

What I'm trying to achieve is send a string to the MAX3100 by looping over my 'spi_write' function.

This function outputs two bytes, one after the other. My understanding of SPI and the MAX3100 is when you send the first byte, you get a byte back. Hence in my code, whenever I send a byte, I loop until the buffer contains data, then read it, then repeat the process.

My issue is, I can send the first character, it skips the second, sends the third and skips the forth. The only way I am able to output the full character sequence is add a large looping delay at the bottom of my spi_write function. So hence if i output 'TEST' I get 'TS'

Does anyone know of a nice way to get around these issues I am facing, I've tried using the SPI interrupts, which didn't seem to work, the MAX IRQ line, again which didn't seem to work. I'm at a loss at the moment.

My code is the following with my comments as to how I think it should be working.

Code:
void spi_write(unsigned char txdata1, unsigned char txdata2)
{
	unsigned char rxdata, rxdata1, rxdata2;
	CS	= 0;	//chip select

	rxdata1 = SSPBUF;	//lose data in buffer

	SSPBUF	= txdata1;	//write the first MAX3100 control byte
				//0b10000000
	while(!STAT_BF);	            //loop until buffer contains data
	rxdata1 = SSPBUF;	            //retrieve data
	

	SSPBUF	= txdata2; 	//write the second MAX3100 data byte
	while(!STAT_BF);	             //loop until buffer contains data
	rxdata2 = SSPBUF; 	//retrieve data

	CS	= 1;		//de-select chip
}

void spi_puts(const char *str)
{	
	while(*str){
		//putch(*str);
		spi_write(0b10000000, *str);
		str++;
	}
}

If anyone could please take a look at this issue, and shed some light it would be appreciated.

Thanks for your input so far.

Regards
Rich
 
I suspect a compiler bug. Can you make an assembly language interlist? If not then an assembly listing will have to do. Depending on how the constant string is stored and where it is stored, the ++str may or may not be working correctly.
 
Hi,

Just skimmed over the max3100 datasheet. You do indeed need to send two bytes (16bits) over SPI per character. That is, if you wish to send the string 'test' you need to call your spi write routine 4 times. Once for each character. Looking at your code earlier in the topic, I think you have this write. You call 'spi write' once per character, with the first byte of each 16-bit word being a config (non data) byte, the second being your ascii character.

You're getting characters through at least, so your spi write routine seems fine. If you weren't sending all 16 bits per frame, and pulling the CS line high before it finished it would discard the data, so nothing would come from the MAX3100's uart.

I think the reason you require a 'large delay' after the spi write routine is that I don't *think* the max3100 has a tx FIFO, only a FIFO on the reciever part. So when you send the second caharacter to it, its still writing the first, and thus discards the new data. But by the time you send the third, its finished writing the first, and so it can send that. How large is this delay you're using?
 
Why not try the suggestion in the datasheet and check the WCOL bit. Microchip wouldn't suggest this without reason.

Something like,
Code:
     rxdata1 = SSPBUF;     //clear BF
     do{
        SSPCON_WCOL=0;     //clear WCOL
        SSPBUF=txdata1;    // write data
     }while(SSPCON_WCOL);  // if collision do it again
     while(!STAT_BF);      // wait for transfer to finish
     rxdata1 = SSPBUF;     // clear BF for next transfer
     do{                   // do next byte

If nothing else, it may give a clue as to what is wrong.

Mike.
 
Last edited:
You don't mention the baudrate of the SPI or the MAX3100. If, as I suspect, the SPI is running very much faster than the UART, you will need to check the availability of the transmit shift register in the UART before writing to it with the SPI.
 
Hey Guys

I have partial good news, after writing a function to check the availability of the TX register in the UART suggested by Papabravo, and waiting until the TX was empty, i am now able to successfully send my string without any issues.

\o/

The other issue I am now facing is getting the MAX3100 UART to interrupt on the IRQ line. I just can't seem to get it to produce a signal.

My UART setup is:

Code:
void spi_init()
{
	STAT_CKE = 1;
	spi_write(0b11000100, 0b00001011);
	while(spi_ready(0b01000000, 0b00000000));
}

I am setting the RM bit (data available in the receive register) but I am not getting a signal generated when data becomes available.

I'm not sure if I am setting up the chip correctly. The datasheet talks about putting the chip into software shutdown mode (SHDN) and applying the settings. Anyone have an ideas about this?

Thanks
Regards
Rich
 
You want to bring the chip out of shutdown and you need to configure the IRQ line for the interrupts that it should respond to. Software shutdown is a low power mode that conserves power but may cause you to miss traffic.

It would appear that a Read Data Operation clears the IRQ.
 
Last edited:
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top