//#######################################################################################################################
//#
//#	ПОДГОТОВКА - ПЕРЕМЕННЫХ, ДЕФАЙНОВ, МАКРОСОВ И Т.Д.
//#
//#######################################################################################################################


//ВКЛЮЧАЕМЫЕ ФАЙЛЫ
#define F_CPU 8000000
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h> 						//eeprom_read_byte(), eeprom_write_byte(), eeprom_read_word(), eeprom_write_word()
#include <avr/pgmspace.h>
char benti [] PROGMEM = "  Benti hхmйrsйklet! >> ";
char kinti [] PROGMEM = "  Kinti hхmйrsйklet! >> ";

//-----------------------------------------------------------------------------------------------------------------------
//ДЕФАЙНЫ
#define INLINE   inline __attribute__((__always_inline__))
#define NOINLINE __attribute__((__noinline__))

#define LedBoardRowInvert	255				/*0-прямое управление строками, 255-инверсное через ULN2303*/
#define	LedBoardSize 		8					/*длина бегущей строки в символах (видимая часть)*/
#define LedBoardSimbWidth 	6					/*ширина символа в пикселях, в бегущей строке*/
#define FontSimbWidth 		5					/*ширина символа в пикселях, в массиве фонта*/
#define TimeOutConst 		60					/*если указанное кол-во секунд, кнопка не нажимается, то выход из ф-ции*/


//-----------------------------------------------------------------------------------------------------------------------
//ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ 
//для уменьшения кода, и увеличения скорости обработки, можно использовать следующие регистры 
//(при условии что не используются соответствующие модули)
//EEARL - 	EEPROM регистр адреса
//EEDR - 	EEPROM регистр данных
//UBRRL - 	USART регистр скорости интерфейса
//TWBR -	TWI регистр скорости передачи
//TWAR - 	TWI регистр адреса
	
#define Flags1   TWBR							/*байт флагов №1 будет размещатся в регистре EEARL (т.к. внутренняя EEPROM не исп-ся)*/
	#define b1LedBoardPageCompleted	(1<<0)		/*флаг включения зуммера*/
	#define b1OneWireGet			(1<<1)		/*флаг необходимости старта команды преобразования температуры в 1wire устройствах*/
	#define b1ClockReadEnable		(1<<2)		/*флаг разрешения чтения данных часов в прерывании*/
	#define b1ClockChange			(1<<3)		/*флаг изменения значения часов*/

#define BtnFlags   TWAR							/*байт флагов кнопок будет размещатся в регистре EEDR (т.к. внутренняя EEPROM не исп-ся)*/
	#define ShortUp			(1<<0)				/*бит короткого нажатия кнопки вверх*/ 
	#define ShortLeft		(1<<1)				/*бит короткого нажатия кнопки вниз*/ 
	#define ShortRight		(1<<2)				/*бит короткого нажатия кнопки влево*/ 
	#define ShortDown		(1<<3)				/*бит короткого нажатия кнопки вправо*/ 
	#define LongUp			(1<<4)				/*бит длиного нажатия кнопки вверх*/ 
	#define LongLeft		(1<<5)				/*бит длиного нажатия кнопки вниз*/ 
	#define LongRight		(1<<6)				/*бит длиного нажатия кнопки влево*/ 
	#define LongDown		(1<<7)				/*бит длиного нажатия кнопки вправо*/ 

volatile uint8_t BtnLongSpeed;							//байт скоростного изменения редактируемого значения 
volatile char BtnTimeOutCoun;							//счетчик для организации выхода по TimeOut-у

char LedBoardBuffer [(LedBoardSize+2)*LedBoardSimbWidth];//ГРАФИЧЕСКИЙ БУФЕР ВЫВОДА ДАННЫХ НА ДИСПЛЕЙ
char LedBoardHorScrollSpeed = 30;						//горизонтальная скорость бегущей строки (1-100 точках\секунду)
char LedBoardVertScrollSpeed = 15;						//вертикальная скорость бегущей строки (1-100 точках\секунду)
char LedBoardFlashCoun = 0;								//переменная режима индикатора FLASH (счет 0-99 за секунду)

