STM32H745 - SPI doesn't transmit any data. - SOLVED
SOLVED - look at edit below!
I am trying to implement SPI on nucleoH745ZI-Q without HAL or any kind of driver, I wrote my own registers pointers and functions like digitalWrite, pinMode or printf. I set up RCC, GPIO and SPI registers (all set, checked with debugger). But I can't get it work. I tried non-interrupt method (sending all data in loop - commented section) - with no luck. Then I tried interrupt method, I literally copied config from STM32CubeH7 Examples (checked registers with debugger and put it in my code), with no luck again. Always there is no sign of life on lines.
What am I doing bad?
Q&A:
- I set up peripheral clock (checked with debugger)
- I set up Alternate Functions and GPIO Clocks (checked with debugger)
- Kernel clock is getting to SPI block (checked with MCO1 - same source)
- Interrupt is called (checked with breakpoint)
main.c
int main(void) {
initClock(); // 480MHz / 240MHz
initSPI();
/* Infinite loop */
while (1) ;
}
void SPI(void) {
if(SPI1->SR != 2) printf("%x\n\r", SPI1->SR); // Debug
if(SPI1->SR & 2) SPI1->TXDR = 'abcd'; // Write data to FIFO if there's place
if(SPI1->SR & 8) SPI1->IER &= ~2; // End of Transmission - disable TXP interrupt
}
uint32_t (* const vector_table[])
__attribute__ ((section(".vectors"))) = {
(uint32_t *) 0x20020000, // 0x000 Stack Pointer
(uint32_t *) main, // 0x004 Reset
(uint32_t *) hardFault, // 0x008 Non maskable interrupt
...
(uint32_t *) SPI, // 0x0CC SPI1
...
}spi.c
void initSPI() {
/**** GPIO ****/
pinMode(A4, ALTERNATE);
pinMode(A5, ALTERNATE);
pinMode(A6, ALTERNATE);
pinMode(B5, ALTERNATE);
PORTA->AFRL |= 0x5550000;
PORTB->AFRL |= 0x500000;
PORTA->OSPEEDR |= 0x3F00;
PORTB->OSPEEDR |= 0xC00;
RCC->APB2ENR |= (1 << 12); // Enable SPI clock
SPI1->CFG1 = 0x60000007; // MBR = 128 (375kHZ), 8-bits frame size
SPI1->CFG2 = 0xA4400000; // AFControl, SSO Enable, Software SS, Master mode
SPI1->CRCPOLY = 0x107; // CRC Polynomial
SPI1->CR2 = 8; // Data size (8 bytes = 8 frames by 8 bits)
SPI1->IFCR = (1 << 9); // Mask Mode Fault (why it's showing up?)
enableIRQ(35); // Enable SPI Interrupt
SPI1->IER = 0x76F; // Enable Interrupts
SPI1->CR1 = (1 << 12); // SS Enable
SPI1->CR1 |= 1; // Enable SPI
SPI1->CR1 |= (1 << 9); // CSTART - Start transmission
/**** Non Interrupt - tried, not worked ****/
//delay(50);
//
//int a[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
//int i = 0;
//while(i < 8) {
// if(SPI1->SR & 2) {
// *(uint8_t *)SPI1->TXDR = a[i++];
// printf("%x\n\r", SPI1->SR);
// }
//}
}Analyzer Capture

EDIT:
Finally i was able to get it work. First of all On my lovely nucleo board SPI_CS are marked incorrectly (PD14 instead of PA4) so there was first mstake. What i've done is I rewrote all configuration from scratch and then it worked. I think that error was accessing TXDR by 8bit - 32bits works now. I changed also Frame size. Anyway There is part of my new code fell free to use it if You like.
spi.c
void initSPI() {
/**** GPIO ****/
pinMode(A4, ALTERNATE);
pinMode(A5, ALTERNATE);
pinMode(A6, ALTERNATE);
pinMode(B5, ALTERNATE);
PORTA->AFRL |= 0x5550000;
PORTB->AFRL |= 0x500000;
PORTA->OSPEEDR |= 0x3F00;
PORTB->OSPEEDR |= 0xC00;
RCC->APB2ENR |= (1 << 12); // Enable SPI clock
SPI1->CFG1 = 0x60070067; // MBR = 128 (375kHZ), 8-bits crc, 8-bits frame size, 4 frames packet size
SPI1->CFG2 = 0x34400000; // SSO Active High, SSO Enable, Software SS, Master mode
SPI1->CR2 = 8; // Data size (8 bytes = 8 frames by 8 bits)
enableIRQ(35); // Enable SPI Interrupt
SPI1->IER = 0x76F; // Enable Interrupts
SPI1->CR1 = (1 << 12) | 1; // Enable SS & SPI
SPI1->CR1 |= (1 << 9); // CSTART - Start transmission
/**** Non Interrupt ****/
/*int i = 0;
while(i < 8) {
if(SPI1->SR & 2) {
if(i++ % 2 == 0) SPI1->TXDR = 0xAAAAAAAA;
else SPI1->TXDR = 0x55555555;
printf("%x %x\n\r", SPI1->SR, SPI1->CR1);
}
if(SPI1->SR & 8) {
printf("done");
SPI1->CR1 &= ~(1 << 12);
break;
}
}*/
}main.c
int main(void) {
initClock(); // 480MHz / 240MHz
initSPI();
while(1);
}
void SPI(void) {
if(SPI1->SR & 2) SPI1->TXDR = 'elo!'; // Write data to FIFO if there's place
if(SPI1->SR & 8) {
printf("done");
SPI1->IFCR = 0xFF8; // Reset SR
SPI1->IER = ~2; // End of Transmission - disable TXP Interrupt
SPI1->CR1 &= ~(1 << 12); // Disable NSS
}
}
uint32_t (* const vector_table[])
__attribute__ ((section(".vectors"))) = {
(uint32_t *) 0x20020000, // 0x000 Stack Pointer
(uint32_t *) main, // 0x004 Reset
(uint32_t *) hardFault, // 0x008 Non maskable interrupt
...
(uint32_t *) SPI, // 0x0CC SPI1
...
}Analyzer Capture:
