Main.C of Mischief Maker 2.0

/*
TV-B-Gone Firmware version 1.2
for use with ATtiny85v and v1.2 hardware
(c) Mitch Altman + Limor Fried 2009
edits, August 16 2009

With some code from:
Kevin Timmerman & Damien Good 7-Dec-07
Monty Goodson 2010

Catherine Poole 2011

Distributed under Creative Commons 2.5 — Attib & Share Alike

/*

#include <avr/io.h>
#include <avr/eeprom.h>
#include <avr/sleep.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include “main.h”
#include “util.h”

extern const PGM_P *NApowerCodes[] PROGMEM;
extern const PGM_P *EUpowerCodes[] PROGMEM;
extern const uint8_t num_NAcodes, num_EUcodes;

void xmitCodeElement(uint16_t ontime, uint16_t offtime, uint8_t PWM_code )
{

TCNT0 = 0;
TIFR = 0;

if(PWM_code) {

// Usually the carrier is around 38KHz, and we generate that with PWM

TCCR0A = _BV(COM0A0) | _BV(WGM01);

TCCR0B = _BV(CS00);
} else {
PORTB |= _BV(IRLED);
}
delay_ten_us(ontime);

TCCR0A = 0;
TCCR0B = 0;

PORTB &= ~_BV(IRLED);

delay_ten_us(offtime);
}

uint8_t bitsleft_r = 0;
uint8_t bits_r=0;
PGM_P code_ptr;

// limit is 8 bits at a time
uint8_t read_bits(uint8_t count)
{
uint8_t i;
uint8_t tmp=0;

for (i=0; i<count; i++) {

if (bitsleft_r == 0) {

bits_r = pgm_read_byte(code_ptr++);

bitsleft_r = 8;
}

bitsleft_r–;

tmp |= (((bits_r >> (bitsleft_r)) & 1) << (count-1-i));
}

return tmp;
}

int main(void) {
uint16_t ontime, offtime;
uint8_t i,j, Loop;
uint8_t region = US;     // by default our code is US

Loop = 0;

TCCR1 = 0;
TCCR0A = 0;
TCCR0B = 0;

i = MCUSR;
MCUSR = 0;
WDTCR = _BV(WDCE) | _BV(WDE);

WDTCR = 0;

DDRB = _BV(LED) | _BV(IRLED);
PORTB = _BV(LED)

& ~_BV(IRLED)
| _BV(REGIONSWITCH);

DEBUGP(putstring_nl(“Hello!”));

/* MVG: For some reason, Brown-out flag is set… skip for now

if (i & _BV(BORF)) {    // Brownout

flashslowLEDx(2);
tvbgone_sleep();
}

delay_ten_us(5000);

// determine region

// MVG: Force to US region for now
//  if (PINB & _BV(REGIONSWITCH)) {
region = US; // US
DEBUGP(putstring_nl(“US”));

// Tell the user what region we’re in  – 3 is US 4 is EU
quickflashLEDx(3+region);

delay_ten_us(25000);

wdt_enable(WDTO_8S); // 1 second long timeout

DEBUGP(putstring(“\n\rNA Codesize: “); putnum_ud(num_NAcodes););
DEBUGP(putstring(“\n\rEU Codesize: “); putnum_ud(num_EUcodes););

do {
if (region == US) {
j = num_NAcodes;
} else {
j = num_EUcodes;
}

for(i=0 ; i < j; i++) {

DEBUGP(putstring(“\n\r\n\rCode #: “); putnum_ud(i));

wdt_reset();

if (region == US) {
code_ptr = (PGM_P)pgm_read_word(NApowerCodes+i);
} else {
code_ptr = (PGM_P)pgm_read_word(EUpowerCodes+i);
}
DEBUGP(putstring(“\n\rAddr: “); putnum_uh(code_ptr));

const uint8_t freq = pgm_read_byte(code_ptr++);

OCR0A = freq;

DEBUGP(putstring(“\n\rOCR1: “); putnum_ud(freq););
DEBUGP(uint16_t x = (freq+1) * 2; putstring(“\n\rFreq: “); putnum_ud(F_CPU/x););

const uint8_t numpairs = pgm_read_byte(code_ptr++);
DEBUGP(putstring(“\n\rOn/off pairs: “); putnum_ud(numpairs));

const uint8_t bitcompression = pgm_read_byte(code_ptr++);
DEBUGP(putstring(“\n\rCompression: “); putnum_ud(bitcompression));

const PGM_P time_ptr = (PGM_P)pgm_read_word(code_ptr);
code_ptr+=2;

for (uint8_t k=0; k<numpairs; k++) {
uint8_t ti;
ti = (read_bits(bitcompression)) * 4;

ontime = pgm_read_word(time_ptr+ti);
offtime = pgm_read_word(time_ptr+ti+2);
DEBUGP(putstring(“\n\rti = “); putnum_ud(ti>>2); putstring(“\tPair = “); putnum_ud(ontime));
DEBUGP(putstring(“\t”); putnum_ud(offtime));
}

for (uint8_t k=0; k<numpairs; k++) {
uint8_t ti;

ti = (read_bits(bitcompression)) * 4;

ontime = pgm_read_word(time_ptr+ti);
offtime = pgm_read_word(time_ptr+ti+2);  // read word 2 – offtime

xmitCodeElement(ontime, offtime, (freq!=0));
}

bitsleft_r=0;

delay_ten_us(25000);

quickflashLED();
}
} while (Loop == 1);

wdt_disable();

delay_ten_us(65500);
delay_ten_us(65500);
quickflashLEDx(4);

tvbgone_sleep();
}

/****************************** SLEEP FUNCTIONS ********/

void tvbgone_sleep( void )
{

TCCR0A = 0;
TCCR0B = 0;

PORTB &= ~(_BV(LED) |
_BV(IRLED));

wdt_disable();
delay_ten_us(1000);

MCUCR = _BV(SM1) |  _BV(SE);
sleep_cpu();
}

/****************************** LED AND DELAY FUNCTIONS ********/
void delay_ten_us(uint16_t us) {
uint8_t timer;
while (us != 0) {

for (timer=0; timer <= DELAY_CNT; timer++) {
NOP;
NOP;
}
NOP;
us–;
}
}

void quickflashLED( void ) {
//  PORTB &= ~_BV(LED);
PORTB |= _BV(LED);
delay_ten_us(3000);
//  PORTB |= _BV(LED);
PORTB &= ~_BV(LED);
}

void quickflashLEDx( uint8_t x ) {
quickflashLED();
while(–x) {
wdt_reset();
delay_ten_us(15000);
quickflashLED();
}
wdt_reset();
}

void flashslowLEDx( uint8_t num_blinks )
{
uint8_t i;
for(i=0;i<num_blinks;i++)
{

PORTB |= _BV(LED);
delay_ten_us(50000);
wdt_reset();
PORTB &= ~_BV(LED);
delay_ten_us(50000);
wdt_reset();
}
}

Advertisements

One thought on “Main.C of Mischief Maker 2.0

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s