Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ZakKemble committed Jun 28, 2014
0 parents commit cdf0903
Show file tree
Hide file tree
Showing 188 changed files with 17,481 additions and 0 deletions.
22 changes: 22 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto

# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union

# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
2 changes: 2 additions & 0 deletions Changelog.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
2013-09-25:
- Initial release
674 changes: 674 additions & 0 deletions License.txt

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions Readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
DIY Digital Wristwatch
http://blog.zakkemble.co.uk/diy-digital-wristwatch/

The firmware .hex and .eep files are compiled for ATmega328P

Fuses for ATmega328/328P
Internal RC 8MHz 6 CK/14CK + 4.1ms startup
Serial program (SPI) enabled
Brown-out at 1.8V
High: 0xDF
Low: 0xD2
Extended: 0xFE

./utils/bitmapConverter.exe
Utility to convert images (in ./imgs/) to pixel byte array

Font used for the large numbers on the main time display is AgencyFB Bold Wide available at http://www.fontsner.com/font/AgencyFBBoldWide-37966.html
My productions are published under GNU GPL v3 (see License.txt).

--------

Zak Kemble
[email protected]
27 changes: 27 additions & 0 deletions TODO.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
This is the software todo list. A different microcontroller with more program space is needed first.

Tidy up code (mostly menu stuff)
Alarm snooze
Options for alarm snooze
Improve alarms menu
- Use new WE/TU icon things
- Enabled icon (tick symbol)
Improve games menu
Options for setting what up and down buttons do when on the main watch display (open stopwatch/alarms/games etc)
Make menu option name animated, move off then back on or something
sleep mode options
- Off
- Low power (dim screen)
Instead of loading all alarms from EEPROM to RAM at startup, just load from EEPROM as needed
Reduce CPU clock if animations are disabled (and at other times too?)
Update the display less often (saves power)
- Only draw when needed
- Seperate logic and drawing
Sometimes the sounder 'pops' due to bad waveform output
Sometimes the watch turns on the display when its not supposed to (system alarm - hour beeps)
Options for LEDs (brightness etc)
Fancy USB plugged in screen anim?
Option for 12 hour time
Delay battery voltage measurement when waking up
Countdown timer
More games?
20 changes: 20 additions & 0 deletions firmware/src/watch.atsln
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Atmel Studio Solution File, Format Version 11.00
Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "watch", "watch\watch.cproj", "{6CE6CA08-5C90-4783-85FD-87623F6DABB4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|AVR = Debug|AVR
Release|AVR = Release|AVR
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6CE6CA08-5C90-4783-85FD-87623F6DABB4}.Debug|AVR.ActiveCfg = Debug|AVR
{6CE6CA08-5C90-4783-85FD-87623F6DABB4}.Debug|AVR.Build.0 = Debug|AVR
{6CE6CA08-5C90-4783-85FD-87623F6DABB4}.Release|AVR.ActiveCfg = Release|AVR
{6CE6CA08-5C90-4783-85FD-87623F6DABB4}.Release|AVR.Build.0 = Release|AVR
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
229 changes: 229 additions & 0 deletions firmware/src/watch/alarm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
/*
* Project: Digital Wristwatch
* Author: Zak Kemble, [email protected]
* Copyright: (C) 2013 by Zak Kemble
* License: GNU GPL v3 (see License.txt)
* Web: http://blog.zakkemble.co.uk/diy-digital-wristwatch/
*/

#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <limits.h>
#include <stdio.h>
#include "common.h"
#include "alarm.h"
#include "devices/buzzer.h"
#include "devices/led.h"
#include "time.h"
#include "draw.h"
#include "resources.h"
#include "devices/buttons.h"
#include "devices/oled.h"
#include "display.h"
#include "watchconfig.h"
#include "pwrmgr.h"

static s_alarm alarms[ALARM_COUNT];
static s_alarm* nextAlarm;
static byte nextAlarmDay;
static bool alarmSetOff;
static draw_f oldDrawFunc;
static button_f oldSelectFunc;
static button_f oldDownFunc;
static button_f oldUpFunc;

static const s_alarm eepAlarms[ALARM_COUNT] EEMEM = {};

static void load(void);
static void save(void);
static bool goingOff(void);
static void getNextAlarm(void);
static uint toMinutes(byte, byte, byte);
static bool select(void);
static display_t draw(void);

void alarm_init()
{
load();

getNextAlarm();
}

s_alarm* alarm_get()
{
return alarms;
}

