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

github.com/ClusterM/ibutton.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2014-01-22 22:06:26 +0400
committerAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2014-01-22 22:06:26 +0400
commitced434cba51302bb36bfecb16da5909f8e5d2d03 (patch)
tree3091a642b2124fc5a9f975b97f2efedcbedd7636
parent3fb28d466c70394eea9a6087bae705a17c4ef0c9 (diff)
Code comments
-rw-r--r--defines.h1
-rw-r--r--ibutton.c194
2 files changed, 121 insertions, 74 deletions
diff --git a/defines.h b/defines.h
index ad715df..f52d25c 100644
--- a/defines.h
+++ b/defines.h
@@ -1,6 +1,7 @@
#define F_CPU 8000000UL
#define UART_BAUD 19200
+#define DEBUG
#define LED_TOP_PORT C
#define LED_TOP_PIN 0
diff --git a/ibutton.c b/ibutton.c
index b47a079..253bfc7 100644
--- a/ibutton.c
+++ b/ibutton.c
@@ -13,8 +13,7 @@
#include "metacom.h"
#include "usb.h"
-#define DEBUG
-
+// Некоторые универсальные ключи
unsigned char VEZDEHOD_KEY1[] PROGMEM = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D};
unsigned char VEZDEHOD_KEY2[] PROGMEM = {0x01, 0xBE, 0x40, 0x11, 0x5A, 0x36, 0x00, 0xE1};
unsigned char VEZDEHOD_KEY3[] PROGMEM = {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F};
@@ -58,17 +57,22 @@ uint8_t debug_log_size = 0;
#else
#define WRITE_LOG(t) ;
#endif
+
ISR(INT0_vect)
{
+ // Выключаем прерывание после срабатывания
+ // Его цель - только вывести устройство из спящего режима
unset_bit(GICR, INT0);
}
ISR(INT1_vect)
{
+ // Выключаем прерывание после срабатывания
+ // Его цель - только вывести устройство из спящего режима
unset_bit(GICR, INT1);
}
-
+// Включает заданные светодиоды по маске
void set_leds(unsigned char leds_mask)
{
if (leds_mask & (1<<0)) set_bit(LED1_PORT, LED1_PIN); else unset_bit(LED1_PORT, LED1_PIN); // top led
@@ -80,29 +84,33 @@ void set_leds(unsigned char leds_mask)
if (leds_mask & (1<<6)) set_bit(LED7_PORT, LED7_PIN); else unset_bit(LED7_PORT, LED7_PIN); // center led
}
+// Ускоряет мигание светодиодами
void speedup_leds(void)
{
leds_time+=32;
}
+// Зажигаем следующий светодиод, если надо,
+// т.е. в каждый момент времени горит только один
void update_leds(void)
{
leds_time++;
- //if (leds_time >= 16) leds_time = 0;
if ((leds_mask & (1<<7)) && ((leds_time >> 13) % 2 == 1))
set_leds(0);
else set_leds(leds_mask & (1UL << (leds_time % 16)));
}
+// Зажигаем следующий светодиод, но больше времени уделяем на горение,
+// т.е. светодиоды визуально светятся ярче
void update_leds_bright(void)
{
leds_time++;
- //if (leds_time > 6) leds_time = 0;
if ((leds_mask & (1<<7)) && ((leds_time >> 13) % 2 == 1))
set_leds(0);
else set_leds(leds_mask & (1UL << (leds_time % 8)));
}
+// Отображает заданную цифру
void show_digit(unsigned char digit)
{
unsigned char mask = 0;
@@ -131,6 +139,7 @@ void show_digit(unsigned char digit)
set_leds(mask);
}
+// Проверяет, есть ли заданный ключ в базе
int key_exists(unsigned char* new_key)
{
unsigned char i, i2, bingo;
@@ -145,19 +154,16 @@ int key_exists(unsigned char* new_key)
return 0;
}
+// Считывает ключ
int read_mode()
{
onewire_init();
-/*
- USART_init();
- set_bit(UCSRB, TXEN); // TX
- */
int t = 0;
unsigned char serial[8];
char read_ok = 0;
- leds_mask = 1<<6;
+ leds_mask = 1<<6; // Во время считывания мигаем средним светодиодом
while (BUTTON_PRESSED)
{
wdt_reset();
@@ -169,23 +175,31 @@ int read_mode()
{
wdt_reset();
update_leds();
- char res = onewire_write_reset();
- if (res)
+ char res = onewire_write_reset(); // Посылает 1-wire ресет
+ if (res) // Если устройство ответило...
{
+ // Посылаем команду считывания ключа
onewire_write_byte(ONEWIRE_COMMAND_READ_ROM);
int b;
+ // Читаем 8 байт из ключа
for (b = 0; b < 8; b++)
serial[b] = onewire_read_byte();
+ // Проверяем CRC
if ((onewire_check_crc(serial, 8) == 0) && !onewire_all_zeros(serial, 8))
{
read_ok = 1;
}
}
- CYFRAL_PULLUP_ENABLE; // 750
- CYFRAL_REFERENCE_ENABLE; //
- long int code = read_cyfral_with_check();
+
+ // Теперь пытаемся прочитать цифрал-клюс
+ CYFRAL_PULLUP_ENABLE; // подтяжка 750 Ом
+ CYFRAL_REFERENCE_ENABLE; // делитель напряженния
+ // Читаем ключ несколько раз, с проверкой
+ long int code = read_cyfral_with_check();
+ // Выключаем назад подтяжку и делитель напряжения
CYFRAL_PULLUP_DISABLE;
CYFRAL_REFERENCE_DISABLE;
+ // Если ключ прочитан успешно...
if (code >= 0)
{
serial[0] = 0xFF;
@@ -195,24 +209,25 @@ int read_mode()
read_ok = 1;
}
t++;
+ // После 2000 неудачных попыток выходим и выключаемся
if (t > 2000)
- {
return 0;
- }
- if (BUTTON_PRESSED || USB_POWERED)
- {
- return 1; //
- }
+ if (BUTTON_PRESSED || USB_POWERED) // При нажатии кнопки или подключения USB...
+ return 1; // возврат в основной режим
+ // Если ключ прочитан успешно...
if (read_ok)
{
read_ok = 0;
t = 0;
+ // Проверяем - нет ли у нас уже такого ключа?
int exists = key_exists(serial);
int num;
+ // Если нет...
if (!exists)
{
+ // Сохраняем ключ
current_key = key_count;
key_count++;
eeprom_write_block(serial, (void*)(key_count*8), 8);
@@ -220,8 +235,10 @@ int read_mode()
num = key_count;
} else
{
+ // Иначе отображаем номер существующего
num = exists;
}
+ // Мигаем три раза номером ключа
for (t = 0; t < 3; t++)
{
show_digit(num);
@@ -244,11 +261,12 @@ int read_mode()
}
}
-int ibutton_read_byte_from_master(unsigned char* value) // . - 0, - 1, - 2
+// Читает байт от мастера. Таймаут - возвращает 0, ресет - 1, удачно - 2
+int ibutton_read_byte_from_master(unsigned char* value)
{
int i;
*value = 0;
- for (i = 0; i < 8; i++) //
+ for (i = 0; i < 8; i++) // Ждем команду
{
TCNT1 = 0; while (!ONEWIRE_MASTER_RX && (TCNT1 < 30000)); if (TCNT1 >= 30000) return 0;
TCNT1 = 0; while (ONEWIRE_MASTER_RX && (TCNT1 < 30000));
@@ -258,87 +276,101 @@ int ibutton_read_byte_from_master(unsigned char* value) //
return 2;
}
+// Посылает мастуру presence-pulse и ждёт команду
int ibutton_wait_for_master3(unsigned char* key)
{
wdt_reset();
- set_leds(0); // , ..
- ONEWIRE_WAIT(20) // delay 20us
- ONEWIRE_MASTER_TX(140);
+ set_leds(0); // Гасим светодиоды, т.к. нет времени ими мигать
+ ONEWIRE_WAIT(20) // Немножко ждём
+ ONEWIRE_MASTER_TX(140); // Presence-pulse
+ // Ждём возобновления линии
TCNT1 = 0; while (ONEWIRE_MASTER_RX && (TCNT1 < 30000));
- if (TCNT1 >= 300) return 1;
+ if (TCNT1 >= 300) return 1; // Если линия долго прижата мастером, это ресет
int i, bit;
unsigned char command = 0;
- i = ibutton_read_byte_from_master(&command); //
+ i = ibutton_read_byte_from_master(&command); // Получаем комманду
if (i != 2) return i;
+ WRITE_LOG(command);
- if (command == ONEWIRE_COMMAND_SKIP_ROM) // SKIP_ROM . .
+ if (command == ONEWIRE_COMMAND_SKIP_ROM) // Если нам сначала прислали SKIP_ROM команду. На практике такого не бывало.
{
i = ibutton_read_byte_from_master(&command);
if (i != 2) return i;
+ WRITE_LOG(command);
}
- WRITE_LOG(command);
- if ((command == ONEWIRE_COMMAND_READ_ROM) || (command == ONEWIRE_COMMAND_READ_ROM_ALT)) // ,
+ if ((command == ONEWIRE_COMMAND_READ_ROM) || (command == ONEWIRE_COMMAND_READ_ROM_ALT)) // Получили запрос, шлём ключ
{
for (i = 0; i < 8; i++)
{
for (bit = 0; bit < 8; bit++)
{
+ // Ждём запроса от мастера
TCNT1 = 0; while ((!ONEWIRE_MASTER_RX) && (TCNT1 < 30000)); if (TCNT1 >= 30000) return 0;
+ // Если нужно передать логический ноль, прижимаем линию
if (((key[i] >> bit) & 1) == 0)
{
ONEWIRE_MASTER_TX(35);
}
+ // Ждём возобновления линии
TCNT1 = 0; while (ONEWIRE_MASTER_RX && (TCNT1 < 30000));
- if (TCNT1 >= 300) return 1;
+ if (TCNT1 >= 300) return 1; // Если линия долго прижата мастером, это ресет
}
}
}
- if (command == ONEWIRE_COMMAND_SEARCH) // !
+ if (command == ONEWIRE_COMMAND_SEARCH) // Мастер выполняет поиск!
{
for (i = 0; i < 8; i++)
{
for (bit = 0; bit < 8; bit++)
{
- char d = (key[i] >> bit) & 1; //
+ char d = (key[i] >> bit) & 1; // Текущий бит
+ // Ждём запроса от мастера
TCNT1 = 0; while ((!ONEWIRE_MASTER_RX) && (TCNT1 < 30000)); if (TCNT1 >= 30000) return 0;
- if (d == 0) //
+ if (d == 0) // Если нужно передать логический ноль, прижимаем линию
{
ONEWIRE_MASTER_TX(35);
}
+ // Ждём возобновления линии
TCNT1 = 0; while (ONEWIRE_MASTER_RX && (TCNT1 < 30000));
- if (TCNT1 >= 300) return 1;
+ if (TCNT1 >= 300) return 1; // Если линия долго прижата мастером, это ресет
+ // Ждём запроса от мастера
TCNT1 = 0; while ((!ONEWIRE_MASTER_RX) && (TCNT1 < 30000)); if (TCNT1 >= 30000) return 0;
- if (d != 0)
+ if (d != 0) // Если нужно передать логическую единицу, прижимаем линию
{
ONEWIRE_MASTER_TX(35);
}
+ // Ждём возобновления линии
TCNT1 = 0; while (ONEWIRE_MASTER_RX && (TCNT1 < 30000));
- if (TCNT1 >= 300) return 1;
+ if (TCNT1 >= 300) return 1; // Если линия долго прижата мастером, это ресет
+ // Ждём сигнала от мастера
TCNT1 = 0; while (!ONEWIRE_MASTER_RX && (TCNT1 < 30000)); if (TCNT1 >= 30000) return 0;
+ // Ждём возобновления линии
TCNT1 = 0; while (ONEWIRE_MASTER_RX && (TCNT1 < 30000));
- if (TCNT1 >= 300) return 1;
+ if (TCNT1 >= 300) return 1; // Если линия долго прижата мастером, это ресет
char d2;
- if (TCNT1 < 45) d2 = 1; else d2 = 0; // ,
- if (d != d2) return 0; // ,
+ if (TCNT1 < 45) d2 = 1; else d2 = 0; // Бит, который подтверждает мастер
+ if (d != d2) return 0; // Если они не совпадают, выходим
}
}
}
return 0;
}
+// Отвечает на ресет мастеру
void ibutton_wait_for_master2(unsigned char* key)
{
int reset;
do
{
reset = ibutton_wait_for_master3(key);
- } while (reset); // ,
+ } while (reset); // Если в результате общения получили ресет, то начинаем общение заново
}
+// Ждём ресета от мастера
void ibutton_wait_for_master(unsigned char* key)
{
int waittime;
@@ -346,33 +378,39 @@ void ibutton_wait_for_master(unsigned char* key)
{
wdt_reset();
TCNT1 = 0;
- while (!ONEWIRE_MASTER_RX && (TCNT1 < 30000)) //
+ while (!ONEWIRE_MASTER_RX && (TCNT1 < 30000)) // Пока нет сигнала
{
wdt_reset();
update_leds();
if (BUTTON_PRESSED || USB_POWERED) return;
};
+ // Если долго не было сигнала, ждём дальше
if (TCNT1 >= 30000) continue;
+ // Если же сигнал есть, считаем время
TCNT1 = 0;
- while (ONEWIRE_MASTER_RX) if (TCNT1 > 30000) TCNT1 = 30000; //
- if (TCNT1 > 300) //
+ while (ONEWIRE_MASTER_RX) if (TCNT1 > 30000) TCNT1 = 30000; // Пока есть сигнал
+ if (TCNT1 > 300) // Не слишком короткий
{
- ibutton_wait_for_master2(key); // ,
- }
+ ibutton_wait_for_master2(key); // Дверь заговорила, отвечаем
+ }
+ // Был сигнал, ждём ресета с нуля
waittime = 0;
}
- ibutton_wait_for_master2(key); // ,
+ ibutton_wait_for_master2(key); // Не дождались, начинаем сами
}
-
+// Режим посылки ключа
int send_mode()
{
+ // Если ключей нет, сразу переходим в режим чтения ключей
if (!key_count) return 1;
int t;
while (1)
{
if (current_key >= key_count) current_key = 0;
+ // Показываем номер текущего ключа
show_digit(current_key+1);
+ // Ждём пока кнопку, отпустят
while (BUTTON_PRESSED)
{
wdt_reset();
@@ -380,35 +418,43 @@ int send_mode()
_delay_ms(1);
}
unsigned char key[8];
+ // В обычном режиме читаем ключ из EEPROM
if (!vezdehod_mode)
eeprom_read_block(key, (void*)((current_key+1)*8), 8);
else
- { // , PGM
+ { // Если режим вездехода, то читаем ключ из PGM памяти
int i;
for (i = 0; i < 8; i++)
key[i] = pgm_read_byte(&VEZDEHOD_KEYS[current_key][i]);
}
+ // Включаем 1-wire
onewire_init();
t = 0;
while (1)
{
- if (key[0] == 0xFF) //
+ if (key[0] == 0xFF) // Цифрал
{
+ // После 1000 попыток выключаемся
if (t > 1000) return 0;
wdt_reset();
speedup_leds();
update_leds();
uint16_t cyfral_key = key[1] + key[2]*0x100;
+ // Посылаем ключ
cyfral_send(cyfral_key);
}
- else if (key[0] == 0xFE) //
+ else if (key[0] == 0xFE) // Метаком
{
+ // После 1000 попыток выключаемся
if (t > 1000) return 0;
wdt_reset();
update_leds();
+ // Посылаем ключ
metacom_send(key+1);
- } else {
+ } else { // iButton
+ // После трёх попыток выключаемся
if (t >= 2) return 0;
+ // Переходим в режим переговоров с дверью
ibutton_wait_for_master(key);
}
@@ -424,7 +470,7 @@ int send_mode()
update_leds_bright();
_delay_ms(1);
t++;
- if (t >= 1000 && !vezdehod_mode) return 1; //
+ if (t >= 1000 && !vezdehod_mode) return 1; // смена режима
}
break;
}
@@ -439,17 +485,17 @@ void sleep()
onewire_init();
set_leds(0);
UCSRB = 0; // disable USART
- unset_bit(PORTD, 0); unset_bit(PORTD, 1); // USART
+ unset_bit(PORTD, 0); unset_bit(PORTD, 1); // Прижимаем USART к земле
set_bit(DDRD, 0); set_bit(DDRD, 1);
LINE_DISABLE;
CYFRAL_PULLUP_DISABLE;
CYFRAL_REFERENCE_DISABLE;
- set_bit(MCUCR, SM1); unset_bit2(MCUCR, SM0, SM2); // Power-down
- set_bit2(GICR, INT1, INT0); //
+ set_bit(MCUCR, SM1); unset_bit2(MCUCR, SM0, SM2); // Power-down спящий режим
+ set_bit2(GICR, INT1, INT0); // Включаем прерывания
- set_bit(WDTCR, WDCE), unset_bit(WDTCR, WDE); //
+ set_bit(WDTCR, WDCE), unset_bit(WDTCR, WDE); // Собаку выключаем
if (BUTTON_PRESSED || USB_POWERED) return;
sleep_mode();
@@ -457,7 +503,7 @@ void sleep()
int main (void)
{
- UCSRB = 0; // disable USART
+ UCSRB = 0; // Выключаем UART, из-за него ток утекает, куда не надо
set_bit(LED1_DDR, LED1_PIN); // top led
set_bit(LED2_DDR, LED2_PIN); // top-right led
@@ -467,14 +513,14 @@ int main (void)
set_bit(LED6_DDR, LED6_PIN); // top-left led
set_bit(LED7_DDR, LED7_PIN); // center led
- unset_bit(BUTTON_DDR, BUTTON_PIN); set_bit(BUTTON_OUT, BUTTON_PIN); //
- unset_bit(USB_DETECT_DDR, USB_DETECT_PIN); set_bit(USB_DETECT_OUT, USB_DETECT_PIN); // USB
- unset_bit(CYFRAL_PULLUP_DDR, CYFRAL_PULLUP_PIN); unset_bit(CYFRAL_PULLUP_OUT, CYFRAL_PULLUP_PIN); // 750
- set_bit(CYFRAL_REFERENCE_DDR, CYFRAL_REFERENCE_PIN); unset_bit(CYFRAL_REFERENCE_OUT, CYFRAL_REFERENCE_PIN); //
- set_bit(LINE_ENABLE_DDR, LINE_ENABLE_PIN); unset_bit(LINE_ENABLE_OUT, LINE_ENABLE_PIN); //
+ unset_bit(BUTTON_DDR, BUTTON_PIN); set_bit(BUTTON_OUT, BUTTON_PIN); // Подтяжка кнопки
+ unset_bit(USB_DETECT_DDR, USB_DETECT_PIN); set_bit(USB_DETECT_OUT, USB_DETECT_PIN); // Подтяжка определения USB
+ unset_bit(CYFRAL_PULLUP_DDR, CYFRAL_PULLUP_PIN); unset_bit(CYFRAL_PULLUP_OUT, CYFRAL_PULLUP_PIN); // Подтяжка 750 Ом выключена
+ set_bit(CYFRAL_REFERENCE_DDR, CYFRAL_REFERENCE_PIN); unset_bit(CYFRAL_REFERENCE_OUT, CYFRAL_REFERENCE_PIN); // Делитель напряжения выключен
+ set_bit(LINE_ENABLE_DDR, LINE_ENABLE_PIN); unset_bit(LINE_ENABLE_OUT, LINE_ENABLE_PIN); // линия выключена
onewire_init();
- //
+ // Лишние ноги прижимаем к земле
set_bit(DDRC, 4); unset_bit(PORTC, 4);
set_bit(DDRC, 5); unset_bit(PORTC, 5);
set_bit(DDRD, 4); unset_bit(PORTD, 4);
@@ -497,19 +543,19 @@ int main (void)
while (1)
{
- set_bit(WDTCR, WDCE), set_bit(WDTCR, WDE); //
- set_bit(WDTCR, WDCE), set_bit3(WDTCR, WDP2, WDP1, WDP0); //
+ set_bit(WDTCR, WDCE), set_bit(WDTCR, WDE); // Собака
+ set_bit(WDTCR, WDCE), set_bit3(WDTCR, WDP2, WDP1, WDP0); // Неспешащая собака
int t = 0;
vezdehod_mode = 0;
do
{
- //
+ // При включении показываем бегущий по кругу светодиод
for(b = 0; b < 6; b++)
{
//set_leds(1<<b);
leds_mask = 1<<b;
- for (i = 0;i < 30; i++) // 30,
+ for (i = 0;i < 30; i++) // Ждём 30мс, обнуляя собаку и обновляя светодиоды
{
wdt_reset();
update_leds();
@@ -517,22 +563,22 @@ int main (void)
}
}
t++;
- if (t == 5) // , ( DEBUG)
+ if (t == 5) // Если долго держим кнопку, то пишем лог для отладки или переходим в режим вездехода (в зависимости от директивы DEBUG)
{
- show_digit(0); // 0
+ show_digit(0); // Показываем 0
#ifdef DEBUG
eeprom_write_byte((void*)1, debug_log_size);
eeprom_write_block((char*)debug_log, (void*)256, debug_log_size*2);
#endif
- debug_log_size = 0; // debug-log
- for (i = 0;i < 500; i++) // 0
+ debug_log_size = 0; // Обнуляем debug-log
+ for (i = 0;i < 500; i++) // Показываем 0 в течении некоторого полусекунды
{
wdt_reset();
update_leds();
_delay_ms(1);
}
- vezdehod_mode = 1; // -!
+ vezdehod_mode = 1; // Включаем режим вездеход-ключей!
current_key = 0;
/*
set_leds(0);