Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

STM8/SPI Chip Select & Interrupt


  • Please log in to reply
7 replies to this topic

#1 ByteMaster

ByteMaster

    Advanced Member

  • Members
  • PipPipPip
  • 76 posts

Posted 15 May 2012 - 09:25 PM

Being the ultra-impatient developer ;) , I want to get a couple of modules running with the GO! platform. It sounds like the standard firmware might not be released in the immediate future so I'm hacking my own communications layer as a temporary measure. What I'd like to do is write something that streams some bytes via SPI from the GO! bus into the STM8 and put those into a buffer. Then when the GO! bus is done sending bytes, I want to call a method to figure out what to do with the buffer. The message could be of variable length. It would seem like when the GO bus releases the chip select line, the communications is done and I can hand off that byte array. From looking at the STM docs it doesn't seem like there is any sort of interrupt that can be handled when the chip select line is released, hopefully I'm wrong? Also if there is any other way of using something in the STM to let me know the SPI exchange is done I'd gladly change my strategy. Right now I'm including the payload length in the message, but I'd like to get rid of that. Any thoughts?!?!?!?! Kevin... Sorry if this isn't the right channel for asking these sorts of questions, but it seems like the most appropriate. Maybe we need a Netduino Stack Exchange Site :rolleyes:
Kevin D. Wolf
Windows Phone Development MVP
President Software Logistics, LLC
Tampa, FL

#2 Matt Isenhower

Matt Isenhower

    Advanced Member

  • Members
  • PipPipPip
  • 74 posts
  • LocationSan Diego, CA

Posted 15 May 2012 - 10:31 PM

Hi Kevin, One option is to enable interrupts for the actual pin that you are using as the SPI CS input (rather than using any SPI-specific interrupt). For example, you could enable a rising interrupt for pin A3 (if that is the pin you are using for SPI CS) and process the incoming message in the interrupt handler for that pin. Currently, with the RGB LED and potentiometer modules, all SPI messages are 18 bytes long, with the last byte being the computed CRC8 value for the message. So an alternative to monitoring the SPI CS pin would be to process each incoming message after receiving the 18th byte (as long as that byte contains a valid CRC). Much of the protocol will be changing once the official generic firmware is released, so it's probably not worth worrying too much about the details of your protocol at this point. Either of these methods should work for now, and you'll be able to update your module's firmware to work with the new protocol in the future (as long as it follows the recommended electrical specifications). Matt
Komodex Labs
Follow me on Twitter: @mattisenhower

#3 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 16 May 2012 - 12:19 AM

To add to what Matt said... You can use the SPI Select pin in one of two modes: hardware or software. If you use it in hardware mode, you'll get an interrupt after every SPI byte is received. But you won't know when your frame started or stopped, apart from your own counting and error correction. If you use it in software mode, you can use an interrupt on the line to enable SPI receive mode...and then trap the select line's deassertion to know that you've been deselected. That's most likely how we'll be doing things with the generic firmware, since the SS line gives us a good synchronization strategy. Chris

#4 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 16 May 2012 - 07:15 AM

Right now I'm including the payload length in the message, but I'd like to get rid of that.

Could you please provide more details on why you'd like to get rid of the payload size in the message?

I am not saying it is good or wrong, both approaches have their pros and cons. There are a few things to consider, though:

  • If you want to use CRC, you need to know the frame size - because you have to transmit the CRC value at specific point (i.e. after the last byte, either by setting CRCNEXT flag or passing the value through SPI_DR 'manually'),
  • I would not rely on SPI_NSS to mark the end of the frame transmission - the module cannot enforce that behavior, what if master does not toggle it during transmission of multiple frames? I would not rely on it to mark the beginning of the transmission neither, it can be asserted even before the module is powered on. The behavior will be probably described in the go!bus protocol specification, but the theory is one thing and practice another - for certain micros the interrupt may not even work, and who knows in what scenario the module will be used (custom master, 'hardcoded' topology, exclusive buses etc.),
  • If you want to have reliable communication, you'd probably need to handle the situation when the frame transmission is interrupted (for any reason) and the module does not receive complete frame. For example, the module can setup a timer during processing the first byte and if the whole frame is not received before the timeout elapses, it discards the data and resets the SPI state to make sure the next frame is not merged with the partially received one, which can have unexpected results. This mechanism covers SPI_NSS marking the end of the transmission, although with a slight delay (depending on the timeout duration).
These are just things from top of my head, please take them with a grain of salt, your mileage may vary. IMHO what you could do is to use some kind of 'switch to stream mode' command (transmitted over the 'standard' 18-byte frame) and then use different kind of communication, suitable for your particular module. I think something like this will be used for example for display modules, where high data throughput is needed.

#5 ByteMaster

ByteMaster

    Advanced Member

  • Members
  • PipPipPip
  • 76 posts

Posted 16 May 2012 - 12:46 PM

Hi Matt - thanks for the reply

One option is to enable interrupts for the actual pin that you are using as the SPI CS input (rather than using any SPI-specific interrupt). For example, you could enable a rising interrupt for pin A3 (if that is the pin you are using for SPI CS) and process the incoming message in the interrupt handler for that pin.


I had thought I read somewhere in the STM8 programming manual that if a pin was configured for an alternative purpose, it could contribute to an external interrupt. I guess I could be wrong and it wouldn't be too difficult to test it.

