cancel
Showing results for 
Search instead for 
Did you mean: 

48/72mhz, PLL*6/PLL*9, with source code

pete2399
Associate II
Posted on September 28, 2012 at 00:13

Hi, first of all thanks for reading this!

This is assembly code (gnu arm) for setting up the ST32F103 to make sound out the DAC. It works in 48mhz PLL mode, but not in What follows is the complete program, demonstrating the problem. Thanks again, -Peter B, RTOS engineer, shbobo.net


.thumb 

.syntax unified

.equ STACKINIT, 0x2000C000

.equ RCC_CR, 0x40021000

.equ RCC_CFGR, 0x40021004

.equ RCC_APB1ENR, 0x4002101C

.equ GPIOA_CRL, 0x40010800

.equ DAC_BOUNDARY, 0x40007400

.equ DAC_DHR12R1, 0x40007408 


@for ST32F103RCT6, uses pin PA4 (DAC)

@compiled with arm-elf-as or arm-linux-gnueabi-as 

@-mcpu=cortex-m3 upload with ST-LINK_CLI.exe

@>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

@the following program sets up an external crystal

@at 8 megahertz, then sets up the PLL to multiply.

@it thus works at 48 megahertz (*6), and produces a saw

@waveform at the DAC output, done by the loop at the end.

@this is a distillation of a much larger program that at 48mhz,

@works with USB, adc, timer, dac, SYstick, and GPIO. 

@but not at 72 mhz.

@the question is, if you comment out the following equate,

@why does it break at 72 megahertz (*9)???? please,

@comment/uncomment the next line about ''FORTYEIGHT''

.equ FORTYEIGHT, 1


vectors: 

.word STACKINIT 

.word initiate + 1 

.word initiate + 1

.word initiate + 1

.word initiate + 1 

.word initiate + 1

.word initiate + 1 


.macro LODESTRA reg, val

ldr r1, =\reg @for setting

ldr r0, =\val @configurations

str r0, [r1] @in Mister ST

.endm


initiate:

LODESTRA RCC_CR, 0x00010081 @ HSEON


CRYSTAL_waiter:

ldr r1, = RCC_CR

ldr r1, [r1]

ldr r0, = 0x00020002 @ HSERDY

tst r1, r0

beq CRYSTAL_waiter


@NOTE THE FOLLOWING TWO POSSIBLE CONFIGURATIONS

.ifdef FORTYEIGHT

.equ CLOCKCONFIG, 0x0051FC00 

@analyzed in bits:

@xxxx reserved

@x000 MCO off

@x101 USBPRE/1, PLL*6

@0001 PLL*6, HSE as source

@1111 ADC=AHB/8 APB2=AHB/16

@1100 APB1=AHB/2

@0000 0000

.else

.equ CLOCKCONFIG, 0x001DFD00 

@analyzed in bits:

@xxxx reserved

@x000 MCO off

@x001 USBPRE/1.5, PLL*9

@1101 PLL*9, HSE as source

@1111 ADC=AHB/8 APB2=AHB/16

@1101 APB1=AHB/4

@0000 0000

.endif 


LODESTRA RCC_CFGR, CLOCKCONFIG

LODESTRA RCC_CR, 0x01010081 @PLL ON


PLL_waiter:

ldr r1, = RCC_CR

ldr r1, [r1]

ldr r0, = 0x02020002 @PLL RDY

tst r1, r0

beq PLL_waiter


LODESTRA RCC_CFGR, (CLOCKCONFIG | 2) @ USE PLL as clock

LODESTRA RCC_APB1ENR, 0x20000000 @ DAC APB1 enable

LODESTRA GPIOA_CRL, 0x44004444 @ analog in for DAC

LODESTRA DAC_BOUNDARY, 0x00010001 @ turn on both DACs

1:

ldr r1, = DAC_DHR12R1 

strh r0, [r1]

subs r0, r0, 1

b 1b @loop a saw waveform forever!

.end

#pll #pll #!bug #72mhz #pll-72mhz #pll
7 REPLIES 7
Posted on September 28, 2012 at 00:36

Doesn't appear to address wait states on the flash, or wait for the PLL source to become the system source.

The former will definitely give you headaches.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on September 28, 2012 at 00:42

Is there some rational to testing irrelevant bits here?

    ldr r0, = 0x00020002 @ HSERDY

   ldr r0, = 0x02020002 @PLL RDY

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
pete2399
Associate II
Posted on September 28, 2012 at 02:34

Hi, thanks for replying so quick.  As regards waiting for the PLL source to settle, note the lines labeled ''PLL_waiter'' up until the ''beq PLL_waiter''.  It is a while loop scheme to test until the RCC control register says PLL is ready.  I hope that elucidates your question on the lines here, they are tst'ing the control register, and its cumulative state of HSE ready, then PLL ready.  thanks again.  -Peter B

Is there some rational to testing irrelevant bits here?

    ldr r0, = 0x00020002 @ HSERDY

   ldr r0, = 0x02020002 @PLL RDY

pete2399
Associate II
Posted on September 28, 2012 at 02:39

BTW, i think i can clarify one other thing.  this code works great at 48mhz, so testing the bits that have already been tested is apparently, OK.  it seems to be something about 72mhz that makes it break.  I've ruled out anything electrical, because, as i said, the PLL works at 48mhz, and the 8mhz sans PLL definitely works too.

Wait states on flash?   You can't mean that at 72mhz, a ''ldr ldr str'' type operation would break?  Thanks again so much to clive1 and anyone else who can maybe try this code out and tell me i'm crazy! 
Posted on September 28, 2012 at 04:02

Thing is, if you test HSI RDY and you change upstream code you've created a bunch of dependencies.

FLASH, you need the equivalent to

    /* Enable Prefetch Buffer */

    FLASH->ACR |= FLASH_ACR_PRFTBE;

    /* Flash 2 wait state */

    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);

    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;

And finally

    /* Wait till PLL is used as system clock source */

    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08);

 

Perhaps some of it is not absolutely necessary, but adds predictability in terms of bringing up analogue parts with board-to-board variability, and then meshing gears as it transitions from one clock to another.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
pete2399
Associate II
Posted on September 29, 2012 at 23:29

Thanks to clive1 i got it going ( i think).

He was right, the prefetch buffer does need to be tweaked.

A recommendation to newbies who want to master the literature on this product:

read RM0008 (about STM32F103xx) AND read PM0075- programming manual specifically about flash memory.  it has key morsels, such as all about the Access Control Register.

to fix my code, i needed to add this macro call before configuring the PLL:

LODESTRA FLASH_ACR, 0x31

I still have a question.

I originally was running the PLL at 48mhz, and i was not loading anything into the ACR, so it was maintaining the restart value of 0x30 (prefetch buffer enabled, no latency).  why did it work at all when it should have been 0x31 (one wait state)?  Actually, 72mhz sysclck works as well at 0x31 as 0x32 (one wait state versus two).  That is confusing, because the PM0075 expressly states that 72mhz must have two wait states on the flash, as Clive1 said.

Well, I'm going to keep the ACR at one wait state for now and see if anything bugs, but it sounds right, and USB is working so...  thanks clive!
Posted on September 30, 2012 at 14:52

The speed of the flash is effected by the voltage and temperature you run the processor at, ST rates it at around 24 MHz. I've run a couple of parts at 32 MHz without wait states, but haven't probed the limits, or tested over operational specs.

36 MHz might also work, but I wouldn't rely on it.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..