main.c File Reference

Patashnik. More...

#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
#include "usrat.h"
#include "rtc.h"
#include "util.h"
#include "voltage.h"
#include "buttonry.h"
Include dependency graph for main.c:

Defines

#define FADETIME   512
#define BLINKTIME   2048
#define BLINKBIT   10

Functions

void set_blinkmode (uint8_t mode)
 Set blinkmode.
void initdisplay ()
 Init display-related DDRs.
void showtime (uint8_t h1, uint8_t h2, uint8_t m1, uint8_t m2)
 Rehash bits to match the schematic.
void showtime_bcd (uint16_t time)
 Immediately display BCD value on nixies.
void duty_set (uint8_t d)
 Sets tubes duty cycle. Valid values are 1..4.
uint8_t duty_get ()
void fadeto (uint16_t t)
uint16_t get_display_value ()
void timer0_init ()
 Start timer 0. Timer0 runs at 1MHz and overflows at 3906 Hz.
 ISR (TIMER0_OVF_vect)
void update_daylight (uint16_t time)
int main ()
 Program main.

Variables

volatile uint16_t time = 0
 current display value
volatile uint16_t timef = 0
 fadeto display value
volatile uint8_t dispctr = 0
 counts 0..15
volatile uint8_t on_duty = 1
 values 1..4, gets multiplied by 4
volatile uint8_t blinktick = 0
volatile uint8_t blinkmode
 current blinking mode
volatile uint16_t blinkctr
 blinkmode counter
volatile uint8_t blinkduty
 blinkmode duty
volatile uint8_t fadeduty
volatile uint8_t fadectr
 crossfade counters
volatile int16_t fadetime
 crossfade time and trigger, write "-1" to start fade to timef

Detailed Description

Patashnik.

Author:
Viacheslav Slavinsky

Define Documentation

#define BLINKBIT   10
#define BLINKTIME   2048
#define FADETIME   512

Function Documentation

uint8_t duty_get (  )  [inline]

00083 { return on_duty; }

void duty_set ( uint8_t  d  ) 

Sets tubes duty cycle. Valid values are 1..4.

00078                          {
00079     on_duty = d;
00080     voltage_adjust(0);
00081 }

Here is the call graph for this function:

void fadeto ( uint16_t  t  ) 

Start fading time to given value. Transition is performed in TIMER0_OVF_vect and takes FADETIME cycles.

00087                         { 
00088     timef = t; fadetime = -1;
00089     voltage_adjust(0);
00090 }

Here is the call graph for this function:

uint16_t get_display_value (  )  [inline]

00092                                     {
00093     return timef;
00094 }

void initdisplay (  ) 

Init display-related DDRs.

00056                    {
00057     DDRA |= 017;    // A, digit#4
00058     DDRC = 0377;
00059     DDRB |= 037;    // DOT and 4 lsb
00060 }

ISR ( TIMER0_OVF_vect   ) 

00103                      {
00104     uint16_t toDisplay = time;
00105     static uint8_t effDuty;
00106     
00107     voltage_adjust_tick();
00108     
00109     if (blinkmode != BLINK_NONE) {
00110         blinkctr = (blinkctr + 1) % BLINKTIME;
00111         if (blinkctr & _BV(BLINKBIT)) {
00112             if (effDuty != blinkduty) {
00113                 blinktick = 1;
00114             }
00115             effDuty = blinkduty;
00116         } else {
00117             effDuty = on_duty;
00118         }
00119     } 
00120     
00121     if (fadetime == -1) {
00122         // start teh fade
00123         fadetime = FADETIME;
00124         fadeduty = 4;
00125         fadectr = 0;
00126     }
00127     
00128     if (fadetime != 0) {
00129         fadetime--;
00130 
00131         if (fadetime % (FADETIME/4) == 0) {
00132             fadeduty--;
00133         }
00134         
00135         if (fadetime == 0) {
00136             fadectr = 0;
00137             time = timef; // end fade
00138         }
00139     } 
00140     
00141 
00142     if (fadectr < fadeduty) {
00143         toDisplay = time;
00144     } 
00145     else {
00146         toDisplay = timef;
00147     }
00148     fadectr = (fadectr + 1) & 3;
00149 
00150 
00151     if (dispctr < on_duty<<2) {
00152         switch (blinkmode) {
00153             case BLINK_HH:
00154                 if (dispctr >= (effDuty<<2)) toDisplay |= 0xff00;
00155                 break;
00156             case BLINK_MM:
00157                 if (dispctr >= (effDuty<<2)) toDisplay |= 0x00ff;
00158                 break;
00159             case BLINK_ALL:
00160                 if (dispctr >= (effDuty<<2)) toDisplay |= 0xffff;
00161                 break;
00162             default:
00163                 break;
00164         }
00165         
00166         if (on_duty > 2 && dispctr < 4) {
00167             // compensation: burn 2nd, 3rd digits 1/4th shorter in bright modes
00168             toDisplay |= 0x0ff0;
00169         }
00170     } else {
00171         if (on_duty < 3 && (dispctr < (on_duty+1)<<2) && ((toDisplay & 0x00f0) == 0x20) && blinkmode == BLINK_NONE) {
00172             // compensation: burn xx2x 1/4th longer
00173             toDisplay |= 0xff0f;
00174         } else {
00175             toDisplay |= 0xffff;
00176         }
00177     }
00178     
00179     showtime_bcd(toDisplay);
00180     
00181     dispctr = (dispctr + 1) & 017;
00182 }

