Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Say time in CW when backlight button i pressed #25

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 17 additions & 6 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,40 @@
#ifndef _CONFIG_H_
#define _CONFIG_H_

#define CONFIG_FREQUENCY 902
#define CONFIG_FREQUENCY 433
#define OPTION_TIME_DISPLAY 0
// CONFIG_METRIC_ONLY is not set
#define CONFIG_METRIC_ONLY
#define FIXEDPOINT
#ifndef THIS_DEVICE_ADDRESS
#define THIS_DEVICE_ADDRESS {0xed,0xc0,0xbb,0x25}
#endif // THIS_DEVICE_ADDRESS
// USE_LCD_CHARGE_PUMP is not set
#define USE_WATCHDOG
// USE_WATCHDOG is not set
// DEBUG is not set
#define CONFIG_DAY_OF_WEEK
#define CONFIG_TEST
// CONFIG_EGGTIMER is not set
// CONFIG_TEST is not set
#define CONFIG_EGGTIMER
// CONFIG_PHASE_CLOCK is not set
#define CONFIG_ALTITUDE
// CONFIG_VARIO is not set
#define CONFIG_VARIO
// CONFIG_ALTI_ACCUMULATOR is not set
// CONFIG_PROUT is not set
// CONFIG_SIDEREAL is not set
// CONFIG_INFOMEM is not set
#define CONFIG_ACCEL
// CONFIG_STRENGTH is not set
#define CONFIG_ALARM
#define CONFIG_BATTERY
#define CONFIG_CLOCK
#define CONFIG_DATE
#define CONFIG_RFBSL
#define CONFIG_STOP_WATCH
#define CONFIG_TEMP
#define CONFIG_USEPPT
// CONFIG_USE_SYNC_TOSET_TIME is not set
// CONFIG_USE_DISCRET_RFBSL is not set
// CONFIG_USE_GPS is not set
// CONFIG_CW_TIME is not set
#define CONFIG_CW

#endif // _CONFIG_H_
206 changes: 197 additions & 9 deletions driver/buzzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,35 @@
void toggle_buzzer(void);
void countdown_buzzer(void);

#ifdef CONFIG_CW
void my_start_buzzer();
#endif /*CONFIG_CW*/


// *************************************************************************************************
// Defines section
#ifdef CONFIG_CW
#define BUZZER_QUEUE_SIZE 100
struct buzzer_queue_element {
u8 cycles;
u16 on_time;
u16 off_time;
};
struct buzzer_queue {
u8 first;
u8 last;
struct buzzer_queue_element queue[BUZZER_QUEUE_SIZE];
};

#endif /*CONFIG_CW*/


// *************************************************************************************************
// Global Variable section
struct buzzer sBuzzer;
#ifdef CONFIG_CW
struct buzzer_queue sBuzzer_queue;
#endif /*CONFIG_CW*/


// *************************************************************************************************
Expand Down Expand Up @@ -96,6 +117,33 @@ void reset_buzzer(void)
// *************************************************************************************************
void start_buzzer(u8 cycles, u16 on_time, u16 off_time)
{
#ifdef CONFIG_CW
// cw play requires queue!!
sBuzzer_queue.queue[ sBuzzer_queue.last ].cycles = cycles;
sBuzzer_queue.queue[ sBuzzer_queue.last ].on_time = on_time;
sBuzzer_queue.queue[ sBuzzer_queue.last ].off_time = off_time;

sBuzzer_queue.last = (sBuzzer_queue.last + 1) % BUZZER_QUEUE_SIZE ; // no queue full check, queue MUST be long enought

if (sBuzzer.state == BUZZER_OFF) {
// if not playing start!
my_start_buzzer();
}
}

