Write Data to Wiimote Memory

Mar 31, 2011 at 4:22 PM

I am curious, is there any way to access the small amount of writable memory on a Wiimote through the WiimoteLib library?

 

I am trying to write some software that will connect two Wiimotes to a computer. I am using the 32feet.Net library to manage the device discovery, but the lack of unique hardware identifier makes this process extremely unreliable. The challenge lies in the fact that I need to create a process simple enough for an 8 year old child to understand.

 

My idea is that I could generate my own identifiers, and write these into an accessible memory location on each device. Is this possible?

Aug 29, 2011 at 4:14 AM
Edited Aug 29, 2011 at 4:17 AM

Yes there is but it isnt implemented in the Wiimote Lib library, you can get more information on how to read from it and write to it here, be careful though its also used for the Mii Data:

http://wiibrew.org/wiki/Wiimote#EEPROM_Memory

One these memory addresses is probably the best to use:

0x002A to 0x0FC9

or

0x15AA to 0x16CF

Reading and writing to these addresses translate into reading and writing to the eeprom.

Aug 29, 2011 at 4:53 AM
Edited Aug 29, 2011 at 9:52 AM

This code is completely untested, so use with caution, but here is a static extension class i did up to get you started:

 

namespace WiimoteLib
{
    /// <summary>
    /// Provides a static class to add extension methods to the
    /// wiimote for reading and writing to EEPROM.
    /// </summary>
    public static class WiimoteEEPROMExtensions
    {
        /// <summary>
        /// The EEPROM Wiimote starting virtual address.
        /// </summary>
        public const int EEPROMStartAddress = 0x0000;

        /// <summary>
        /// The EEPROM Wiimote ending virtual address.
        /// </summary>
        public const int EEPROMEndAddress = 0x0FC9;

        /// <summary>
        /// The maximum data that can be read or written at a time.
        /// </summary>
        public const int EEPROMReadWriteMax = Wiimote.ReportLength - 6;

        /// <summary>
        /// An array of [(n), (min, max)] safe addresses (inclusive).
        /// </summary>
        public static readonly int[,] EEPROMSafeAddresses = new int[,] { { 0x002A, 0x0FC9 }, { 0x15AA, 0x16CF } };

        /// <summary>
        /// Checks an EEPROM address range.
        /// </summary>
        /// <param name="address">The starting address.</param>
        /// <param name="length">The length of the range.</param>
        /// <param name="allowUnsafeAreas">True to allow access to unsafe areas (ie. areas which are used for the Wii (Mii data)).</param>
        private static void CheckEEPROMAddressRange(int address, int length, bool allowUnsafeAreas)
        {
            // Calculate ending address
            int liEndAddress = address + length - 1;

            // Check length
            if (length > EEPROMReadWriteMax)
                throw new WiimoteException(
                    string.Format(
                        "EEPROM Reading and writing restricted to no more than '{0}' bytes.",
                        EEPROMReadWriteMax)
                    );

            // Check starting address
            if (address < EEPROMStartAddress)
                throw new WiimoteException(
                    string.Format(
                        "Starting EEPROM address '{0}' invalid.",
                        address, EEPROMStartAddress, EEPROMEndAddress)
                    );

            // Check ending address
            if (liEndAddress > EEPROMEndAddress)
                throw new WiimoteException(
                    string.Format(
                        "Ending EEPROM address '{0}' invalid.",
                        liEndAddress, EEPROMStartAddress, EEPROMEndAddress)
                    );

            // Check unsafe areas if required
            if (!allowUnsafeAreas)
            {
                bool lbSafe = false;

                // For each safe range
                for (int liCounter = 0; liCounter < EEPROMSafeAddresses.GetLength(0); liCounter++)
                    // Check to ensure both starting and ending are within safe range
                    if (
                        address >= EEPROMSafeAddresses[liCounter, 0] &&
                        address <= EEPROMSafeAddresses[liCounter, 1] &&
                        liEndAddress >= EEPROMSafeAddresses[liCounter, 0] &&
                        liEndAddress <= EEPROMSafeAddresses[liCounter, 1]
                       )
                    {
                        // Set as safe if it is within a single range
                        lbSafe = true;
                        break;
                    }
                if (!lbSafe)
                    throw new WiimoteException(
                        string.Format(
                            "EEPROM address '{0}' does not completely fall in any safe zones.",
                            address)
                        );
            }
        }

        /// <summary>
        /// Writes a series of bytes to the EEPROM.
        /// </summary>
        /// <param name="wiimote">The wiimote to write to.</param>
        /// <param name="address">The starting address (EEPROMStartAddress to EEPROMEndAddress).</param>
        /// <param name="data">The data to write (restricted to EEPROMReadWriteMax length).</param>
        /// <param name="allowUnsafeAreas">True to allow writing to areas that the Wii uses for data.</param>
        internal static void WriteEEPROM(this Wiimote wiimote, int address, byte[] data, bool allowUnsafeAreas)
        {
            // Check address
            CheckEEPROMAddressRange(address, data.Length, allowUnsafeAreas);

            // Write data
            wiimote.WriteData(address, (byte)data.Length, data);
        }
        /// <summary>
        /// Reads a series of bytes from the EEPROM.
        /// </summary>
        /// <param name="wiimote">The wiimote to read from.</param>
        /// <param name="address">The starting address (EEPROMStartAddress to EEPROMEndAddress).</param>
        /// <param name="length">The length of the data to read (restricted to EEPROMReadWriteMax).</param>
        /// <param name="allowUnsafeAreas">True to allow reading from areas that the Wii uses for data.</param>
        internal static byte[] ReadEEPROM(this Wiimote wiimote, int address, short length, bool allowUnsafeAreas)
        {
            // Check address
            CheckEEPROMAddressRange(address, length, allowUnsafeAreas);

            // Read data
            return wiimote.ReadData(address, length);
        }
    }
}

 

Just call ReadEEPROM and WriteEEPROM with valid addresses and you should be fine.