Enabling HXTAL clock on LONGAN NANO

Dear Forum members,
I have a Longan nano board and i want to enable the 8M crystal oscillator. I tried the following code in assembler and the led flashes. I added lines inside the code to read the SCSS bits of RCU_CFG0 register and light BLUE led if bits are 01 indicating HXTAL selected as clock source else the LED will flash in RED. I always get the LED flashing RED even though I enabled the HXTALEN bit in RCU_CTL and forced the SCS bit in RCU_CFG0 to the required values. How can i know that the board has switched to HXTAL clock source. My code is as following. Please point out what mistake I am committing. I don’t know a word of C or C++.
Thanks and Regards
Sajeev

.global start

start:				# entry point for linker

GPIO_BOP_OFFSET   = 0x10 	# GPIO port bit operation register
GPIO_OCTL_OFFSET  = 0x0C 	# GPIO port output control register
GPIO_CTL0_OFFSET  = 0x00 	# GPIO port control register 0
GPIO_CTL1_OFFSET  = 0x04 	# GPIO port control register 1
GPIO_BASE_ADDR_A = 0x40010800   # GD32VF103 Manual: Section 7.5 (green and blue LEDs)
GPIO_BASE_ADDR_C = 0x40011000   # GD32VF103 Manual: Section 7.5 (red LED)
RCU_APB2EN_PAEN_BIT = 2		# APB2 bus clock enable for portA
RCU_APB2EN_PCEN_BIT = 4		# APB2 bus clock enable for portC
RCU_BASE_ADDR = 0x40021000	# clock register base address
RCU_APB2EN_OFFSET   = 0x18	# APB2 bus enable register
GPIO_MODE_PP_50MHZ    = 0x3 	# push-pull output, max speed 50MHz
RCU_CTL_OFFSET  = 0x00     # reset 0x0000 0083
RCU_CFG0_OFFSET = 0x04    # reset 0x0000 0000
#PLL source clock x 27 = 0b11010
RCU_AHBEN_OFFSET = 0x14   # reset 0x0000 0014
RCU_CFG1_OFFSET  = 0x2C

main:

	li a0,RCU_BASE_ADDR			# Load a0 register with RCU base address
	add a1,a1,x0				# load 0 i register a1 
	sw a1,RCU_CTL_OFFSET(a0)		# store word 0x0000 0000 in RCU_CTL register, clear all clock settings
	li a1,(1<<16)  				# load a1 register with 1 shifted to HXTALEN bit position (#li a1,((1<<19)|(1<<16))
	sw a1,RCU_CTL_OFFSET(a0)		# store the value in RCU_CTL register
	lw a1,RCU_CFG0_OFFSET(a0)		# copy to a1 register RCU_CFG0 register contents
	li a2,(1<<0)				# select CK_HXTAL as the CK_SYS source by setting bit 0 of RCU_CFG0
	or a1,a1,a2				# OR contents of a1 with a2
	sw a1,RCU_CFG0_OFFSET(a0)		# store OR-ed value in RCU_CFG0 register
Xloop:
	lw a1,0(a0)				# copy value in RCU_CTL register
	li a2 ,(1<<17)				# load mask for bit 17 (HXTALSTB). if set HXTAL operation stable
	and a1,a1,a2				# AND copied contents of RCU_CTL and HXTALSTB bit mask in a1 and a2 and  result in a1
	beq a1,x0, Xloop			# if a1 is 0 HXTALSTB bit not set, wait ,loop till Xtal stab bit is set
	
			

	# enable GPIO A,B ; prepare PA1,PA2,PC13 green,blue,red LEDS


