|
|
- #include <xc.h>
- #include <avr/io.h>
-
- //this req'd for (and before calling) delay
- //see delay.h
- //compiler optimizations must also be enabled
- #define F_CPU 8000000
- #include <util/delay.h>
-
- #include <avr/interrupt.h>
- //#include <avr/sleep.h>
- //#include <util/atomic.h>
- //#include <avr/wdt.h>
-
-
-
-
-
- //tests5 tested and works (at ~950hz). unplug cable to programmer to see pin 4 active.
- //however...
- //tests6 DEADEND
- //never worked right. giving up and using delay.
-
- //reference: https://www.avrfreaks.net/forum/sample-project-attiny10
- //https://blog.podkalicki.com/attiny13-blinky-with-timer-compa/
- //watchdog is too slow and inaccurate to get 6000Hz
-
- //ISR(TIM0_COMPA_vect)
- //{
- // // Toggle PB2 Hi/Low depending on current state
- // PINB = 1<<2;
- // TIFR0 |= 1<<OCF0A; //clear flag (is this required here? documentation unclear)
- // //PORTB ^= _BV(LED_PIN); // toggle LED pin
- //}
-
-
- /*
- Delay in powerdown mode. Wake up by watchdog interrupt.
- * //NOTE: see earlier code, e.g. tests3 in attiny10 elec projects 2020
- */
- /*
- void delay_power_down_wdt(uint8_t wdto)
- {
- wdt_reset();
- wdt_enable(wdto);
- WDTCSR |= (1<<WDIE);
- //so far (with 128Khz clk) this sleep will be about 30-40 seconds.
-
- //(however, I'll add the below to)
- //adjust sleep speed here:
-
- // 0110 is 1hz at 128KHz
- //WDTCSR |= (0<< WDP3);
- //WDTCSR |= (1<< WDP2);
- //WDTCSR |= (1<< WDP1);
- //WDTCSR |= (0<< WDP0);
-
- set_sleep_mode(SLEEP_MODE_PWR_DOWN);
- sleep_enable();
- // Make sure interrups are enabled and the I flag is restored
- NONATOMIC_BLOCK(NONATOMIC_RESTORESTATE)
- {
- sleep_cpu();
- wdt_disable();
- }
- sleep_disable();
- }
- */
-
- int main(void)
- {
-
- //// //Write CCP (to enable changing clock)
- CCP = 0xD8;
- //// //change CLK to 128KHz
- // CLKMSR = 0b01;
- //change clk to 8mhz
- CLKMSR = 0b00;
-
- //clock prescaler from divide by 8 (defualt) to none
-
- //CLKPS0 = 0x0;
- //CLKPS1 = 0x0;
- //Just omit the bits that are reserved, see also clkmsr which is 2 bit active
- // 8 bit inactive
- CLKPSR = 0b0000;
-
- //notes: test results (osccal is 8 bit)
- // osccal | hz output
- // 0xe6 10khz
- // 0x06 3.58khz
- // 0x0F 3.83Khz
- // 0x2F 4.62Khz
- // 0x5F 5.84Khz
- // 0x65 6.003KHz -winrar (for this chip))
- // 0x8F 7.27Khz
- OSCCAL = 0x65;
-
- //////// OCR0A = 0;
- //////// TCNT0 = 0;
- //////// TCCR0A = 0;
- //////// TCCR0B = 0;
- ////////
- //////// TCCR0A |= _BV(WGM01); // set timer counter mode to CTC
- //////// // TCCR0B |= _BV(CS02)|_BV(CS00); // set prescaler to 1024 (CLK=1200000Hz/1024/256=4.57Hz, 0.22s)
- //////// TCCR0B |= _BV(CS00); // set prescaler to 1 (CLK=1MHz/1)
- //OCR0A is 16 bits. in ASM it must be loaded separately.
- //in C, it can be loaded > 256? (test)
-
- //520 about 950hz, 25us wide pulse
- //OCR0A = 520; // with one timer, ever 166.667hz we want to count once (3000hz)
-
- //OCR0A = 1; //475hz
-
- //this goes to 475hz (pulses). doesn't make sense.
- //// OCR0AH = 0xFF; //
- //// OCR0AL = 0xFF;
-
- //attiny10 output compare broken apparently
- //this still 960hz, with 100us or so pulse size (high is 100us, low is longer)
- //OCR0A = 100;
-
-
- //inline asm to load values into 16 bit register
-
- //; variables
- //; For 1 Hz output, the timer delay has to be 1/2 second (1/2 second on / 1/2 second off)
- //; delay = OCR0A * 1024 * 8 / 8000000
- //; for 1/2 second, OCR0A = 488 (0x01E8)
- //.EQU OCR0AHigh = 0x01
- //.EQU OCR0ALow = 0xe8
- // in bash type: printf "%x\n" 488
- //.EQU OCR0AHigh = 0x02
- //.EQU OCR0ALow = 0x08
-
- // ldi r17, OCR0AHigh //; Sets the output compare register value
- //ldi r16, OCR0ALow
-
- //this asm doesn't work (why?) //perhaps OCR0A is really just 8 bits on attiny10...?)
- ////// asm volatile(
- ////// "ldi r17, 0x02"
- ////// "ldi r16, 0x08"
- ////// "out OCR0AH, r17"
- ////// "out OCR0AL, r16"
- ////// );
-
- //this asm works
- // asm volatile("nop\n\t"
- //"nop\n\t"
- //"nop\n\t"
- //"nop\n\t"
- //::);
- ////////
- //////// TIMSK0 |= _BV(OCIE0A); // enable Timer CTC interrupt
- ////////
- // PB2 change to output
- DDRB = 1<<2;
- //// sei();
-
-
- int x = 0;
- while(1)
- {
-
- //this goes about 60.3KHz.
- //experiment FAIL
- //will just buy a 6KHz oscillator.
-
- PINB = 1<<2;
- //EDIT: disabled optimization in mplab (level 0)
- //and ended up geting much slower IO
- //asm("nop;");
- //for(x=0;x<10;x++){
-
- //note it's _delay_us not delay_us
-
- //delay_us(1) is 44.3KHz
- //_delay_us(8); //9 is 6.4KHz, 8 is roughly 7.2KHz
- //delay_us(10) is 5.8KHz
- //not much granularity there...)
- //so adding the following...
- if( x == 3){
- _delay_us(4);//these two are 5.98 or so KHz
- x = 0;
- goto jump;
- }
-
- //NOTE: the above ends up causing an ugly looking clock. may not matter
- //for fpga clocking off of rising edge, BUT, it is ugly, should remove,
- //and just do single delay. Will do in part 9.
-
- x++;
- jump:
- //in combination with the jump, gives closer to 6KHz
- _delay_us(8);
-
-
-
- ///below didn't work out, so using osccal
- //bit convuluted anyways
- /*if( x == 4){
- _delay_us(1);
- //x = 0;
- goto jump;
- }
- if( x == 8){
- _delay_us(2);
- x = 0;
- goto jump;
- }
- x++;
- jump:
- //in combination with the jump, gives closer to 6KHz
- _delay_us(8);*/
-
-
- //the above idles at 5.98 - 5.99KHz.
- //best so far.
- //Now, calibrate oscillator with OSCCAL
-
- //if more accuracy desired.
- //or adjust if clause above
-
- //tried to make my own delay in ASM, BUT
- //compiler keeps optimizing it out (even w/out optimization enabled)
- //... some other flag may be culprit. So instead will use delay_us. Two delay
- //functions are delay_ms and delay_us. see headers at top and delay.h)
- /* __asm__("mov r16, r17;"
- "mov r17, r16;"
- "inc r16;"
- "dec r16;"
- "mov r16, r17;"
- "mov r17, r16;"
- "inc r16;"
- "dec r16;"
- "clr r16;"
- "clr r17;"
- "clr r18;"
- "clr r19;"
- "clr r20;"
- "clr r21;"
- "clr r22;"
- "clr r23;"
- "mov r16, r17;"
- "mov r17, r16;"
- "inc r16;"
- "dec r16;"
- "mov r16, r17;"
- "mov r17, r16;"
- "clr r16;"
- "clr r17;"
- "clr r18;"
- "clr r19;"
- "clr r20;"
- "clr r21;"
- "clr r22;"
- "clr r23;"
- "mov r16, r17;"
- "mov r17, r16;"
- "inc r16;"
- "dec r16;"
- "mov r16, r17;"
- "mov r17, r16;"
-
-
- );*/
-
-
-
- //mplab delay is:
- /** \ingroup util_delay_basic
-
- Delay loop using an 8-bit counter \c __count, so up to 256
- iterations are possible. (The value 256 would have to be passed
- as 0.) The loop executes three CPU cycles per iteration, not
- including the overhead the compiler needs to setup the counter
- register.
-
- Thus, at a CPU speed of 1 MHz, delays of up to 768 microseconds
- can be achieved.
- */
- //////////void
- //////////_delay_loop_1(uint8_t __count)
- //////////{
- ////////// __asm__ volatile (
- ////////// "1: dec %0" "\n\t"
- ////////// "brne 1b"
- ////////// : "=r" (__count)
- ////////// : "0" (__count)
- ////////// );
- //////////}
- //////////
- //////////
- //ignore below
- // asm("nop;""nop;""nop;""nop;""nop;"
- //"nop;""nop;"//"nop;""nop;"//"nop;""nop;"
- //);
- //}//just this asm block is about 121.22KHz
-
- }
- }
-
|