Hello, trying to hack SPI1 working "bare metal"

Generic boards that are not Maple or Maple mini clones, and don't contain the additional USB reset hardware
tiger762
Posts: 22
Joined: Tue Jan 26, 2016 11:40 pm

Hello, trying to hack SPI1 working "bare metal"

Postby tiger762 » Thu Feb 23, 2017 2:29 am

This is my function to initialize SPI. I've included the relevant page number from RM0008. Note the use of the "bit-band" to perform atomic bit setting/clearing (base address 0x42000000):

void InitializeSPI () {
*((volatile long *)(0x42000000 + (0x40021004 - 0x40000000)*32 + 13*4)) = 1; // RCC_APB2ENR.PPRE2[2] p.101 \
*((volatile long *)(0x42000000 + (0x40021004 - 0x40000000)*32 + 12*4)) = 0; // RCC_APB2ENR.PPRE2[1] p.101 |--- PCLK2 divided by 2
*((volatile long *)(0x42000000 + (0x40021004 - 0x40000000)*32 + 11*4)) = 0; // RCC_APB2ENR.PPRE2[0] p.101 /
*((volatile long *)(0x42000000 + (0x40021018 - 0x40000000)*32 + 12*4)) = 1; // RCC_APB2ENR.SPI1EN p.112
*((volatile long *)(0x42000000 + (0x40021018 - 0x40000000)*32 + 2*4)) = 1; // RCC_APB2ENR.IOPAEN p.112
*((volatile long *)(0x42000000 + (0x40021018 - 0x40000000)*32 + 0*4)) = 1; // RCC_APB2ENR.AFIOEN p.112
*((volatile long *)(0x42000000 + (0x4002100c - 0x40000000)*32 + 12*4)) = 1; // RCC_APB2RSTR.SPI1RST p.106
*((volatile long *)(0x42000000 + (0x4002100c - 0x40000000)*32 + 0*4)) = 1; // RCC_APB2RSTR.AFIORST p.105
*((volatile long *)(0x42000000 + (0x40013000 - 0x40000000)*32 + 2*4)) = 1; // SPI1_CR1.MSTR p.747
*((volatile long *)(0x42000000 + (0x40013000 - 0x40000000)*32 + 5*4)) = 1; // SPI1_CR1.BR[2] \
*((volatile long *)(0x42000000 + (0x40013000 - 0x40000000)*32 + 4*4)) = 1; // SPI1_CR1.BR[1] |--- 111 means FPCLK/256 p.746
*((volatile long *)(0x42000000 + (0x40013000 - 0x40000000)*32 + 3*4)) = 1; // SPI1_CR1.BR[0] /
*((volatile long *)(0x42000000 + (0x40013000 - 0x40000000)*32 + 6*4)) = 1; // SPI1_CR1.SPE p.746
SetMode (PA5, OUTPUT_ALT_PUSHPULL | MODE_OUTPUT_10MHZ); // p.166
SetMode (PA6, INPUT_FLOAT | MODE_INPUT); // p.166
SetMode (PA7, OUTPUT_ALT_PUSHPULL | MODE_OUTPUT_10MHZ); // p.166
}

and the ubiquitous 'write_spi' function:

UCHAR write_spi (UCHAR value) {
UCHAR ret;
SPI1_DR = value;
while (!(SPI1_RXNE));
ret = SPI1_DR;
return (ret);
}

Using a Saleae logic analyzer, I see CSN dropping low (for the benefit of the NRF24L01 I am trying to speak with) but SCLK never sends out a train of pulses.

Something in my RCC and/or GPIO config is missing a step. The reference manual (RM0008) is not 100% thorough on this point. Any help appreciated!

zmemw16
Posts: 1097
Joined: Wed Jul 08, 2015 2:09 pm
Location: St Annes, Lancs,UK

Re: Hello, trying to hack SPI1 working "bare metal"

Postby zmemw16 » Thu Feb 23, 2017 7:24 am

you don't seem to setup SCK PA4 as an output :?:

doesn't it istr default to being an input.

stephen

stevestrong
Posts: 1000
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: Hello, trying to hack SPI1 working "bare metal"

Postby stevestrong » Thu Feb 23, 2017 11:57 am

