changeset 2620:55ad6e12c647

* cdl/stm32_wallclock.cdl: * src/stm32_wallclock.cxx: Driver for on-chip RTC unit.
author nickg
date Tue, 11 Nov 2008 17:20:24 +0000
parents e00f121867c8
children ea61135f2839
files packages/devs/wallclock/cortexm/stm32/current/ChangeLog packages/devs/wallclock/cortexm/stm32/current/cdl/wallclock_stm32.cdl packages/devs/wallclock/cortexm/stm32/current/src/stm32_wallclock.cxx
diffstat 3 files changed, 364 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/packages/devs/wallclock/cortexm/stm32/current/ChangeLog
@@ -0,0 +1,43 @@
+2008-11-05  Simon Kallweit  <simon.kalweit@intefo.ch>
+
+	* cdl/wallclock_stm32.cdl:
+	* src/stm32_wallclock.cxx:
+	Adapted to ecoscentric cortexm port.
+
+2008-10-27  Simon Kallweit  <simon.kallweit@intefo.ch>
+
+	* cdl/stm32_wallclock.cdl:
+	* src/stm32_wallclock.cxx:
+	Driver for on-chip RTC unit.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos 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 or (at your option) any later version.
+//
+// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
new file mode 100644
--- /dev/null
+++ b/packages/devs/wallclock/cortexm/stm32/current/cdl/wallclock_stm32.cdl
@@ -0,0 +1,77 @@
+# ====================================================================
+#
+#      wallclock_stm32.cdl
+#
+#      Hardware support for STM32 on-chip RTC.
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008 Free Software Foundation, Inc.
+##
+## eCos 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 or (at your option) any later version.
+##
+## eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      Simon Kallweit
+# Contributors:   
+# Date:           2008-10-27
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_WALLCLOCK_STM32 {
+    display       "STM32 RTC wallclock support"
+    description   "
+        Wallclock support for on-chip RTC on STM32 devices.driver for the
+        STM32 controller and compatibles"
+
+    parent        CYGPKG_IO_WALLCLOCK
+    active_if     CYGPKG_IO_WALLCLOCK
+    active_if     CYGPKG_HAL_CORTEXM_STM32
+
+    compile       stm32_wallclock.cxx
+
+    implements    CYGINT_WALLCLOCK_HW_IMPLEMENTATIONS
+    active_if     CYGIMP_WALLCLOCK_HARDWARE
+    implements    CYGINT_WALLCLOCK_SET_GET_MODE_SUPPORTED
+    
+    cdl_option CYGIMP_WALLCLOCK_HARDWARE {
+        parent          CYGPKG_IO_WALLCLOCK_IMPLEMENTATION
+        display         "Hardware wallclock"
+        default_value   1
+        implements      CYGINT_WALLCLOCK_IMPLEMENTATIONS
+    }
+    
+    cdl_option CYGHWR_DEVS_WALLCLOCK_STM32_RTC_SOURCE {
+        display             "RTC clock source"
+        flavor              data
+        default_value       { "LSE" }
+        legal_values        { "LSE" "LSI" "HSE_128" }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/packages/devs/wallclock/cortexm/stm32/current/src/stm32_wallclock.cxx
@@ -0,0 +1,244 @@
+//==========================================================================
+//
+//      stm32_wallclock.cxx
+//
+//      Wallclock implementation for STM32
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos 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 or (at your option) any later version.
+//
+// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     Simon Kallweit
+// Contributors:  
+// Date:          2008-10-27
+// Purpose:       Wallclock driver for STM32
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_cortexm.h>
+#include <pkgconf/hal_cortexm_stm32.h>
+#include <pkgconf/wallclock.h>
+#include <pkgconf/devs_wallclock_stm32.h>
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/io/wallclock.hxx>
+
+//==========================================================================
+// Clock Initialization values
+
+#if defined(CYGHWR_DEVS_WALLCLOCK_STM32_RTC_SOURCE_LSE)
+# define CYGHWR_DEVS_WALLCLOCK_STM32_RTCSEL CYGHWR_HAL_STM32_RCC_BDCR_RTCSEL_LSE
+# define CYGHWR_DEVS_WALLCLOCK_STM32_CLOCK 32768
+#elif defined(CYGHWR_DEVS_WALLCLOCK_STM32_RTC_SOURCE_LSI)
+# define CYGHWR_DEVS_WALLCLOCK_STM32_RTCSEL CYGHWR_HAL_STM32_RCC_BDCR_RTCSEL_LSI
+# define CYGHWR_DEVS_WALLCLOCK_STM32_CLOCK 40000
+#elif defined(CYGHWR_DEVS_WALLCLOCK_STM32_RTC_SOURCE_HSE_128)
+# define CYGHWR_DEVS_WALLCLOCK_STM32_RTCSEL CYGHWR_HAL_STM32_RCC_BDCR_RTCSEL_HSE
+# define CYGHWR_DEVS_WALLCLOCK_STM32_CLOCK (CYGARC_HAL_CORTEXM_STM32_INPUT_CLOCK / 128)
+#endif
+
+// Wait for registers to be synchronized
+static void
+wait_sync(void)
+{
+    CYG_ADDRESS rtc = CYGHWR_HAL_STM32_RTC;
+    cyg_uint16 crl;
+    
+    do
+    {
+        HAL_READ_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CRL, crl );
+    } while ( !(crl & CYGHWR_HAL_STM32_RTC_CRL_RSF) );
+}
+
+// Wait for last write operation to finish
+static void
+wait_rtoff(void)
+{
+    CYG_ADDRESS rtc = CYGHWR_HAL_STM32_RTC;
+    cyg_uint16 crl;
+    
+    do
+    {
+        HAL_READ_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CRL, crl );
+    } while ( !(crl & CYGHWR_HAL_STM32_RTC_CRL_RTOFF) );
+}
+
+// Enter/leave configuration mode
+static void
+config_mode(int val)
+{
+    CYG_ADDRESS rtc = CYGHWR_HAL_STM32_RTC;
+    cyg_uint16 crl;
+    
+    if (val)
+        wait_rtoff();
+
+    HAL_READ_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CRL, crl );
+    if (val)
+        crl |= CYGHWR_HAL_STM32_RTC_CRL_CNF;
+    else
+        crl &= ~CYGHWR_HAL_STM32_RTC_CRL_CNF;
+    HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CRL, crl );
+    
+    if (!val)
+        wait_rtoff();
+}
+
+void
+Cyg_WallClock::init_hw_seconds(void)
+{
+    CYG_ADDRESS rcc = CYGHWR_HAL_STM32_RCC;
+    CYG_ADDRESS rtc = CYGHWR_HAL_STM32_RTC;
+    cyg_uint32 bdcr, csr;
+    cyg_uint32 prescaler = CYGHWR_DEVS_WALLCLOCK_STM32_CLOCK - 1;
+    
+    // Reset the backup domain if clock source does not match as
+    // RTCSEL can only be written to backup domain once
+    HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_BDCR, bdcr );
+    if ((bdcr & CYGHWR_HAL_STM32_RCC_BDCR_RTCSEL_XXX) !=
+        CYGHWR_DEVS_WALLCLOCK_STM32_RTCSEL)
+    {
+        // Reset backup domain
+        CYGHWR_HAL_STM32_BD_RESET();
+    }
+
+    // Disable backup domain protection
+    CYGHWR_HAL_STM32_BD_UNPROTECT(1);
+    
+#if defined(CYGHWR_DEVS_WALLCLOCK_STM32_RTC_SOURCE_LSI)
+    // Start up LSI clock
+    HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CSR, csr );
+    csr |= CYGHWR_HAL_STM32_RCC_CSR_LSION;
+    HAL_WRITE_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CSR, csr );
+    
+    // Wait for LSI clock to startup
+    do
+    {
+        HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CSR, csr );
+    } while( !(csr & CYGHWR_HAL_STM32_RCC_CSR_LSIRDY) );
+#endif
+    
+#if defined(CYGHWR_DEVS_WALLCLOCK_STM32_RTC_SOURCE_LSE)
+    // Start up LSE clock
+    HAL_WRITE_UINT32( rcc+CYGHWR_HAL_STM32_RCC_BDCR, CYGHWR_HAL_STM32_RCC_BDCR_LSEON );
+
+    // Wait for LSE clock to startup
+    do
+    {
+        HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_BDCR, bdcr );
+    } while( !(bdcr & CYGHWR_HAL_STM32_RCC_BDCR_LSERDY) );
+#endif
+    
+    // Enable RTC
+    HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_BDCR, bdcr );
+    bdcr |= CYGHWR_DEVS_WALLCLOCK_STM32_RTCSEL;
+    bdcr |= CYGHWR_HAL_STM32_RCC_BDCR_RTCEN;
+    HAL_WRITE_UINT32( rcc+CYGHWR_HAL_STM32_RCC_BDCR, bdcr );
+    
+    // Synchronize registers
+    wait_sync();
+    
+    // Enter configuration mode
+    config_mode(1);
+    
+    // Disable all interrupts
+    HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CRH, 0 );
+    
+    // Set prescaler load value
+    HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_PRLL, prescaler & 0xffff);
+    HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_PRLH, prescaler >> 16);
+    
+    // Reset alarm value
+    HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_ALRL, 0 );
+    HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_ALRH, 0 );
+    
+#ifndef CYGSEM_WALLCLOCK_SET_GET_MODE
+    // Reset counter value
+    HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CNTL, 0 );
+    HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CNTH, 0 );
+#endif
+    
+    // Leave configuration mode
+    config_mode(0);
+    
+    // Restore backup domain protection
+    CYGHWR_HAL_STM32_BD_UNPROTECT(0);
+}
+
+cyg_uint32
+Cyg_WallClock::get_hw_seconds(void)
+{
+    CYG_ADDRESS rtc = CYGHWR_HAL_STM32_RTC;
+    cyg_uint16 cnt;
+    cyg_uint32 secs;
+    
+    // Synchronize registers
+    wait_sync();
+    
+    // Read counter value
+    HAL_READ_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CNTL, cnt );
+    secs = cnt;
+    HAL_READ_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CNTH, cnt );
+    secs |= (cnt << 16);
+    
+    return secs;
+}
+
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+void
+Cyg_WallClock::set_hw_seconds(cyg_uint32 secs)
+{
+    CYG_ADDRESS rtc = CYGHWR_HAL_STM32_RTC;
+
+    // Disable backup domain protection
+    CYGHWR_HAL_STM32_BD_UNPROTECT(1);
+    
+    // Enter configuration mode
+    config_mode(1);
+    
+    // Set counter value
+    HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CNTL, secs & 0xffff );
+    HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CNTH, secs >> 16 );
+    
+    // Leave configuration mode
+    config_mode(0);
+    
+    // Restore backup domain protection
+    CYGHWR_HAL_STM32_BD_UNPROTECT(0);
+}
+#endif