From 1ae44013703af4e8757abe6adb70745861bf8f9f Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sun, 16 Dec 2012 19:20:11 +0100 Subject: digital/ucoolib/ucoolib/utils: add delay functions --- digital/ucoolib/ucoolib/utils/delay.arm.cc | 76 ++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 digital/ucoolib/ucoolib/utils/delay.arm.cc (limited to 'digital/ucoolib/ucoolib/utils/delay.arm.cc') diff --git a/digital/ucoolib/ucoolib/utils/delay.arm.cc b/digital/ucoolib/ucoolib/utils/delay.arm.cc new file mode 100644 index 00000000..8410c8d1 --- /dev/null +++ b/digital/ucoolib/ucoolib/utils/delay.arm.cc @@ -0,0 +1,76 @@ +// ucoolib - Microcontroller object oriented library. {{{ +// +// Copyright (C) 2012 Nicolas Schodet +// +// APBTeam: +// Web: http://apbteam.org/ +// Email: team AT apbteam DOT org +// +// 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 2 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, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// }}} +#include "delay.arm.hh" + +#include + +#include +#include + +namespace ucoo { + +void +delay_us (int us) +{ + // Horrible hack: there is no record of the current systick speed, make + // guesses based on APB2 clock. Also, suppose that frequency is a multiple + // of 1 MHz (to avoid 64 bit division). + int systick_mhz = rcc_ppre2_frequency / (4 * 1000000); + int cycles = systick_mhz * us; + STK_CTRL = 0; + // Loop several times if cycles is too big for the systick timer. Some + // nanoseconds are lost every second, I can live with that, it simplifies + // code. + while (cycles) + { + int loop_cycles = std::min (1 << 24, cycles); + STK_LOAD = loop_cycles - 1; + STK_VAL = 0; + STK_CTRL = STK_CTRL_ENABLE; + while (!(STK_CTRL & STK_CTRL_COUNTFLAG)) + ; + STK_CTRL = 0; + cycles -= loop_cycles; + } +} + +void +delay_ns (int ns) +{ + // Horrible hack: there is no record of the current hclock speed, make + // guesses based on APB2 clock. Also, suppose that frequency is a multiple + // of 1 MHz (to avoid 64 bit division). + int hclock_mhz = rcc_ppre2_frequency / (1000000 / 2); + int cycles = (hclock_mhz * ns + 999) / 1000; + STK_CTRL = 0; + // Loop once, ns is supposed to be small. + STK_LOAD = cycles - 1; + STK_VAL = 0; + STK_CTRL = STK_CTRL_CLKSOURCE_AHB | STK_CTRL_ENABLE; + while (!(STK_CTRL & STK_CTRL_COUNTFLAG)) + ; + STK_CTRL = 0; +} + +} // namespace ucoo -- cgit v1.2.3