/*
This file is part of JOP, the Java Optimized Processor
see <http://www.jopdesign.com/>
Copyright (C) 2001-2008, Martin Schoeberl (martin@jopdesign.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ejip123.util;
import com.jopdesign.sys.Const;
import com.jopdesign.sys.Native;
import joprt.RtThread;
/** Buffered serial line. Uses a periodic {@link RtThread} for the loop(). */
public class Serial{
private static final int BUF_LEN = 128;
private static final int BUF_MSK = 0x7f;
private static final int DATA = 1;
private static final int STATUS = 0;
// private static final int PERIOD = 3000;
/** I/O address for UART. */
private int io_status;
private int io_data;
/** Send buffer for serial line. */
private int[] txBuf;
/** Receive buffer for serial line. */
private int[] rxBuf;
private int rdptTx, wrptTx;
private int rdptRx, wrptRx;
private final Object monitor;
//private Serial ser;
public Serial(int prio, int us, int addr){
io_status = addr + STATUS;
io_data = addr + DATA;
txBuf = new int[BUF_LEN]; // should be byte
rxBuf = new int[BUF_LEN];
rdptTx = wrptTx = 0;
rdptRx = wrptRx = 0;
monitor = new Object();
new RtThread(prio, us){
public void run(){
for(; ;){
waitForNextPeriod();
loop();
}
}
};
}
/** read and write loop. */
private void loop(){
synchronized(monitor){
// read serial data
int i = wrptRx;
int j = rdptRx;
while((Native.rd(io_status)&Const.MSK_UA_RDRF) != 0 && ((i + 1)&BUF_MSK) != j){
rxBuf[i] = Native.rd(io_data);
i = (i + 1)&BUF_MSK;
}
wrptRx = i;
// write serial data
i = rdptTx;
j = wrptTx;
while((Native.rd(io_status)&Const.MSK_UA_TDRE) != 0 && i != j){
// FIXME deadlock in simulator under windows if there is no slip connection established
Native.wr(txBuf[i], io_data);
i = (i + 1)&BUF_MSK;
}
rdptTx = i;
}
}
public int rxCnt(){
int ret;
synchronized(monitor){
ret = (wrptRx - rdptRx)&BUF_MSK;
}
return ret;
}
public int txFreeCnt(){
int ret;
synchronized(monitor){
ret = (rdptTx - 1 - wrptTx)&BUF_MSK;
}
return ret;
}
public int rd(){
int ch;
synchronized(monitor){
int i = rdptRx;
rdptRx = (i + 1)&BUF_MSK;
ch = rxBuf[i];
}
return ch;
}
public void wr(int c){
synchronized(monitor){
int i = wrptTx;
wrptTx = (i + 1)&BUF_MSK;
txBuf[i] = c;
}
}
public void setDTR(boolean arg){
synchronized(monitor){
Native.wr(arg ? 1 : 0, io_status);
}
}
}