void my_start_buzzer()
{
u8 cycles = sBuzzer_queue.queue[ sBuzzer_queue.first ].cycles;
u16 on_time = sBuzzer_queue.queue[ sBuzzer_queue.first ].on_time;
u16 off_time = sBuzzer_queue.queue[ sBuzzer_queue.first ].off_time;

if (sBuzzer_queue.first == sBuzzer_queue.last) {
// queue empty
return;
}
sBuzzer_queue.first = (sBuzzer_queue.first + 1) % BUZZER_QUEUE_SIZE ;

#endif /*CONFIG_CW*/
// Store new buzzer duration while buzzer is off
if (sBuzzer.time == 0)
{
Expand All @@ -109,23 +157,45 @@ void start_buzzer(u8 cycles, u16 on_time, u16 off_time)
TA1CTL = TACLR | MC_1 | TASSEL__ACLK;

// Set PWM frequency
TA1CCR0 = sBuzzer.steps;
TA1CCR0 = sBuzzer.steps;

// Enable IRQ, set output mode "toggle"
TA1CCTL0 = OUTMOD_4;

// Allow buzzer PWM output on P2.7
P2SEL |= BIT7;

// Activate Timer0_A3 periodic interrupts
fptr_Timer0_A3_function = toggle_buzzer;
Timer0_A3_Start(sBuzzer.on_time);

// Preload timer advance variable
sTimer.timer0_A3_ticks = sBuzzer.off_time;
#ifdef CONFIG_CW
if (on_time > 0 ) { // we use on_time = 0 to play only silence
#endif /*CONFIG_CW*/
// Allow buzzer PWM output on P2.7
P2SEL |= BIT7;

Timer0_A3_Start(sBuzzer.on_time);

// Preload timer advance variable
sTimer.timer0_A3_ticks = sBuzzer.off_time;

// Start with buzzer output on
sBuzzer.state = BUZZER_ON_OUTPUT_ENABLED;
#ifdef CONFIG_CW
} else {
// we use on_time = 0 to play only silence

// Start with buzzer output on
sBuzzer.state = BUZZER_ON_OUTPUT_ENABLED;
// Reset and disable buzzer PWM output
P2OUT &= ~BIT7;
P2SEL &= ~BIT7;

Timer0_A3_Start(sBuzzer.off_time);

// Preload timer advance variable even if we know it's 0
sTimer.timer0_A3_ticks = sBuzzer.on_time;

// Start with buzzer output off
sBuzzer.state = BUZZER_ON_OUTPUT_DISABLED;

}
#endif /*CONFIG_CW*/
}
}

Expand Down Expand Up @@ -179,6 +249,11 @@ void toggle_buzzer(void)

// Reload Timer0_A4 IRQ to turn off output
sTimer.timer0_A3_ticks = sBuzzer.off_time;
#ifdef CONFIG_CW
} else {
// play next sequence if any
my_start_buzzer();
#endif /*CONFIG_CW*/
}
}
}
Expand Down Expand Up @@ -238,3 +313,116 @@ void countdown_buzzer(void)
stop_buzzer();
}
}


#ifdef CONFIG_CW
// All this will be put in a separate file later

#include "clock.h"

// some ideas from cwlib
#define DOT_MAGIC 1200 /* Dot length magic number. The Dot
length is 1200/WPM msec */
#define INITIAL_SEND_SPEED 18 /* Initial send speed in WPM */


#define DOT_TICKS CONV_MS_TO_TICKS(DOT_MAGIC/INITIAL_SEND_SPEED)
#define DASH_TICKS CONV_MS_TO_TICKS(DOT_MAGIC/INITIAL_SEND_SPEED*3)

#define FIRST_CW_CHAR '0'
#define LAST_CW_CHAR 'Z'
struct cw_char {
u8 nsymbols;
u8 *symbols; // use a sort of compression: symbols represent number of dots if < 128 else number of dash in 1-complement
} cw_font[] = {
{1, (u8[]) {250}}, // 0 -----
{2, (u8[]) {1, 251}}, // 1 .----
{2, (u8[]) {2, 252}}, // 2 ..---
{2, (u8[]) {3, 253}}, // 3 ...--
{2, (u8[]) {4, 254}}, // 4 ....-
{1, (u8[]) {5}}, // 5 .....
{2, (u8[]) {254, 4}}, // 6 _....
{2, (u8[]) {253, 3}}, // 7 --...
{2, (u8[]) {252, 2}}, // 8 ---..
{2, (u8[]) {251, 1}}, // 9 ----.
{2, (u8[]) {252, 3}}, // : ---...
{0, NULL}, // ; NONE
{0, NULL}, // < NONE
{3, (u8[]) {254, 3 ,254}}, // = -...-
{0, NULL}, // > NONE
{3, (u8[]) {253, 2, 253}}, // ? ..--..
{0, NULL}, // @ NONE
{2, (u8[]) {1, 254}}, // A .-
{2, (u8[]) {254, 3}}, // B -...
{4, (u8[]) {254, 1, 254, 1}},// C -.-.
{2, (u8[]) {254, 2}}, // D -..
{1, (u8[]) {1}}, // E .
{3, (u8[]) {2, 254, 1}}, // F ..-.
{2, (u8[]) {253, 1}}, // G --.
{1, (u8[]) {4}}, // H ....
{1, (u8[]) {2}}, // I ..
{2, (u8[]) {1, 252}}, // J .---
{3, (u8[]) {254, 1, 254}}, // K -.-
{3, (u8[]) {1, 254, 2}}, // L .-..
{1, (u8[]) {253}}, // M --
{2, (u8[]) {254, 1}}, // N -.
{1, (u8[]) {252}}, // O ---
{3, (u8[]) {1, 253, 1}}, // P .--.
{3, (u8[]) {253, 1, 254}}, // Q --.-
{3, (u8[]) {1, 254, 1}}, // R .-.
{1, (u8[]) {3}}, // S ...
{1, (u8[]) {254}}, // T -
{2, (u8[]) {2, 254}}, // U ..-
{2, (u8[]) {3, 254}}, // V ...-
{2, (u8[]) {1, 253}}, // W .--
{3, (u8[]) {254, 2, 254}}, // X -..-
{3, (u8[]) {254, 1, 253}}, // Y -.--
{2, (u8[]) {253, 2}} // Z --..
};

