Configure SPI on STM32F4 Discovery


Configure SPI on STM32F4 Discovery



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;
}



}





What have I forgot? Is there any register that I've missed to configure?
– Benji
2 days ago





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 button
– Benji
2 days ago




1 Answer
1



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.





I changed to Macros now
– Benji
2 days ago





I think the commenst is wrong there. it should be 0 for the LEDS.
– Benji
2 days ago





That's true, it should be 28. but that's not solving the problem with SPI, this was just for the LED
– Benji
2 days ago





edit_3: Im trying to set the control register so that the TXE bit in Status Register is Set when tx buffer is empty, so I know when to send the next byte.
– Benji
2 days ago






I must have missed to configure some bus or register or something.
– Benji
2 days ago






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

how to run turtle graphics in Colaboratory

Export result set on Dbeaver to CSV