Here is the call graph for this function:

int main (  ) 

Program main.

00231            {
00232     uint8_t i;
00233     uint16_t rtime;
00234     uint8_t byte;
00235     volatile uint16_t skip = 0;
00236     uint8_t uart_enabled = 0;
00237     
00238     pump_nomoar();
00239     
00240     usart_init(F_CPU/16/19200-1);
00241     
00242     printf_P(PSTR("\033[2J\033[HB%s WILL I DREAM? %02x\n"), BUILDNUM, MCUCSR);
00243 
00244     sei();
00245 
00246     pump_init();
00247     
00248     adc_init();
00249     
00250     
00251     initdisplay();
00252     
00253     duty_set(1);
00254 
00255     rtc_init();
00256     
00257     buttons_init();
00258  
00259     time = 0xffff;   
00260     timef = 0x1838;
00261     fadetime = -1;
00262     
00263     timer0_init();
00264 
00265     _delay_ms(1000);
00266 
00267     timef = 0xffff;
00268     fadetime = -1;
00269     _delay_ms(750);  
00270     
00271     wdt_enable(WDTO_250MS);
00272     
00273     for(i = 0;;) {
00274         wdt_reset();
00275         
00276         // handle keyboard commands
00277         if (uart_available()) {
00278             byte = uart_getchar();
00279             switch (uart_enabled) {
00280                 case 0: if (byte == 'z') 
00281                             uart_enabled = 1;
00282                         else
00283                             uart_enabled = 0;
00284                         break;
00285                 case 1: if (byte == 'c') 
00286                             uart_enabled = 2;
00287                         else
00288                             uart_enabled = 0;
00289                         break;
00290                 case 2:
00291                         switch (byte) { 
00292                         case '`':   pump_nomoar();
00293                                      break;
00294                         case 'r':   rtc_dump();
00295                                     break;
00296                         case 't':   printf_P(PSTR("time=%04x\n"), time);
00297                                     break;
00298                         case 'd':   duty_set(on_duty % 4 + 1);
00299                                     break;
00300                         case 'b':   blinkmode = (blinkmode + 1) % 4;
00301                                     blinkduty = 0;
00302                                     blinkctr = BLINKTIME;
00303                                     break;
00304                         case '.':   break;
00305                         case '=':   // die
00306                                     for(;;);
00307                                     break;
00308                         default:
00309                                     break;
00310                         }
00311             
00312                         if (byte >= '0' && byte <= '9') {
00313                             byte = byte - '0';
00314                             fadeto((byte<<12)+(byte<<8)+(byte<<4)+byte);
00315                             skip = 255;
00316                         }
00317                         
00318                         printf_P(PSTR("OCR1A=%d ICR1=%d S=%d V=%d\n"), OCR1A, ICR1, voltage_setpoint, voltage);
00319                         break;
00320             }
00321             
00322         }
00323         
00324         if (skip != 0) {
00325             skip--;
00326         } else {
00327             rtime = rtc_gettime();//voltage;
00328             update_daylight(rtime);
00329             if (!is_setting() && rtime != time && rtime != timef) {
00330                 fadeto(rtime);
00331             }            
00332         }
00333 
00334         buttonry_tick(PIND & _BV(3), PIND & _BV(4));
00335     
00336         if (blinktick) {        
00337             blinktick = 0;
00338             if (blinkhandler != NULL) {
00339                 blinkhandler(1);
00340             }
00341         }
00342         
00343         _delay_ms(50);
00344     }
00345 }