li a0, RCU_BASE_ADDR				   		# clock base address
li a1,(1 << RCU_APB2EN_PAEN_BIT| 1 << RCU_APB2EN_PCEN_BIT) 	# a , c ports enabled
sw a1, RCU_APB2EN_OFFSET(a0)					# store in rcu apb2enable register
li a0,GPIO_BASE_ADDR_A						# GPIO A base address
li a1,((GPIO_MODE_PP_50MHZ << 4 | GPIO_MODE_PP_50MHZ << 8)) 	# binary from right to left 0b11  loaded fro 4 to 5,, 0b0011 =pushpull output,50mhz on pin 1,pin2
sw a1,GPIO_CTL0_OFFSET(a0)					# store in GPIO control register0 (GPIO_CTL0 controls pin 0 to pin7)
li a0,GPIO_BASE_ADDR_C						# GPIO C base address		
li a1,(GPIO_MODE_PP_50MHZ << 20 )				# 0b0011 shifted 20 positions left enables pin 13 as pushpull output with 50mhs speed
sw a1,GPIO_CTL1_OFFSET(a0)					# store in GPIO control register1 (GPIO_CTL1 controls pin 8 to pin15)

li a0,GPIO_BASE_ADDR_C						# GPIO C base address
li a1, (1 << 13)						# value of 1 shifted 13 positions left loaded in a1
sw a1,GPIO_BOP_OFFSET(a0)					# store in GPIO bit operate register to make pin 13 high (led red off)
li a0,GPIO_BASE_ADDR_A						# GPIO A base address
li a1,(1 << 2 | 1 << 1)						# value of 1 lhs 2 OR 1 lhs 2 loaded in a1
sw a1,GPIO_BOP_OFFSET(a0)					# store in GPIO bit operate register to make pin 1, pin 2 high ( led blue and green off)

li a0,RCU_BASE_ADDR						# check SCSS bits to confirm clock source switched to HXTAL ,if bit 2 of RCU_CTL register set HXTAL is source
lw a1,0(a0)							# copy contents of RCU_CTL to a1
li a2 ,(1<<2)							# load bitmask for SCSS , 01 is HXTAL source,
and a1,a1,a2							# and contents of a1 with a2
bne a1,x0,hipll							# if a1 is not 0 after AND-ing (means bit 2 is set in a1) jump tp label hipll


li a0,GPIO_BASE_ADDR_C						# GPIO C base address (RED LED lights if SCSS bits are 0 means IRC8 is source)
li a1,(1 << 29)							# value of 1 shifted 29 positions left loaded in a1
sw a1,GPIO_BOP_OFFSET(a0)					# store in GPIO bit operate register to make pin 1 low (led red on)
call delay
j blink



hipll:								# blue LED will light up if HXTAL is source in SCSS bits
li a0,GPIO_BASE_ADDR_A						# GPIO A base address
li a1,(1 << 17)							# value of 1 shifted 18 positions left loaded in a1
sw a1,GPIO_BOP_OFFSET(a0)					# store in GPIO bit operate register to make pin 2 low (led on)
call delay
j blink




blink:					# infinite loop blinks RED LED on pin 13 (pc13)
li a0,GPIO_BASE_ADDR_C			# load a0 with GPIO_BASE_ADDR_C value
li a1, (1 << 13)			# load a1 value 1 lhs 13 positions , 1 written in 13th bit will make pin 13 high (off = 1  on = 0, pins are active low, led connected to power always)
sw a1,GPIO_BOP_OFFSET(a0)		# store the value to GPIO_BIT operate register , 1 written to 0-15 bits makes respective pin high , 1 written to 16-31 bits make pin 0-15 low
call delay				# call delay loop
li a0,GPIO_BASE_ADDR_C			# load a0 with GPIO_BASE_ADDR_C value
li a1, (1 << 29 )			# load a1 value 1 lhs 29 positions , 1 written in 29th bit will make pin 13 low (off = 1  on = 0, pins are active low, led connected to power always)
sw a1,GPIO_BOP_OFFSET(a0)		# store the value to GPIO_BIT operate register , 1 written to 0-15 bits makes respective pin high , 1 written to 16-31 bits make pin 0-15 low
call delay				# call delay loop
j blink					# jump to label blink to loop over

delay:
li t1,2000000
loop:
addi t1,t1,-1
bne t1,zero,loop
ret




Hi everyone,
I found out the bug in the code. The procedure to setup the HXTAL was correct but the debug portion with the LED had a bug which was giving wrong indication.
The following portion had the bug

