From 4090604d9a119adc4200d86b46bb3bc73cb1d10f Mon Sep 17 00:00:00 2001 From: lebrush Date: Thu, 16 May 2013 17:11:44 +0200 Subject: [PATCH 1/2] Extended GenericUSCI to support i2c protocol as well. Added a I2CUnit which allows to implement easily i2c chipsets --- com/tado/mspsim/chip/I2CUnit.java | 309 ++++++++++++++++++++++++++ com/tado/mspsim/utils/RingBuffer.java | 190 ++++++++++++++++ se/sics/mspsim/core/GenericUSCI.java | 142 +++++++++--- 3 files changed, 613 insertions(+), 28 deletions(-) create mode 100644 com/tado/mspsim/chip/I2CUnit.java create mode 100644 com/tado/mspsim/utils/RingBuffer.java diff --git a/com/tado/mspsim/chip/I2CUnit.java b/com/tado/mspsim/chip/I2CUnit.java new file mode 100644 index 0000000..0cbbe4d --- /dev/null +++ b/com/tado/mspsim/chip/I2CUnit.java @@ -0,0 +1,309 @@ +package com.tado.mspsim.chip; + +import se.sics.mspsim.core.GenericUSCI; +import se.sics.mspsim.core.MSP430Core; +import se.sics.mspsim.core.TimeEvent; +import se.sics.mspsim.core.USARTListener; +import se.sics.mspsim.core.USARTSource; + +/** + * Simple I2C unit + * + * Any class extending this unit can use the i2c protocol by just implementing + * two methods for reading and writing registers. + * + * @author Víctor Ariño + */ +public abstract class I2CUnit implements USARTListener { + + /** + * Auxiliar class for emulating the i2c signaling. This is necessary as + * there's no line messages in the emulator. + * + * @author Víctor Ariño + */ + public class I2CData { + + /** + * Several mask for messages. This may not implement a real i2c but is + * useful for message passing + */ + public final static int START = 0x100; + public final static int STOP = 0x200; + public final static int ACK = 0x400; + public final static int NACK = 0x800; + + private int data; + + public I2CData(int data) { + this.data = data; + } + + protected int getData() { + return data & 0xff; + } + + protected boolean isStart() { + return (data & START) == START; + } + + protected boolean isStop() { + return (data & STOP) == STOP; + } + + protected boolean isAck() { + return data == ACK; + } + + protected int getAddress() { + if (isStart()) { + return (data & 0xfe) >> 1; + } + return 0; + } + + protected boolean isRead() { + if (isStart()) { + return (data & 0x01) != 0x01; + } + return false; + } + } + + /** + * Address of the I2C peripheral + */ + protected int busAddress = 0x00; + + /** + * String name for logging + */ + protected String name = "Unknown"; + + /** + * Enable debug + */ + protected boolean DEBUG = false; + + /** + * Is a read message or a write + */ + private boolean isRead = false; + + /** + * Memory address of the peripheral to read/write + */ + private int registerAddress = 0x00; + + /** + * Length in bytes of the bus address + */ + protected int regAddressLen = 1; + + /** + * Length in bytes of the buffer value + */ + protected int numBytesTotal = 2; + + /** + * Number of received value bytes + */ + private int numBytesRxTx = 0; + + /** + * Received bytes of the address + */ + private int regAddressBytesRx = 0; + + /** + * Value to read/write + */ + private int value; + + /** + * Is the peripheral ready to receive / send data? + */ + private boolean ready = false; + + private MSP430Core cpu; + private USARTSource source; + private boolean txScheduled = false; + + /** + * Tx Event Handler + */ + private TimeEvent txTrigger = new TimeEvent(0) { + public void execute(long t) { + /* Transmit the next pending byte to the uC */ + if (numBytesTotal > numBytesRxTx) { + int tmp = (value >> ((numBytesTotal - numBytesRxTx - 1) * 8)) & 0xff; + log(" " + tmp); + source.byteReceived(tmp); + numBytesRxTx++; + } + txScheduled = false; + } + }; + + /** + * Class constructor + * + * @param name + * @param address + * @param src + * @param cpu + */ + public I2CUnit(String name, int address, USARTSource src, MSP430Core cpu) { + this.name = name; + busAddress = address; + if (src != null) { + src.addUSARTListener((USARTListener) this); + } + this.cpu = cpu; + source = src; + } + + /** + * The microcontroller requested to write a register of the i2c peripheral + * + * @param address + * address of the register + * @param value + * value to write + */ + protected abstract void registerWrite(int address, int value); + + /** + * Read a register of the peripheral + * + * @param address + * address of the register to read + * @return write this value + */ + protected abstract int registerRead(int address); + + @Override + public void dataReceived(USARTSource source, int data) { + + I2CData d = new I2CData(data); + + if (d.isStart()) { + if (d.getAddress() != busAddress) { + // Message not for us! + return; + } + + isRead = d.isRead(); + numBytesRxTx = 0; + ready = true; + + log(" read?" + isRead); + + source.byteReceived(I2CData.ACK); + + /* + * Read the register if necessary. When a write reset the memory + * address to avoid strange situations + */ + if (isRead) { + value = registerRead(registerAddress); + scheduleTransmission(); + } else { + registerAddress = 0x00; + value = 0; + regAddressBytesRx = 0; + } + return; + } + + if (ready) { + /* + * In case of stop condition write the register if necessary and set + * the end of the message acceptance + */ + if (d.isStop()) { + log(""); + if (!isRead && numBytesRxTx > 1) { + registerWrite(registerAddress, value); + } + + ready = false; + return; + } + + /* If the master transmits and ACK we can transmit the next byte */ + if (d.isAck() && isRead) { + log(""); + if (numBytesRxTx < numBytesTotal) { + scheduleTransmission(); + } + } + + /* + * Write messages are for the address and for the value. First the + * address of the register is received. Afterwards the value itself + */ + if (!isRead) { + if (regAddressBytesRx < regAddressLen) { + log(""); + registerAddress = d.getData(); + regAddressBytesRx++; + } else if (numBytesRxTx < numBytesTotal) { + value <<= 8; + value |= d.getData(); + numBytesRxTx++; + log("" + value); + } else { + logw("Received more bytes than expected!"); + } + source.byteReceived(I2CData.ACK); + } + } + } + + /** + * Schedule a transmission with the correct baud rate + */ + private void scheduleTransmission() { + int baudRate = defaultBaudRate; + + if (source instanceof GenericUSCI) { + baudRate = ((GenericUSCI) source).getBaudRate(); + } + + if (!txScheduled && numBytesRxTx < numBytesTotal) { + cpu.scheduleCycleEvent(txTrigger, cpu.cpuCycles + 1); + txScheduled = true; + } + } + + /** + * Log a message when the DEBUG flag is set + * + * @param msg + */ + protected void log(String msg) { + if (DEBUG) { + System.out.println("(i2c) " + name + ": " + msg); + } + } + + /** + * Log a warning message + * + * @param msg + */ + protected void logw(String msg) { + System.err.println("(i2c) " + name + ": WARNING " + msg); + } + + /** + * Default baud rate for the communications + */ + private int defaultBaudRate = 100; + + protected void setDefaultBaudRate(int br) { + defaultBaudRate = br; + } + +} diff --git a/com/tado/mspsim/utils/RingBuffer.java b/com/tado/mspsim/utils/RingBuffer.java new file mode 100644 index 0000000..5c064e7 --- /dev/null +++ b/com/tado/mspsim/utils/RingBuffer.java @@ -0,0 +1,190 @@ +package com.tado.mspsim.utils; + +/****************************************************************************** + * File: RingBuffer.java + * + * Author: Keith Schwarz (htiek@cs.stanford.edu) + * + * An implementation of a synchronized queue backed by a ring buffer. This + * functionality and implementation is similar to the ArrayBlockingQueue class, + * but I thought that I'd implement my own version to get a better feel for how + * it works. + * + * A ring buffer is a space-efficient, locality-friendly implementation of a + * FIFO queue. It is implemented as a fixed-sized array that is treated as + * though it wraps around like a ring; it has no well-defined start or end + * point. This array stores two pointers, a read pointer and a write pointer, + * delineating where the next insert should take place and from where the next + * element should be dequeued. For example: + * + * [2] [3] [ ] [ ] [ ] [ ] [0] [1] + * ^ ^ + * | | + * write read + * + * When using a ring buffer, one must be careful not to let the read and write + * pointers cross one another. If this happens, future write operations will + * start overwriting old elements that have not yet been consumed. For this + * reason, most ring buffers adopt one of two strategies. First, the ring buffer + * can increase its size whenever it runs out of room. This approach allows the + * buffer to grow arbitrarily large if need be. The second option, and the one + * used in this implementation, is simply to block on a read or write when data + * is not available. This allows the ring buffer to implement the + * producer/consumer pattern fairly easily; any number of threads can begin + * creating data while some number of threads consume it, and at no time are too + * many elements kept in memory waiting to be read. + */ + +public final class RingBuffer { + /* The actual ring buffer. */ + private final T[] elements; + + /* The write pointer, represented as an offset into the array. */ + private int offset = 0; + + /* + * The read pointer is encoded implicitly by keeping track of the number of + * unconsumed elements. We can then determine its position by backing up that + * many positions before the read position. + */ + private int unconsumedElements = 0; + + /** + * Constructs a new RingBuffer with the specified capacity, which must be + * positive. + * + * @param size + * The capacity of the new ring buffer. + * @throws IllegalArgumentException + * If the capacity is negative. + */ + @SuppressWarnings("unchecked") + public RingBuffer(int size) { + /* Validate the size. */ + if (size <= 0) + throw new IllegalArgumentException( + "RingBuffer capacity must be positive."); + + /* Construct the array to be that size. */ + elements = (T[]) new Object[size]; + } + + /** + * Clear the buffer + */ + @SuppressWarnings("unchecked") + public synchronized void clear() { + offset = 0; + unconsumedElements = 0; + for (int i = 0; i < elements.length; i++) { + elements[i] = null; + } + } + + /** + * Appends an element to the ring buffer, blocking until space becomes + * available. + * + * @param elem + * The element to add to the ring buffer. + */ + public synchronized boolean add(T elem) { + /* + * Block until the capacity is nonzero. Otherwise we don't have any space + * to write. + */ + if (unconsumedElements == elements.length) + return false; + + /* + * Write the element into the next open spot, then advance the write + * pointer forward a step. + */ + elements[offset] = elem; + offset = (offset + 1) % elements.length; + + /* + * Increase the number of unconsumed elements by one, then notify any + * threads that are waiting that more data is now available. + */ + ++unconsumedElements; + return true; + } + + /** + * Returns the maximum capacity of the ring buffer. + * + * @return The maximum capacity of the ring buffer. + */ + public int capacity() { + return elements.length; + } + + /** + * Observes, but does not dequeue, the next available element, blocking until + * data becomes available. + * + * @return The next available element. + */ + public synchronized T peek() { + /* Wait for data to become available. */ + if (unconsumedElements == 0) + return null; + + /* + * Hand back the next value. The index of this next value is a bit tricky + * to compute. We know that there are unconsumedElements elements waiting + * to be read, and they're contiguously before the write position. + * However, the buffer wraps around itself, and so we can't just do a + * naive subtraction; that might end up giving us a negative index. To + * avoid this, we'll use a clever trick in which we'll add to the index + * the capacity minus the distance. This value must be positive, since the + * distance is never greater than the capacity, and if we then wrap this + * value around using the modulus operator we'll end up with a valid + * index. All of this machinery works because + * + * (x + (n - k)) mod n == (x - k) mod n + * + * And Java's modulus operator works best on positive values. + */ + return elements[(offset + (capacity() - unconsumedElements)) % capacity()]; + } + + /** + * Removes and returns the next available element, blocking until data + * becomes available. + * + * @return The next available element + */ + public synchronized T remove() { + /* Use peek() to get the element to return. */ + T result = peek(); + + /* Mark that one fewer elements are now available to read. */ + --unconsumedElements; + + /* Because there is more space left, wake up any waiting threads. */ + notifyAll(); + + return result; + } + + /** + * Returns the number of elements that are currently being stored in the ring + * buffer. + * + * @return The number of elements currently stored in the ring buffer. + */ + public synchronized int size() { + return unconsumedElements; + } + + /** + * Returns whether the ring buffer is empty. + * + * @return Whether the ring buffer is empty. + */ + public synchronized boolean isEmpty() { + return size() == 0; + } +} \ No newline at end of file diff --git a/se/sics/mspsim/core/GenericUSCI.java b/se/sics/mspsim/core/GenericUSCI.java index 8bda145..11966c0 100644 --- a/se/sics/mspsim/core/GenericUSCI.java +++ b/se/sics/mspsim/core/GenericUSCI.java @@ -1,7 +1,13 @@ package se.sics.mspsim.core; -/* +import com.tado.mspsim.chip.I2CUnit.I2CData; +import com.tado.mspsim.utils.RingBuffer; + +/** * GenericUSCI - for newer MSP430's + * + * @author Unknown + * @author Víctor Ariño */ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource { @@ -14,13 +20,16 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource { public static final int STAT = 0x0a; public static final int RXBUF = 0x0c; public static final int TXBUF = 0x0e; + + // i2C Registers + public static final int I2COA = 0x10; + public static final int I2CSA = 0x12; // Interrupt related public static final int IE = 0x1c; public static final int IFG = 0x1d; public static final int IV = 0x1e; - // Misc flags public static final int RXIFG = 0x01; public static final int TXIFG = 0x02; @@ -43,8 +52,6 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource { private int tickPerByte = 1000; private long nextTXReady = -1; - private int nextTXByte = -1; - private int txShiftReg = -1; private boolean transmitting = false; private int ctl0; @@ -56,7 +63,7 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource { private int txbuf; private int stat; - private boolean spiMode = false; + private boolean syncMode = false; /* always on for now - but SWRST controls it */ private boolean moduleEnabled = true; @@ -70,7 +77,14 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource { handleTransmit(t); } }; - + private boolean i2cEnabled; + private boolean i2cTransmitter; + private int i2cSlaveAddress; + private int i2cOwnAddress; + private boolean readyForNextTransmit; + private boolean stopConditionPending; + + private RingBuffer txBuffer = new RingBuffer<>(100); public GenericUSCI(MSP430Core cpu, int uartIndex, int[] memory, MSP430Config config) { super(config.uartConfig[uartIndex].name, cpu, memory, config.uartConfig[uartIndex].offset); @@ -85,14 +99,14 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource { } public void reset(int type) { - nextTXReady = cpu.cycles + 100; - txShiftReg = nextTXByte = -1; + nextTXReady = cpu.cycles + tickPerByte + 100; transmitting = false; clrBitIFG(RXIFG); setBitIFG(TXIFG); /* empty at start! */ stat &= ~USCI_BUSY; moduleEnabled = true; //false; updateIV(); + txBuffer.clear(); } void updateIV() { @@ -140,30 +154,37 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource { private void handleTransmit(long cycles) { if (cpu.getMode() >= MSP430Core.MODE_LPM3) { - System.out.println(getName() + " Warning: USART transmission during LPM!!! " + nextTXByte); + System.out.println(getName() + " Warning: USART transmission during LPM!!! "); } - + if (transmitting) { /* in this case we have shifted out the last character */ USARTListener listener = this.usartListener; - if (listener != null && txShiftReg != -1) { - listener.dataReceived(this, txShiftReg); + if (listener != null && !txBuffer.isEmpty()) { + int t = txBuffer.remove(); + listener.dataReceived(this, t); + + if (i2cEnabled) { + if ((t & I2CData.START) > 0) { + ctl1 &= ~0x02; + } else if ((t & I2CData.STOP) > 0) { + ctl1 &= ~0x04; + } + } } /* nothing more to transmit after this - stop transmission */ - if (nextTXByte == -1) { - /* ~BUSY - nothing more to send - and last data already in RX */ - stat &= ~USCI_BUSY; - transmitting = false; - txShiftReg = -1; + if (txBuffer.isEmpty()) { + /* ~BUSY - nothing more to send - and last data already in RX */ + stat &= ~USCI_BUSY; + transmitting = false; + setBitIFG(TXIFG); } } /* any more chars to transmit? */ - if (nextTXByte != -1) { - txShiftReg = nextTXByte; - nextTXByte = -1; + if (!txBuffer.isEmpty()) { /* txbuf always empty after this */ - setBitIFG(TXIFG); + clrBitIFG(TXIFG); transmitting = true; nextTXReady = cycles + tickPerByte + 1; cpu.scheduleCycleEvent(txTrigger, nextTXReady); @@ -215,15 +236,14 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource { // address + " = " + data); switch (address) { case CTL0: - ctl0 = data; - spiMode = (data & 0x01) > 0; + syncMode = (data & 0x01) > 0; + i2cEnabled = (data & 0x06) == 0x06; if (DEBUG) log(" write to UxxCTL0 " + data); break; case CTL1: /* emulate the reset */ if ((ctl1 & SWRST) == SWRST && (data & SWRST) == 0) reset(0); - ctl1 = data; moduleEnabled = (data & SWRST) == 0; if (DEBUG) log(" write to UxxCTL1 " + data + " => ModEn:" + moduleEnabled); @@ -239,6 +259,34 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource { } } updateBaudRate(); + + /* + * When in I2C mode and an start or stop condition is reached + * just transmit the corresponding signals. + */ + if (i2cEnabled) { + if ((data & 0x04) > 0 && (ctl1 & 0x04) == 0) { // stop condition + txBuffer.add(I2CData.STOP); + } + if ((data & 0x02) > 0 && (ctl1 & 0x02) == 0) { + i2cTransmitter = (data & 0x10) == 0x10; + /* Transmit a start condition START|ADDR|R/W */ + int t = I2CData.START; + t |= i2cSlaveAddress << 1; + t |= i2cTransmitter ? 1 : 0; + txBuffer.add(t); + rxbuf = 0; + } + clrBitIFG(TXIFG); + stat |= USCI_BUSY; + if (!transmitting) { + nextTXReady = cycles + 1; //tickPerByte + 3; + cpu.scheduleCycleEvent(txTrigger, nextTXReady); + } + } + + ctl1 = data; + break; case MCTL: mctl = data; @@ -272,12 +320,11 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource { // Schedule on cycles here // TODO: adding 3 extra cycles here seems to give // slightly better timing in some test... - - nextTXByte = data; + txBuffer.add(data); if (!transmitting) { /* how long time will the copy from the TX_BUF to the shift reg take? */ /* assume 3 cycles? */ - nextTXReady = cycles + 1; //tickPerByte + 3; + nextTXReady = cycles + tickPerByte + 1; //tickPerByte + 3; cpu.scheduleCycleEvent(txTrigger, nextTXReady); } } else { @@ -285,6 +332,14 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource { } txbuf = data; break; + + case I2CSA: + i2cSlaveAddress = data & 0x3ff; + break; + + case I2COA: + i2cOwnAddress = data & 0x3ff; + break; } } @@ -313,6 +368,20 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource { /* This should be changed to a state rather than an "event" */ /* Force callback since this is not used as a state */ stateChanged(USARTListener.RXFLAG_CLEARED, true); + + /* For timing issues we have to send the ACK after reading the + * register */ + if (!i2cTransmitter) { + txBuffer.add(I2CData.ACK); + stat |= USCI_BUSY; + if (!transmitting) { + /* how long time will the copy from the TX_BUF to the shift reg take? */ + /* assume 3 cycles? */ + nextTXReady = cpu.cpuCycles + tickPerByte + 1; //tickPerByte + 3; + cpu.scheduleCycleEvent(txTrigger, nextTXReady); + } + } + return tmp; case MCTL: return mctl; @@ -351,9 +420,16 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource { //System.out.println(getName() + " byte received: " + b); if (DEBUG) { - log(" byteReceived: " + b + " " + (char) b); + log("byteReceived: " + b + " " + (char) b); } + + /* Ignore i2c ACK messages */ + if (i2cEnabled && b == I2CData.ACK) { + return; + } + rxbuf = b & 0xff; + // Indicate interrupt also! setBitIFG(RXIFG); @@ -380,5 +456,15 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource { return "UTXIE: " + isIEBitsSet(TXIFG) + " URXIE:" + isIEBitsSet(RXIFG) + "\n" + "UTXIFG: " + ((getIFG() & TXIFG) > 0) + " URXIFG:" + ((getIFG() & RXIFG) > 0); } + + public int getBaudRate() { + return tickPerByte; + } + + protected void vlog(String msg) { + if (i2cEnabled) { + System.out.println("USCI "+msg); + } + } } From 38a29ba0ab74ca0791adb6eb358afcd7a6ccbb81 Mon Sep 17 00:00:00 2001 From: lebrush Date: Tue, 4 Jun 2013 11:36:37 +0200 Subject: [PATCH 2/2] Merged into se.sics package and added license information. --- .../tado => se/sics}/mspsim/chip/I2CUnit.java | 35 ++++++++++++++++++- se/sics/mspsim/core/GenericUSCI.java | 5 +-- .../sics/mspsim/util}/RingBuffer.java | 2 +- 3 files changed, 38 insertions(+), 4 deletions(-) rename {com/tado => se/sics}/mspsim/chip/I2CUnit.java (78%) rename {com/tado/mspsim/utils => se/sics/mspsim/util}/RingBuffer.java (99%) diff --git a/com/tado/mspsim/chip/I2CUnit.java b/se/sics/mspsim/chip/I2CUnit.java similarity index 78% rename from com/tado/mspsim/chip/I2CUnit.java rename to se/sics/mspsim/chip/I2CUnit.java index 0cbbe4d..e273fe8 100644 --- a/com/tado/mspsim/chip/I2CUnit.java +++ b/se/sics/mspsim/chip/I2CUnit.java @@ -1,4 +1,37 @@ -package com.tado.mspsim.chip; +/* Copyright (c) 2013, tado° GmbH. Munich, Germany. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of MSPSim. + * + * Author: Víctor Ariño + * + */ + +package se.sics.mspsim.chip; import se.sics.mspsim.core.GenericUSCI; import se.sics.mspsim.core.MSP430Core; diff --git a/se/sics/mspsim/core/GenericUSCI.java b/se/sics/mspsim/core/GenericUSCI.java index 11966c0..7ac5c84 100644 --- a/se/sics/mspsim/core/GenericUSCI.java +++ b/se/sics/mspsim/core/GenericUSCI.java @@ -1,7 +1,8 @@ package se.sics.mspsim.core; -import com.tado.mspsim.chip.I2CUnit.I2CData; -import com.tado.mspsim.utils.RingBuffer; +import se.sics.mspsim.chip.I2CUnit.I2CData; +import se.sics.mspsim.util.RingBuffer; + /** * GenericUSCI - for newer MSP430's diff --git a/com/tado/mspsim/utils/RingBuffer.java b/se/sics/mspsim/util/RingBuffer.java similarity index 99% rename from com/tado/mspsim/utils/RingBuffer.java rename to se/sics/mspsim/util/RingBuffer.java index 5c064e7..104a947 100644 --- a/com/tado/mspsim/utils/RingBuffer.java +++ b/se/sics/mspsim/util/RingBuffer.java @@ -1,4 +1,4 @@ -package com.tado.mspsim.utils; +package se.sics.mspsim.util; /****************************************************************************** * File: RingBuffer.java