STM8/SPI Chip Select & Interrupt
#1
Posted 15 May 2012 - 09:25 PM
Windows Phone Development MVP
President Software Logistics, LLC
Tampa, FL
#2
Posted 15 May 2012 - 10:31 PM
#3
Posted 16 May 2012 - 12:19 AM
#4
Posted 16 May 2012 - 07:15 AM
Could you please provide more details on why you'd like to get rid of the payload size in the message?Right now I'm including the payload length in the message, but I'd like to get rid of that.
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).
#5
Posted 16 May 2012 - 12:46 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.
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.
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.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).
Good Point!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
Thanks!
Kevin...
Windows Phone Development MVP
President Software Logistics, LLC
Tampa, FL
#6
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...
Windows Phone Development MVP
President Software Logistics, LLC
Tampa, FL
#7
Posted 16 May 2012 - 01:07 PM
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
Thanks again -
Kevin...
Windows Phone Development MVP
President Software Logistics, LLC
Tampa, FL
#8
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...
Windows Phone Development MVP
President Software Logistics, LLC
Tampa, FL
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users