How to get relaxation oscillator working. ** solved ** But now How to wakeup from deepsleep

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
danjperron
Posts: 51
Joined: Thu Dec 27, 2018 11:38 pm
Location: Québec, Canada

How to get relaxation oscillator working. ** solved ** But now How to wakeup from deepsleep

Post by danjperron » Wed Jul 13, 2022 2:18 pm

The Pico has GPIOs that could run a relaxation oscillator.
I tried to make it work but can't figure it out.

On the RP2040 datasheet stipulates that it is simply to set the GPIO has CLOCK GPIN, outinvert , and use one of the gpclk generators.
chapter 2.15.2.4 (page 185)

My RC network is 1M ohm and 1nF.
I'm using GPIO 20 and 21.

The scope toggle both Pin high and everything stay high after. no clock.

This is my code

Code: Select all

from machine import Pin,mem32
import time

IO_BANK0_BASE = 0x40014000
CLOCKS_BASE = 0x40008000
PADS_BANK0_BASE = 0x4001C000

CLK_GPOUT0_CTRL = 0
CLK_GPOUT1_CTRL = 0xc
CLK_GPOUT2_CTRL = 0x18
CLK_GPOUT3_CTRL = 0x24


atomicXOR = 0x1000
atomicRW  = 0
atomicOR = 0x2000
atomicNOR = 0x3000

def setPinFuncSel(pin, funcsel, InvertOut=False):
    pin_addr = 4 + pin *8
    #reset funcsel
    mem32[IO_BANK0_BASE | pin_addr | atomicNOR]= (0x1f | (0x3<<8))
    #set funcsel
    if InvertOut:
        mem32[IO_BANK0_BASE | pin_addr | atomicOR]= (funcsel | (0x1<<8))
    else:
        mem32[IO_BANK0_BASE | pin_addr | atomicOR]= funcsel
    
def getPinFuncSel(pin):
    pin_addr = 4 + pin *8
    print("pin_addr :",hex(pin_addr))
    return  mem32[IO_BANK0_BASE | pin_addr]


def setPad(pin, value):
    machine.mem32[PADS_BANK0_BASE | (4+ (4 * pin))] = value
    
def getPad(pin):
    return machine.mem32[PADS_BANK0_BASE | (4+ (4 * pin))]
   

#pin20 to OUT , Pin21 to IN
pin20 = Pin(20,Pin.IN)
pin21 = Pin(21,Pin.OUT)

#change Pin20 and pin21 function
# do I need schmitt trigger?
setPad(20,0x40)
setPad(21,0x40)
setPinFuncSel(20,8)
setPinFuncSel(21,8,True)
 

# set relaxation oscillator
CLK_GPOUT_CTRL = CLK_GPOUT0_CTRL
#disable 
mem32[CLOCKS_BASE|CLK_GPOUT_CTRL|atomicNOR] = 1<<11  
#set clksrcpin0
mem32[CLOCKS_BASE|CLK_GPOUT_CTRL|atomicNOR] = (0xF << 5)    
mem32[CLOCKS_BASE|CLK_GPOUT_CTRL|atomicOR] = (0x1 << 5)
#enable clocks
mem32[CLOCKS_BASE|CLK_GPOUT_CTRL|atomicOR] = 1<<11


while True:
  time.sleep_ms(10)


Last edited by danjperron on Fri Jul 15, 2022 3:22 am, edited 4 times in total.

TheSilverBullet
Posts: 50
Joined: Thu Jul 07, 2022 7:40 am

Re: How to get relaxation oscillator working

Post by TheSilverBullet » Wed Jul 13, 2022 2:29 pm

from the datasheet:
…simply send the clock source (GPIN0 or GPIN1)…

danjperron
Posts: 51
Joined: Thu Dec 27, 2018 11:38 pm
Location: Québec, Canada

Re: How to get relaxation oscillator working

Post by danjperron » Wed Jul 13, 2022 3:00 pm

Code: Select all

