I'm bare metal programming an ATtiny13A. So I'm making assembly, then the opcodes, then the intel hex. And for now running it in SimulIDE 1.1.0
I made a basic program that should setup the ADC to auto-trigger when the Timer/Counter gets Compare Match A. And I'm trying to put the system into IDLE mode right after starting the counter, and I'm setting the MCUCR reg for idle mode, including the enable bit. And then I'm giving the SLEEP command.
Except for maybe the ADC INT Flag, ADIF, I think the rest are setup right, and the Global int flag is set 1. It says in the datasheet, that you can clear ADIF, by setting 1. But looking in the ADCSRA reg in SimulIDE, it gets set to 0, even though my code was right. Maybe that's fine and not an issue.
So after the sleep command, I'm expecting the CPU to powerdown, but the ADC and T/C will keep running. Then the T/C should count up to MATCH the value in OCR0A. The T/C is set to Clear Timer on Compare. The output registers OC0A,B are set to toggle. I put nothing in any timer interrupt vector location, besides RJMP to main prgm.
The ADC is set to auto-trigger on Compare Match A, so I'm guessing it watches OC0A for a state change, and ADIF is set low, and ADIE is high for allowing the interrupt. I didn't see an explanation of how the T/C tells the ADC to trigger, or anything that says to set more interrupts. If I get it, the WGM and COM0x settings handle that.
So at the ADC INT vector, I put an RJMP to a routine, word 40 ATM (but the code in not working so never mind the exact end section). And I put a RETI at the end of it, expecting then the RETI would lead to the instruction after SLEEP.
Maybe I'm supposed to be doing PUSH/POP with the stack for those return instruction addresses ?
But I'm not sure the timer is running, I don't see the TCNT0 counter reg getting incremented, and the ADC never gets trigger as far as I can tell. It never gives any result. In the sim, the main osc is only set to ~1MHz, and only 1 instruction/sec.
But also for the SLEEP command, I get an error, saying it's not being fully implemented. The timer should count up ~83ms in real life, in the sim IDK, I have it slowed way down. But the PC goes to the next command, and carry's on. But I get the error
Warning: AVR SLEEP instruction not Fully implemented
Now for the sleep command, am I supposed to be storing in the stack, the location of the SLEEP ( or 1 after it) ? Or is that done automatically by the SLEEP command ? I don't see anything in the stack tho, I did set the top as 0x9F. Looking this up on the web, I just get the same old pages over and over, and usually only in C, not assembly. So IDK what PUSH or POP commands might be going on.
But the PC is jumping right to the next command after sleep, I had a NOP there, then I tried loading the code for disabling sleep-enable. And whatever the T/C is really doing, the ADC never seems to do anything. I've never seen the PC go to the ADC INT vector at 0x09, or to the little routine a few steps ahead of SLEEP. I had RJMP before it too, so it really never got there.
The end code and some rmps and branch aren't finished since it's not working. But all I was trying to do, is read a sine-wave with the ADC, and if the count was under 256, ADCH would be 0, and then I would do a CPI, and Branch IF Carry flag Set, and light up an LED. Otherwise, it would jump back to enabling sleep modes, reset the counter and SLEEP again, and count up and read the ADC again.
Here's a look at the main I/O reg's on PC36, so the NOP right before the sleep command. I added some of them so it would be easy to change the final intelhex in the spreadsheet. Besides ADIF in the ADCSRA set to 0, so it's 0xAB, not 0xBB, everything is as I set as I think it should be. I also had LED's on OC0A/B. They toggle some, but something wrong, certainly with the ADC not triggering, and the SLEEP.
The SLEEP on PC37, definitely takes longer, but then it just goes up to W39 and RJMP's to W34 and loops forever.
0 RJMP 9 1 RJMP 8 2 RJMP 7 3 RJMP 6 4 RJMP 5 5 RJMP 4 6 RJMP 3 7 RJMP 2 8 RJMP 1 9 RJMP 30 ;ADC interrupt leads to W40 10 EOR R0,R0 11 LDI R16,64 ; loads 0100 0000 for ADMUX 12 OUT 7,R16 ;sets ADMUX use 1V1ref and PB5=ADC0 13 LDI R17,187 :loads 1011 1011 for ADCSRA 14 OUT 6,R17 ;enables ADC, ADCinterrupts, /8 prescaler 15 LDI R18,3 ;loads 0000 0011 for ADCSRB 16 OUT 3,R18 ;sets ADC to trigger on T/C CompareMatchA 17 LDI R19,63 ;loads 0011 1111 for DIDR0 18 OUT 20,R19 ;disables DigitalData buffers for all 6 ports 19 LDI R20,129 ;loads 1000 0001 for GTCCR 20 OUT 40,R20 ;holds the T/C in reset while setting up 21 LDI R21,82 ;loads 0101 0010 for TCCR0A 22 OUT 47,R21 ;set OC0x to toogle on CompareMatch, WGM to ClearTimer on CompareMatch 23 LDI R22,5 ;loads 0000 0101 for TCCR0B 24 OUT 51,R22 ;does not Force CompareMatch, also sets a bit of WGM 25 LDI R23,100 ;loads 100d for OCR0A 26 OUT 54,R23 ;uses to compare with TCNT0 count 27 LDI R24,11 ;loads 0000 1011 for DDRB 28 OUT 23,R24 ;sets PB0,1,2 as outputs 29 OUT 63,R0 ;Clears SREG 30 SEI ;enable Global Interrupts 31 LDI R25,159 ;load 0x9F for SPL 32 OUT 61,R25 ;sets SPL to top of SRAM 33 LDI R26,32 ;loads 00010 0000 for MCUCR 34 OUT 53,R26 ;chooses IDLE sleep and enables SleepMode 35 OUT 40,R0 ;clears GTCCR so the T/C should start running 36 RJMP 0 37 SLEEP 38 OUT 53,R0 ;disables SleepMode 39 RJMP -6 40 OUT 53,R0 ;disables SleepMode 41 IN 4,30 ;loads ADCH 42 IN 5,31 ;loads ADCL 43 CPI R31,1 ;ADCH-1 might set CarryFlag 44 BRCS 2 ;rjmp +2 if Cflag set , ADC count <256 45 RETI 46 NOP 47 SBI 24,3 48 NOP 49 OUT 40,R20
|