Device Access API
Proposal for Java ME 8

Package com.oracle.deviceaccess.mmio

Interfaces and classes for performing memory-mapped I/O.

See: Description

Package com.oracle.deviceaccess.mmio Description

Interfaces and classes for performing memory-mapped I/O.

Memory mapped I/O is typically used for controlling hardware peripherals by reading from and writing to registers or memory blocks of the hardware mapped to the system memory. The MMIO APIs allows for low level control over the peripheral.

In order to access a specific memory block a device has been mapped to, an application should first open and obtain an MMIODevice instance for the memory-mapped I/O device the application wants to control and access, using its numerical ID, name, type (interface) and/or properties:

Using its ID
 MMIODevice device = (MMIODevice) PeripheralManager.open(7);
 
Using its name and interface
 MMIODevice device = PeripheralManager.open("RTC", MMIODevice.class, null);
 
Once the peripheral opened, the application can retrieve registers using methods of the MMIODevice interface such as the MMIODevice.getRegister method.
 device.getRegister("Seconds", Byte.class);
 
When done, the application should call the MMIODevice.close method to close the MMIO device.
 device.close();
 
The following sample codes give examples of using the MMIO API to communicate Real Time Clock device:
 static final int INTERRUPT = 0;
 
 try (MMIODevice rtc = PeripheralManager.open("RTC", MMIODevice.class, null)) {
     //The RTC device has 14 bytes of clock and control registers and 50 bytes
     // of general purpose RAM (see the data sheet of the 146818 Real Time Clock such as HITACHI HD146818).
     RawRegister seconds = rtc.getRegister("Seconds", Byte.class);
     RawRegister secAlarm = rtc.getRegister("SecAlarm", Byte.class);
     RawRegister minutes = rtc.getRegister("Minutes", Byte.class);
     RawRegister minAlarm = rtc.getRegister("MinAlarm", Byte.class);
     RawRegister hours = rtc.getRegister("Hours", Byte.class);
     RawRegister hrAlarm = rtc.getRegister("HrAlarm", Byte.class);
     ... // More registers
     RawRegister registerA = rtc.getRegister("RegisterA", Byte.class);
     RawRegister registerB = rtc.getRegister("RegisterB", Byte.class);
     RawRegister registerC = rtc.getRegister("RegisterC", Byte.class);
     RawRegister registerD = rtc.getRegister("RegisterD", Byte.class);
     RawBlock userRAM = rtc.getBlock("UserRam");
     ...
 } catch (IOException ioe) {
     // handle exception
 }
 
Note that the preceding example is using a try-with-resources statement and that the MMI0Device.close method is automatically invoked by the platform at the end of the statement.
 // Sets the daily alarm for after some delay
 public void setAlarm(MMIODevice rtc, byte delaySeconds, byte delayMinutes, byte delayHours) throws IOException,
         PeripheralException {
     Register<Byte> seconds = rtc.getByteRegister("Seconds", Byte.class);
     Register<Byte> secAlarm = rtc.getByteRegister("SecAlarm", Byte.class);
     Register<Byte> minutes = rtc.getByteRegister("Minutes", Byte.class);
     Register<Byte> minAlarm = rtc.getByteRegister("MinAlarm", Byte.class);
     Register<Byte> hours = rtc.getByteRegister("Hours", Byte.class);
     Register<Byte> hrAlarm = rtc.getByteRegister("HrAlarm", Byte.class);
     Register<Byte> registerB = rtc.getByteRegister("RegisterB", Byte.class);
     RawBlock userRAM = rtc.getBlock("UserRam", Byte.class);
 
     // Directly read from/write to the registers using RawByte instances.
     byte currentSeconds = seconds.get();
     byte currentMinutes = minutes.get();
     byte currentHours = hours.get();
     int i = (currentSeconds + delaySeconds) % 60;
     int j = (currentSeconds + delaySeconds) / 60;
     secAlarm.set((byte) i);
     i = (currentMinutes + delayMinutes + j) % 60;
     j = (currentMinutes + delayMinutes + j) / 60;
     minAlarm.set((byte) i);
     i = (currentHours + delayHours + j) % 24;
     hrAlarm.set((byte) i);
     rtc.setMMIOEventListener(INTERRUPT, new MMIOEventListener() {
 
         public void eventDispatched(MMIOEvent event) {
             try {
                 MMIODevice rtc = event.getDevice();
                 Register<Byte> registerC = rtc.getByteRegister("RegisterC", Byte.class);
                 // Check the Alarm Interrupt Flag (AF)
                 if ((registerC.get() & 0X20) != 0) {
                     // Notify application of alarm
                 }
             } catch (IOException ioe) {
                 // handle exception
             }
         }
     });
     // Set the Alarm Interrupt Enabled (AIE) flag
     registerB.set((byte) (registerB.get() | 0X20));
 }
 
Alternatively, in this example, the value of RegisterC could be automatically captured upon occurrence of an interrupt request from the Real Time Clock device as follows:
 rtc.setMMIOEventListener(INTERRUPT, "RegisterC", new MMIOEventListener() {
 
     public void eventDispatched(MMIOEvent event) {
         Byte v = event.getCapturedRegisterValue();
         // Check the Alarm Interrupt Flag (AF)
         if ((v.byteValue() & 0X20) != 0) {
             // Notify application of alarm
         }
     }
 });
 

Unless otherwise noted, passing a null argument to a constructor or method in any class or interface in this package will cause a NullPointerException to be thrown.

Device Access API
Proposal for Java ME 8