/* * Wi-Fi Detector opensource firmware * Utility functions * * Copyright (C) 2007 Michael Buesch * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include "util.h" #include "calibration.h" #include "main.h" #include "lcd.h" #include #include #include void mdelay(uint16_t msecs) { uint8_t timer, i; TCCR0B = DELAY_1MS_TIMERFREQ; do { /* Delay one millisecond */ for (i = DELAY_1MS_LOOP_TIMES; i; i--) { TCNT0 = 0; do { timer = TCNT0; } while (timer < DELAY_1MS_LOOP); } } while (--msecs); TCCR0B = 0; } void udelay(uint16_t usecs) { uint8_t tmp; __asm__ __volatile__( "1: \n" " ldi %1, %2 \n" "2: \n" " dec %1 \n" " brne 2b \n" " dec %A3 \n" " brne 1b \n" " cp %B3, __zero_reg__ \n" " breq 3f \n" " dec %B3 \n" " ldi %A3, 0xFF \n" " rjmp 1b \n" "3: \n" : "=d" (usecs), "=d" (tmp) : "M" (DELAY_1US_LOOP), "0" (usecs) ); } uint8_t eeprom_read8(const eeprom_uint8_t *addr) { eeprom_busy_wait(); return eeprom_read_byte((const uint8_t *)addr); } uint16_t eeprom_read16(const eeprom_uint16_t *addr) { eeprom_busy_wait(); return eeprom_read_word((const uint16_t *)addr); } void eeprom_write8(eeprom_uint8_t *addr, uint8_t value) { eeprom_busy_wait(); eeprom_write_byte((uint8_t *)addr, value); } void eeprom_write16(eeprom_uint16_t *addr, uint16_t value) { eeprom_busy_wait(); eeprom_write_word((uint16_t *)addr, value); } uint8_t hexdigit_to_ascii(uint8_t digit) { /* Convert a hexadecimal digit (0-F) to an ASCII character */ if (digit >= 0xA) digit += 0x41 - 0xA; else digit += 0x30; return digit; } void num16_to_ascii(uint8_t *buf, uint16_t v) { uint16_t orig = v; if (orig >= 10000) { *buf++ = v / 10000 + '0'; v %= 10000; } if (orig >= 1000) { *buf++ = v / 1000 + '0'; v %= 1000; } if (orig >= 100) { *buf++ = v / 100 + '0'; v %= 100; } if (orig >= 10) { *buf++ = v / 10 + '0'; v %= 10; } *buf++ = v + '0'; *buf = '\0'; } void panic(const prog_char *msg) { emergency_shutdown(); lcd_clear_buffer(); print(PSTR("Whee! PANIC :(")); lcd_charcursor(1, 0); print(msg); lcd_commit(); infinite_sleep(); } void infinite_sleep(void) { cli(); set_sleep_mode(SLEEP_MODE_PWR_DOWN); while (1) sleep_mode(); }