ATtiny25 - assembly - BOD disable for sleep mode - error

Hello guys

I am begging for your help as I am stuck here and do not understand why.
I am trying to disable the BOD by software during sleep mode, as indicated in the AVR manual.
If I understood correctly the instructions, AT Tiny 25 can disable the BOD Level 2 fuse on sleep mode to save energy by software if setting the SODS and BODSE in a special sequences.
So I have enabled the BOD fuse. I wrote the code respecting the sequence (I guess), but when compiling with Studio 7 (version 7.0.132), I get the error "Undefined symbol: BODS & BODSE.".
I checked the limitation and the the ATtiny 25 should be able to do it !

FYI: BODLEVEL fuses are set as follows: L:0x62 H:0xDD E:0xFF

;init brown out detection desealble for sleep mode
		ldi		r23, (1<<BODS)|(1<<BODSE)			; En 2 fois 1- pour autoriser ecriture 
		out		MCUCR, r23							; envoyer autorisation ecriture 
		ldi		r23, (1<<BODS)|(0<<BODSE)			; Ecrire valeur a envoyer dans R23 
		out		MCUCR, r23							; Envoyer R23 dans MCUCR

		
;init WDT for interrupt mode
		ldi		r23, (1<<WDCE)|(1<<WDE)
		out		WDTCR, r23
		ldi		r23, (1<<WDIE)|(0<<WDE)|(0<<WDP0)|(1<<WDP1)|(0<<WDP2)|(0<<WDP3)	; sec time out WDT interrupt; no system reset
		out		WDTCR, r23
        sei				; global interrupt enable bit is active
	
L1_INTERIEUR:		;init sleep modes
		ldi		r23, (1<<SM1)	;Power-down mode
		out		MCUCR, r23
		in		r23, MCUCR
		ldi		r23, (1<<SE)	;sleep mode enabled
		out		MCUCR, r23		;put MCU into sleep

L1A_INTERIEUR:	
		in R15,SREG
		wdr
		sleep	

Thanks in advance for your help :slight_smile:

Please explain why you write one value to a register, then immediately overwrite that with another value.

		ldi		r23, (1<<WDCE)|(1<<WDE)
		out		WDTCR, r23
		ldi		r23, (1<<WDIE)|(0<<WDE)|(0<<WDP0)|(1<<WDP1)|(0<<WDP2)|(0<<WDP3)	; sec time out WDT interrupt; no system reset
		out		WDTCR, r23

Hint: shifting a zero to the left is pointless.

Morning

I wrote this part of code quite a long time ago but at this time i have done this to respect the 43ATtiny25/45/85 [DATASHEET]. 2586Q–AVR–08/2013

"To prevent unintentional disabling of the Watchdog or unintentional change of time-out period, two different safety levels are selected by the fuse WDTON as shown in Table 8-1 Refer to “Timed Sequences for Changing the Configuration of the Watchdog Timer” on page 43 for details.
Figure 8-7. Watchdog Timer

8.4.1 Timed Sequences for Changing the Configuration of the Watchdog Timer
The sequence for changing configuration differs slightly between the two safety levels. Separate procedures are described for each level.
8.4.1.1 Safety Level 1
In this mode, the Watchdog Timer is initially disabled, but can be enabled by writing the WDE bit to one without any restriction. A timed sequence is needed when disabling an enabled Watchdog Timer. To disable an enabled Watchdog Timer, the following procedure must be followed:

  1. In the same operation, write a logic one to WDCE and WDE. A logic one must be written to WDE regard-less of the previous value of the WDE bit.
  2. Within the next four clock cycles, in the same operation, write the WDE and WDP bits as desired, but with the WDCE bit cleared.

Maybe not the best or conventional way to do it but this is working ..
the compiling issue is on the BODS and BODSE.

Kindly, let me know the answers to the following questions:
1. What are the current fuse bit settings (EF, HF, LF) of the ATtiny25 with which you are working?
2. What Programmer you are using to program the ATtiny25 --
(1) AVR Programmer?
(2) Digispark ATtiny85 Dev Board?
(3) Arduiono as ISP?

Hello Mostafa

Seems you are always helping me :slight_smile:
Learning programing is a long way especaily when you start from scratch as i am doing .. but i am still learning daily ..

I will try to answer all your questions below :

1. What are the current fuse bit settings (EF, HF, LF) of the ATtiny25 with which you are working? EF =0x62 , HF=0xDD, LF=0xFF
2. What Programmer you are using to program the ATtiny25 -- I am using microchip studio 7 (version 7.0.2594) and writting with AVRdude with Arduino uno R3 as ISP