Is there any reason why not to use a "human readable" version of setting the registers?
For example:

Code: Select all

spi_reg_map * regs = SPI1->regs;
regs->DR = 0x00FF;
while ( (regs->SR & SPI_SR_RXNE)==0 ) ;


Be careful by writing: if you have already data waiting to be read out, your reading at the end of the function will return that one instead of the last read one.

tiger762
Posts: 22
Joined: Tue Jan 26, 2016 11:40 pm

Re: Hello, trying to hack SPI1 working "bare metal"

Postby tiger762 » Thu Feb 23, 2017 12:45 pm

In my setup() is where I set up the CSN (PA4):

void setup (void) {
SetMode (PA4, MODE_OUTPUT_10MHZ | OUTPUT_PUSHPULL);
SetMode (PC13, MODE_OUTPUT_10MHZ | OUTPUT_OPENDRAIN);
InitializeUART ();
InitializeSPI ();
Console ("\r\nHello!!!\r\n");
}

Basically, I can't get SCLK to oscillate. I keep seeing reference to "attaching SPI1 to alternate pins PA5,PA6,PA7"

Either like this:

gpioInitStructure.Alternate = GPIO_AF5_SPI1;

or this one fellow who does it like this:

void InitialiseSPI(void)
SPI_InitTypeDef SPI_InitStruct;
// Connect SPI1 pins to SPI alternate function.
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);

GPIO_AF5_SPI1 is either 5 or 20 (4 tiems 5) or 0x00F00000

The stm32f103 does not have a GPIOx_AFR register, so I might be mixing metaphors here.

Setting up the USART1 "bare metal" was so much easier. It required a couple of GPIO setup and an RCC and that was that.

stevestrong
Posts: 1000
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: Hello, trying to hack SPI1 working "bare metal"

Postby stevestrong » Thu Feb 23, 2017 2:39 pm

I think this thread should be moved to viewforum.php?f=48, as it does not use the Arduino_STM32 repo.
Meanwhile you could check these lines of code, maybe helps.

tiger762
Posts: 22
Joined: Tue Jan 26, 2016 11:40 pm

Re: Hello, trying to hack SPI1 working "bare metal"

Postby tiger762 » Thu Feb 23, 2017 3:05 pm

Started off that way, before I realized the specs were insufficient and the Internet blurs the hardware distinction among the stm32 family. So I tried to remove any possible ambiguity. There are RCC and SPI register settings to be made. I'm left guessing which one(s) I am missing.

If the author(s) of RM0008 had been nice enough to include ALL necessary register settings, that would have been wonderful :(

stevestrong wrote:Is there any reason why not to use a "human readable" version of setting the registers?
For example:

Code: Select all

spi_reg_map * regs = SPI1->regs;
regs->DR = 0x00FF;
while ( (regs->SR & SPI_SR_RXNE)==0 ) ;


Be careful by writing: if you have already data waiting to be read out, your reading at the end of the function will return that one instead of the last read one.

stevestrong
Posts: 1000
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: Hello, trying to hack SPI1 working "bare metal"

Postby stevestrong » Thu Feb 23, 2017 3:22 pm

If you would really check the lines of code (and track the called function) I linked to my previous post, you could maybe solve your issue.

User avatar
RogerClark
Posts: 5543
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: Hello, trying to hack SPI1 working "bare metal"

Postby RogerClark » Thu Feb 23, 2017 9:45 pm

I will log in as admin and move this thread ( to the STM core as suggested by @stevstrong

tiger762
Posts: 22
Joined: Tue Jan 26, 2016 11:40 pm

Re: Hello, trying to hack SPI1 working "bare metal"

Postby tiger762 » Thu Feb 23, 2017 10:26 pm

Actually, the answer was to include setting "SSM_ENABLE" (bit 9) and "INT_SLAVE_SEL" (bit 8) in SPI_CR1

stevestrong
Posts: 1000
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: Hello, trying to hack SPI1 working "bare metal"

Postby stevestrong » Fri Feb 24, 2017 8:06 am

Please mark it as SOLVED in the title if it is the case.


Return to “Generic STM32F103”

Who is online

Users browsing this forum: No registered users and 3 guests