char ClockSimbVertScrollSpeed = 6;						//скорость вертикального скроллинга меняющихся цифр часов (12-мин ..... 1-максимальная)
char ClockMiliSecond;									//милисекунды часов (в шестнадцатеричном формате)
char ClockData [7] =									//массив переменных внутренних часов (в двоично-десятичном формате)
	{0x00,0x00,0x00,0x01,0x01,0x01,0x12};				//секунды, минуты, часы, день, дата, месяц, год
char ClockGraphBuf [LedBoardSimbWidth*8];				//дополнительный графический буфер часов на 8 символов
int  ClockPosition = 0;									//позиция вывода часов в строку (0-вывода нет, 1-занимает 1 пиксель слева, 2-2, и т.д.)
char ClockChangeMask = 0;								//маска изменившихся цыфр часов (для организации плавной прокрутки)
							
char OneWireErr;										//байт ошибок 1wire устройств
char OneWireCheckSumm;									//счетчик контрольной суммы обмена по 1wire
char OneWireReadBuf [9];								//накопитель данных 1wire (чтение в прерывании)
int  OneWireTermoData [2];								//массив данных температуры (2 устройства по 2 байта)


//-----------------------------------------------------------------------------------------------------------------------
//ПРОТОТИПЫ ФУНКЦИЙ	
static void LedBoardIntPrint (signed int integer, uint8_t IntPos, uint8_t IntLength, uint8_t DotPosition);
static void LedBoardSimbPrint (unsigned char simbol, unsigned char position);
static void LedBoardMessageShow (char *pAdrTxt);
static void LedBoardMessageScrollLeft (char *pAdrTxt);
static void LedBoardTermoShow (char Position, uint8_t NumDev);
static void LedBoardTermoScrollLeft (uint8_t NumDev);
static void LedBoardClockShow (uint8_t Position);
static void LedBoardClockScrollLeft (void);
static void LedBoardClearScrollLeft (void);
static void LedBoardClearScrollDown (void);
static void LedBoard1PixScrollLeft (void);
static void LedBoardOut (char NumLine);

static void IICStart (void);					//софтовая реализация I2C
static void IICStop (void);

static void IICClockReadData (void);			//ф-ции работы с МС часов DS1307
static void IICClockWriteData (void);

static void ClockBufferProcess (void);
static void ClockSimbToBuf (char byte, char Shift);

static char IICByteWrite (char);
static char IICByteRead (char);
static char IICBit (char);

static uint8_t OneWireData (uint8_t, char);
static void OneWireIntTermoGet (void);
static void OneWireReset (char);
static void CheckSumm (char);

static void Delay (unsigned char);
static void VarProcessing (void);
static void MainInit (void);


static void BtnGet (void);						//ф-ции обслуживания кнопок


