diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 13e0046334..6b5194f147 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -81,6 +81,9 @@ #ifdef IRIVER_H300_SERIES #include "pcf50606.h" /* for pcf50606_read */ #endif +#ifdef IAUDIO_X5 +#include "ds2411.h" +#endif /*---------------------------------------------------*/ /* SPECIAL DEBUG STUFF */ @@ -535,8 +538,9 @@ static bool dbg_hw_info(void) #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250 char buf[32]; unsigned manu, id; /* flash IDs */ - bool got_id; /* flag if we managed to get the flash IDs */ + int got_id; /* flag if we managed to get the flash IDs */ int oldmode; /* saved memory guard mode */ + int line = 0; oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */ @@ -551,13 +555,41 @@ static bool dbg_hw_info(void) lcd_setfont(FONT_SYSFIXED); lcd_clear_display(); - lcd_puts(0, 0, "[Hardware info]"); + lcd_puts(0, line++, "[Hardware info]"); if (got_id) snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id); else snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */ - lcd_puts(0, 1, buf); + lcd_puts(0, line++, buf); + +#ifdef IAUDIO_X5 + { + struct ds2411_id id; + + line++; + lcd_puts(0, line++, "Serial Number:"); + + got_id = ds2411_read_id(&id); + + if (got_id == DS2411_OK) + { + snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code); + lcd_puts(0, line++, buf); + snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X", + (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2], + (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]); + lcd_puts(0, line++, buf); + snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc); + lcd_puts(0, line++, buf); + } + else + { + snprintf(buf, 32, "READ ERR=%d", got_id); + lcd_puts(0, line++, buf); + } + } +#endif lcd_update(); diff --git a/firmware/SOURCES b/firmware/SOURCES index 2d2296a439..945f400243 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -364,6 +364,7 @@ target/coldfire/iaudio/system-iaudio.c target/coldfire/iaudio/usb-iaudio.c target/coldfire/iaudio/x5/backlight-x5.c target/coldfire/iaudio/x5/button-x5.c +target/coldfire/iaudio/x5/ds2411-x5.c target/coldfire/iaudio/x5/lcd-as-x5.S target/coldfire/iaudio/x5/lcd-x5.c target/coldfire/iaudio/x5/m5636-x5.c diff --git a/firmware/export/ds2411.h b/firmware/export/ds2411.h new file mode 100644 index 0000000000..c55579cba5 --- /dev/null +++ b/firmware/export/ds2411.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Michael Sevakis + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef _DS2411_H_ +#define _DS2411_H_ + +#include + +/* + * Byte 0: 8-bit family code (always 01h) + * Bytes 1-6: 48-bit serial number + * Byte 7: 8-bit CRC code + */ +struct ds2411_id +{ + unsigned char family_code; + unsigned char uid[6]; + unsigned char crc; +} __attribute__((packed)); + +extern int ds2411_read_id(struct ds2411_id *id); + +/* return values */ +enum ds2411_id_return_codes +{ + DS2411_NO_PRESENCE = -3, + DS2411_INVALID_FAMILY_CODE, + DS2411_INVALID_CRC, + DS2411_OK = 0, +}; + +#endif /* _DS2411_H_ */ diff --git a/firmware/target/coldfire/iaudio/x5/ds2411-x5.c b/firmware/target/coldfire/iaudio/x5/ds2411-x5.c new file mode 100644 index 0000000000..a8b2ae705c --- /dev/null +++ b/firmware/target/coldfire/iaudio/x5/ds2411-x5.c @@ -0,0 +1,206 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Michael Sevakis + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "system.h" +#include "cpu.h" +#include "ds2411.h" +#include "logf.h" + +/* Delay factor that depends on CPU frequency */ +static unsigned int ds2411_delay_factor = 0; + +#define DS2411_BIT (1 << 22) + +/* Delay the specified number of microseconds - plus a tiny bit */ +#define DELAY(uS) \ + asm volatile( \ + "move.l %[x], %%d0 \n" \ + "mulu.l %[factor], %%d0 \n" \ + "1: \n" \ + "subq.l #1, %%d0 \n" \ + "bhi.s 1b \n" \ + : : [factor]"d"(ds2411_delay_factor), [x]"d"(uS) : "d0"); + +/* Calculate the CRC of a byte */ +static unsigned char ds2411_calc_crc(unsigned char byte) +{ + /* POLYNOMIAL = X^8 + X^5 + X^4 + 1 */ + static const unsigned char eor[8] = + { + 0x5e, /* 01011110 */ + 0xbc, /* 10111100 */ + 0x61, /* 01100001 */ + 0xc2, /* 11000010 */ + 0x9d, /* 10011101 */ + 0x23, /* 00100011 */ + 0x46, /* 01000110 */ + 0x8c, /* 10001100 */ + }; + + unsigned char crc = 0; + int i = 0; + + do + { + if (byte & (1 << i)) + crc ^= eor[i]; + } + while (++i < 8); + + return crc; +} /* ds2411_calc_crc */ + +/* Write a byte to the DS2411 - LSb first */ +static void ds2411_write_byte(unsigned char data) +{ + int i = 0; + + do + { + if (data & 0x01) + { + /* Write a "1": Hold line low, then leave line pulled up and wait + out the remainder of Tslot */ + or_l(DS2411_BIT, &GPIO_ENABLE); + DELAY(6); + and_l(~DS2411_BIT, &GPIO_ENABLE); + DELAY(60); + } + else + { + /* Write a "0": Hold line low, then leave line pulled up and wait + out the remainder of Tslot which is just Trec */ + or_l(DS2411_BIT, &GPIO_ENABLE); + DELAY(60); + and_l(~DS2411_BIT, &GPIO_ENABLE); + DELAY(6); + } + + data >>= 1; + } + while (++i < 8); +} /* ds2411_write_byte */ + +/* Read a byte from the DS2411 - LSb first */ +static unsigned char ds2411_read_byte(void) +{ + int i = 0; + unsigned data = 0; + + do + { + /* Hold line low to begin bit read: Tf + Trl */ + or_l(DS2411_BIT, &GPIO_ENABLE); + DELAY(6); + + /* Set line high and delay before sampling within the master + sampling window: Tmsr - max 15us from Trl start */ + and_l(~DS2411_BIT, &GPIO_ENABLE); + DELAY(9); + + /* Sample data line */ + if ((GPIO_READ & DS2411_BIT) != 0) + data |= 1 << i; + + /* Wait out the remainder of Tslot */ + DELAY(60); + } + while (++i < 8); + + return data; +} /* ds2411_read_byte */ + +/* + * Byte 0: 8-bit family code (01h) + * Bytes 1-6: 48-bit serial number + * Byte 7: 8-bit CRC code + */ +int ds2411_read_id(struct ds2411_id *id) +{ + int i; + unsigned char crc; + + /* Initialize delay factor based on loop time: 3*(uS-1) + 3 */ + ds2411_delay_factor = MIN(cpu_frequency / (1000000*3), 1); + + /* Init GPIO 1 wire bus for bit banging with a pullup resistor where + * it is set low as output and switched between input and output mode. + * Required for bidirectional communication on a single wire. + */ + or_l(DS2411_BIT, &GPIO_FUNCTION); /* Set pin as GPIO */ + and_l(~DS2411_BIT, &GPIO_ENABLE); /* Set as input */ + and_l(~DS2411_BIT, &GPIO_OUT); /* Set low when set as output */ + + /* Delay 100us to stabilize */ + DELAY(100); + + /* Issue reset pulse - 480uS or more to ensure standard (not overdrive) + mode - we don't have the timing accuracy for that. */ + or_l(DS2411_BIT, &GPIO_ENABLE); + /* Delay 560us: (Trstlmin + Trstlmax) / 2*/ + DELAY(560); + and_l(~DS2411_BIT, &GPIO_ENABLE); + /* Delay 66us: Tpdhmax + 6 */ + DELAY(66); + + /* Read presence pulse - line should be pulled low at proper time by the + slave device */ + if (GPIO_READ & DS2411_BIT) + { + logf("ds2411: no presence pulse"); + return DS2411_NO_PRESENCE; + } + + /* Trsth + 1 - 66 = Tpdhmax + Tpdlmax + Trecmin + 1 - 66 */ + DELAY(240); + + /* ds2411 should be ready for data transfer */ + + /* Send Read ROM command */ + ds2411_write_byte(0x33); + + /* Read ROM serial number and CRC */ + i = 0, crc = 0; + + do + { + unsigned char byte = ds2411_read_byte(); + ((unsigned char *)id)[i] = byte; + crc = ds2411_calc_crc(crc ^ byte); + } + while (++i < 8); + + /* Check that family code is ok */ + if (id->family_code != 0x01) + { + logf("ds2411: invalid family code=%02X", (unsigned)id->family_code); + return DS2411_INVALID_FAMILY_CODE; + } + + /* Check that CRC was ok */ + if (crc != 0) /* Because last loop eors the CRC with the resulting CRC */ + { + logf("ds2411: invalid CRC=%02X", (unsigned)id->crc); + return DS2411_INVALID_CRC; + } + + /* Good ID read */ + return DS2411_OK; +} /* ds2411_read_id */