AnsweredAssumed Answered

SPI1 Almost working but no MOSI?

Question asked by ostrovskiy.boris on Sep 11, 2014
Latest reply on Sep 11, 2014 by ostrovskiy.boris
I'm trying to get SPI1 up and running with STM32F4 as a master.
This was the source code / tutorial.
The only changes are: MOSI is on pin PB5 instead of PA6 in the example and CS is on PA4 instead of PE7.
Using a scope I see the clock, the CS but no MOSI. Any thoughts?

These are my init_SPI1, SPI1_send and SPI1test functions:

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
     * PB5 = MOSI
     */
    GPIO_InitStruct.GPIO_Pin = 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 SCK, MISO to SPI alternate function
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
         
        GPIO_InitStruct.GPIO_Pin = 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(GPIOB, &GPIO_InitStruct);
         
        // connect SPI1 pins MOSI to SPI alternate function
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_SPI1);
     
    // enable clock for used IO pins
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
         
    /* Configure the chip select pin
       in this case we will use PA4 */
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
     
    GPIOA->BSRRL |= GPIO_Pin_4; // set PA4 high
     
    // enable peripheral clock
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
     
    /* configure SPI1 in Mode 0
     * CPOL = 0 --> clock is low 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_Master;     // transmit in master mode, NSS pin has to be always high
    SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide
    SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;        // clock is low when idle
    SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge
    SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; // set the NSS management to internal and pull internal NSS high
    SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // SPI frequency is APB2 frequency / 16
    SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first
    SPI_Init(SPI1, &SPI_InitStruct);
     
    SPI_Cmd(SPI1, ENABLE); // enable SPI1
         
        GPIOA->BSRRH |= GPIO_Pin_4; // set PA4 (CS) low
        SPI1_send(0x6A);  // USER_CTRL (Write)
        SPI1_send(0x10);  // Disable I2C, enable SPI
        GPIOA->BSRRL |= GPIO_Pin_4; // set PA4 (CS) high
         
}
 
/* This funtion is used to transmit and receive data
 * with SPI1
 *          data --> data to be transmitted
 *          returns received value
 */
uint8_t SPI1_send(uint8_t data){
    SPI1->DR = data; // write data to be transmitted to the SPI data register
    while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete
    while( !(SPI1->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete
    while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore
    return SPI1->DR; // return received data from SPI data register
}
 
uint8_t SPI1test(){
  uint8_t received_val;
  GPIOA->BSRRH |= GPIO_Pin_4; // set PA4 (CS) low
  SPI1_send(0xF5);  // WhoAmI 0x75 (MSB=1 -> READ)
  received_val = SPI1_send(0x00); // transmit dummy byte and receive data
  GPIOA->BSRRL |= GPIO_Pin_4; // set PA4 (CS) high
  return received_val; 
}

Outcomes