{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# PMOD TIMER\n",
    "\n",
    "In this notebook, PMOD Timer functionalities are illustrated. The Timer has two sub-modules: Timer0 and Timer1. \n",
    "\n",
    "The Generate output and Capture Input of Timer 0 are assumed to be connected to PMODA pin1. \n",
    "    1. The Generate function outputs one clock (10 ns) pulse after a desired period. \n",
    "    2. The Capture input is sensitive to a rising edge or high level logic.\n",
    "\n",
    "To see the results of this notebook, you will need a [Digilent Analog Discovery 2](http://store.digilentinc.com/analog-discovery-2-100msps-usb-oscilloscope-logic-analyzer-and-variable-power-supply/) <tr>\n",
    "<td> <img src=http://cdn6.bigcommerce.com/s-7gavg/products/468/images/2617/Analog_Discovery_2_obl_Academic_600__01249.1447804398.1280.1280.png alt=\"Drawing\" style=\"width: 250px;\"/> </td>\n",
    "</tr>\n",
    "\n",
    "and [WaveForms 2015](https://reference.digilentinc.com/waveforms3#newest)\n",
    "\n",
    "<tr>\n",
    "<td> <img src=http://cdn6.bigcommerce.com/s-7gavg/products/481/images/2623/TILE_WaveForms2015_150__84968.1447878611.1280.1280.png alt=\"Drawing\" style=\"width: 250px;\"/> </td>\n",
    "<td> <img src=http://cdn6.bigcommerce.com/s-7gavg/products/481/images/3961/img.07.0__38949.1458772469.1280.1280.png alt=\"Drawing\" style=\"width: 250px;\"/> </td>\n",
    "</tr>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Instantiation\n",
    "Import overlay to use the timers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from pynq import Overlay\n",
    "Overlay(\"base.bit\").download()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Instantiate Pmod_Timer class. The method `stop()` will stop both timer sub-modules.\n",
    "\n",
    "In this example, we will use pin 1 of the PMODA interface. PMODB and other pins can also be used."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "from time import sleep\n",
    "from pynq.iop import Pmod_Timer\n",
    "from pynq.iop import PMODA\n",
    "\n",
    "pt = Pmod_Timer(PMODA,1)\n",
    "pt.stop()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Generate pulses for a certain period of time\n",
    "In this example, we choose the Digilent Analog Discovery 2 as the scope. \n",
    "\n",
    "* The `1+` pin (of channel 1) has to be connected to pin 0 on PMODA interface. \n",
    "* The `1-` pin (of channel 1) has to be connected to `GND` on PMODA interface. \n",
    "\n",
    "\n",
    "Use the following settings for waveform.\n",
    "\n",
    "<img src=\"data/generate_1us_forever_settings.jpg\" width=\"200px\"/>\n",
    "\n",
    "Generate a 10 ns clock pulse every 1 microseconds for 4 seconds and then stop the generation.\n",
    "\n",
    "Note that pulses are generated every $(count+2)\\times10$ ns. Here count is defined as period.\n",
    "\n",
    "You should see output like this:\n",
    "\n",
    "<img src=\"data/generate_1us_forever.jpg\" width=\"800px\"/>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Generate a 10 ns pulse every (period+2)*10 ns\n",
    "period=98\n",
    "pt.generate_pulse(period)\n",
    "\n",
    "# Sleep for 4 seconds and stop the timer\n",
    "sleep(4)\n",
    "pt.stop()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Generate a certain number of pulses\n",
    "Note first parameter is the period interval. \n",
    "Denoting the desired period as $T$ (in ns), we need to set the first parameter `period` to:\n",
    "\n",
    "$period = \\frac{T}{10} - 2 $\n",
    "\n",
    "The second parameter is the number of pulses to be generated.\n",
    "\n",
    "Run the following cell and you should see output in the scope like this:\n",
    "\n",
    "<img src=\"data/generate_1us_n_times.jpg\" width=\"800px\"/>\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Generate 3 pulses at every 1 us\n",
    "count=3\n",
    "period=98\n",
    "pt.generate_pulse(period, count)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now generate the pulses at every 1 $\\mu$s interval."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Generate pulses per 1 us forever\n",
    "count=0\n",
    "period=98\n",
    "pt.generate_pulse(period, count)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Stop the generation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "pt.stop()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Determine if an event has occurred at the input \n",
    "\n",
    "An event is either a rising edge or a high logic level. The parameter is duration, $[(period+2)*10]$ ns, in which the event is to be detected. It returns 0 if no event occurred, otherwise it returns 1.\n",
    "\n",
    "Use a waveform generator in this example. Connect W1 channel of the Analog Discovery to Pin 1 of PMODA.\n",
    "\n",
    "Do not run the waveform generation in the next cell."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Detect any event within 10 us\n",
    "period=998\n",
    "pt.event_detected(period)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now run the waveform generation and then run the next cell. Set the waveform generator settings as shown below:\n",
    "\n",
    "<img src=\"data/measure_period_200KHz.jpg\" width=\"200px\"/>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Detect any event within 20 ms\n",
    "period=199998\n",
    "pt.event_detected(period)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. Count number of events occurred during a desired period \n",
    "\n",
    "An event is either a rising edge or a high logic level. The parameter is duration, $[(period+2)*10]$ ns, in which the number of event are counted. In this example we are interested in number of events occurring in 10 $\\mu$s.\n",
    "\n",
    "Use a waveform generator in this example. Use the following settings of the waveform generator and run the generator. Then run the next example.\n",
    "\n",
    "<img src=\"data/count_events_10us.jpg\" width=\"200px\"/>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Count number of events within 10 us\n",
    "period=998\n",
    "pt.event_count(period)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. Measure period between two rising edges \n",
    "\n",
    "An event is either a rising edge or a high logic level. It expects at least two rising edges. The return result is in units of nanoseconds.\n",
    "\n",
    "Use a waveform generator in this example. Use the following settings of the waveform generator and run the generation. Then run the next example.\n",
    "\n",
    "<img src=\"data/measure_period_200KHz.jpg\" width=\"200px\"/>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The measured waveform frequency: 200000.0 Hz\n"
     ]
    }
   ],
   "source": [
    "period = pt.get_period_ns()\n",
    "print(\"The measured waveform frequency: {} Hz\".format(1e9/period))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.4.3+"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
