Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:48

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (c) 2016 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #include <bsp.h>
0029 #include <bsp/power.h>
0030 #include <bsp/irq.h>
0031 
0032 #include <libchip/chip.h>
0033 
0034 void atsam_power_change_state(
0035     const atsam_power_control *controls,
0036     size_t n,
0037     atsam_power_state state
0038 )
0039 {
0040     size_t i;
0041 
0042     switch (state) {
0043         case ATSAM_POWER_ON:
0044             for (i = n; i > 0; --i) {
0045                 const atsam_power_control *c;
0046 
0047                 c = &controls[i - 1];
0048                 (*c->handler)(c, state);
0049             }
0050 
0051             break;
0052         case ATSAM_POWER_INIT:
0053         case ATSAM_POWER_OFF:
0054             for (i = 0; i < n; ++i) {
0055                 const atsam_power_control *c;
0056 
0057                 c = &controls[i];
0058                 (*c->handler)(c, state);
0059             }
0060 
0061             break;
0062         default:
0063             break;
0064     }
0065 }
0066 
0067 void atsam_power_handler_peripheral(
0068     const atsam_power_control *control,
0069     atsam_power_state state
0070 )
0071 {
0072     uint32_t id;
0073     uint32_t end;
0074 
0075     id = control->data.peripherals.first;
0076     end = control->data.peripherals.last + 1;
0077 
0078     switch (state) {
0079         case ATSAM_POWER_ON:
0080             while (id != end) {
0081                 PMC_EnablePeripheral(id);
0082                 ++id;
0083             }
0084             break;
0085         case ATSAM_POWER_OFF:
0086             while (id != end) {
0087                 PMC_DisablePeripheral(id);
0088                 ++id;
0089             }
0090             break;
0091         default:
0092             break;
0093     }
0094 }
0095 
0096 void atsam_power_handler_sleep_mode(const atsam_power_control *control, atsam_power_state state)
0097 {
0098     (void) control;
0099 
0100     switch (state) {
0101         case ATSAM_POWER_OFF:
0102             /* Enable Low Power Mode in the Fast Startup Mode Register */
0103             PMC->PMC_FSMR &= (uint32_t)~PMC_FSMR_LPM;
0104             /* Do not set deep sleep, but "normal" sleep */
0105             SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
0106 
0107             __asm__ volatile ("wfi");
0108             break;
0109         default:
0110             break;
0111     }
0112 }