1 Like

Thank you for providing me the information.

I am studying your case using my Digispark ATtiny85 Dev Board and C++. After that I will map the C++ codes into AVR Assembly Codes which is friendly for me as I am basically an Assembly Language Programmer.

But more i do think about, I think the error message should come from the "tn25def.inc" i am using.
I do not have the BODS and BODSE definition in the MCUCR.
Do you think that can be a start ?

; MCUCR - MCU Control Register
;.equ ISC00 = 0 ; Interrupt Sense Control 0 bit 0
;.equ ISC01 = 1 ; Interrupt Sense Control 0 bit 1
.equ SM0 = 3 ; Sleep Mode Select Bit 0
.equ SM1 = 4 ; Sleep Mode Select Bit 1
.equ SE = 5 ; Sleep Enable
.equ PUD = 6 ; Pull-up Disable

and it seems you are the only Assembly Language Programmer here ..
the question now is why do i try to learn code directly in assembly instead of using upper level language .. certainly i like to suffer :slight_smile:
and also think that the best way to fully understand what is happening.

This is not true at all!

Most of the members of this Forum are veteran programmers who are versed in assembly language programming and other HLL. I marginally meet the working level in ASM and C++.

You may collect the following Digispark ATtiny85 Dev Board (Fig-1) which provides an excellent debugging platform.
DigisparkAttiny85Board
Figure-1:

at least you are the one answering to me :slight_smile:

1. Have you checked that your ATtiny25 is functional by blinking a LED being connected at any available IO-pin? Are you using external crystal or resonator -- what is the frequency?

2. Would be glad to see your complete ASM Program that you have developed using Microchip studio. Please, use English Language to narrate the comments and the labels of the program.

3. Kindly, describe in sequence the expected functional behavior of your ATtiny25. For example:
(1) Intialization as needed (including stack pointer)
(2) Blinking a LED at PB0 for three times at 100 ms interval as an indcation of the statrtup of the MCU.
(3) MCU enters into power-down sleep mode.
(4) Watchdog Timeout (what is the timeout period) event will wake up the MCU.
(5) Blinks LED at PB0 for five times as an indication of wake up.
(6) MCU enters into sleep mode again.

Note: By virtue of fuse bit settings, the BOD Circuit is active. You can disable it by configuring fuse bits or through code execution. I think you want to use the later -- am I correct?

yes the attiny25 is functional and the .. it has been produced week 16 of 2023 so latest version.
But the problem is that I can not even built the solution with studio 7.. as the error appearing is "Undefined symbol: BODS & BODSE"
that's why I was thinking about the MCU control register definition in the tn25def.inc

That's why I have requested you (in my post #12) to post the complete ASM Program so that I clearly understand your objectives and problems.

Mostafa

i have a made a little code to show you the concept ..
In my application in order to save the max energy, i have disable all clocks to save maximum energy thats why you have the loop count down.

Everything does work fine out of the

;
; test 1.asm
;
; Created: 28/01/2024 
; Author : Tic & Tac
;


; REGISTER USAGE
;               | sbr/cbr            | sbrs/sbrc       | Comment

; R16           |                    |                 |
; R17           |                    |                 |
; R18           |                    |                 |
; R19           |                    |                 |
; R20           |                    |                 |
; R21           |                    |                 |
; R22           |                    |                 |
; R23           |                    |                 |
; R24           |                    |                 |
; R25           |                    |                 |
; R26           |                    |                 |
; R27           |                    |                 |
; R28           |                    |                 |
; R29           |                    |                 |
; R30           |                    |                 |
; R31           |                    |                 |
; R32           |                    |                 |
; R33           |                    |                 |
; R34           |                    |                 |
; R35           |                    |                 |


.include "tn25def.inc"		;Include bibliotheque


;=========================================================================   Interrupt Watchdog- Vector Table - DEBUT  ==========================================================================================================================


		.cseg
		.org	$0000		;External Pin, Power-on Reset, Brown-out Reset, Watchdog system Reset
RESET:	nop
		rjmp	START

		.org	$000D		;WDT Timeout interrupt vector
		reti

		.org	$0010		;application space	

;=========================================================================  Interrupt Watchdog- Vector Table - FIN  ==========================================================================================================================

;=========================================================================  Port Parameter +Value  - DEBUT  ==========================================================================================================================

