0
votes

Im not able to get any data out from the MOSI pin, or the CLK pin when measuring with an oscilloscope on the pins.

this is my code:

include

include "stm32f407xx.h"

void delay(){

                  int i;

                  for(i = 0; i < 1000000; i++);

}

int main(){

           // Enable RCC APB2 clock for SYSCFG (for externalinterrupt)
                  RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
                  // Enable RCC APB1 clock for SPI2
                  RCC->APB1ENR |= (1 << 14);
                  // GPIOA for pushbutton
                  RCC->AHB1ENR |= (1 << 0);
                  // GPIOB for SPI
                  RCC->AHB1ENR |= (1 << 1);
                  // GPIOD for LED
                  RCC->AHB1ENR |= (1 << 3);

/////// GPIO B init for MOSI, MISO och CLK pins:

                  GPIOB->MODER |= (2 << (2*13)); //Sets pin 13 as Alternate function
                  GPIOB->MODER |= (2 << (2*14)); //Sets pin 14 as Alternate function
                  GPIOB->MODER |= (2 << (2*15)); //Sets pin 15 as Alternate function
                  GPIOB->OTYPER |= PUSH_PULL_PIN_13;
                  GPIOB->OTYPER |= PUSH_PULL_PIN_14;
                  GPIOB->OTYPER |= PUSH_PULL_PIN_15;

                  GPIOB->OSPEEDR |= OSPEEDR_MEDIUM_PIN_13;
                  GPIOB->OSPEEDR |= OSPEEDR_MEDIUM_PIN_14;
                  GPIOB->OSPEEDR |= OSPEEDR_MEDIUM_PIN_15;

                  GPIOB->PUPDR |= PUPDR_PULLDOWN_PIN_13; // Pull down for CLK
                  GPIOB->PUPDR |= PUPDR_PULLUP_PIN_14; // Pull up for MISO
                  GPIOB->PUPDR |= PUPDR_PULLUP_PIN_15; // Pull up for MOSI

                  GPIOB->AFR[1] |= ALT_FUNC_AF5_PIN_13;  // 5 för AF5 till pin 13
                  GPIOB->AFR[1] |= ALT_FUNC_AF5_PIN_14;  // 5 för AF5 till pin 14
                  GPIOB->AFR[1] |= ALT_FUNC_AF5_PIN_15;  // 5 för AF5 till pin 15

///////// GPIO A init for pushbutton

                  GPIOA->MODER |= MODER_INPUT_PIN_0;

GPIO D init for LED

                  GPIOD->MODER |= MODER_OUTPUT_PIN_12; //Sets pin 12 as output
                  GPIOD->MODER |= MODER_OUTPUT_PIN_13; //Sets pin 13 as output
                  GPIOD->MODER |= MODER_OUTPUT_PIN_14; //Sets pin 14 as output
                  GPIOD->MODER |= MODER_OUTPUT_PIN_15; //Sets pin 15 as output

                  GPIOD->OTYPER |= PUSH_PULL_PIN_12;
                  GPIOD->OTYPER |= PUSH_PULL_PIN_13;
                  GPIOD->OTYPER |= PUSH_PULL_PIN_14;
                  GPIOD->OTYPER |= PUSH_PULL_PIN_15;

                  GPIOD->OSPEEDR |= OSPEEDR_MEDIUM_PIN_12;
                  GPIOD->OSPEEDR |= OSPEEDR_MEDIUM_PIN_13;
                  GPIOD->OSPEEDR |= OSPEEDR_MEDIUM_PIN_14;
                  GPIOD->OSPEEDR |= OSPEEDR_MEDIUM_PIN_15;

                  GPIOD->PUPDR |= PUPDR_PULLDOWN_PIN_12; //Frågetecken på denna, ska det vara 0 1 eller 2??
                  GPIOD->PUPDR |= PUPDR_PULLDOWN_PIN_13; //Frågetecken på denna, ska det vara 0 1 eller 2??
                  GPIOD->PUPDR |= PUPDR_PULLDOWN_PIN_14; //Frågetecken på denna, ska det vara 0 1 eller 2??
                  GPIOD->PUPDR |= PUPDR_PULLDOWN_PIN_15; //Frågetecken på denna, ska det vara 0 1 eller 2??

                  GPIOD->AFR[1] |= ALT_FUNC_AF0_PIN_12;  // 0 för AF0 till pin 12
                  GPIOD->AFR[1] |= ALT_FUNC_AF0_PIN_13;  // 0 för AF0 till pin 13
                  GPIOD->AFR[1] |= ALT_FUNC_AF0_PIN_14;  // 0 för AF0 till pin 14
                  GPIOD->AFR[1] |= ALT_FUNC_AF0_PIN_15;  // 0 för AF0 till pin 15

//////// SPI init

                  SPI2->CR1 |= (0 << CR1_CLOCK_PHASE);       //Set clockphase in CR1 register
                  SPI2->CR1 |= (1 << CR1_CLOCK_POLARITY);    //Set polarity in CR1 register
                  SPI2->CR1 |= (4 << CR1_BAUD_RATE);         //Set baudrate
                  SPI2->CR1 |= (1 << CR1_DATA_FRAME_FORMAT); //16-bit transmission
                  SPI2->CR1 |= (1 << CR1_ENABLE_SPI);        //Enable SPI
                  SPI2->CR1 |= (1 << CR1_MASTER_SELECT);     //MASTER SELECTION
                  SPI2->CR1 |= (1 << CR1_LSB_FIRST);         //LSB FIRST
                  SPI2->CR1 |= (1 << CR1_SLAVE_SELECT);      //SSI set
                  SPI2->CR1 |= (1 << CR1_SW_SLAVE_MANAGE);   //SSM, software slave management selected, which means SSI will be used insted of I/O
                  SPI2->CR1 |= (0 << CR1_RECEIVE_ONLY);      //Transmit and Receive
                  SPI2->CR1 |= (0 << CR1_CRC_TRANSFER);      //NOT USED, CRC
                  //SPI2->CR1 |= (0 << CR1_CRC_CALCULATION); //NOT USED, CRC calculation disabled
                  //SPI2->CR1 |= (0 << CR1_BIDIOE);          //enable transmit-only if set
                  SPI2->CR1 |= (0 << CR1_BIDIMODE);          //1-line bidirectional mode if set

//////// Enable external interrupt

                  //SYSCFG->EXTICR[0] |= (0 << 0); //Enable
                  EXTI->IMR |= (1 << 0);      //Enable interrupt
                  EXTI->RTSR |= (1 << 0);    //set Risnig edge interrupt
                  EXTI->FTSR |= (0 << 0);    //falling edge interrupt (disabled)
                  NVIC_EnableIRQ(EXTI0_IRQn);
                  SPI2->CR2 |= (1 << 7);

                  while(1){
                         GPIOD->ODR |= (1 << 12); // led ON
                         delay();
                         GPIOD->ODR &= ~(1 << 12); // led OFF
                         delay();
                  }

                  return 0;

}

