SPI on STM32 won't work without pullup resistors and even then performs poorly
You should reset the value of the pins you are changing before setting the bits.

The reset value of GPIOA_CRL is 0x4444 4444. So each pin is initialized with 0b0100, if you do a |= 0b0011 you end up with 0b0111 which is an open drain output. Same with 0b1011 becomes 0b1111 and that is an alternate function open drain.

So you need to do something like this:

// Reset pin configuration
GPIOA-&gt;CRL &amp;= ~(0b1111 &lt;&lt; 4 * 4);  // Reset Pin A4
GPIOA-&gt;CRL &amp;= ~(0b1111 &lt;&lt; 5 * 4);  // Reset Pin A5
GPIOA-&gt;CRL &amp;= ~(0b1111 &lt;&lt; 7 * 4);  // Reset Pin A7
GPIOA-&gt;CRL |= 0b0011 &lt;&lt; 4 * 4;  // Set pin A4 as PP out 50mHz for SS
GPIOA-&gt;CRL |= 0b1011 &lt;&lt; 5 * 4;  // Set pin A5 AltFunc PP out 50mHz for SCK
GPIOA-&gt;CRL |= 0b1011 &lt;&lt; 7 * 4;  // Set pin A7 AltFunc PP out 50mHz for MOSI