/* This file is part of JOP, the Java Optimized Processor see <http://www.jopdesign.com/> Copyright (C) 2010, Thomas Hassler, Lukas Marx 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/>. */ /** * @author Thomas Hassler e0425918@student.tuwien.ac.at * @author Lukas Marx lukas.marx@gmail.com * @version 1.0 */ package ttpa.protocol; import com.jopdesign.sys.Const; import com.jopdesign.sys.Native; /** * NodeMaster */ public class NodeMaster extends Node { /** the rose file of the node master */ private Rosefile rosefile; /** declares which section of the rose file is active */ private RoseSect masterActiveSection; /** the active rodl of the node */ private Rodl masterActiveRodl; /** irg length of a round */ private int masterIrgLength; /** number of rodls */ private int masterRodlAnz; /** rodl counter */ private int masterRodlCounter = 0; /** stores the number of a rodl */ private int masterRodlNr; /** epoch counter, is increased every round */ private byte epochCounter; /** * @param myRosefile rose file of the node master * @param myFileName file name of the node * @param myRecAnz number of records * @param myLogName logical name of the node */ public NodeMaster(Rosefile myRosefile, int myFileName, int myRecAnz, byte myLogName) { super(TtpaConst.MASTER, myFileName, myRecAnz, myLogName); this.rosefile = myRosefile; } /** * is called when a new round is started * increases the epoch counter */ private void newRound() { epochCounter++; } /** * stores the active section in master_active_section * and the number of rodls in master_rodl_anz */ public void getSectionValues() { masterActiveSection = rosefile.getActiveSection(); masterRodlAnz = masterActiveSection.getRodlDescAnz(); } /** * stored the active rodl in master_active_rodl, * the irg length of the comming round in master_irg_length * and the number of the active rodl in master_rodl_nr */ public void getRodlValues() { masterActiveRodl = masterActiveSection.getRodlDesc(masterRodlCounter).getRodl(); masterIrgLength = masterActiveSection.getRodlDesc(masterRodlCounter).getIrg(); masterRodlNr = masterActiveRodl.getRodlNr(); } /** * is called when a new rodl begins */ public void rodlStart() { Start.node.setSlotCounter(0); // reset slot counter newRound(); // increase epoch counter // MSA if ( masterRodlNr == TtpaConst.MSA ) { byte msa_log = Start.node.getMsaObject().getMasterMsaLog(); // read log name to send byte msa_rec = Start.node.getMsaObject().getMasterMsaRec(); // read record name to send /* calculate the combined file name and operation byte * file name is 0x3D (documentation file) and operation is to write */ Start.node.getMsaObject().calcFileNameOp( (byte) 0x3D, TtpaConst.OP_WRITE ); // initialize MSA object getMsaObject().init( epochCounter, msa_log, Start.node.getMsaObject().getMasterMsaFileOp(), msa_rec ); /* increase logical name and return to 0x01 if 0xFB is reached * because 0xFB is the first value that is not used to address slave nodes and 0x00 broadcast */ if ( msa_log++ == 0xFB - 1 ) { msa_log = (byte) 0x01; // return to log name 0x01 if ( msa_rec++ == 0x02 ) // increase record name { msa_rec = 0x01; // return to record name 0x01 if 0x02 was reached } } Start.node.getMsaObject().setMasterMsaLog(msa_log); // save new logical name to be sent Start.node.getMsaObject().setMasterMsaRec(msa_rec); // save new record name to be sent } // MSD else if ( masterRodlNr == TtpaConst.MSD ) { // this node is addressed if ( Start.node.getMsaObject().getMsaLogName() == Start.node.getLogName() || Start.node.getMsaObject().getMsaLogName() == TtpaConst.BROADCAST ) { Start.node.getMsdObject().setAddressed(true); // operation is write if ( Start.node.getMsaObject().getOp() == TtpaConst.OP_WRITE ) { /* initialize MSD round */ Start.node.getMsdObject().init(Start.node.getMsaObject().getMsaRecName()); } } } // coming round is a MP round else { // initialize MP object getMpObject().init(masterActiveRodl); // calculate next MP slot setLastSlot(getMpObject().mpSlot()); } } /** * this function is called by the timer each slot * it executes whatever in this slot has to be done */ public void doNextSlot() { if ( masterRodlNr == TtpaConst.MSA ) // MSA slot { setLastSlot(getMsaObject().msaSendFrame()); } else if ( masterRodlNr == TtpaConst.MSD ) // MSD slot { // do msd slots setLastSlot(Start.node.getMsdObject().doMsdSlot()); } else // MP slot { Start.node.doMpSlotAction(); } // increase slot counter Start.node.setSlotCounter(Start.node.getSlotCounter() + 1); // this was not the last slot and it is a MP round if ( !isLastSlot() && masterRodlNr != 1 && masterRodlNr != 5 ) { // calculate the next MP slot setLastSlot(getMpObject().mpSlot()); } // this is the last slot else if ( isLastSlot() ) { rodlEnd(); // end of the round, calculate next round } } /** * is called when a round ends * sets the timer to IRG and calculates values for next round */ public void rodlEnd() { setTimerToIrg(masterIrgLength); // IRG // increaste master_rodl_counter or reset the counter if all rodls are done if (masterRodlCounter++ == masterRodlAnz - 1) { masterRodlCounter = 0; } /* calculate values for the next round */ getRodlValues(); rodlStart(); } /** * sets the timer to length of the IRG * * @param irg_length length of irg in slots (1-15) */ public void setTimerToIrg(int irg_length) { // set timer to value RoundTimer.setStartTime( RoundTimer.getStartTime() + (irg_length * TtpaConst.SLOT_LENGTH) ); Native.wr(1, Const.IO_INTCLEARALL); // clear pending interrupts Native.wr(RoundTimer.getStartTime(), Const.IO_TIMER); // write value to timer Native.wr(1, Const.IO_INTCLEARALL); } }