from the datasheet:
…simply send the clock source (GPIN0 or GPIN1)…
This is exactly my problem!! Where is the clock source???
Its not a external clock but an oscillator build simply with a resistor and capacitor.
page 184 (2.15.2.4) show exactly how it supposes to work.
The diagram show GPIN0 => gpclk0-3 => OUT to where ?? I assume GPOUT0 but doesn't look like it

TheSilverBullet
Posts: 50
Joined: Thu Jul 07, 2022 7:40 am

Re: How to get relaxation oscillator working

Post by TheSilverBullet » Wed Jul 13, 2022 3:12 pm

danjperron wrote:
Wed Jul 13, 2022 3:00 pm

Code: Select all

from the datasheet:
…simply send the clock source (GPIN0 or GPIN1)…
This is exactly my problem!! Where is the clock source???
Its not a external clock but an oscillator build simply with a resistor and capacitor.
page 184 (2.15.2.4) show exactly how it supposes to work.
The diagram show GPIN0 => gpclk0-3 => OUT to where ?? I assume GPOUT0 but doesn't look like it
Could have been explained better in the datasheet.
The GPIO pin in combination with external capacitor and resistor and the internal inverter feedback is the oscillator.

It should say: (we) send the inverted signal back to GPIO[0 or 1]
Assume all is setup properly and you have a low signal at GPIO0. That signal is propagated through the internal circuitry, inverted and put (internally) on GPIO0. Now it's high and the whole process starts over, high becomes low, that is put on GPIO0. The resulting frequency is the result from the internal propagation time in addition to the charging/draining of the capacitor.

ADDED:
Just had another look at the datasheet and it could also be that GPIO0 and GPIO1 are both needed.
The diagram 2.15.2.4. Relaxation Oscillators suggests that two pins are connected via resistor and at the ›input‹ pin a capacitor is connected to ground.
But that doesn't fit the description that »1 or 2 relaxation oscillators can be constructed« when, at the same time two pins are required and only pin 0 and 1 are valid.
Strange…

ADDED:
Think I got it. Pin 0 and Pin 1 can both be inputs for generated clock signals. That explains »1 or 2 relaxation oscillators can be constructed«
Now we need also outputs (either one or two) and they could be pin 21 23,24,25 (I think)
Last edited by TheSilverBullet on Wed Jul 13, 2022 3:34 pm, edited 1 time in total.

danjperron
Posts: 51
Joined: Thu Dec 27, 2018 11:38 pm
Location: Québec, Canada

Re: How to get relaxation oscillator working

Post by danjperron » Wed Jul 13, 2022 3:25 pm

thanks Silverbullet but

How to I put the resistor on the same pin?????

My point is that GPIN0 is GPIO20 then the OUTPUT for gpclk0 has to be GPOUT0 which is GPIO21.

I will check again tonight.


Update *** Maybe the best way to check is to set the source to xosc_clksrc and see if I got clock on GPIO21.

TheSilverBullet
Posts: 50
Joined: Thu Jul 07, 2022 7:40 am

Re: How to get relaxation oscillator working

Post by TheSilverBullet » Wed Jul 13, 2022 3:39 pm

danjperron wrote:
Wed Jul 13, 2022 3:25 pm
How to I put the resistor on the same pin?????
You can't.
danjperron wrote:
Wed Jul 13, 2022 3:25 pm
My point is that GPIN0 is GPIO20 then the OUTPUT for gpclk0 has to be GPOUT0 which is GPIO21.
I'd try GPIO0 or GPIO1 as input and maybe GPIO20 as output.
Connect GPIO0 and GPIO20 with the resistor, put the capacitor on GPIO0 and ground.

danjperron
Posts: 51
Joined: Thu Dec 27, 2018 11:38 pm
Location: Québec, Canada

Re: How to get relaxation oscillator working

Post by danjperron » Wed Jul 13, 2022 3:41 pm

Code: Select all

I'd try GPIO0 or GPIO1 as input and maybe GPIO20 as output.
Connect GPIO0 and GPIO20 with the resistor, put the capacitor on GPIO0 and ground.
You are confusing GPIO0 and GPIO1 to GPIN0 and GPIN1 which are completely different. check function select page 237 on the datasheet.

