AnsweredAssumed Answered

Configure STM32F4 Discovery as SPI slave?

Question asked by khorvongkarn.prach on Jul 2, 2014
Hi,

I want to have STM32F4 Discovery as SPI slave and PIC18F2580 as SPI master. I tried  to modify examples found on the internet to suit my need, but none of them work. I have neither access to oscilloscope nor logic analyzer, so it's very difficult for me to understand why the code doesn't work.

The following is configuration I'm using for PIC (Master mode):
Note: I used this configuration for master to make communication between 2 PICs and it worked.

/* SMP: Sample bit
 * SPI Master mode:
 *      1 = Input data sampled at end of data output time
 *      0 = Input data sampled at middle of data output time
 * SPI Slave mode:
 *      SMP must be cleared in slave mode
 */
#define _SMP            0
  
/* CKE: SPI Clock Select bit
 *      1 = Transmit occurs on transition from active to idle clock state
 *      0 = Transmit occurs on transition from idle to active clock state
 */
#define _CKE            0
  
/* CKP: Clock Polarity Select bit
 *      1 = Idle state for clock is a high level
 *      0 = Idle state for clock is a low level
 */
#define _CKP            1
  
/* Synchronous Serial Port Mode Select bits
 *      0101 = Slave mode, clock = SCK pin, SS pin disabled (can be used as I/O pin)
 *      0100 = Slave mode, clock = SCK pin, SS pin enabled
 *      0011 = Master mode, clock = TMR2 output/2
 *      0010 = Master mode, clock = Fosc/64
 *      0001 = Master mode, clock = Fosc/16
 *      0000 = Master mode, clock = Fosc/4
 */
#define _SSPM_MASTER    0b0000
  
void SPI_init() {
    TRISA = 0x00;               /* set all port A pins as output pins */
    ADCON1 = 0x0F;              /* set all port A pins, including SS (RA5), as digital I/O */
  
    TRISC = 0b00010000;         /* Set SCK pin (RC3) as output
                                 * SDI pin (RC4) as input
                                 * SDO pin (RC5) as output */
  
    SSPSTAT = 0b00000000;       /* Initialize SSPSTAT register to POR state */
    SSPSTATbits.SMP = _SMP;     /* Configure sample bit */
    SSPSTATbits.CKE = _CKE;     /* Configure clock select bit */
  
    SSPCON1 = 0b00000000;       /* Initialize SSPCON1 register to POR state */
    SSPCON1bits.CKP = _CKP;     /* Configure clock polarity select bit */
    SSPCON1bits.SSPEN = 1;      /* Enable SPI (set SCK, SDO, SDI, and SS as serial port pins)*/
  
    SSPCON1bits.SSPM = _SSPM_MASTER;    /* Configure sync mode bits for master */
}

And this is the configuration I'm using for STM32F4 Discovery (Slave mode):

void init_SPI1(void) {
      
    GPIO_InitTypeDef GPIO_InitStruct;
    SPI_InitTypeDef SPI_InitStruct;
      
    // enable clock for used IO pins
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
      
    /* configure pins used by SPI1
     * PA5 = SCK
     * PA6 = MISO
     * PA7 = MOSI
     */
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
      
    // connect SPI1 pins to SPI alternate function
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
      
    // enable clock for used IO pins
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
      
    // enable peripheral clock
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
      
    /*
     * CPOL = 1 --> clock is high when idle
     * CPHA = 0 --> data is sampled at the first edge
     */
    SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex mode, seperate MOSI and MISO lines
    SPI_InitStruct.SPI_Mode = SPI_Mode_Slave;     // transmit in slave mode
    SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide
    SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;        // clock is high when idle
    SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge
    SPI_InitStruct.SPI_NSS = SPI_NSS_Soft; // set the NSS management to internal and pull internal NSS high
    SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_LSB;// data is transmitted MSB first
    SPI_Init(SPI1, &SPI_InitStruct);
      
    SPI_Cmd(SPI1, ENABLE); // enable SPI1
}

I'm connecting
 - SCK (PA5) to PIC's SCK (RC3)
 - MISO (PA6) to PIC's SDI (RC4)
 - MOSI (PA7) to PIC's SDO (RC5)

Any help would be highly appreciated. Thank you in advance for your suggestions and sorry for my bad English.

Best Regards,
Pat

Outcomes