iAudio X5: Enable reading of DS2411 serial number. See it under System|Debug|View HW info.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12723 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
04ea446edc
commit
89a38d4273
4 changed files with 290 additions and 3 deletions
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
48
firmware/export/ds2411.h
Normal file
48
firmware/export/ds2411.h
Normal file
|
@ -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 <stdbool.h>
|
||||
|
||||
/*
|
||||
* 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_ */
|
206
firmware/target/coldfire/iaudio/x5/ds2411-x5.c
Normal file
206
firmware/target/coldfire/iaudio/x5/ds2411-x5.c
Normal file
|
@ -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 */
|
Loading…
Reference in a new issue