//-----------------------------------------------------------------------------------------------------------------------
//КОНСТАНТЫ В PROGRAM MEMORY					
char SimbMass [] PROGMEM = {							//массив знакогенератора
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFA,0x00,0x00,	// !
	0x00,0xC0,0x00,0xC0,0x00,0x28,0xFE,0x28,0xFE,0x28,	//"#
	0x24,0x54,0xFE,0x54,0x48,0xC4,0xC8,0x10,0x26,0x46,	//$%
	0x6C,0x92,0xAA,0x44,0x0A,0x00,0xA0,0xC0,0x00,0x00,	//&'
	0x00,0x38,0x44,0x82,0x00,0x00,0x82,0x44,0x38,0x00,	//()
	0x28,0x10,0x7C,0x10,0x28,0x10,0x10,0x7C,0x10,0x10,	//*+
	0x00,0x05,0x06,0x00,0x00,0x10,0x10,0x10,0x10,0x10,	//,-
	0x00,0x06,0x06,0x00,0x00,0x04,0x08,0x10,0x20,0x40,	//./
	0x7C,0x8A,0x92,0xA2,0x7C,0x00,0x42,0xFE,0x02,0x00,	//01
	0x42,0x86,0x8A,0x92,0x62,0x84,0x82,0xA2,0xD2,0x8C,	//23
	0x18,0x28,0x48,0xFE,0x08,0xE4,0xA2,0xA2,0xA2,0x9C,	//45
	0x3C,0x52,0x92,0x92,0x0C,0xC0,0x80,0x8E,0x90,0xE0,	//67
	0x6C,0x92,0x92,0x92,0x6C,0x60,0x92,0x92,0x94,0x78,	//89
	0x00,0x6C,0x6C,0x00,0x00,0x00,0x6A,0x6C,0x00,0x00,	//:;
	0x10,0x28,0x44,0x82,0x00,0x28,0x28,0x28,0x28,0x28,	//<=
	0x00,0x82,0x44,0x28,0x10,0x40,0x80,0x8A,0x90,0x60,	//>?
	0x4C,0x92,0x9E,0x82,0x7C,0x7E,0x88,0x88,0x88,0x7E,	//@A
	0xFE,0x92,0x92,0x92,0x6C,0x7C,0x82,0x82,0x82,0x44,	//BC
	0xFE,0x82,0x82,0x44,0x38,0xFE,0x92,0x92,0x92,0x82,	//DE
	0xFE,0x90,0x90,0x90,0x80,0x7C,0x82,0x92,0x92,0x5E,	//FG
	0xFE,0x10,0x10,0x10,0xFE,0x00,0x82,0xFE,0x82,0x00,	//HI
	0x04,0x02,0x82,0xFC,0x80,0xFE,0x10,0x28,0x44,0x82,	//JK
	0xFE,0x02,0x02,0x02,0x02,0xFE,0x40,0x30,0x40,0xFE,	//LM
	0xFE,0x20,0x10,0x08,0xFE,0x7C,0x82,0x82,0x82,0x7C,	//NO
	0xFE,0x90,0x90,0x90,0x60,0x7C,0x82,0x8A,0x84,0x7A,	//PQ
	0xFE,0x90,0x98,0x94,0x62,0x62,0x92,0x92,0x92,0x8C,	//RS
	0x80,0x80,0xFE,0x80,0x80,0xFC,0x02,0x02,0x02,0xFC,	//TU
	0xF8,0x04,0x02,0x04,0xF8,0xFC,0x02,0x1C,0x02,0xFC,	//VW
	0xC6,0x28,0x10,0x28,0xC6,0xE0,0x10,0x0E,0x10,0xE0,	//XY
	0x86,0x8A,0x92,0xA2,0xC2,0xFE,0x82,0x82,0x00,0x00,	//Z[
	0xA8,0x68,0x3E,0x68,0xA8,0x00,0x82,0x82,0xFE,0x00,	//\]
	0x20,0x40,0x80,0x40,0x20,0x02,0x02,0x02,0x02,0x00,	//^_
	0x00,0x60,0x90,0x60,0x00,0x04,0x2A,0x2A,0x2A,0x1E,	//`a
	0xFE,0x12,0x22,0x22,0x1C,0x1C,0x22,0x22,0x22,0x04,	//bc
	0x1C,0x22,0x22,0x12,0xFE,0x1C,0x2A,0x2A,0x2A,0x18,	//de
	0x10,0x7E,0x90,0x80,0x40,0x30,0x4A,0x4A,0x4A,0x7C,	//fg
	0xFE,0x10,0x20,0x20,0x1E,0x00,0x22,0xBE,0x02,0x00,	//hi
	0x04,0x02,0x22,0xBC,0x00,0xFE,0x08,0x14,0x22,0x00,	//jk
	0x00,0x82,0xFE,0x02,0x00,0x3E,0x20,0x18,0x20,0x1E,	//lm
	0x3E,0x10,0x20,0x20,0x1E,0x1C,0x22,0x22,0x22,0x1C,	//no
	0x3E,0x28,0x28,0x28,0x10,0x10,0x28,0x28,0x18,0x3E,	//pq
	0x3E,0x10,0x20,0x20,0x10,0x12,0x2A,0x2A,0x2A,0x04,	//rs
	0x20,0xFC,0x22,0x02,0x04,0x3C,0x02,0x02,0x04,0x3E,	//tu
	0x38,0x04,0x02,0x04,0x38,0x3C,0x02,0x1C,0x02,0x3C,	//vw
	0x22,0x14,0x08,0x14,0x22,0x30,0x0A,0x0A,0x0A,0x3C,	//xy
	0x22,0x26,0x2A,0x32,0x22,0x00,0x10,0x6C,0x82,0x00,	//z{
	0x00,0x00,0xFE,0x00,0x00,0x00,0x82,0x6C,0x10,0x00,	//|}
	0x10,0x10,0x54,0x38,0x10,0x10,0x38,0x54,0x10,0x10,	//~
	0x7E,0x88,0x88,0x88,0x7E,0xFE,0x92,0x92,0x92,0xCC,	//АБ
	0xFE,0x92,0x92,0x92,0x6C,0xFE,0x80,0x80,0x80,0xC0,	//ВГ
	0x07,0x8A,0xF2,0x82,0xFF,0xFE,0x92,0x92,0x92,0x82,	//ДЕ
	0xEE,0x10,0xFE,0x10,0xEE,0x82,0x92,0x92,0x92,0x7C,	//ЖЗ
	0xFE,0x08,0x10,0x20,0xFE,0x3E,0x84,0x48,0x90,0x3E,	//ИЙ
	0xFE,0x10,0x28,0x44,0x82,0x04,0x82,0xFC,0x80,0xFE,	//КЛ
	0xFE,0x40,0x30,0x40,0xFE,0xFE,0x10,0x10,0x10,0xFE,	//МН
	0x7C,0x82,0x82,0x82,0x7C,0xFE,0x80,0x80,0x80,0xFE,	//ОП
	0xFE,0x90,0x90,0x90,0x60,0x7C,0x82,0x82,0x82,0x44,	//РС
	0x80,0x80,0xFE,0x80,0x80,0xE2,0x14,0x08,0x10,0xE0,	//ТУ
	0x38,0x44,0xFE,0x44,0x38,0xC6,0x28,0x10,0x28,0xC6,	//ФХ
	0xFC,0x04,0x04,0x04,0xFE,0xE0,0x10,0x10,0x10,0xFE,	//ЦЧ
	0xFE,0x02,0xFE,0x02,0xFE,0xFC,0x04,0xFC,0x04,0xFE,	//ШЩ
	0x80,0xFE,0x12,0x12,0x0C,0xFE,0x12,0x0C,0x00,0xFE,	//ЪЫ
	0xFE,0x12,0x12,0x12,0x0C,0x44,0x82,0x92,0x92,0x7C,	//ЬЭ
	0xFE,0x10,0x7C,0x82,0x7C,0x62,0x94,0x98,0x90,0xFE,	//ЮЯ
	0x04,0x2A,0x2A,0x2A,0x1E,0x04,0x2A,0xEA,0x2A,0x1E,	//аб
	0x3E,0x2A,0x2A,0x2A,0x14,0x3E,0x20,0x20,0x20,0x30,	//вг
	0x27,0x2A,0x32,0x22,0x3F,0x1C,0x2A,0x2A,0x2A,0x18,	//де
	0x36,0x08,0x3E,0x08,0x36,0x22,0x22,0x2A,0x2A,0x14,	//жз
	0x3E,0x04,0x08,0x10,0x3E,0x1C,0x2A,0xEA,0x2A,0x18,	//ий
	0x3E,0x08,0x14,0x22,0x00,0x04,0x22,0x3C,0x20,0x3E,	//кл
	0x3E,0x10,0x08,0x10,0x3E,0x00,0x22,0xFE,0x02,0x00,	//мн
	0x1C,0x22,0x22,0x22,0x1C,0x3E,0x20,0x20,0x20,0x3E,	//оп
	0x3E,0x28,0x28,0x28,0x10,0x1C,0x22,0x22,0x22,0x04,	//рс
	0x20,0x20,0x3E,0x20,0x20,0x1C,0x22,0xE2,0x22,0x1C,	//ту
	0x18,0x24,0x7E,0x24,0x18,0x1C,0xE2,0x22,0xE2,0x1C,	//фх
	0x1C,0xA2,0x22,0xA2,0x1C,0x30,0x08,0x08,0x08,0x3E,	//цч
	0x3E,0x02,0x3E,0x02,0x3E,0x3E,0x02,0x3E,0x02,0x3F,	//шщ
	0x3C,0x02,0xC2,0x04,0x3E,0x3C,0xC2,0x02,0xC4,0x3E,	//ъы
	0x3C,0x82,0x02,0x84,0x3E,0x14,0x22,0x2A,0x2A,0x1C,	//ьэ
	0x3E,0x08,0x1C,0x22,0x1C,0x10,0x2A,0x2C,0x28,0x3E	//юя
};			
							

