- Main Page
- Related Pages
- Data Structures
- Files

# pwm.c

Go to the documentation of this file.

    00001 /*This file has been prepared for Doxygen automatic documentation generation.*/
    00018 /* Copyright (C) 2006-2008, Atmel Corporation All rights reserved.
    00019  *
    00020  * Redistribution and use in source and binary forms, with or without
    00021  * modification, are permitted provided that the following conditions are met:
    00022  *
    00023  * 1. Redistributions of source code must retain the above copyright notice,
    00024  * this list of conditions and the following disclaimer.
    00025  *
    00026  * 2. Redistributions in binary form must reproduce the above copyright notice,
    00027  * this list of conditions and the following disclaimer in the documentation
    00028  * and/or other materials provided with the distribution.
    00029  *
    00030  * 3. The name of ATMEL may not be used to endorse or promote products derived
    00031  * from this software without specific prior written permission.
    00032  *
    00033  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
    00034  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    00035  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
    00036  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
    00037  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    00038  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    00039  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    00040  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00041  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    00042  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00043  */
    00044
    00045
    00046 #include "compiler.h"
    00047 #include "pwm.h"
    00048
    00049
    00050 int pwm_init(const pwm_opt_t *opt)
    00051 {
    00052   volatile avr32_pwm_t *pwm = &AVR32_PWM;
    00053   Bool global_interrupt_enabled = Is_global_interrupt_enabled();
    00054
    00055   if (opt == 0 ) // Null pointer.
    00056     return PWM_INVALID_INPUT;
    00057
    00058   // Disable interrupt.
    00059   if (global_interrupt_enabled) Disable_global_interrupt();
    00060   pwm->idr = ((1 << (AVR32_PWM_LINES_MSB + 1)) - 1) << AVR32_PWM_IDR_CHID0_OFFSET;
    00061   pwm->isr;
    00062   if (global_interrupt_enabled) Enable_global_interrupt();
    00063
    00064   // Set PWM mode register.
    00065   pwm->mr =
    00066     ((opt->diva)<<AVR32_PWM_DIVA_OFFSET) |
    00067     ((opt->divb)<<AVR32_PWM_DIVB_OFFSET) |
    00068     ((opt->prea)<<AVR32_PWM_PREA_OFFSET) |
    00069     ((opt->preb)<<AVR32_PWM_PREB_OFFSET)
    00070     ;
    00071
    00072   return PWM_SUCCESS;
    00073 }
    00074
    00075
    00076 int pwm_channel_init( unsigned int channel_id, const avr32_pwm_channel_t *pwm_channel)
    00077 {
    00078   volatile avr32_pwm_t *pwm = &AVR32_PWM;
    00079
    00080   if (pwm_channel == 0) // Null pointer.
    00081     return PWM_INVALID_ARGUMENT;
    00082   if (channel_id > AVR32_PWM_LINES_MSB) // Control input values.
    00083     return PWM_INVALID_INPUT;
    00084
    00085   pwm->channel[channel_id].cmr= pwm_channel->cmr;   // Channel mode.
    00086   pwm->channel[channel_id].cdty= pwm_channel->cdty; // Duty cycle, should be < CPRD.
    00087   pwm->channel[channel_id].cprd= pwm_channel->cprd; // Channel period.
    00088
    00089   return PWM_SUCCESS;
    00090 }
    00091
    00092
    00093 int pwm_start_channels(unsigned long channels_bitmask)
    00094 {
    00095   if (channels_bitmask & ~((1 << (AVR32_PWM_LINES_MSB + 1)) - 1))
    00096     return PWM_INVALID_INPUT;
    00097
    00098   AVR32_PWM.ena = channels_bitmask; // Enable channels.
    00099
    00100   return PWM_SUCCESS;
    00101 }
    00102
    00103
    00104 int pwm_stop_channels(unsigned long channels_bitmask)
    00105 {
    00106   if (channels_bitmask & ~((1 << (AVR32_PWM_LINES_MSB + 1)) - 1))
    00107     return PWM_INVALID_INPUT;
    00108
    00109   AVR32_PWM.dis = channels_bitmask; // Disable channels.
    00110
    00111   return PWM_SUCCESS;
    00112 }
    00113
    00114
    00115 int pwm_sync_update_channel(unsigned int channel_id, const avr32_pwm_channel_t *pwm_channel)
    00116 {
    00117   volatile avr32_pwm_t *pwm = &AVR32_PWM;
    00118
    00119   if (channel_id > AVR32_PWM_LINES_MSB)
    00120      return PWM_INVALID_INPUT;
    00121
    00122   AVR32_PWM.isr;                                    // Acknowledgement and clear previous register state.
    00123   pwm->channel[channel_id].cmr= pwm_channel->cmr;   // Channel mode register: update of the period or duty cycle.
    00124   while (!(AVR32_PWM.isr & (1 << channel_id)));     // Wait until the last write has been taken into account.
    00125   pwm->channel[channel_id].cupd= pwm_channel->cupd; // Channel update CPRDx or CDTYx according to CPD value in CMRx.
    00126
    00127   return PWM_SUCCESS;
    00128 }
    00129
    00130
    00131 int pwm_async_update_channel(unsigned int channel_id, const avr32_pwm_channel_t *pwm_channel)
    00132 {
    00133   volatile avr32_pwm_t *pwm = &AVR32_PWM;
    00134
    00135   if (channel_id > AVR32_PWM_LINES_MSB)
    00136      return PWM_INVALID_INPUT;
    00137
    00138   pwm->channel[channel_id].cmr= pwm_channel->cmr;   // Channel mode register: update of the period or duty cycle.
    00139   pwm->channel[channel_id].cupd= pwm_channel->cupd; // Channel update CPRDx or CDTYx according to CPD value in CMRx.
    00140
    00141   return PWM_SUCCESS;
    00142 }