s_alarm* alarm_getNext()
{
return nextAlarm;
}

byte alarm_getNextDay()
{
return nextAlarmDay;
}

char alarm_getDayLetter(byte day)
{
static byte days[] = {'M','T','W','T','F','S','S'};
return days[day];
}

void alarm_save()
{
save();
}

void alarm_update()
{
static bool buzzHigh = false;

bool wasGoingOff = alarmSetOff;
if(goingOff() && alarmSetOff)
{
if(wasGoingOff != alarmSetOff)
{
oldDrawFunc = display_setDrawFunc(draw);
oldSelectFunc = buttons_setFunc(BTN_SELECT, select);
oldDownFunc = buttons_setFunc(BTN_DOWN, NULL);
oldUpFunc = buttons_setFunc(BTN_UP, NULL);
pwrmgr_setState(PWR_ACTIVE_ALARM, PWR_STATE_IDLE);
}

if(!buzzer_buzzing())
{
if(buzzHigh)
{
buzzer_buzz(200, TONE_5KHZ, VOL_ALARM);
led_flash(LED_GREEN, 150, 255);
oled_setInvert(true);
}
else
{
buzzer_buzz(200, TONE_3KHZ, VOL_ALARM);
led_flash(LED_RED, 150, 255);
oled_setInvert(false);
}
buzzHigh = !buzzHigh;
}
}
}

void alarm_updateNextAlarm()
{
getNextAlarm();
}

static bool goingOff()
{
if(nextAlarm != NULL && alarmDayEnabled(nextAlarm->days, timeData.day) && nextAlarm->hour == timeData.hours && nextAlarm->min == timeData.mins)
{
if(timeData.secs == 0)
{
alarmSetOff = true;
getNextAlarm();
}
return true;
}
return false;
}

static void load()
{
eeprom_read_block(alarms, eepAlarms, sizeof(s_alarm) * ALARM_COUNT);
}

static void save()
{
eeprom_update_block(alarms, (s_alarm*)eepAlarms, sizeof(s_alarm) * ALARM_COUNT);
getNextAlarm();
}

// This func needs to be ran when an alarm has changed, time has changed and an alarm has gone off
static void getNextAlarm()
{
s_alarm* next = NULL;
uint nextTime = UINT_MAX;

// Now in minutes from start of week
uint now = toMinutes(timeData.hours, timeData.mins + 1, timeData.day);

// Loop through alarms
LOOPR(ALARM_COUNT, i)
{
// Not enabled
if(!alarms[i].enabled)
continue;

// Loop through days
LOOPR(7, d)
{
// Day not enabled
if(!alarmDayEnabled(alarms[i].days, d))
continue;

// Alarm time in minutes from start of weeek
uint alarmTime = toMinutes(alarms[i].hour, alarms[i].min, d);

// Minutes to alarm
int timeTo = alarmTime - now;

// Negative result, must mean alarm time is earlier in the week than now, add a weeks time
if(timeTo < 0)
timeTo += ((6*1440) + (23*60) + 59); // 10079

// Is minutes to alarm less than the last minutes to alarm?
if((uint)timeTo < nextTime)
{
// This is our next alarm
nextTime = timeTo;
next = &alarms[i];
nextAlarmDay = d;
}
}
}

// Set next alarm
nextAlarm = next;
}

static uint toMinutes(byte hours, byte mins, byte dow)
{
uint total = mins;
total += hours * 60;
total += dow * 1440;
return total;
}

static bool select()
{
display_setDrawFunc(oldDrawFunc);
buttons_setFunc(BTN_SELECT, oldSelectFunc);
buttons_setFunc(BTN_DOWN, oldDownFunc);
buttons_setFunc(BTN_UP, oldUpFunc);
oled_setInvert(watchConfig.invert);
pwrmgr_setState(PWR_ACTIVE_ALARM, PWR_STATE_NONE);
alarmSetOff = false;
return true;
}

static display_t draw()
{
if((millis8_t)millis() < 128)
{
s_image a = {16, 16, menu_alarm, 32, 32, WHITE, NOINVERT, 0};
draw_bitmap_s2(&a);
}

// Draw time
char buff[6];
sprintf_P(buff, PSTR(TIME_FORMAT_SMALL), timeData.hours, timeData.mins);
draw_string(buff,NOINVERT,79,20);

// Draw day
strcpy_P(buff, days[timeData.day]);
draw_string(buff,false,86,36);

return DISPLAY_DONE;
}
Loading

0 comments on commit cdf0903

Please sign in to comment.