|
http://www.mastincrosbie.com/Marks_LEGO_projects/Dump_memory_contents_of_an_I2C_device.html Dump memory contents of an I2C device May 2008 I
wanted to load my own macros into the NRLink-Nx sensor from
mindsensors.com. The first challenge was to understand how to send and
receive I2C messages. Then I had to understand the register layout on
the NRLink. It turns out that it is pretty simple; if you send an I2C
message to write to a particular location then you can update the
macros stored in the NRLink EEPROM. The RobotC sendI2CMsg() function
writes the bytes into the NRLink EEPROM. As
a test program I wanted to dump out the contents of the EEPROM, so I
modified the sample code provided by mindsensors and created this
EEPROM RAM dump utility. A couple of features:
The I2CMemoryDump.c
is reproduced below, and tested in RobotC 1.22 beta with NXT firmware
7.35. The
function that dumps the I2C memory address space to a file is
dumpNRLinkRAM(). It iterates through the I2C address space and writes
the memory contents into a file on the NXT named testFile.dat.
//*!!Sensor, S1, NRLINK,
sensorI2CCustomStd9V, , !!*// //*!!
!!*// //*!!Start automatically generated configuration
code. !!*// const tSensors NRLINK = (tSensors) S1; //sensorI2CCustomStd9V
//*!!!!*// //*!!CLICK to edit 'wizard' created sensor & motor
configuration. !!*//
/* * * Dump the contents of the EEPROM in the mindsensors
NRLINK * sensor and record them to a data log file and print
on the screen * * Use this program to debug writing macros into the
NRLink-Nx device * * Modified by Mark Crosbie [email protected] 1 April 2008 * To install macros that power both motors
simultaneously * For more information visit http://markclego.mastincrosbie.com * * * Original code written by Dr. Nitin Patil * Copyright (c) mindsensors.com 2006, 2007 * for more info visit www.mindsensors.com * */
//definations for NRLink
const ubyte NRLinkID = 0x02; const ubyte NRLinkDataBytes = 0x40; const ubyte NRLinkCommandReg = 0x41; const ubyte NRLinkReadResult = 0x42; const ubyte NRLinkWriteData = 0x42; const tSensors NRLinkPort = NRLINK; // Connect NRLink sensor to
this port!!
const ubyte NRLinkDefault = 0x44; const ubyte NRLinkFlush = 0x46; const ubyte NRLinkHighSpeed = 0x48; const ubyte NRLinkLongRange = 0x4C; const ubyte NRLinkShortRange = 0x53; const ubyte NRLinkSetADPAON = 0x4E; const ubyte NRLinkSETADPAOFF = 0x4F; const ubyte NRLinkTxUnassembled = 0x55;
const ubyte NRLinkSelectPF = 0x50;
///////////////////////////////////////////////////////////////////////////// // // send Command to NrLink interface // ///////////////////////////////////////////////////////////////////////////// void NRLinkCommand(byte NRLinkCommand) {
byte NRLinkMsg[5]; const byte MsgSize = 0; const byte Address = 1; const byte CommandAddress = 2; const byte Command = 3;
//
Build the I2C message NRLinkMsg[MsgSize] = 3; NRLinkMsg[Address] = NRLinkID; NRLinkMsg[CommandAddress] = NRLinkCommandReg ; NRLinkMsg[Command] = NRLinkCommand;
while (nI2CStatus[NRLinkPort] ==
STAT_COMM_PENDING) { // Wait for I2C bus to be ready } //
when the I2C bus is ready, send the message you built sendI2CMsg(NRLinkPort, NRLinkMsg[0], 0); }
// Print the contents of the NRLink RAM starting and // ending at the addresses given // // Each line is printed and the display wraps around // every 8 lines void readMacros(ubyte startAddr, ubyte endAddr) {
ubyte i, line; ubyte addr; const int kReplyLength = 1; ubyte nReplyBytes[kReplyLength];
string s1, s2;
TI2CStatus err;
typedef struct{ byte nMsgSize; byte nDeviceAddress; byte nLocationPtr; } TI2C_Output;
TI2C_Output sOutput; sOutput.nMsgSize = 2; sOutput.nDeviceAddress = 0x02; sOutput.nLocationPtr = 0;
eraseDisplay();
line=0; addr = startAddr; for(i=(int)startAddr; i < (int)endAddr; i++) {
nI2CBytesReady[NRLinkPort]=0; err = NO_ERR; do { err = nI2CStatus[NRLinkPort]; wait1Msec(2); }while(err == STAT_COMM_PENDING);
sOutput.nLocationPtr = addr; addr++;
sendI2CMsg(NRLinkPort, sOutput.nMsgSize,
kReplyLength);
err = NO_ERR; do { err = nI2CStatus[NRLinkPort]; wait1Msec(2); }while(err == STAT_COMM_PENDING);
err = nI2CStatus[NRLinkPort]; if (err == NO_ERR){ readI2CReply(NRLinkPort, nReplyBytes[0], kReplyLength);
StringFormat(s1, "%x: %d", i, nReplyBytes[0]); //StringFormat(s2, "%2x %2x", nReplyBytes[1],
nReplyBytes[2]);
s2 = ""; s2 += nReplyBytes[0];
nxtDisplayTextLine(line%8, "%s %s", s1, s2); wait10Msec(100); } else { nxtDisplayTextLine(line%8, "%2x: err %d", i, err); wait10Msec(100); } line++; } }
// Write the contents of the NRLink RAM into a file on
the NXT that // can be downloaded from the RobotC IDE onto your PC // // File is named testFile.dat // void dumpNRLinkRAM() {
int i; byte addr; const int kReplyLength = 1; ubyte nReplyBytes[kReplyLength];
const string sFileName = "testFile.dat"; TFileIOResult nIoResult; TFileHandle hFileHandle; int nFileSize = 256;
TI2CStatus err;
typedef struct{ byte nMsgSize; byte nDeviceAddress; byte nLocationPtr; } TI2C_Output;
TI2C_Output sOutput; sOutput.nMsgSize = 2; sOutput.nDeviceAddress = 0x02; sOutput.nLocationPtr = 0;
Delete(sFileName, nIoResult); hFileHandle = 0; OpenWrite(hFileHandle, nIoResult, sFileName,
nFileSize);
nxtDisplayTextLine(2, "Dumping NRLink");
addr = 0; for(i=0x00; i <= 0xff; i++) {
nI2CBytesReady[NRLinkPort]=0; err = NO_ERR; do { err = nI2CStatus[NRLinkPort]; wait1Msec(2); }while(err == STAT_COMM_PENDING);
sOutput.nLocationPtr = addr; addr++;
sendI2CMsg(NRLinkPort, sOutput.nMsgSize,
kReplyLength);
err = NO_ERR; do { err = nI2CStatus[NRLinkPort]; wait1Msec(2); }while(err == STAT_COMM_PENDING);
err = nI2CStatus[NRLinkPort]; if (err == NO_ERR){ readI2CReply(NRLinkPort, nReplyBytes[0], kReplyLength); WriteByte(hFileHandle, nIoResult, nReplyBytes[0]); } else { WriteByte(hFileHandle, nIoResult, 0xff); } }
Close(hFileHandle, nIoResult);
nxtDisplayTextLine(3, "Done"); }
///////////////////////////////////////////////////////////////////////////// // // Run some commands and macro to control PF Motors
using NRLink. // /////////////////////////////////////////////////////////////////////////////
task main() {
nI2CBytesReady[NRLinkPort] = 0; SensorType[NRLinkPort] = sensorI2CCustom9V; // Note, use this, NOT
CustomFast9V!! NRLinkCommand(NRLinkFlush); NRLinkCommand(NRLinkDefault); // NRLinkCommand(NRLinkLongRange); NRLinkCommand(NRLinkSelectPF);
eraseDisplay();
dumpNRLinkRAM();
wait10Msec(100);
// print the contents of the NRlink RAM starting and
ending at these addresses readMacros(0x0, 0x17);
wait10Msec(1000); } Last updated 23
May, 2008
All content © 2008 Mark Crosbie [email protected]
LEGO® is a trademark of the LEGO Group of companies which does not sponsor, authorize or endorse this site. This site, its owner and contents are in no way affiliated with or endorsed by the LEGO Group. For more please read the LEGO Fair Play policy.
|
