ASIF AHMAD
/
cortexm0sleepmode
sleep library for cortex m0
Fork of cortexm0sleepmodes by
Revision 0:e8a124690cda, committed 2013-09-27
- Comitter:
- asifahmad
- Date:
- Fri Sep 27 18:13:20 2013 +0000
- Commit message:
- sleep
Changed in this revision
diff -r 000000000000 -r e8a124690cda mbed.bld --- /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
diff -r 000000000000 -r e8a124690cda pca9865.h --- /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
diff -r 000000000000 -r e8a124690cda pmu.c --- /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
diff -r 000000000000 -r e8a124690cda pmu.h --- /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