Here is the call graph for this function:

void set_blinkmode ( uint8_t  mode  )  [inline]

Set blinkmode.

00051                                         {
00052     blinkmode = mode;
00053 }

void showtime ( uint8_t  h1,
uint8_t  h2,
uint8_t  m1,
uint8_t  m2 
) [inline]

Rehash bits to match the schematic.

00063                                                                      {
00064     PORTA = (PORTA & ~017) | ((m2&4)<<1) | ((m2&8)>>2) | (m2&1) | ((m2&2)<<1);
00065     
00066     PORTB = (PORTB & ~017) | ((m1&1)<<3) | (m1&2) | ((m1&4)>>2) | ((m1&8)>>1);
00067     
00068     PORTC =  ((h2&1)<<3) | (h2&2) | ((h2&4)>>2) | ((h2&8)>>1) |
00069             ((((h1&1)<<3)| (h1&2) | ((h1&4)>>2) | ((h1&8)>>1)) << 4);
00070 }

void showtime_bcd ( uint16_t  time  ) 

Immediately display BCD value on nixies.

00073                                  {
00074     showtime((time & 0xf000)>>12, (time & 0x0f00)>>8, (time & 0x00f0)>>4, time & 0x000f);
00075 }

Here is the call graph for this function:

void timer0_init (  ) 

Start timer 0. Timer0 runs at 1MHz and overflows at 3906 Hz.

00097                    {
00098     TIMSK |= _BV(TOIE0);    // enable Timer0 overflow interrupt
00099     TCCR0 = _BV(CS01);      // clk/8 -> 1mhz, overflow rate 3906hz
00100 }

void update_daylight ( uint16_t  time  ) 

Update DST: 02:00->03:00 on the last sunday of March 03:00->02:00 on the last sunday of October

And try to do this only once.

00190                                     {
00191     static uint8_t daylight_adjusted = 0;
00192 
00193     if (time == 0x0000) daylight_adjusted = 0;
00194     
00195     if (daylight_adjusted) return;
00196     
00197     if (time == 0x0200 || time == 0x0300) {
00198         if (rtc_xdow(-1) == 0) {
00199             switch (rtc_xmonth(-1)) {
00200                 case 3:
00201                     if (rtc_xday(-1) > 0x24) {
00202                         // last sunday of march
00203                         if (time == 0x0200) {
00204                             rtc_xhour(3);
00205                             daylight_adjusted = 1;
00206                         }
00207                     } else {
00208                         daylight_adjusted = 1;
00209                     }
00210                     break;
00211                 case 10:
00212                     if (rtc_xday(-1) > 0x24) {
00213                         // last sunday of october
00214                         if (time == 0x0300) {
00215                             rtc_xhour(2);
00216                             daylight_adjusted = 1;
00217                         }
00218                     } else {
00219                         daylight_adjusted = 1;
00220                     }  
00221                     break;
00222                 default:
00223                     daylight_adjusted = 1; 
00224                     break;
00225             }
00226         }
00227     }
00228 }


Variable Documentation

volatile uint16_t blinkctr

blinkmode counter

volatile uint8_t blinkduty

blinkmode duty

volatile uint8_t blinkmode

current blinking mode

volatile uint8_t blinktick = 0
volatile uint8_t dispctr = 0

counts 0..15

volatile uint8_t fadectr

crossfade counters

volatile uint8_t fadeduty
volatile int16_t fadetime

crossfade time and trigger, write "-1" to start fade to timef

volatile uint8_t on_duty = 1

values 1..4, gets multiplied by 4

volatile uint16_t time = 0

current display value

volatile uint16_t timef = 0

fadeto display value


Generated on Sat Dec 12 00:45:14 2009 for Patashnik by  doxygen 1.6.1