/* * Name: CounterCanvas.java * Author: Jason Schwier, Rensselaer Polytechnic Institute * Date: 7 October 2005 * * Description: This class provides the variables and functions to plot the output of PCA0 given * the value of the registers PCA0L and PCA0H to start counting and the system clock. A * triangular waveform is produced by calculating the period of the counter from the * system clock and the start value. This plot does not take input directly from the user, it * only provides the functions for painting the single canvas. * * Changes: From 19 July - corrected the period from doing Integer division to Double division * * Rights: You may form derivatives of this file to fit your needs, as long as some credit is given to myself and * RPI for providing a starting basis of your work. */ import java.awt.*; import java.applet.Applet; import java.lang.*; public class CounterCanvas extends Canvas { // Canvas size values private int xSize = 500; private int ySize = 250; // Graphic axis size values private int xAxisStart = 10; private int xAxisEnd = xSize - 20; private int yAxisStart = 40; private int yAxisEnd = ySize - 10; private int maxRealXAxis = 20; // set in drawAxes() private int maxRealYAxis = 68000; // in counter value // Input / derived values from the applet private static int compareValue = 32768; private static int startValue = 0; private static double period = (double)65536 / (double)1000 / 22.1184; private static String systemClock = "SYSCLK"; // Determine where the origin is private int horizontalAxisUp = 40; private int verticalAxisLeft = 40; // Function called from the applet to tranfer the input values and derived values // from the user to this function public void captureValues( int compare, int start, double periodValue, String sysClock ) { compareValue = compare; startValue = start; period = periodValue; systemClock = sysClock; } // Draw both axes, hash marks on the axes, and labels for the hash marks private void drawAxes( Graphics g ) { // Horizontal Axis g.drawLine( xAxisStart, ySize-horizontalAxisUp, xAxisEnd, ySize-horizontalAxisUp ); // Vertical Axis g.drawLine( verticalAxisLeft, yAxisStart, verticalAxisLeft, yAxisEnd ); // Vertical Axis Hashes // Hashes at 16384, 32768, 49152, 65535 int hashHalfLength = 5; for( int i = 16384; i <= 65536; i += 16384 ) { int hashTemp = realToGraphicYAxis( i, maxRealYAxis, yAxisStart, ySize-horizontalAxisUp ); g.drawLine( verticalAxisLeft-hashHalfLength, hashTemp, verticalAxisLeft+hashHalfLength, hashTemp ); String hashLabel = Integer.toString( (i / 1000) ) + "K"; g.drawString( hashLabel, hashHalfLength, hashTemp+hashHalfLength ); } // Allow for a variable X axis scale based on which system clock is chosen // These values should match the corresponding values for the pulse plot int hashInterval; if( systemClock == "SYSCLK" ) { maxRealXAxis = 12; hashInterval = 2; } else if( systemClock == "SYSCLK/4" ) { maxRealXAxis = 50; hashInterval = 10; } else //if( systemClock == "SYSCLK/12" ) { maxRealXAxis = 150; hashInterval = 30; } // Horizontal Axis Hashes // Hashes every specified interval for( int i = hashInterval; i <= maxRealXAxis; i += hashInterval ) { int hashTemp = realToGraphicXAxis( i, maxRealXAxis, verticalAxisLeft, xAxisEnd ); g.drawLine( hashTemp, ySize-horizontalAxisUp-hashHalfLength, hashTemp, ySize-horizontalAxisUp+hashHalfLength ); String hashLabel = Integer.toString( i ) + " ms"; g.drawString( hashLabel, hashTemp-(4*hashHalfLength), ySize-(2*hashHalfLength) ); } } // Draw the triangular plot of the counter itself private void drawPlot( Graphics g ) { int skipInitial = 0; // Millisecond value of the start register double startMS = period * startValue / (double)65536; // Millisecond value of the time between starting and the period of the count double periodFraction = period - startMS; g.setColor( Color.blue ); // Draw the first line to start from zero to the counter maximum g.drawLine( realToGraphicXAxis(0, maxRealXAxis, verticalAxisLeft, xAxisEnd), realToGraphicYAxis(0, maxRealYAxis, yAxisStart, ySize-horizontalAxisUp), realToGraphicXAxis(period, maxRealXAxis, verticalAxisLeft, xAxisEnd), realToGraphicYAxis(65536, maxRealYAxis, yAxisStart, ySize-horizontalAxisUp) ); // Minimum counting value will be the start register value int minY = realToGraphicYAxis( startValue, maxRealYAxis, yAxisStart, ySize-horizontalAxisUp ); // Maximum counting value will be the full 16-bit value int maxY = realToGraphicYAxis( 65536, maxRealYAxis, yAxisStart, ySize-horizontalAxisUp ); for( double startVal = startMS; startVal < maxRealXAxis; startVal += periodFraction ) { // Determine the two X coordinates for the each end of the line int minX = realToGraphicXAxis( startVal, maxRealXAxis, verticalAxisLeft, xAxisEnd ); int maxX = realToGraphicXAxis( startVal+periodFraction, maxRealXAxis, verticalAxisLeft, xAxisEnd ); if( maxX <= xAxisEnd ) { // This prevents the initial line from being drawn here, but draws all times afterward // Since it was drawn already above if( skipInitial == 0 ) { skipInitial = 1; } else { // Draw the angled line demonstrating the counter g.drawLine( minX, minY, maxX, maxY ); } // Draw the vertical line connecting each triangle g.drawLine( maxX, maxY, maxX, minY ); } } g.setColor( Color.black ); } // Convert between the real X axis and the graphical X axis of the plot private int realToGraphicXAxis( double realCoord, double maxRealCoord, int axisStart, int axisEnd ) { // Calculate the multiplicative scalar which is determined by the ending coordinate of both // the real axis and the length of the graphical axis double axisScalar = (axisEnd - axisStart) / maxRealCoord; // Include the additive factor which is determined by the starting place of the graphical axis // to account for a zero real coordinate double graphicCoord = (realCoord * axisScalar) + axisStart; return ( (int) graphicCoord ); } // Convert between the real Y axis and the graphical Y axis of the plot private int realToGraphicYAxis( int realCoord, int maxRealCoord, int axisStart, int axisEnd ) { // Calculate the multiplicative scalar which is determined by the ending coordinate of both // the real axis and the length of the graphical axis, remember the vertical axis is inverted double axisScalar = (axisStart - axisEnd) / ((double)maxRealCoord); // Include the additive factor which is determined by the ending point of the graphical axis // to account for a zero real coordinate. It is end because of the inverted graphical axis. double graphicCoord = (realCoord * axisScalar) + axisEnd; return ( (int) graphicCoord ); } // Overridden default paint routine for Canvas public void paint( Graphics g ) { // Draw the title FontMetrics fontmetric = getFontMetrics( g.getFont() ); String title = "PCA0 Counter Plot"; int xRel = fontmetric.stringWidth( title ) / 2; g.drawString( title, (xSize/2)-xRel, 30 ); // Draw the axes, hashes, and the hash labels drawAxes( g ); // Draw the plot itself drawPlot( g ); } }