sleep library for cortex m0

Dependencies:   mbed

Fork of cortexm0sleepmodes by ASIF AHMAD

Files at this revision

API Documentation at this revision

Comitter:
asifahmad
Date:
Fri Sep 27 18:13:20 2013 +0000
Commit message:
sleep

Changed in this revision

mbed.bld Show annotated file Show diff for this revision Revisions of this file
pca9865.h Show annotated file Show diff for this revision Revisions of this file
pmu.c Show annotated file Show diff for this revision Revisions of this file
pmu.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Sep 27 18:13:20 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/a9913a65894f
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pca9865.h	Fri Sep 27 18:13:20 2013 +0000
@@ -0,0 +1,74 @@
+/**************************************************************************/
+/*!
+    @file     pca9685.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _PCA9685_H_
+#define _PCA9685_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+
+#define PCA9685_ADDRESS           (0x40<<1)    // 1000000
+#define PCA9685_READBIT           (0x01)
+
+enum
+{
+  PCA9685_REG_SUBADR1            = 0x02,
+  PCA9685_REG_SUBADR2            = 0x03,
+  PCA9685_REG_SUBADR3            = 0x04,
+  PCA9685_REG_MODE1              = 0x00,
+  PCA9685_REG_PRESCALE           = 0xFE,
+  PCA9685_REG_LED0_ON_L          = 0x06,
+  PCA9685_REG_LED0_ON_H          = 0x07,
+  PCA9685_REG_LED0_OFF_L         = 0x08,
+  PCA9685_REG_LED0_OFF_H         = 0x09,
+  PCA9685_REG_ALLLED_ON_L        = 0xFA,
+  PCA9685_REG_ALLLED_ON_H        = 0xFB,
+  PCA9685_REG_ALLLED_OFF_L       = 0xFC,
+  PCA9685_REG_ALLLED_OFF_H       = 0xFD
+};
+
+error_t pca9685Init (uint8_t address);
+error_t pca9685SetFrequency (uint16_t freqHz);
+error_t pca9685SetPWM (uint16_t channel, uint16_t on, uint16_t off);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pmu.c	Fri Sep 27 18:13:20 2013 +0000
@@ -0,0 +1,255 @@
+
+/**************************************************************************/
+/*!
+    @file     pca9685.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Drivers for NXP's PCA9685 12-bit 16-channel PWM Driver
+
+    @section DESCRIPTION
+
+    The PCA9685 is an I2C-bus controlled 16-channel LED controller
+    optimized for LCD Red/Green/Blue/Amber (RGBA) color backlighting
+    applications. Each LED output has its own 12-bit resolution (4096
+    steps) fixed frequency individual PWM controller that operates at a
+    programmable frequency from 40 Hz to 1000 Hz with a duty cycle that
+    is adjustable from 0 % to 100 % to allow the LED to be set to a
+    specific brightness value. All outputs are set to the same PWM
+    frequency.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <string.h>
+#include "pca9685.h"
+#include "core/gpio/gpio.h"
+#include "core/delay/delay.h"
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+static bool _pca9685Initialised = false;
+static uint8_t _pca9685Address = PCA9685_ADDRESS;
+
+/**************************************************************************/
+/*!
+    @brief  Writes the specified number of bytes over I2C
+*/
+/**************************************************************************/
+error_t pca9685WriteBytes(uint8_t reg, uint8_t *buffer, size_t length)
+{
+  uint32_t i;
+
+  /* Try to avoid buffer overflow */
+  ASSERT(length <= I2C_BUFSIZE - 2, ERROR_BUFFEROVERFLOW);
+
+  /* Fill write buffer */
+  for ( i = 2; i < length+2; i++ )
+  {
+    I2CMasterBuffer[i] = buffer[i-2];
+  }
+
+  /* Write transaction */
+  I2CWriteLength = 2+length;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = _pca9685Address;
+  I2CMasterBuffer[1] = reg;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the specified number of bytes over I2C
+*/
+/**************************************************************************/
+error_t pca9685ReadBytes(uint8_t reg, uint8_t *buffer, size_t length)
+{
+  uint32_t i;
+
+  /* Try to avoid buffer overflow */
+  ASSERT(length <= I2C_BUFSIZE, ERROR_BUFFEROVERFLOW);
+
+  /* Read and write need to be handled in separate transactions or the
+     PCA9685 increments the current register one step ahead of where
+     we should be. */
+
+  /* Write transaction */
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = _pca9685Address;
+  I2CMasterBuffer[1] = reg;
+  i2cEngine();
+
+  /* Read transaction */
+  I2CWriteLength = 0;
+  I2CReadLength = length;
+  I2CMasterBuffer[0] = _pca9685Address | PCA9685_READBIT;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  /* Fill the buffer with the I2C response */
+  for ( i = 0; i < length; i++ )
+  {
+    buffer[i] = I2CSlaveBuffer[i];
+  }
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Writes an 8 bit value over I2C
+*/
+/**************************************************************************/
+error_t pca9685Write8 (uint8_t reg, uint8_t value)
+{
+  uint8_t buffer = value;
+  return pca9685WriteBytes(reg, &buffer, 1);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a single byte over I2C
+*/
+/**************************************************************************/
+error_t pca9685Read8(uint8_t reg, uint8_t *result)
+{
+  return pca9685ReadBytes(reg, result, 1);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises the I2C block
+
+    @param address  The device I2C address (left-shifted 1 bit)
+*/
+/**************************************************************************/
+error_t pca9685Init(uint8_t address)
+{
+  // Initialise I2C
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  ASSERT(!(i2cCheckAddress(_pca9685Address)), ERROR_I2C_DEVICENOTFOUND);
+
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_MODE1, 0x00));
+
+  _pca9685Initialised = true;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the PWM clock frequency (40-1000Hz)
+
+    @param freqHz  Approximate frequency in Hz (40-1000)
+*/
+/**************************************************************************/
+error_t pca9685SetFrequency(uint16_t freqHz)
+{
+  uint32_t prescaleValue;
+  uint8_t oldMode, newMode;
+
+  ASSERT(_pca9685Initialised, ERROR_DEVICENOTINITIALISED);
+
+  if (freqHz < 40)
+  {
+    freqHz = 40;
+  }
+
+  if (freqHz > 1000)
+  {
+    freqHz = 1000;
+  }
+
+  // prescaleValue = round(25MHz / (4096*updateRate)) - 1
+  prescaleValue = 25000000;   // 25 MHz
+  prescaleValue /= 4096;      // 12-bit
+  prescaleValue /= freqHz;
+  prescaleValue -= 1;
+
+  ASSERT_STATUS(pca9685Read8(PCA9685_REG_MODE1, &oldMode));
+  newMode = (oldMode & 0x7F) | 0x10;
+
+  // Go to sleep
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_MODE1, newMode));
+
+  // Set prescale
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_PRESCALE, prescaleValue & 0xFF));
+
+  // Wakeup
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_MODE1, oldMode));
+  delay(5);
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_MODE1, oldMode | 0x80));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the PWM output of the specified channel
+
+    @param channel  The channel number [0..15]
+    @param on       The 12-bit start point (low to high transition)
+    @param off      The 12-bit stop point (high to low transition)
+*/
+/**************************************************************************/
+error_t pca9685SetPWM(uint16_t channel, uint16_t on, uint16_t off)
+{
+  ASSERT(_pca9685Initialised, ERROR_DEVICENOTINITIALISED);
+
+  if (on > 0xFFF)
+  {
+    on = 0xFFF;
+  }
+
+  if (off < on)
+  {
+    off = on;
+  }
+
+  if (off > 0xFFF)
+  {
+    off = 0xFFF;
+  }
+
+  /* Set the on and off values */
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_LED0_ON_L+4*channel, on & 0xFF));
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_LED0_ON_H+4*channel, on >> 8));
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_LED0_OFF_L+4*channel, off & 0xFF));
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_LED0_OFF_H+4*channel, off >> 8));
+
+  return ERROR_NONE;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pmu.h	Fri Sep 27 18:13:20 2013 +0000
@@ -0,0 +1,69 @@
+/**************************************************************************/
+/*!
+    @file     pmu.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __PMU_H__
+#define __PMU_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+#define MCU_SLEEP           (0)
+#define MCU_DEEP_SLEEP      (1)
+#define MCU_POWER_DOWN      (2)
+
+#define NVIC_LP_SEVONPEND   (0x10)
+#define NVIC_LP_SLEEPDEEP   (0x04)
+#define NVIC_LP_SLEEPONEXIT (0x02)
+
+#define IRC_OUT_PD          (0x1<<0)
+#define IRC_PD              (0x1<<1)
+#define FLASH_PD            (0x1<<2)
+#define BOD_PD              (0x1<<3)
+#define ADC_PD              (0x1<<4)
+#define SYS_OSC_PD          (0x1<<5)
+#define WDT_OSC_PD          (0x1<<6)
+#define SYS_PLL_PD          (0x1<<7)
+#define USBPLL_PD           (0x1<<8)
+#define USBPAD_PD           (0x1<<10)
+
+void PMU_Sleep( uint32_t SleepMode, uint32_t SleepCtrl );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file