li a0,RCU_BASE_ADDR						# check SCSS bits to confirm clock source switched to HXTAL ,if bit 2 of RCU_CTL register set HXTAL is source
 lw a1,0(a0)	#WRONG ADDRESS			# copy contents of RCU_CTL to a1
li a2 ,(1<<2)							# load bitmask for SCSS , 01 is HXTAL source,
and a1,a1,a2							# and contents of a1 with a2
bne a1,x0,hipll

I had typed wrong
lw , a1,0(a0)
the correct line would be
lw, a1 ,RCU_CFG0_OFFSET(a0)

I was checking clock status bits in wrong register. should be checking in RCU_CFG0

The corrected code would be as below

.global start

start:				# entry point for linker

GPIO_BOP_OFFSET   = 0x10 	# GPIO port bit operation register
GPIO_OCTL_OFFSET  = 0x0C 	# GPIO port output control register
GPIO_CTL0_OFFSET  = 0x00 	# GPIO port control register 0
GPIO_CTL1_OFFSET  = 0x04 	# GPIO port control register 1
GPIO_BASE_ADDR_A = 0x40010800   # GD32VF103 Manual: Section 7.5 (green and blue LEDs)
GPIO_BASE_ADDR_C = 0x40011000   # GD32VF103 Manual: Section 7.5 (red LED)
RCU_APB2EN_PAEN_BIT = 2		# APB2 bus clock enable for portA
RCU_APB2EN_PCEN_BIT = 4		# APB2 bus clock enable for portC
RCU_BASE_ADDR = 0x40021000	# clock register base address
RCU_APB2EN_OFFSET   = 0x18	# APB2 bus enable register
GPIO_MODE_PP_50MHZ    = 0x3 	# push-pull output, max speed 50MHz
RCU_CTL_OFFSET  = 0x00     # reset 0x0000 0083
RCU_CFG0_OFFSET = 0x04    # reset 0x0000 0000
#PLL source clock x 27 = 0b11010
RCU_AHBEN_OFFSET = 0x14   # reset 0x0000 0014
RCU_CFG1_OFFSET  = 0x2C

main:

	li a0,RCU_BASE_ADDR			# Load a0 register with RCU base address
	add a1,a1,x0				# load 0 i register a1 
	sw a1,RCU_CTL_OFFSET(a0)		# store word 0x0000 0000 in RCU_CTL register, clear all clock settings
	li a1,(1<<16)  				# load a1 register with 1 shifted to HXTALEN bit position (#li a1,((1<<19)|(1<<16))
	sw a1,RCU_CTL_OFFSET(a0)		# store the value in RCU_CTL register
	lw a1,RCU_CFG0_OFFSET(a0)		# copy to a1 register RCU_CFG0 register contents
	li a2,(1<<0)				# select CK_HXTAL as the CK_SYS source by setting bit 0 of RCU_CFG0
	or a1,a1,a2				# OR contents of a1 with a2
	sw a1,RCU_CFG0_OFFSET(a0)		# store OR-ed value in RCU_CFG0 register
Xloop:
	lw a1,0(a0)				# copy value in RCU_CTL register
	li a2 ,(1<<17)				# load mask for bit 17 (HXTALSTB). if set HXTAL operation stable
	and a1,a1,a2				# AND copied contents of RCU_CTL and HXTALSTB bit mask in a1 and a2 and  result in a1
	beq a1,x0, Xloop			# if a1 is 0 HXTALSTB bit not set, wait ,loop till Xtal stab bit is set
	
			

	# enable GPIO A,B ; prepare PA1,PA2,PC13 green,blue,red LEDS