char DSReadingMap [] PROGMEM = {//карта массива, распределенного в прерывании чтения температуры 
	0x0D,0x33,0x00,0x0D,0xCC,0xBE,0x01,0x02,0x0C,0x0C,0x03,0x0C,0x0C,0x0C,0x0C,0x0B,
	0x0D,0x33,0x04,0x0D,0xCC,0xBE,0x05,0x06,0x0C,0x0C,0x07,0x0C,0x0C,0x0C,0x0C,0x0E,
	0x0D,0xCC,0x44,0x0F
};


//-----------------------------------------------------------------------------------------------------------------------
//ФУНКЦИЯ ИНИЦИАЛИЗАЦИИ устройства
 void MainInit (void)
{

	//настройка портов LedBoard
	#define LedBoardRowPORT 	PORTD				/*порт дисплея*/
	#define LedBoardRowDDR 		DDRD				/*управление портом дисплея*/
	#define LedBoardDataPORT 	PORTB				/*порт дисплея*/
	#define LedBoardDataDDR 	DDRB				/*управление портом дисплея*/
	#define LedBoardData 		(1<<6)				/*линия данных*/
	#define LedBoardClc 		(1<<7)				/*линия тактирования*/
	#define LedBoardStrobe 		(1<<5)				/*линия строба*/
	#define LedBoardOn	 		(1<<4)				/*линия включения строки*/

	LedBoardRowDDR = 0xFF;							//порт выводов строчной развертки на вывод
	LedBoardDataDDR |= LedBoardData|LedBoardClc		//
	|LedBoardStrobe|LedBoardOn;

	//настройка порта клавиатуры
	#define BtnPORT 			PORTC				/*порт дисплея*/
	#define BtnDDR 				DDRC				/*управление портом дисплея*/
	#define BtnPIN 				PINC				/*порт чтения кнопок*/
	#define Button1				(1<<2)				/*кнопка 1*/
	#define Button2				(1<<3)				/*кнопка 2*/
	#define Button3				(1<<4)				/*кнопка 3*/
	#define Button4				(1<<5)				/*кнопка 4*/

	BtnPORT |= Button1|Button2|Button3|Button4;		//подтяжка для кнопки

	//настройка порта IIC
	#define IICDDR				DDRC				/*порт управления I2C*/
	#define IICPORT				PORTC				/*порт вывода данных на линию I2C*/
	#define IICPIN				PINC				/*порт ввода данных с линий I2C*/
	#define IICData				(1<<0)				/*линия DATA*/
	#define IICClc				(1<<1)				/*линия CLC*/

	//настройка порта 1WIRE
	#define OneWireDDR			DDRB				/*настройка порта линий 1,2*/
	#define OneWirePORT			PORTB				/*порт записи линии 1,2*/
	#define OneWirePIN			PINB				/*порт чтения линии 1,2*/
	#define OneWireLine1 		(1<<0)				/*пин линии 1*/
	#define OneWireLine2 		(1<<1)				/*пин линии 2*/

	//настройка выводов контроля по осциллу.....
	DDRB  |= 0x0c;								

	//настройка прерывания по таймеру счетчику
	TIMSK = 0x80;	 							//режим работы - прерывание по совпадению
	TCCR2 = 0x0e;								//режим таймера T2 = CTC (0x08 сброс при совпадении)(0x06 предделитель на 256)
	OCR2  = 38;									//регистр сравнения (сброс таймера счетч по совп. при 38, прерывание = 800Hz) 

	Flags1 = 0;									//флаговые байты - инициализация
	BtnFlags = 0;

	sei ();										//разрешаем глобально прерывания

	LedBoardDataPORT |= LedBoardOn;				//включение отображения LedBoard
	Flags1 |= b1ClockReadEnable;				//включение часов
}


//#######################################################################################################################
//#
//#	УСЕ! С ПОДГОТОВКОЙ
//#
//#######################################################################################################################

