/* This module is for sending high speed morse code
 * using a GPIO pin for debugging purposes. You'll need
 * something to view and decode the code. I did it with a 
 * digital storage oscilloscope.
 *
 * I used it on a PXA255, and used GPIO 20. Update 
 * setpin and clearpin for your hardware.
 *
 * quickly written by Raphael Assenat <raph@raphnet.net>
 */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <asm/hardware.h>

// 26 letters + 10 numbers
static unsigned char *code[] =
{
	".-",	// A
	"-...",	// B
	"-.-.",	// C
	"-..",	// D
	".",	// E
	"..-.",	// F
	"--.",	// G
	"....", // H
	"..",	// I
	".---",	// J
	"-.-",	// K
	".-..",	// L
	"--",	// M
	"-.",	// N
	"---",	// O
	".--.",	// P
	"--.-",	// Q
	".-.",	// R
	"...",	// S
	"-",	// T
	"..-",	// U
	"...-",	// V
	".--",	// W
	"-..-",	// X
	"-.--",	// Y
	"--..",	// Z
	"-----",//0
	".----",// 1
	"..---",// 2
	"...--",// 3
	"....-",// 4
	".....",//5
	"-....",//6
	"--...",//7
	"---..",//8
	"----." //9
};

#define DID_PERIOD	1
#define DAH_PERIOD	4
#define PAUSE_PERIOD 8

static void setpin(void)
{
	GPSR = GPIO_GPIO20;
}

static void clearpin(void)
{
	GPCR = GPIO_GPIO20;
}

static void did(void)
{
	setpin();
	mdelay(DID_PERIOD);
	clearpin();
	mdelay(DID_PERIOD);
}

static void dah(void)
{
	setpin();
	mdelay(DAH_PERIOD);
	clearpin();
	mdelay(DID_PERIOD);
}

static void letter_pause(void)
{
	mdelay(PAUSE_PERIOD);
}

static void morse_code(int index)
{
	char *seq = code[index];

	while (*seq) {
		if (*seq == '-') { dah(); }
		if (*seq == '.') { did(); }
		seq++;
	}
}

static void morse_sendChar2(char c)
{
	// convert to upper case
	if (c>=97 && c <=122) { c -= 32; }

	if (c >= 48 && c <= 57) {
		morse_code(c - 48 + 26);
	}

	if (c >= 65 && c <= 90) {
		morse_code(c-65);
	}
}

void morse_sendChar(char c)
{
	morse_sendChar2(c);
	letter_pause();
}

void morse_sendStr(char *str)
{
	while (*str)
	{
		morse_sendChar2(*str);
		letter_pause();
		str++;
	}
}

int __init morse_init(void)	
{
	clearpin();
	morse_sendStr("cq");
	printk("morse: Morse code debugging facility ready\n");
	return 0;
}

void __exit morse_exit(void)
{
}

module_init(morse_init);
module_exit(morse_exit);
MODULE_LICENSE("GPL");