li a0, RCU_BASE_ADDR				   		# clock base address
li a1,(1 << RCU_APB2EN_PAEN_BIT| 1 << RCU_APB2EN_PCEN_BIT) 	# a , c ports enabled
sw a1, RCU_APB2EN_OFFSET(a0)					# store in rcu apb2enable register
li a0,GPIO_BASE_ADDR_A						# GPIO A base address
li a1,((GPIO_MODE_PP_50MHZ << 4 | GPIO_MODE_PP_50MHZ << 8)) 	# binary from right to left 0b11  loaded fro 4 to 5,, 0b0011 =pushpull output,50mhz on pin 1,pin2
sw a1,GPIO_CTL0_OFFSET(a0)					# store in GPIO control register0 (GPIO_CTL0 controls pin 0 to pin7)
li a0,GPIO_BASE_ADDR_C						# GPIO C base address		
li a1,(GPIO_MODE_PP_50MHZ << 20 )				# 0b0011 shifted 20 positions left enables pin 13 as pushpull output with 50mhs speed
sw a1,GPIO_CTL1_OFFSET(a0)					# store in GPIO control register1 (GPIO_CTL1 controls pin 8 to pin15)

li a0,GPIO_BASE_ADDR_C						# GPIO C base address
li a1, (1 << 13)						# value of 1 shifted 13 positions left loaded in a1
sw a1,GPIO_BOP_OFFSET(a0)					# store in GPIO bit operate register to make pin 13 high (led red off)
li a0,GPIO_BASE_ADDR_A						# GPIO A base address
li a1,(1 << 2 | 1 << 1)						# value of 1 lhs 2 OR 1 lhs 2 loaded in a1
sw a1,GPIO_BOP_OFFSET(a0)					# store in GPIO bit operate register to make pin 1, pin 2 high ( led blue and green off)

li a0,RCU_BASE_ADDR						# check SCSS bits to confirm clock source switched to HXTAL ,if bit 2 of RCU_CTL register set HXTAL is source
lw a1,RCU_CFG0_OFFSET(a0)							# copy contents of RCU_CTL to a1
li a2 ,(1<<2)							# load bitmask for SCSS , 01 is HXTAL source,
and a1,a1,a2							# and contents of a1 with a2
bne a1,x0,hipll							# if a1 is not 0 after AND-ing (means bit 2 is set in a1) jump tp label hipll


li a0,GPIO_BASE_ADDR_C						# GPIO C base address (RED LED lights if SCSS bits are 0 means IRC8 is source)
li a1,(1 << 29)							# value of 1 shifted 29 positions left loaded in a1
sw a1,GPIO_BOP_OFFSET(a0)					# store in GPIO bit operate register to make pin 1 low (led red on)
call delay
j blink



hipll:								# blue LED will light up if HXTAL is source in SCSS bits
li a0,GPIO_BASE_ADDR_A						# GPIO A base address
li a1,(1 << 17)							# value of 1 shifted 18 positions left loaded in a1
sw a1,GPIO_BOP_OFFSET(a0)					# store in GPIO bit operate register to make pin 2 low (led on)
call delay
j blink




blink:					# infinite loop blinks RED LED on pin 13 (pc13)
li a0,GPIO_BASE_ADDR_C			# load a0 with GPIO_BASE_ADDR_C value
li a1, (1 << 13)			# load a1 value 1 lhs 13 positions , 1 written in 13th bit will make pin 13 high (off = 1  on = 0, pins are active low, led connected to power always)
sw a1,GPIO_BOP_OFFSET(a0)		# store the value to GPIO_BIT operate register , 1 written to 0-15 bits makes respective pin high , 1 written to 16-31 bits make pin 0-15 low
call delay				# call delay loop
li a0,GPIO_BASE_ADDR_C			# load a0 with GPIO_BASE_ADDR_C value
li a1, (1 << 29 )			# load a1 value 1 lhs 29 positions , 1 written in 29th bit will make pin 13 low (off = 1  on = 0, pins are active low, led connected to power always)
sw a1,GPIO_BOP_OFFSET(a0)		# store the value to GPIO_BIT operate register , 1 written to 0-15 bits makes respective pin high , 1 written to 16-31 bits make pin 0-15 low
call delay				# call delay loop
j blink					# jump to label blink to loop over

delay:
li t1,2000000
loop:
addi t1,t1,-1
bne t1,zero,loop
ret

Thanks and regards
Sajeev