Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/intercom.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2013-09-09 17:11:28 +0400
committerAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2013-09-09 17:11:28 +0400
commitf79e8baa103ced7b57d1ce1bf9b705914f131a34 (patch)
tree5bbc5abd4a69cd776585f0b3570f429a416bbd2f
parentecad86fddd6ffc7de27fa6c69635448646a2a91d (diff)
New CLUNET, UTF-8 translation
-rw-r--r--clunet.c138
-rw-r--r--clunet.h112
-rw-r--r--clunet_config.h3
-rw-r--r--intercom.c120
4 files changed, 193 insertions, 180 deletions
diff --git a/clunet.c b/clunet.c
index 3288fd9..1c00e58 100644
--- a/clunet.c
+++ b/clunet.c
@@ -1,7 +1,7 @@
/* Name: clunet.c
* Project: CLUNET network driver
* Author: Alexey Avdyukhin
- * Creation Date: 2013-07-22
+ * Creation Date: 2013-09-09
* License: DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
*/
@@ -26,7 +26,7 @@ volatile unsigned char clunetReadingCurrentBit;
volatile unsigned char clunetCurrentPrio;
volatile unsigned char clunetReceivingState = 0;
-volatile unsigned char clunetReceivingPrio = 0;
+//volatile unsigned char clunetReceivingPrio = 0;
volatile unsigned char clunetTimerStart = 0;
volatile unsigned char clunetTimerPeriods = 0;
@@ -55,73 +55,73 @@ char check_crc(char* data, unsigned char size)
ISR(CLUNET_TIMER_COMP_VECTOR)
{
- unsigned char now = CLUNET_TIMER_REG; //
+ unsigned char now = CLUNET_TIMER_REG; // Запоминаем текущее время
switch (clunetSendingState)
{
- case CLUNET_SENDING_STATE_PREINIT: //
+ case CLUNET_SENDING_STATE_PREINIT: // Нужно подождать перед отправкой
CLUNET_TIMER_REG_OCR = now + CLUNET_T;
- clunetSendingState = CLUNET_SENDING_STATE_INIT; //
+ clunetSendingState = CLUNET_SENDING_STATE_INIT; // Начинаем следующую фазу
return;
- case CLUNET_SENDING_STATE_STOP: // ,
- CLUNET_SEND_0; //
+ case CLUNET_SENDING_STATE_STOP: // Завершение передачи, но надо ещё подождать
+ CLUNET_SEND_0; // Отпускаем линию
CLUNET_TIMER_REG_OCR = now + CLUNET_T;
clunetSendingState = CLUNET_SENDING_STATE_DONE;
return;
- case CLUNET_SENDING_STATE_DONE: //
- CLUNET_DISABLE_TIMER_COMP; // -
- clunetSendingState = CLUNET_SENDING_STATE_IDLE; // ,
+ case CLUNET_SENDING_STATE_DONE: // Завершение передачи
+ CLUNET_DISABLE_TIMER_COMP; // Выключаем таймер-сравнение
+ clunetSendingState = CLUNET_SENDING_STATE_IDLE; // Ставим флаг, что передатчик свободен
return;
}
- if (/*!((clunetReadingState == CLUNET_READING_STATE_DATA) && // [
- (clunetCurrentPrio > clunetReceivingPrio) //
- && (clunetSendingState == CLUNET_SENDING_STATE_INIT)) // ]
- &&*/ (!CLUNET_SENDING && CLUNET_READING)) // . ,
+ if (/*!((clunetReadingState == CLUNET_READING_STATE_DATA) && // Если мы сейчас не [получаем данные
+ (clunetCurrentPrio > clunetReceivingPrio) // И приоритет получаемых данных не ниже
+ && (clunetSendingState == CLUNET_SENDING_STATE_INIT)) // И мы не пытаемся начать инициализацию]
+ &&*/ (!CLUNET_SENDING && CLUNET_READING)) // То идёт проверка на конфликт. Если мы линию не держим, но она уже занята
{
- CLUNET_DISABLE_TIMER_COMP; // -
- clunetSendingState = CLUNET_SENDING_STATE_WAITING_LINE; //
- return; //
+ CLUNET_DISABLE_TIMER_COMP; // Выключаем таймер-сравнение
+ clunetSendingState = CLUNET_SENDING_STATE_WAITING_LINE; // Переходим в режим ожидания линии
+ return; // И умолкаем
}
- CLUNET_SEND_INVERT; // ,
+ CLUNET_SEND_INVERT; // Сразу инвртируем значение сигнала, у нас это запланировано
- if (!CLUNET_SENDING) // ...
+ if (!CLUNET_SENDING) // Если мы отпустили линию...
{
- CLUNET_TIMER_REG_OCR = now + CLUNET_T; // CLUNET_T
+ CLUNET_TIMER_REG_OCR = now + CLUNET_T; // То вернёмся в это прерывание через CLUNET_T единиц времени
return;
}
switch (clunetSendingState)
{
- case CLUNET_SENDING_STATE_INIT: //
+ case CLUNET_SENDING_STATE_INIT: // Инициализация
CLUNET_TIMER_REG_OCR = now + CLUNET_INIT_T;
- clunetSendingState = CLUNET_SENDING_STATE_PRIO1; //
+ clunetSendingState = CLUNET_SENDING_STATE_PRIO1; // Начинаем следующую фазу
return;
- case CLUNET_SENDING_STATE_PRIO1: // ,
- if ((clunetCurrentPrio-1) & 2) // 1, 3T, 0, 1T
+ case CLUNET_SENDING_STATE_PRIO1: // Фаза передачи приоритета, старший бит
+ if ((clunetCurrentPrio-1) & 2) // Если 1, то ждём 3T, а если 0, то 1T
CLUNET_TIMER_REG_OCR = now + CLUNET_1_T;
else CLUNET_TIMER_REG_OCR = now + CLUNET_0_T;
clunetSendingState = CLUNET_SENDING_STATE_PRIO2;
return;
- case CLUNET_SENDING_STATE_PRIO2: // ,
- if ((clunetCurrentPrio-1) & 1) // 1, 3T, 0, 1T
+ case CLUNET_SENDING_STATE_PRIO2: // Фаза передачи приоритета, младший бит
+ if ((clunetCurrentPrio-1) & 1) // Если 1, то ждём 3T, а если 0, то 1T
CLUNET_TIMER_REG_OCR = now + CLUNET_1_T;
else CLUNET_TIMER_REG_OCR = now + CLUNET_0_T;
clunetSendingState = CLUNET_SENDING_STATE_DATA;
return;
- case CLUNET_SENDING_STATE_DATA: //
- if (dataToSend[clunetSendingCurrentByte] & (1 << clunetSendingCurrentBit)) // 1, 3T, 0, 1T
+ case CLUNET_SENDING_STATE_DATA: // Фаза передачи данных
+ if (dataToSend[clunetSendingCurrentByte] & (1 << clunetSendingCurrentBit)) // Если 1, то ждём 3T, а если 0, то 1T
CLUNET_TIMER_REG_OCR = now + CLUNET_1_T;
else CLUNET_TIMER_REG_OCR = now + CLUNET_0_T;
- clunetSendingCurrentBit++; //
+ clunetSendingCurrentBit++; // Переходим к следующему биту
if (clunetSendingCurrentBit >= 8)
{
clunetSendingCurrentBit = 0;
clunetSendingCurrentByte++;
}
- if (clunetSendingCurrentByte >= clunetSendingDataLength) //
+ if (clunetSendingCurrentByte >= clunetSendingDataLength) // Данные закончились
{
- clunetSendingState = CLUNET_SENDING_STATE_STOP; //
+ clunetSendingState = CLUNET_SENDING_STATE_STOP; // Следующая фаза
}
return;
}
@@ -131,18 +131,18 @@ ISR(CLUNET_TIMER_COMP_VECTOR)
void clunet_start_send()
{
CLUNET_SEND_0;
- if (clunetSendingState != CLUNET_SENDING_STATE_PREINIT) // ...
- clunetSendingState = CLUNET_SENDING_STATE_INIT; //
- clunetSendingCurrentByte = clunetSendingCurrentBit = 0; //
- CLUNET_TIMER_REG_OCR = CLUNET_TIMER_REG+CLUNET_T; // , -
- CLUNET_ENABLE_TIMER_COMP; // -
+ if (clunetSendingState != CLUNET_SENDING_STATE_PREINIT) // Если не нужна пауза...
+ clunetSendingState = CLUNET_SENDING_STATE_INIT; // Инициализация передачи
+ clunetSendingCurrentByte = clunetSendingCurrentBit = 0; // Обнуляем счётчик
+ CLUNET_TIMER_REG_OCR = CLUNET_TIMER_REG+CLUNET_T; // Планируем таймер, обычно почему-то прерывание срабатывает сразу
+ CLUNET_ENABLE_TIMER_COMP; // Включаем прерывание таймера-сравнения
}
void clunet_send(unsigned char address, unsigned char prio, unsigned char command, char* data, unsigned char size)
{
- if (CLUNET_OFFSET_DATA+size+1 > CLUNET_SEND_BUFFER_SIZE) return; //
- CLUNET_DISABLE_TIMER_COMP;CLUNET_SEND_0; // ,
- //
+ if (CLUNET_OFFSET_DATA+size+1 > CLUNET_SEND_BUFFER_SIZE) return; // Не хватает буфера
+ CLUNET_DISABLE_TIMER_COMP;CLUNET_SEND_0; // Прерываем текущую передачу, если есть такая
+ // Заполняем переменные
if (clunetSendingState != CLUNET_SENDING_STATE_PREINIT)
clunetSendingState = CLUNET_SENDING_STATE_IDLE;
clunetCurrentPrio = prio;
@@ -156,11 +156,11 @@ void clunet_send(unsigned char address, unsigned char prio, unsigned char comman
dataToSend[CLUNET_OFFSET_DATA+size] = check_crc((char*)dataToSend, CLUNET_OFFSET_DATA+size);
clunetSendingDataLength = CLUNET_OFFSET_DATA + size + 1;
if (
- (clunetReadingState == CLUNET_READING_STATE_IDLE) // ,
-// || ((clunetReadingState == CLUNET_READING_STATE_DATA) && (prio > clunetReceivingPrio)) // ,
+ (clunetReadingState == CLUNET_READING_STATE_IDLE) // Если мы ничего не получаем в данный момент, то посылаем сразу
+// || ((clunetReadingState == CLUNET_READING_STATE_DATA) && (prio > clunetReceivingPrio)) // Либо если получаем, но с более низким приоритетом
)
- clunet_start_send(); //
- else clunetSendingState = CLUNET_SENDING_STATE_WAITING_LINE; //
+ clunet_start_send(); // Запускаем передачу сразу
+ else clunetSendingState = CLUNET_SENDING_STATE_WAITING_LINE; // Иначе ждём линию
}
inline void clunet_data_received(unsigned char src_address, unsigned char dst_address, unsigned char command, char* data, unsigned char size)
@@ -168,12 +168,12 @@ inline void clunet_data_received(unsigned char src_address, unsigned char dst_ad
if (on_data_received_sniff)
(*on_data_received_sniff)(src_address, dst_address, command, data, size);
- if (src_address == CLUNET_DEVICE_ID) return; // !
+ if (src_address == CLUNET_DEVICE_ID) return; // Игнорируем сообщения от самого себя!
if ((dst_address != CLUNET_DEVICE_ID) &&
- (dst_address != CLUNET_BROADCAST_ADDRESS)) return; //
+ (dst_address != CLUNET_BROADCAST_ADDRESS)) return; // Игнорируем сообщения не для нас
- if (command == CLUNET_COMMAND_REBOOT) // . ,
+ if (command == CLUNET_COMMAND_REBOOT) // Просто ребут. И да, ребутнуть себя мы можем
{
cli();
set_bit(WDTCR, WDE);
@@ -182,14 +182,19 @@ inline void clunet_data_received(unsigned char src_address, unsigned char dst_ad
if ((clunetSendingState == CLUNET_SENDING_STATE_IDLE) || (clunetCurrentPrio <= CLUNET_PRIORITY_MESSAGE))
{
- if (command == CLUNET_COMMAND_DISCOVERY) //
+ if (command == CLUNET_COMMAND_DISCOVERY) // Ответ на поиск устройств
{
+#ifdef CLUNET_DEVICE_NAME
char buf[] = CLUNET_DEVICE_NAME;
int len = 0; while(buf[len]) len++;
clunetSendingState = CLUNET_SENDING_STATE_PREINIT;
clunet_send(src_address, CLUNET_PRIORITY_MESSAGE, CLUNET_COMMAND_DISCOVERY_RESPONSE, buf, len);
+#else
+ clunetSendingState = CLUNET_SENDING_STATE_PREINIT;
+ clunet_send(src_address, CLUNET_PRIORITY_MESSAGE, CLUNET_COMMAND_DISCOVERY_RESPONSE, 0, 0);
+#endif
}
- else if (command == CLUNET_COMMAND_PING) //
+ else if (command == CLUNET_COMMAND_PING) // Ответ на пинг
{
clunetSendingState = CLUNET_SENDING_STATE_PREINIT;
clunet_send(src_address, CLUNET_PRIORITY_COMMAND, CLUNET_COMMAND_PING_REPLY, data, size);
@@ -199,7 +204,7 @@ inline void clunet_data_received(unsigned char src_address, unsigned char dst_ad
if (on_data_received)
(*on_data_received)(src_address, dst_address, command, data, size);
- if ((clunetSendingState == CLUNET_SENDING_STATE_WAITING_LINE) && !CLUNET_READING) // , ,
+ if ((clunetSendingState == CLUNET_SENDING_STATE_WAITING_LINE) && !CLUNET_READING) // Если есть неотосланные данные, шлём, линия освободилась
{
clunetSendingState = CLUNET_SENDING_STATE_PREINIT;
clunet_start_send();
@@ -210,13 +215,13 @@ ISR(CLUNET_TIMER_OVF_VECTOR)
{
if (clunetTimerPeriods < 3)
clunetTimerPeriods++;
- else // ,
+ else // Слишком долго нет сигнала, сброс и отключение прерывания
{
- CLUNET_SEND_0; // ? ...
+ CLUNET_SEND_0; // А вдруг мы забыли линию отжать? Хотя по идее не должно...
clunetReadingState = CLUNET_READING_STATE_IDLE;
if ((clunetSendingState == CLUNET_SENDING_STATE_IDLE) && (!CLUNET_READING))
CLUNET_DISABLE_TIMER_OVF;
- if ((clunetSendingState == CLUNET_SENDING_STATE_WAITING_LINE) && (!CLUNET_READING)) // , ,
+ if ((clunetSendingState == CLUNET_SENDING_STATE_WAITING_LINE) && (!CLUNET_READING)) // Если есть неотосланные данные, шлём, линия освободилась
clunet_start_send();
}
}
@@ -225,40 +230,44 @@ ISR(CLUNET_TIMER_OVF_VECTOR)
ISR(CLUNET_INT_VECTOR)
{
unsigned char time = (unsigned char)((CLUNET_TIMER_REG-clunetTimerStart) & 0xFF);
- if (!CLUNET_READING) //
+ if (!CLUNET_READING) // Линию отпустило
{
CLUNET_ENABLE_TIMER_OVF;
- if (time >= (CLUNET_INIT_T+CLUNET_1_T)/2) // - ,
+ if (time >= (CLUNET_INIT_T+CLUNET_1_T)/2) // Если кто-то долго жмёт линию, это инициализация
{
clunetReadingState = CLUNET_READING_STATE_PRIO1;
}
- else switch (clunetReadingState) // ,
+ else switch (clunetReadingState) // А если не долго, то смотрим на этап
{
- case CLUNET_READING_STATE_PRIO1: // ,
+ case CLUNET_READING_STATE_PRIO1: // Получение приоритета, клиенту он не нужен
+ /*
if (time > (CLUNET_0_T+CLUNET_1_T)/2)
clunetReceivingPrio = 3;
else clunetReceivingPrio = 1;
+ */
clunetReadingState = CLUNET_READING_STATE_PRIO2;
break;
- case CLUNET_READING_STATE_PRIO2: // ,
+ case CLUNET_READING_STATE_PRIO2: // Получение приоритета, клиенту он не нужен
+ /*
if (time > (CLUNET_0_T+CLUNET_1_T)/2)
clunetReceivingPrio++;
+ */
clunetReadingState = CLUNET_READING_STATE_DATA;
clunetReadingCurrentByte = 0;
clunetReadingCurrentBit = 0;
dataToRead[0] = 0;
break;
- case CLUNET_READING_STATE_DATA: //
+ case CLUNET_READING_STATE_DATA: // Чтение всех данных
if (time > (CLUNET_0_T+CLUNET_1_T)/2)
dataToRead[clunetReadingCurrentByte] |= (1 << clunetReadingCurrentBit);
clunetReadingCurrentBit++;
- if (clunetReadingCurrentBit >= 8) //
+ if (clunetReadingCurrentBit >= 8) // Переходим к следующему байту
{
clunetReadingCurrentByte++;
clunetReadingCurrentBit = 0;
if (clunetReadingCurrentByte < CLUNET_READ_BUFFER_SIZE)
dataToRead[clunetReadingCurrentByte] = 0;
- else //
+ else // Если буфер закончился
{
clunetReadingState = CLUNET_READING_STATE_IDLE;
return;
@@ -266,9 +275,9 @@ ISR(CLUNET_INT_VECTOR)
}
if ((clunetReadingCurrentByte > CLUNET_OFFSET_SIZE) && (clunetReadingCurrentByte > dataToRead[CLUNET_OFFSET_SIZE]+CLUNET_OFFSET_DATA))
{
- // , !
+ // Получили данные полностью, ура!
clunetReadingState = CLUNET_READING_STATE_IDLE;
- char crc = check_crc((char*)dataToRead,clunetReadingCurrentByte); // CRC
+ char crc = check_crc((char*)dataToRead,clunetReadingCurrentByte); // Проверяем CRC
if (crc == 0)
clunet_data_received(dataToRead[CLUNET_OFFSET_SRC_ADDRESS], dataToRead[CLUNET_OFFSET_DST_ADDRESS], dataToRead[CLUNET_OFFSET_COMMAND], (char*)(dataToRead+CLUNET_OFFSET_DATA), dataToRead[CLUNET_OFFSET_SIZE]);
}
@@ -290,13 +299,16 @@ void clunet_init()
CLUNET_READ_INIT;
CLUNET_TIMER_INIT;
CLUNET_INIT_INT;
+#ifdef CLUNET_ENABLE_INT
CLUNET_ENABLE_INT;
+#warning CLUNET_ENABLE_INT is deprecated
+#endif
char reset_source = MCUCSR;
clunet_send(CLUNET_BROADCAST_ADDRESS, CLUNET_PRIORITY_MESSAGE, CLUNET_COMMAND_BOOT_COMPLETED, &reset_source, 1);
MCUCSR = 0;
}
-int clunet_ready_to_send() // 0, ,
+int clunet_ready_to_send() // Возвращает 0, если готов к передаче, иначе приоритет текущей задачи
{
if (clunetSendingState == CLUNET_SENDING_STATE_IDLE) return 0;
return clunetCurrentPrio;
diff --git a/clunet.h b/clunet.h
index f19145c..5869611 100644
--- a/clunet.h
+++ b/clunet.h
@@ -1,7 +1,7 @@
/* Name: clunet.h
* Project: CLUNET network driver
* Author: Alexey Avdyukhin
- * Creation Date: 2013-07-23
+ * Creation Date: 2013-09-09
* License: DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
*/
@@ -36,124 +36,126 @@
#define CLUNET_BROADCAST_ADDRESS 0xFF
#define CLUNET_COMMAND_DISCOVERY 0x00
-/* , */
+/* Поиск других устройств, параметров нет */
#define CLUNET_COMMAND_DISCOVERY_RESPONSE 0x01
-/* , - () */
+/* Ответ устройств на поиск, в качестве параметра - название устройства (текст) */
#define CLUNET_COMMAND_BOOT_CONTROL 0x02
-/* . - .
-<-0 -
-->1 -
-<-2 - , -
-->3 , 4 - , - ( )
-<-4
-->5 */
+/* Работа с загрузчиком. Данные - субкоманда.
+<-0 - загрузчик запущен
+->1 - перейти в режим обновления прошивки
+<-2 - подтверждение перехода, плюс два байта - размер страницы
+->3 запись прошивки, 4 байта - адрес, всё остальное - данные (равные размеру страницы)
+<-4 блок прошивки записан
+->5 выход из режима прошивки */
#define CLUNET_COMMAND_REBOOT 0x03
-/* . */
+/* Перезагружает устройство в загрузчик. */
#define CLUNET_COMMAND_BOOT_COMPLETED 0x04
-/* , . - MCU , . */
+/* Посылается устройством после инициализации библиотеки, сообщает об успешной загрузке устройства. Параметр - содержимое MCU регистра, говорящее о причине перезагрузки. */
#define CLUNET_COMMAND_DOOR_INFO 0x05
-/* .
-0 -
-1 -
-2 - */
+/*Информация об открытии двери.
+0 - закрыта
+1 - открыта
+2 - тревога */
#define CLUNET_COMMAND_DEVICE_POWER_INFO_REQUEST 0x06
-/* */
+/* Запрашивает информацию о состоянии выключателей */
#define CLUNET_COMMAND_DEVICE_POWER_INFO 0x07
-/* . - . */
+/* Состояние выключателей. Параметр - битовая маска состояния выключателей. */
#define CLUNET_COMMAND_DEVICE_POWER_COMMAND 0x08
-/* / . - . 0xFE - , 0xFF - . */
+/* Включает/выключает выключатели. Параметр - битовая маска. Для света 0xFE - убавить свет, а 0xFF - прибавить. */
#define CLUNET_COMMAND_SET_TIMER 0x09
-/* . - - ( ) */
+/* Установка таймера. Параметр - кол-во секунд (два байта) */
#define CLUNET_COMMAND_RC_BUTTON_PRESSED 0x0A
-/* . - , - .
- 01 - (Sony ?) - 4 .
-02 - . */
+/* Нажата кнопка на пульте. Первый байт - тип кода, далее - номер кнопки.
+На данный момент 01 - самый популярный стандарт (Sony вроде?) длина кода кнопки - 4 байта.
+02 - удержание кнопки его же. */
#define CLUNET_COMMAND_RC_BUTTON_PRESSED_RAW 0x0B
-/* . 4 . 2 - 2 - 0.032 . (1/8000000*256 ) */
+/* Недекодированные данные о нажатой кнопке на пульте для нестандартных пультов. Идут пачками по 4 байта. 2 из которых - длительность сигнала и 2 - длительность его отсутствия в 0.032 долях миллисекунды. (1/8000000*256 сек) */
#define CLUNET_COMMAND_RC_BUTTON_SEND 0x0C
-/* . CLUNET_COMMAND_RC_BUTTON_PRESSED, (- ), Sony ~30 */
+/* Заэмулировать кнопку пульта. Формат данных аналогичен CLUNET_COMMAND_RC_BUTTON_PRESSED, плюс в конце опциональный байт длительности удержания кнопки (кол-во дополнительных сигналов), для Sony это ~30мс */
#define CLUNET_COMMAND_RC_BUTTON_SEND_RAW 0x0D
-/* . CLUNET_COMMAND_RC_BUTTON_PRESSED_RAW. */
+/* Заэмулировать кнопку пульта на основе сырых данных. Формат данных аналогичен CLUNET_COMMAND_RC_BUTTON_PRESSED_RAW. */
#define CLUNET_COMMAND_LIGHT_LEVEL 0x0E
-/* . - 2 (0x0000 - 0x1FFF, 0x1FFF - 0 , 0x0000 - 5 ). */
+/* Сообщает об уровне освещения. Параметр - 2 байта (0x0000 - 0x1FFF, где 0x1FFF - 0 вольт между фотодиодом и землёй, а 0x0000 - 5 вольт). */
#define CLUNET_COMMAND_ONEWIRE_START_SEARCH 0x0F
-/* 1-wire , . */
+/* Запуск поиска 1-wire устройств, данные пустые. */
#define CLUNET_COMMAND_ONEWIRE_DEVICE_FOUND 0x10
-/* 1-wire . - 8 , , CRC. */
+/* Сообщает о найденном 1-wire устройсте. Данные - 8 байт, включающие тип устройства, серийный номер и CRC. */
#define CLUNET_COMMAND_TEMPERATURE 0x11
-/* . 1 - , 6 - , 2 - ( , !) */
+/* Сообщает о температуре. 1 байт - тип устройства, 6 - серийник, 2 - температура в формате устройства (смотреть на тип, чтобы декодировать!) */
#define CLUNET_COMMAND_TIME 0x12
-/* . - , , , ( 1900), ( 0), ( 1) */
+/* Сообщает время. Шесть байт - часы, минуты, секунды, год (от 1900), месяц (от 0), день (от 1) */
#define CLUNET_COMMAND_WHEEL 0x13
-/* , - ID , - */
+/* Сообщает обороты колеса мыши, первый байт - ID колеса, далее два байта - обороты */
#define CLUNET_COMMAND_VOLTAGE 0x14
-/* , - ID , - , 0x3FF = 5.12 */
+/* Сообщает напряжение на батарейке, первый байт - ID устройства, далее два байта - вольтаж, где 0x3FF = 5.12 */
#define CLUNET_COMMAND_MOTION 0x15
-/* , , - ID / */
+/* Сообщает, что в помещении есть движение, первый байт - ID датчика/камеры */
#define CLUNET_COMMAND_INTERCOM_RING 0x16
-/* */
+/* Звонок в домофон */
#define CLUNET_COMMAND_INTERCOM_MESSAGE 0x17
-/* , 4 - */
+/* Новое сообщение на автоответчике домофона, в данных 4 байта - номер сообщения */
#define CLUNET_COMMAND_INTERCOM_MODE_REQUEST 0x18
-/* */
+/* Запрашивает режим работы домофона */
#define CLUNET_COMMAND_INTERCOM_MODE_INFO 0x19
-/* , - , - */
+/* Сообщает режим работы домофона, первый байт - постоянный режим, второй - временный */
#define CLUNET_COMMAND_INTERCOM_MODE_SET 0x1A
-/* , - ( 0xFF, ), - () */
+/* Задаёт режим работы домофона, первый байт - постоянный режим (или 0xFF, чтобы не трогать), второй - временный (опционально) */
#define CLUNET_COMMAND_INTERCOM_RECORD_REQUEST 0x1B
-/* ,
- 4 ,
- 1 , 1 , 0 - */
+/* Запрашивает запись у домофона, подтверждает доставку или завершает передачу
+ Если 4 байта, то это номер запрашиваемой записи
+ Если 1 байт, то 1 в случае подтверждения получения пакета, 0 - завершение передачи */
#define CLUNET_COMMAND_INTERCOM_RECORD_DATA 0x1C
-/* . 4 - , 4 - , - */
+/* Передаёт кусок записи с автоответчика. Первые 4 байта - номер записи, далее 4 байта - смещение от начала файла, всё далее - данные из файла */
#define CLUNET_COMMAND_PING 0xFE
-/* , , */
+/* Пинг, на эту команду устройство должно ответить следующей командой, возвратив весь буфер */
#define CLUNET_COMMAND_PING_REPLY 0xFF
-/* , , */
+/* Ответ на пинг, в данных то, что было прислано в предыдущей команде */
#define CLUNET_PRIORITY_NOTICE 1
-/* 1 - , */
+/* Приоритет пакета 1 - неважное уведомление, которое вообще может быть потеряно без последствий */
#define CLUNET_PRIORITY_INFO 2
-/* 2 - - , */
+/* Приоритет пакета 2 - какая-то информация, не очень важная */
#define CLUNET_PRIORITY_MESSAGE 3
-/* 3 - - */
+/* Приоритет пакета 3 - сообщение с какой-то важной информацией */
#define CLUNET_PRIORITY_COMMAND 4
-/* 4 - , */
+/* Приоритет пакета 4 - команда, на которую нужно сразу отреагировать */
+#ifndef CLUNET_T
#define CLUNET_T ((F_CPU / CLUNET_TIMER_PRESCALER) / 15625)
+#endif
#if CLUNET_T < 8
# error Timer frequency is too small, increase CPU frequency or decrease timer prescaler
#endif
@@ -200,20 +202,20 @@
# error CLUNET_READ_BUFFER_SIZE must be <= 255
#endif
-//
+// Инициализация
void clunet_init();
-//
+// Отправка пакета
void clunet_send(unsigned char address, unsigned char prio, unsigned char command, char* data, unsigned char size);
-// 0, ,
+// Возвращает 0, если готов к передаче, иначе приоритет текущей задачи
int clunet_ready_to_send();
-// ,
-// - ,
+// Установка функций, которые вызываются при получении пакетов
+// Эта - получает пакеты, которые адресованы нам
void clunet_set_on_data_received(void (*f)(unsigned char src_address, unsigned char dst_address, unsigned char command, char* data, unsigned char size));
-// - , ,
+// А эта - абсолютно все, которые ходят по сети, включая наши
void clunet_set_on_data_received_sniff(void (*f)(unsigned char src_address, unsigned char dst_address, unsigned char command, char* data, unsigned char size));
char check_crc(char* data, unsigned char size);
diff --git a/clunet_config.h b/clunet_config.h
index 7369e95..925fb28 100644
--- a/clunet_config.h
+++ b/clunet_config.h
@@ -47,8 +47,7 @@
#define CLUNET_DISABLE_TIMER_OVF unset_bit(TIMSK, TOIE2)
//
-#define CLUNET_INIT_INT {set_bit(EICRA,ISC10);unset_bit(EICRA,ISC11);}
-#define CLUNET_ENABLE_INT set_bit(EIMSK, INT1)
+#define CLUNET_INIT_INT {set_bit(EICRA,ISC10);unset_bit(EICRA,ISC11);set_bit(EIMSK, INT1);}
//
#define CLUNET_TIMER_COMP_VECTOR TIMER2_COMP_vect
diff --git a/intercom.c b/intercom.c
index 9204e26..2851841 100644
--- a/intercom.c
+++ b/intercom.c
@@ -13,8 +13,8 @@
#include "transfer.h"
-volatile unsigned char mode_current = 1; //
-volatile unsigned char mode_temp = 0; //
+volatile unsigned char mode_current = 1; // Текущий режим
+volatile unsigned char mode_temp = 0; // Режим на один раз
volatile unsigned long int record_num = 0;
char buffer[32];
@@ -43,41 +43,41 @@ void send_current_mode(unsigned char dest)
{
buffer[0] = mode_current;
buffer[1] = mode_temp;
- clunet_send(dest, CLUNET_PRIORITY_INFO, CLUNET_COMMAND_INTERCOM_MODE_INFO, (char*)&buffer, 2); //
+ clunet_send(dest, CLUNET_PRIORITY_INFO, CLUNET_COMMAND_INTERCOM_MODE_INFO, (char*)&buffer, 2); // Отправляем в сеть текущий режим
}
void save_mode()
{
- eeprom_write_byte((void*)4, mode_current); //
- eeprom_write_byte((void*)5, mode_temp); //
+ eeprom_write_byte((void*)4, mode_current); // Режим
+ eeprom_write_byte((void*)5, mode_temp); // Временный режим
send_current_mode(CLUNET_BROADCAST_ADDRESS);
}
void data_received(unsigned char src_address, unsigned char dst_address, unsigned char command, char* data, unsigned char size)
{
- if (command == CLUNET_COMMAND_TIME && size >= 6) //
+ if (command == CLUNET_COMMAND_TIME && size >= 6) // Синхронизация времени
{
set_time(data[3]+2000, data[4], data[5], data[0],data[1],data[2]);
}
- else if (command == CLUNET_COMMAND_INTERCOM_MODE_REQUEST) //
+ else if (command == CLUNET_COMMAND_INTERCOM_MODE_REQUEST) // У нас запрашивают режим
{
send_current_mode(src_address);
}
- else if (command == CLUNET_COMMAND_INTERCOM_MODE_SET) //
+ else if (command == CLUNET_COMMAND_INTERCOM_MODE_SET) // Установка режима
{
if (size >= 1 && (unsigned char)data[0] != 0xFF) mode_current = data[0];
if (size >= 2 && (unsigned char)data[1] != 0xFF) mode_temp = data[1];
save_mode();
}
- else if (command == CLUNET_COMMAND_INTERCOM_RECORD_REQUEST) //
+ else if (command == CLUNET_COMMAND_INTERCOM_RECORD_REQUEST) // Передача записей
{
- if (size == 4) transfer_start(*((unsigned long int*)data), src_address); //
- else if (size == 1 && data[0] == 1) transfer_ack(); // ,
- else if (size == 1 && data[0] == 0) transfer_stop(); //
+ if (size == 4) transfer_start(*((unsigned long int*)data), src_address); // Начинаем передачу
+ else if (size == 1 && data[0] == 1) transfer_ack(); // Подтвержают приём, переходим к следующему куску
+ else if (size == 1 && data[0] == 0) transfer_stop(); // Прекращение передачи данных
}
}
-int is_LINE_POWER() // ,
+int is_LINE_POWER() // Определяет, что есть стабильный сигнал в линии
{
int i;
for (i = 0; i < 10; i++)
@@ -88,7 +88,7 @@ int is_LINE_POWER() // ,
return 1;
}
-void intercom_bell() //
+void intercom_bell() // Издаёт звук входящего звонка
{
int t;
for (t = 0; t < 9; t++)
@@ -101,7 +101,7 @@ void intercom_bell() //
}
}
-int answer_play(char* filename) //
+int answer_play(char* filename) // Отвечает и воспроизводит файл
{
ANSWER;
MODE_MYSOUND;
@@ -110,7 +110,7 @@ int answer_play(char* filename) //
{
while (sound_read() >= 0)
{
- if (!LINE_POWER || OFFHOOK) // ,
+ if (!LINE_POWER || OFFHOOK) // Сняли трубку, или сигнал исчез
{
sound_stop();
return 1;
@@ -121,23 +121,23 @@ int answer_play(char* filename) //
return 0;
}
-int answer_play_open(char* filename) // ,
+int answer_play_open(char* filename) // Отвечает, воспроизводит файл и открывает дверь
{
- if (answer_play(filename)) return 1; // ,
+ if (answer_play(filename)) return 1; // Сняли трубку, или сигнал исчез
OPEN;
return 0;
}
-int answer_record(char* filename1, char* filename2) // , ,
+int answer_record(char* filename1, char* filename2) // Отвечает, записывает сообщение,
{
- if (answer_play(filename1)) return 1; // ,
- beep(3000, 500); //
- sprintf(buffer, "/%08lu.wav", record_num); //
- clunet_send(CLUNET_BROADCAST_ADDRESS, CLUNET_PRIORITY_INFO, CLUNET_COMMAND_INTERCOM_MESSAGE, (char*)&record_num, sizeof(record_num)); //
+ if (answer_play(filename1)) return 1; // Отвечаем, предлагаем оставить сообщение
+ beep(3000, 500); // Биип
+ sprintf(buffer, "/%08lu.wav", record_num); // Формируем имя файла
+ clunet_send(CLUNET_BROADCAST_ADDRESS, CLUNET_PRIORITY_INFO, CLUNET_COMMAND_INTERCOM_MESSAGE, (char*)&record_num, sizeof(record_num)); // Отправляем в сеть сообщение
record_num++;
- eeprom_write_dword((void*)0, record_num); // -
- if (rec_wav(buffer) == 0) //
+ eeprom_write_dword((void*)0, record_num); // Запоминаем кол-во записей
+ if (rec_wav(buffer) == 0) // Пишем сообщение
{
int s = 0;
long int totalSize = 0;
@@ -145,7 +145,7 @@ int answer_record(char* filename1, char* filename2) // ,
{
s = sound_write();
totalSize += s;
- if (!LINE_POWER || OFFHOOK) // ,
+ if (!LINE_POWER || OFFHOOK) // Сняли трубку, или сигнал исчез
{
sound_stop();
return 1;
@@ -153,11 +153,11 @@ int answer_record(char* filename1, char* filename2) // ,
}
sound_stop();
}
- if (play_wav_pgm(filename2) == 0) // ,
+ if (play_wav_pgm(filename2) == 0) // Если пациент дождался, благодарим
{
while (sound_read() >= 0)
{
- if (!LINE_POWER || OFFHOOK) // ,
+ if (!LINE_POWER || OFFHOOK) // Сняли трубку, или сигнал исчез
{
sound_stop();
return 1;
@@ -168,19 +168,19 @@ int answer_record(char* filename1, char* filename2) // ,
return 0;
}
-void incoming_ring() //
+void incoming_ring() // Выполняется при любом входящем звонке
{
LED_RED_ON;
- unsigned char mode = (mode_temp != 0) ? mode_temp : mode_current; //
- // ,
+ unsigned char mode = (mode_temp != 0) ? mode_temp : mode_current; // Текущий режим
+ // Сообщение о звонке, указываем текущий режим
clunet_send(CLUNET_BROADCAST_ADDRESS, CLUNET_PRIORITY_INFO, CLUNET_COMMAND_INTERCOM_RING, (char*)&mode, 1);
intercom_bell();
- if (mode_temp) //
+ if (mode_temp) // Обнуляем временный режим
{
mode_temp = 0;
save_mode();
}
- if (!LINE_POWER) // ,
+ if (!LINE_POWER) // Аварийное откртие двери, если набрали и сразу сбросили
{
mode_temp = 0xFF;
save_mode();
@@ -189,38 +189,38 @@ void incoming_ring() //
{
switch (mode)
{
- case 1: // , ,
+ case 1: // Автоответчик, долго ждёт ответа, потом записывает
answer_record(AUTOLONG_WAV, SAVED_WAV);
break;
- case 2: // ,
+ case 2: // Автоответчик, сразу записывает
answer_record(AUTOFAST_WAV, SAVED_WAV);
break;
- case 3: // ,
+ case 3: // Приветствует хозяина, открывает дверь
answer_play_open(OPENME_WAV);
break;
- case 4: // ,
+ case 4: // Приветствует гостя, открывает дверь
answer_play_open(OPEN_WAV);
break;
- case 5: // . .
+ case 5: // Долго ждёт ответа. Сообщение не пишет.
answer_play(WAITLONG_WAV);
break;
- case 9: // , . , , .
+ case 9: // Здрасти, здрастите. Проходи, братишка, проходи.
answer_play_open(MODE9_WAV);
break;
- case 0xFF: //
+ case 0xFF: // Аварийное откртие двери
answer_play_open(EMERGENCY_OPEN_WAV);
}
MODE_NORMAL;
- _delay_ms(200); // ,
+ _delay_ms(200); // На случай, если контакты снятия трубки не успели разомкнуться
HANGUP;
}
- while (LINE_POWER); //
+ while (LINE_POWER); // Ждём пока не пропадёт сигнал
LED_RED_OFF;
- while (OFFHOOK); //
- _delay_ms(100); //
+ while (OFFHOOK); // И пользователь не положит трубку
+ _delay_ms(100); // Защита от дребезга контактов
}
-int count_disk() // ,
+int count_disk() // Считает, что набрали на диске
{
int cnt = 1;
while (1)
@@ -280,7 +280,7 @@ void say_mode(char istemp)
}
}
-void select_mode(char istemp) //
+void select_mode(char istemp) // Выбот режима
{
say_mode(istemp);
while (!CONTROL && OFFHOOK) play_wav_auto_pgm(MODELIST_WAV);
@@ -300,11 +300,11 @@ void select_mode(char istemp) //
void play_record(long unsigned int num)
{
- sprintf(buffer, "/%08lu.wav", num); //
+ sprintf(buffer, "/%08lu.wav", num); // Формируем имя файла
play_wav_auto(buffer);
}
-void control_mode() //
+void control_mode() // Режим управления
{
LED_GREEN_ON;
while (OFFHOOK)
@@ -332,7 +332,7 @@ void control_mode() //
}
}
LED_GREEN_OFF;
- _delay_ms(100); //
+ _delay_ms(100); // Защита от дребезга контактов
}
int main (void)
@@ -342,19 +342,19 @@ int main (void)
time_init();
sei();
//eeprom_write_dword((void*)0, 0);
- record_num = eeprom_read_dword((void*)0); // -
- mode_current = eeprom_read_byte((void*)4); //
- mode_temp = eeprom_read_byte((void*)5); //
+ record_num = eeprom_read_dword((void*)0); // Читаем кол-во записей
+ mode_current = eeprom_read_byte((void*)4); // Режим
+ mode_temp = eeprom_read_byte((void*)5); // Временный режим
disk_initialize(0);
- unset_bit(DDRA, 3); set_bit(PORTA, 3); //
- unset_bit(DDRA, 4); unset_bit(PORTA, 4); //
- set_bit(DDRA, 5); HANGUP; //
- set_bit(DDRA, 6); MODE_NORMAL; //
- unset_bit(DDRG, 0); set_bit(PORTG, 0); // ,
- set_bit(DDRD, 6); set_bit(DDRD, 7); //
- unset_bit(DDRA, 7); set_bit(PORTA, 7); //
+ unset_bit(DDRA, 3); set_bit(PORTA, 3); // Определение сигнала в линии
+ unset_bit(DDRA, 4); unset_bit(PORTA, 4); // Открывалка двери
+ set_bit(DDRA, 5); HANGUP; // Реле снимания трубки
+ set_bit(DDRA, 6); MODE_NORMAL; // Реле выбора режима
+ unset_bit(DDRG, 0); set_bit(PORTG, 0); // Определение, лежит ли трубка
+ set_bit(DDRD, 6); set_bit(DDRD, 7); // Светодиоды
+ unset_bit(DDRA, 7); set_bit(PORTA, 7); // Счётчик оборотов диска
unset_bit(DDRF, 0); // ADC+
unset_bit(PORTF, 0);
@@ -385,7 +385,7 @@ int main (void)
{
if (is_LINE_POWER()) incoming_ring();
if (OFFHOOK) control_mode();
- transfer_data(); // .
+ transfer_data(); // Передаём данные на досуге.
//play_wav_auto("/00000007.wav");
}
}