Even if we can't use it in an external interrupt, there are usually a couple other unused pins on the device, one of which I could tie to the "Slave Select"/SS line rather than "Chip Select"/CS as I called it.

Currently, with the RGB LED and potentiometer modules, all SPI messages are 18 bytes long, with the last byte being the computed CRC8 value for the message. So an alternative to monitoring the SPI CS pin would be to process each incoming message after receiving the 18th byte (as long as that byte contains a valid CRC).

I'm fairly certain some of my messages will be more than 18 bytes and some considerably less. I guess when the chip is running at 16MHz with a fast SPI bus it might not be a big deal. Just trying to be as efficient as possible.


Much of the protocol will be changing once the official generic firmware is released, so it's probably not worth worrying too much about the details of your protocol at this point. Either of these methods should work for now, and you'll be able to update your module's firmware to work with the new protocol in the future (as long as it follows the recommended electrical specifications).

Matt

Good Point!

Thanks!

Kevin...
Kevin D. Wolf
Windows Phone Development MVP
President Software Logistics, LLC
Tampa, FL

#6 ByteMaster

ByteMaster

    Advanced Member

  • Members
  • PipPipPip
  • 76 posts

Posted 16 May 2012 - 12:48 PM

If you use it in software mode, you can use an interrupt on the line to enable SPI receive mode...and then trap the select line's deassertion to know that you've been deselected. That's most likely how we'll be doing things with the generic firmware, since the SS line gives us a good synchronization strategy.

Chris


Interesting...I never considered looking at the software mode, I think I'll have to read up on that this afternoon. I think I see where you are going with this.

Thanks

Kevin...
Kevin D. Wolf
Windows Phone Development MVP
President Software Logistics, LLC
Tampa, FL

#7 ByteMaster

ByteMaster

    Advanced Member

  • Members
  • PipPipPip
  • 76 posts

Posted 16 May 2012 - 01:07 PM

Thanks CW2 - I guess for what I'm doing, I'm controlling both sides of the equation and not necessarily trying to create an industry standard. But reliable communications is a must so you brought up some good points.

To your primary question:

Could you please provide more details on why you'd like to get rid of the payload size in the message?


I guess more than anything the primary reason is it's just an extra one or two bytes that get sent that are probably not necessary. But as Matt said earlier in the conversation, this is really just temporary until we get a more standardized approach so what's a few extra micro seconds/clock cycles to simplify things. I guess my original vision was some sort of State Machine on both ends that just read in a byte (or handled an interrupt), and depending on what state and figure out what to do with it.

You did bring up a good point though

you'd probably need to handle the situation when the frame transmission is interrupted (for any reason) and the module does not receive complete frame.


I know my module code "libraries" will send a frame as a transaction, but really don't know enough about NETMF to know if some other higher priority interrupt could come in and suspend my modules SPI transmission. Right now I'm feeling very much overwhelmed by the stuff I need, er - I guess really want to learn, but getting under the hood of NETMF should probably be a higher priority.

Thanks again -

Kevin...
Kevin D. Wolf
Windows Phone Development MVP
President Software Logistics, LLC
Tampa, FL

#8 ByteMaster

ByteMaster

    Advanced Member

  • Members
  • PipPipPip
  • 76 posts

Posted 18 May 2012 - 01:36 PM

One option is to enable interrupts for the actual pin that you are using as the SPI CS input (rather than using any SPI-specific interrupt). For example, you could enable a rising interrupt for pin A3 (if that is the pin you are using for SPI CS) and process the incoming message in the interrupt handler for that pin.


Ok - coming off of vacation mode...I think I finally understand this direction and what Chris suggested. So basically configure SPI to use Software NSS Management or the SPI_NSS_SOFT option in SPI_Init.

SPI_Init(SPI_FIRSTBIT_MSB, SPI_BAUDRATEPRESCALER_2, SPI_MODE_SLAVE, SPI_CLOCKPOLARITY_LOW, SPI_CLOCKPHASE_2EDGE, SPI_DATADIRECTION_2LINES_FULLDUPLEX, SPI_NSS_SOFT, 0x07);

Then configure the input pin that was originally configured for hardware SS as just a GPIO interrupt;

	GPIO_Init(NSS_PORT, NSS_PIN, GPIO_MODE_IN_FL_IT);	
	
	EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOA, EXTI_SENSITIVITY_RISE_FALL);

Then in the interrupt handler do something like
INTERRUPT_HANDLER(EXTI_PORTA_IRQHandler, 3)
{
	if(GPIO_ReadInputPin(GPIOA, GPIO_PIN_3) == SET)
		GO_SS_Released();
	else
		GO_SS_Asserted();
}


to determine when the transmission starts and ends. Got it...this is exactly what I was looking for.

This still brings up CW2's point:

If you want to have reliable communication, you'd probably need to handle the situation when the frame transmission is interrupted (for any reason) and the module does not receive complete frame.


As I mentioned earlier, not knowing about the NETMF internals, is there a case where a higher priority interrupt could come in and suspend the SPI transition from the Master? I think when checking the CRC byte at the end of the message, I know if it's a valid message or not. Maybe implement some ACK/NAK handshaking. Seems like it's starting to get a bit complex/chatty though :(

Kevin...
Kevin D. Wolf
Windows Phone Development MVP
President Software Logistics, LLC
Tampa, FL




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.