pic24 spi slave MISO function - Page 1
Forum section: electronics / general

author: snarkysparky
author_rank: Frequent Contributor
timestamp: April 09, 2020, 06:13:23 pm
content: Using a pic24f04ka200 as a slave to another micro.Reception from master is good. But when I write data to SPI1BUF for sending back to master nothingcomes out of SDO1 pin on the next reception. Pin9 ( SDO1 ) is setup as output.Can SPI1BUF be written anytime after completion of a transaction. ( txbuf should always be empty right ? )Does it matter the state of SS1 line.ThanksCode:if(SPI1STATbits.SPIRBF) // spi recieved a word{SpiWordHold = SPI1BUF;SpiWordRecFlag = 1;IFS0bits.SPI1IF = 0;if(SpiWordHold == 0x1111){DebugOutOn();DebugBitTimer = 5000;asm BSET LATB, #4}SpiReturnWord = 0x2525;SPI1BUF = SpiReturnWord; // setup return val for next xmissionDebugOutput(SpiWordHold);}setup isCode:void SpiSetup(void){// slave setup copied from DS70005185A-page 17//**** denotes changes from app noteSPI1BUF = 0;IFS0bits.SPI1IF = 0; // Clear the Interrupt flagIEC0bits.SPI1IE = 0; // Disable the interrupt// SPI1CON1 Register SettingsSPI1CON1bits.DISSCK = 0; // Internal Serial Clock is enabledSPI1CON1bits.DISSDO = 0; // SDOx pin is controlled by the moduleSPI1CON1bits.MODE16 = 1; // Communication is word-wide (16 bits)SPI1CON1bits.SMP = 0; // Input data is sampled at the middle of data//***********SPI1CON1bits.SSEN = 1; // needed to enable slave select ****//***********// output time.SPI1CON1bits.CKE = 1; // Serial output data changes on transition ****// from active clock state to idle clock stateSPI1CON1bits.CKP = 0; // Idle state for clock is a low level; active// state is a high levelSPI1CON1bits.MSTEN = 0; // Master mode disabledSPI1STATbits.SPIROV=0; // No Receive Overflow has occurredSPI1STATbits.SPIEN = 1; // Enable SPI module// Interrupt Controller Settings/// IFS0bits.SPI1IF = 0; // Clear the Interrupt flag. don't need interrupt// IEC0bits.SPI1IE = 1; // Enable the interrupt}

author: snarkysparky
author_rank: Frequent Contributor
timestamp: April 09, 2020, 06:48:02 pm
content: Well a hail mary pass did the trick. Not sure why.I just have to poll this code very frequently.Code:if(!SPI1STATbits.SPITBF) // buffer empty ??{SPI1BUF = SpiReturnWord;}Datasheet could use some work explaining this. If anyone sees where this is clearly explained please reply.Thanks

author: NorthGuy
author_rank: Super Contributor
timestamp: April 09, 2020, 08:50:45 pm
content: Since the data is exchanged during the SPI transaction, you must write data before the transaction (otherwise there will be nothing to transmit during the transaction), then read data after the transaction (because the data do not exist yet until the transaction is complete). I don't see how this could be any other way.

author: carranzafp
author_rank: Newbie
timestamp: May 17, 2022, 02:07:08 pm
content: Consider that when the RX isr it's being triggered your micro will switch to the isr in about 20-30 cycles, by that time the spi exchange has already happened, and if you did not fill in the data beforehand you will send a wrong answer to the master. You can do some stuff to improve for example:a) You can enable enhanced buffer if it's available for your PIC family and you will have a FIFO of 8 words to fill in the response.b) Fill in the queue beforehandc) On your main poll the buffer queue empty bit to fill it again until all data has been transmittedd) Make SPI transfer on the master as slow as possiblee) Run SPI slave at a higher frequency if your application allows itf) Use circular buffers to handle the queuesIts kinda hard to get proper synchrony by pure SPI, on some implementations that I have done I had to use other pins to signal to the master when the response is ready, so for example in the first stage the master sends a cmd over spi, upon ISR reception on the PIC slave it turns on a "busy" pin, the slave has all the time that it requires to fill in the response buffer and then turn off the "busy" pin so the master can start exchanging more bytes to read the response.

author: ledtester
author_rank: Super Contributor
timestamp: May 17, 2022, 04:01:18 pm
content: You can view an SPI transfer as beginning with the /CS line going low. So you could allocate a GPIO pin on the PIC slave as a /CS line and the full protocol would be:1. master brings the /CS line low2. master waits X number of microseconds3. master initiates SPI transferThe wait in step 2 gives the PIC slave time to load the SPI transfer registers with the data that it wants to return.

author: jpanhalt
author_rank: Super Contributor
timestamp: May 17, 2022, 05:46:44 pm
content: Quote from: ledtester on May 17, 2022, 04:01:18 pmWith PIC16F series, the designated !SS pin must be used when it is a slave. When its master, you can use any GPIO. With that 24F, it's pin 12 (attached).