TheSilverBullet
Posts: 50
Joined: Thu Jul 07, 2022 7:40 am

Re: How to get relaxation oscillator working

Post by TheSilverBullet » Wed Jul 13, 2022 4:04 pm

You are confusing GPIO0 and GPIO1 to GPIN0 and GPIN1 which are completely different. check function select page 237 on the datasheet.
[/quote]

You might be right. GPIO0 vs.GPIN0. What a clever way to write a datasheet.

Actually that was the first thing that hit me coming from STM32F4s and AVRs.
The RP2040 datasheet.
Why do it the way everybody does it? Let's try something different… 8-)

BTW. What release is your datasheet? Mine is version 1.7.1 and the tables are at completely different locations.

danjperron
Posts: 51
Joined: Thu Dec 27, 2018 11:38 pm
Location: Québec, Canada

Re: How to get relaxation oscillator working

Post by danjperron » Wed Jul 13, 2022 4:45 pm

I'm using the latest RP2040 datasheet which is 1.8 (17 Jun 2022).

When I specify a page is not the one from the reader but the actual page on the sheet.

danjperron
Posts: 51
Joined: Thu Dec 27, 2018 11:38 pm
Location: Québec, Canada

Re: How to get relaxation oscillator working

Post by danjperron » Thu Jul 14, 2022 1:16 am

Yeah!!!! got it working!!!!
You enable the clkgpl then you change the clock source.
Also the RC network need to be near the pin otherwise noise gets in.

I did a deepsleep and it was still working.

Next step will be to wakeup from deepsleep by routing this clock to the RTC.
RelaxationOsc.jpg
relaxation osc
RelaxationOsc.jpg (44.71 KiB) Viewed 5871 times
This is my preliminary code

Code: Select all

from machine import Pin,mem32
import time

IO_BANK0_BASE = 0x40014000
CLOCKS_BASE = 0x40008000
PADS_BANK0_BASE = 0x4001C000

CLK_GPOUT0_CTRL = 0
CLK_GOUT0_DIV = 4


atomicXOR = 0x1000
atomicRW  = 0
atomicOR = 0x2000
atomicNOR = 0x3000

def setPinFuncSel(pin, funcsel, InvertOut=False):
    pin_addr = 4 + (pin *8)
    #reset funcsel
    mem32[IO_BANK0_BASE | pin_addr | atomicNOR]= (0x1f | (0x3<<8))
    #set funcsel
    if InvertOut:
        mem32[IO_BANK0_BASE | pin_addr | atomicOR]= (funcsel | (0x1<<8))
    else:
        mem32[IO_BANK0_BASE | pin_addr | atomicOR]= funcsel
    
def getPinFuncSel(pin):
    pin_addr = 4 + (pin *8)
    print("pin_addr :",hex(pin_addr))
    return  mem32[IO_BANK0_BASE | pin_addr]


def setPad(pin, value):
    machine.mem32[PADS_BANK0_BASE | (4+ (4 * pin))] = value
    
def getPad(pin):
    return machine.mem32[PADS_BANK0_BASE | (4+ (4 * pin))]
   

#pin20 to OUT , Pin21 to IN
pin20 = Pin(20,Pin.IN)
pin21 = Pin(21,Pin.OUT)
pin21.value(0)

setPad(21,0x31)

setPinFuncSel(20,8)
setPinFuncSel(21,8,True)
setPad(20,0b01000011)

# set relaxation oscillator
CLK_GPOUT_CTRL = CLK_GPOUT0_CTRL
#disable 
mem32[CLOCKS_BASE|CLK_GPOUT_CTRL|atomicNOR] = 1<<11  

# divide by 1
mem32[CLOCKS_BASE|CLK_GOUT0_DIV]= 1<<8

#enable clocks
mem32[CLOCKS_BASE|CLK_GPOUT_CTRL|atomicOR] = 1<<11

#set clksrcpin0
mem32[CLOCKS_BASE|CLK_GPOUT_CTRL|atomicNOR] = (0xF << 5)    
mem32[CLOCKS_BASE|CLK_GPOUT_CTRL|atomicOR] = (0x1 << 5)

Post Reply