You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

302 lines
8.5 KiB

#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
}
}