START:	;init PORTB
		sbi DDRB,PB0							;PB/0 OUT. all others port IN (charge pump entree)
		sbi DDRB,PB1							;PB/1 OUT. all others port IN (Half bridge)
		sbi DDRB,PB2							;PB/2 OUT. all others port IN (Half bridge)
		sbi DDRB,PB3							;PB/3 OUT. all others port IN (charge pump sortie)
		sbi DDRB,PB4							;PB/4 OUT. all others port IN (Light)
		cbi DDRB,PB5							;PB/5 INPUT. 
		
		cbi portb,pb0							; OFF alimentation Charge pump	(verification)
		cbi portb,pb1							; OFF alimentation Charge pump	(verification)
		cbi portb,pb2							; OFF alimentation Charge pump	(verification)
		cbi portb,pb3							; OFF alimentation Charge pump	(verification)
		cbi portb,pb4							; OFF alimentation Charge pump	(verification)
		cbi portb,pb5							; set pulldown input

		ldi R17,0x32							; EEprom Adress Low
		ldi R24,0x04							; pulse lengh setting 
		ldi R26,0x02							; compteur signal court / long (si R26=0 alors long
		ldi R27,0x0a							; ( avant b) Valeur du nombre de relative JUMP dans R25 (19 hexa = 25 decimal)


	;==============================================================================================
	;                                       Start -  flash PB0 - 2 times 
	;==============================================================================================
	
	;loop count down (used as timer)
	sbi PORTB,PB4								; light ON PB4
		ldi R20,0x20
		Tempo_EEPROM_311:
				ldi R19,0xff
				Tempo_EEPROM_031:
				dec R19							; Dec value R -1 
			brne Tempo_EEPROM_031				; Compare Valu and loop till = 0		
		dec R20									; Dec value R -1  
	brne Tempo_EEPROM_311						; Compare Valu and loop till = 0  		
cbi PORTB,PB4									; light OFF PB4

;loop count down (used as timer)
ldi R20,0xff
		Tempo_EEPROM_3111:
				ldi R19,0xff
				Tempo_EEPROM_03111:
				dec R19							; Dec value R -1
			brne Tempo_EEPROM_03111				; Compare Valu and loop till = 0	
		dec R20									; Dec value R -1 
	brne Tempo_EEPROM_3111						; Compare Valu and loop till = 0  		
sbi PORTB,PB4									; light ON PB4

;loop count down (used as timer)
ldi R20,0x20
		Tempo_EEPROM_3113:
				ldi R19,0xff
				Tempo_EEPROM_03112:
				dec R19							; Dec value R -1 
			brne Tempo_EEPROM_03112				; Compare Valu and loop till = 0		
		dec R20									; Decrememnte 1 a R(egistre)20 a chaque passage 
	brne Tempo_EEPROM_3113						; Compare Valeur R(egristre)20 et boucle tant que pas egal a 0   		
cbi PORTB,PB4									; light OFF PB4



	;==============================================================================================
	;                                         Watch dog - setting 
	;==============================================================================================

		out SREG,R15									; load SREG


;init brown out detection desealble for sleep mode
		;ldi		r23, (1<<BODSE)						; En 2 fois 1- pour autoriser ecriture  (1<<BODSE)|(1<<BODS)	
		;out		MCUCR, r23							; envoyer autorisation ecriture 
		;ldi		r23, (1<<BODS)|(0<<BODSE)			; Ecrire valeur a envoyer dans R23 
		;out		MCUCR, r23							; Envoyer R23 dans MCUCR

		
;init WDT for interrupt mode
		ldi		r23, (1<<WDCE)|(1<<WDE)
		out		WDTCR, r23
		ldi		r23, (1<<WDIE)|(0<<WDE)|(0<<WDP0)|(1<<WDP1)|(0<<WDP2)|(0<<WDP3)	; sec time out WDT interrupt; no system reset
		out		WDTCR, r23
        sei												; global interrupt enable bit is active
	
L1_INTERIEUR:											;init sleep modes
		ldi		r23, (1<<SM1)							;Power-down mode
		out		MCUCR, r23
		in		r23, MCUCR
		ldi		r23, (1<<SE)							;sleep mode enabled
		out		MCUCR, r23								;put MCU into sleep

L1A_INTERIEUR:	
		in R15,SREG										;save Sreg
		wdr
		sleep											


L2_INTERIEUR:		;wakeup label; flash LED

	
	;==============================================================================================
	;                             Count down Watch Dog - 3 times + light each count down 
	;==============================================================================================

	ldi R27,0x06										; Set value count down 

Loop_watchdog_INTERIEUR:								; count down  6 = 0.64ms * 6 loops 
		dec R27											; Decrememnte 1 a R(egistre)27 a chaque passage 
		
		;loop count down (used as timer)
		sbi PORTB,PB4									; light ON PB4
		ldi R20,0x20
		Tempo_001:
				ldi R19,0xff
				Tempo_002:
				dec R19									; Dec value R -1
			brne Tempo_002								; Compare Valu and loop till = 0 		
		dec R20											; Dec value R -1 
		brne Tempo_001									; Compare Valu and loop till = 0  		
		cbi PORTB,PB4									; light OFF PB4
		
		brne L1A_INTERIEUR			; Compare Valeur R(egristre)27 et boucle tant que pas egal a 0	
		ldi R27,0x0b		; Valeur du nombre de relative JUMP dans R27 (longeur watchdog)


	;==============================================================================================
	;                             Wake up Watch dog - 3 times
	;==============================================================================================


		;loop count down (used as timer)
		sbi PORTB,PB4							; light ON PB4
		ldi R20,0x20
		Tempo_out_001:
				ldi R19,0xff
				Tempo_out_002:
				dec R19							; Dec value R -1
			brne Tempo_out_002					; Compare Valu and loop till = 0 		
		dec R20									; Dec value R -1
		brne Tempo_out_001						; Compare Valu and loop till = 0   		
		cbi PORTB,PB4							; light OFF PB4

		;loop count down (used as timer)
		ldi R20,0xff
		Tempo_out_0011:
				ldi R19,0xff
				Tempo_out_00211:
				dec R19							; Dec value R -1
			brne Tempo_out_00211				; Compare Valu and loop till = 0 		
		dec R20									; Dec value R -1
		brne Tempo_out_0011						; Compare Valu and loop till = 0   		
		sbi PORTB,PB4							; light OFF PB4

		;loop count down (used as timer)
		ldi R20,0x20
		Tempo_out_0013:
				ldi R19,0xff
				Tempo_out_00212:
				dec R19							; Dec value R -1 
			brne Tempo_out_00212				; Compare Valu and loop till = 0 		
		dec R20									; Dec value R -1 
		brne Tempo_out_0013						; Compare Valu and loop till = 0   		
	cbi PORTB,PB4								; light OFF PB4

	;loop count down (used as timer)
	ldi R20,0xff
		Tempo_out_00213:
				ldi R19,0xff
				Tempo_out_00214:
				dec R19							; Dec value R -1 
			brne Tempo_out_00214				; Compare Valu and loop till = 0 		
		dec R20									; Dec value R -1
		brne Tempo_out_00213					; Compare Valu and loop till = 0    		
		sbi PORTB,PB4							; light OFF PB4

	;loop count down (used as timer)
	ldi R20,0x20
		Tempo_out_00314:
				ldi R19,0xff
				Tempo_out_00315:
				dec R19							; Dec value R -1 
			brne Tempo_out_00315				; Compare Valu and loop till = 0 		
		dec R20									; Dec value R -1
	brne Tempo_out_00314						; Compare Valu and loop till = 0    		
	cbi PORTB,PB4								; light OFF PB4


rjmp L1A_INTERIEUR					; jumpG

As you can see the BODS instruction are set as comment that i could test the program

;init brown out detection desealble for sleep mode
		;ldi		r23, (1<<BODSE)						; En 2 fois 1- pour autoriser ecriture  (1<<BODSE)|(1<<BODS)	
		;out		MCUCR, r23							; envoyer autorisation ecriture 
		;ldi		r23, (1<<BODS)|(0<<BODSE)			; Ecrire valeur a envoyer dans R23 
		;out		MCUCR, r23							; Envoyer R23 dans MCUCR

to answer your question : the target of setting the DOBS is to save maximum energy during watchdog.
I need the BOD to be sure that the Attiny is starting properly in case of low battery (during recharge phase)

One function i would like to ass is a blinking led when the power is reaching 3.6V ( but i guess this is another story !

please let me know if missed something ..

Thank you very much for the ASM program. I am optimistic that some meaningful result will comeout as I have the full development setup for AVR ASM and AVR C++ Platform for ATtiny25/45/85 architecture.

Please read the following excerpt taken from data sheets and judge why the symbolic names BODS and BOSE are not recognized by the Assembler.

I have check that and my tiny25 is a H version


So BDO disable functionality should be implemented on my chip at least ..

I am not sure. Forum members (@westfw) may speak in this regards.