void EXTI0_IRQHandler(){

         EXTI->PR |= (1 << 0); //Clears interrupt pending bit

         while(1){
                GPIOD->ODR |= (1 << 13); //Blå led ON
                delay();
                GPIOD->ODR &= ~(1 << 13); //Blå led OFF
                delay();
                // Here I want to Send Data
                SPI2->DR |= 0xFF;
         }

}

1
What have I forgot? Is there any register that I've missed to configure?Bei
funcionality, the master should send data when the user button is pushed, which will initiate an interrupt and the sending should be done in the interrupt function called "void EXTI0_IRQHandler()" . This interrupt works fine, the leds are blinking in a different color when pushing the buttonBei

1 Answers

0
votes

Please use appropriate macros definition from stm32f407xx.h file. It's much better to read:

TIM2->DIER |= TIM_DIER_UIE; /* interrupt enable on 1st channel */

than:

TIM2->DIER |= (1 << 1); /* interrupt enable on 1st channel */

It will avoid confusions, and maybe indicate where is your problem. In current code format it is much time taking to decode if You set registers correctly.

edit: ok, got some smell:

GPIOD->AFR[1] |= (0 << (30));  // 5 för AF0 till pin 15

AFR registers are 4 bits per pin. Why are You shifting value by 30 ? Shouldn't it be 28 ?

edit_2: Is your push button triggers EXTI irq ? If yes -- that is not good... I don't remember if on this board is any hardware that provide button debounce funcionality, even though, You should put it in code. Now, interrupt may be triggered many, many times instead of 1 irq = 1 pushbutton press.

edit_3:

SPI2->CR2 |= (1 << 7);

Enable irq when TX buffer empty. Buffer is empty, untill You press the button. This causes not-stoping invoking of SPI2 interrupt, and You don't have defined handler for it. Try to clarify what You are trying to achieve, and how this should be done.