void cw_chars(char *str)
{
// quick and dirty use of pointer
for (; *str != 0; str++) {
u8 c = (u8) (*str);
struct cw_char cw_c;
u8 i;

c = (c<FIRST_CW_CHAR || c>LAST_CW_CHAR) ? ('?' - FIRST_CW_CHAR) : (c - FIRST_CW_CHAR) ;
// transmit a ? for all unknown char
// and calculate symbol table index
cw_c = cw_font[c];
for (i = 0; i < cw_c.nsymbols; i++) {
if (cw_c.symbols[i] < 128 ) {
// play dots
start_buzzer(cw_c.symbols[i], DOT_TICKS, DOT_TICKS);
} else {
// play dash
start_buzzer(~cw_c.symbols[i], DASH_TICKS, DOT_TICKS);
}
}
// every symbol end with a "dot silent" so add rest of a "dash silent" to end the char
start_buzzer(1, 0, DASH_TICKS - DOT_TICKS);
}
// extra delay to separate next word (minus usual end char silent)
start_buzzer(1, 0, DOT_TICKS * 7 - DASH_TICKS);
}

void cw_say_time()
{
char now[5];
u8 *str;

str = itoa(sTime.hour, 2, 0);
now[0] = *str;
now[1] = *(str+1);
str = itoa(sTime.minute, 2, 0);
now[2] = *str;
now[3] = *(str+1);
now[4] = 0;

cw_chars(now);
}


#endif
4 changes: 4 additions & 0 deletions driver/buzzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ extern void toggle_buzzer(void);
extern u8 is_buzzer(void);
extern void countdown_buzzer(void);

#ifdef CONFIG_CW
void cw_chars(char *str);
void cw_say_time();
#endif /*CONFIG_CW*/

// *************************************************************************************************
// Defines section
Expand Down
24 changes: 21 additions & 3 deletions ezchronos.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ int main(void)
display_all_off();
#endif

#ifdef CONFIG_CW
cw_chars("V01"); // say version number to the world
#endif /*CONFIG_CW*/

// Main control loop: wait in low power mode until some event needs to be processed
while(1)
{
Expand Down Expand Up @@ -534,7 +538,12 @@ void wakeup_event(void)

// Clear button flag
button.flag.down = 0;
}
} else if (button.flag.backlight) {
#ifdef CONFIG_CW
cw_say_time();
#endif // CONFIG_CW
button.flag.backlight = 0;
}
}

// Process internal events
Expand Down Expand Up @@ -658,8 +667,17 @@ void display_update(void)
line = LINE2;

// Select message to display
if (message.flag.type_locked) memcpy(string, " LOCT", 6);
else if (message.flag.type_unlocked) memcpy(string, " OPEN", 6);
if (message.flag.type_locked) {
memcpy(string, " LOCT", 6);
#ifdef CONFIG_CW
cw_chars("LOCK");
#endif /*CONFIG_CW*/
} else if (message.flag.type_unlocked) {
memcpy(string, " OPEN", 6);
#ifdef CONFIG_CW
cw_chars("UNLOCK");
#endif /*CONFIG_CW*/
}
else if (message.flag.type_lobatt) memcpy(string, "LOBATT", 6);
else if (message.flag.type_no_beep_on) memcpy(string, " SILNT", 6);
else if (message.flag.type_no_beep_off) memcpy(string, " BEEP", 6);
Expand Down
11 changes: 9 additions & 2 deletions tools/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,7 @@ def rand_hw():
"name": "Temperature",
"depends": [],
"default": True}



###IMPLEMENTED BY LeanChronos. gventosa 09.10.2010
DATA["CONFIG_USEPPT"] = {
"name": "Use PPT",
Expand Down Expand Up @@ -243,6 +242,14 @@ def rand_hw():
"default": False,
"help": "Send time in morse code"}

# by IZ3GME new modules with cw playing
DATA["CONFIG_CW"] = {
"name": "CW Extensions",
"depends": [],
"default": False,
"help": "A more general CW extention (different and indipendent from CW_TIME)"}


HEADER = """
#ifndef _CONFIG_H_
#define _CONFIG_H_
Expand Down