mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-17 23:48:13 +08:00
修复mico-sdk错误
This commit is contained in:
@@ -1 +1 @@
|
||||
# This file needs to be customized to your MCU and is intentionally left blank
|
||||
# This file needs to be customized to your MCU and is intentionally left blank
|
||||
|
||||
@@ -1 +1 @@
|
||||
# This file needs to be customized to your MCU and is intentionally left blank
|
||||
# This file needs to be customized to your MCU and is intentionally left blank
|
||||
|
||||
@@ -51,45 +51,45 @@
|
||||
* The file is automatically generated and will be re-written when
|
||||
* running the ASF driver selector tool. Any changes will be discarded.
|
||||
*/
|
||||
|
||||
// From module: CPU specific features
|
||||
#include <mega_reset_cause.h>
|
||||
|
||||
// From module: Delay routines
|
||||
#include <delay.h>
|
||||
|
||||
// From module: GPIO - General purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: IOPORT - General purpose I/O service
|
||||
#include <ioport.h>
|
||||
|
||||
// From module: Interrupt management - megaAVR and tinyAVR implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEGA compiler driver
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - MEGARF implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - MEGA RF A1 implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: USART - Serial interface - MEGARF implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart_megarf.h>
|
||||
|
||||
// From module: CPU specific features
|
||||
#include <mega_reset_cause.h>
|
||||
|
||||
// From module: Delay routines
|
||||
#include <delay.h>
|
||||
|
||||
// From module: GPIO - General purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: IOPORT - General purpose I/O service
|
||||
#include <ioport.h>
|
||||
|
||||
// From module: Interrupt management - megaAVR and tinyAVR implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEGA compiler driver
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - MEGARF implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - MEGA RF A1 implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: USART - Serial interface - MEGARF implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart_megarf.h>
|
||||
|
||||
#endif // ASF_H
|
||||
|
||||
@@ -51,45 +51,45 @@
|
||||
* The file is automatically generated and will be re-written when
|
||||
* running the ASF driver selector tool. Any changes will be discarded.
|
||||
*/
|
||||
|
||||
// From module: CPU specific features
|
||||
#include <mega_reset_cause.h>
|
||||
|
||||
// From module: Delay routines
|
||||
#include <delay.h>
|
||||
|
||||
// From module: GPIO - General purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: IOPORT - General purpose I/O service
|
||||
#include <ioport.h>
|
||||
|
||||
// From module: Interrupt management - megaAVR and tinyAVR implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEGA compiler driver
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - MEGARF implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - MEGA RF A1 implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: USART - Serial interface - MEGARF implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart_megarf.h>
|
||||
|
||||
// From module: CPU specific features
|
||||
#include <mega_reset_cause.h>
|
||||
|
||||
// From module: Delay routines
|
||||
#include <delay.h>
|
||||
|
||||
// From module: GPIO - General purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: IOPORT - General purpose I/O service
|
||||
#include <ioport.h>
|
||||
|
||||
// From module: Interrupt management - megaAVR and tinyAVR implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEGA compiler driver
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - MEGARF implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - MEGA RF A1 implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: USART - Serial interface - MEGARF implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart_megarf.h>
|
||||
|
||||
#endif // ASF_H
|
||||
|
||||
@@ -51,45 +51,45 @@
|
||||
* The file is automatically generated and will be re-written when
|
||||
* running the ASF driver selector tool. Any changes will be discarded.
|
||||
*/
|
||||
|
||||
// From module: CPU specific features
|
||||
#include <mega_reset_cause.h>
|
||||
|
||||
// From module: Delay routines
|
||||
#include <delay.h>
|
||||
|
||||
// From module: GPIO - General purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: IOPORT - General purpose I/O service
|
||||
#include <ioport.h>
|
||||
|
||||
// From module: Interrupt management - megaAVR and tinyAVR implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEGA compiler driver
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - MEGARF implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - MEGA RF A1 implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: USART - Serial interface - MEGARF implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart_megarf.h>
|
||||
|
||||
// From module: CPU specific features
|
||||
#include <mega_reset_cause.h>
|
||||
|
||||
// From module: Delay routines
|
||||
#include <delay.h>
|
||||
|
||||
// From module: GPIO - General purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: IOPORT - General purpose I/O service
|
||||
#include <ioport.h>
|
||||
|
||||
// From module: Interrupt management - megaAVR and tinyAVR implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEGA compiler driver
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - MEGARF implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - MEGA RF A1 implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: USART - Serial interface - MEGARF implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart_megarf.h>
|
||||
|
||||
#endif // ASF_H
|
||||
|
||||
@@ -51,45 +51,45 @@
|
||||
* The file is automatically generated and will be re-written when
|
||||
* running the ASF driver selector tool. Any changes will be discarded.
|
||||
*/
|
||||
|
||||
// From module: CPU specific features
|
||||
#include <mega_reset_cause.h>
|
||||
|
||||
// From module: Delay routines
|
||||
#include <delay.h>
|
||||
|
||||
// From module: GPIO - General purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: IOPORT - General purpose I/O service
|
||||
#include <ioport.h>
|
||||
|
||||
// From module: Interrupt management - megaAVR and tinyAVR implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEGA compiler driver
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - MEGARF implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - MEGA RF A1 implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: USART - Serial interface - MEGARF implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart_megarf.h>
|
||||
|
||||
// From module: CPU specific features
|
||||
#include <mega_reset_cause.h>
|
||||
|
||||
// From module: Delay routines
|
||||
#include <delay.h>
|
||||
|
||||
// From module: GPIO - General purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: IOPORT - General purpose I/O service
|
||||
#include <ioport.h>
|
||||
|
||||
// From module: Interrupt management - megaAVR and tinyAVR implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEGA compiler driver
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - MEGARF implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - MEGA RF A1 implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: USART - Serial interface - MEGARF implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart_megarf.h>
|
||||
|
||||
#endif // ASF_H
|
||||
|
||||
@@ -1,54 +1,54 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM3/SAM4 Sleep manager implementation.
|
||||
*
|
||||
* Copyright (c) 2012-2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* 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. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 4. This software may only be redistributed and used in connection with an
|
||||
* Atmel microcontroller product.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
|
||||
*/
|
||||
|
||||
#include <compiler.h>
|
||||
#include <sleepmgr.h>
|
||||
|
||||
#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__)
|
||||
|
||||
uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES];
|
||||
|
||||
#endif /* CONFIG_SLEEPMGR_ENABLE */
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM3/SAM4 Sleep manager implementation.
|
||||
*
|
||||
* Copyright (c) 2012-2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* 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. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 4. This software may only be redistributed and used in connection with an
|
||||
* Atmel microcontroller product.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
|
||||
*/
|
||||
|
||||
#include <compiler.h>
|
||||
#include <sleepmgr.h>
|
||||
|
||||
#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__)
|
||||
|
||||
uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES];
|
||||
|
||||
#endif /* CONFIG_SLEEPMGR_ENABLE */
|
||||
|
||||
@@ -1,136 +1,136 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM3/SAM4 Sleep manager implementation.
|
||||
*
|
||||
* Copyright (c) 2012-2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* 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. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 4. This software may only be redistributed and used in connection with an
|
||||
* Atmel microcontroller product.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
|
||||
*/
|
||||
|
||||
#ifndef SAM_SLEEPMGR_INCLUDED
|
||||
#define SAM_SLEEPMGR_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <compiler.h>
|
||||
#include <conf_sleepmgr.h>
|
||||
#include <sleep.h>
|
||||
#include <interrupt.h>
|
||||
|
||||
/**
|
||||
* \weakgroup sleepmgr_group
|
||||
* @{
|
||||
*/
|
||||
#if (SAMG51 || SAMG53 || SAMG54)
|
||||
enum sleepmgr_mode {
|
||||
//! Active mode.
|
||||
SLEEPMGR_ACTIVE = 0,
|
||||
/*! Wait mode, wakeup fast (in 3ms).
|
||||
* Potential Wake Up sources: fast startup events */
|
||||
SLEEPMGR_WAIT_FAST,
|
||||
/*! Wait mode.
|
||||
* Potential Wake Up sources: fast startup events */
|
||||
SLEEPMGR_WAIT,
|
||||
|
||||
SLEEPMGR_NR_OF_MODES,
|
||||
};
|
||||
|
||||
#else
|
||||
enum sleepmgr_mode {
|
||||
//! Active mode.
|
||||
SLEEPMGR_ACTIVE = 0,
|
||||
/*! WFE sleep mode.
|
||||
* Potential Wake Up sources:
|
||||
* fast startup events (USB, RTC, RTT, WKUPs),
|
||||
* interrupt, and events. */
|
||||
SLEEPMGR_SLEEP_WFE,
|
||||
/*! WFI sleep mode.
|
||||
* Potential Wake Up sources: fast startup events and interrupt. */
|
||||
SLEEPMGR_SLEEP_WFI,
|
||||
/*! Wait mode, wakeup fast (in 3ms).
|
||||
* XTAL is not disabled when sleep.
|
||||
* Potential Wake Up sources: fast startup events */
|
||||
SLEEPMGR_WAIT_FAST,
|
||||
/*! Wait mode.
|
||||
* Potential Wake Up sources: fast startup events */
|
||||
SLEEPMGR_WAIT,
|
||||
//! Backup mode. Potential Wake Up sources: WKUPs, SM, RTT, RTC.
|
||||
SLEEPMGR_BACKUP,
|
||||
|
||||
SLEEPMGR_NR_OF_MODES,
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* \name Internal arrays
|
||||
* @{
|
||||
*/
|
||||
#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__)
|
||||
//! Sleep mode lock counters
|
||||
extern uint8_t sleepmgr_locks[];
|
||||
#endif /* CONFIG_SLEEPMGR_ENABLE */
|
||||
//! @}
|
||||
|
||||
|
||||
static inline void sleepmgr_sleep(const enum sleepmgr_mode sleep_mode)
|
||||
{
|
||||
Assert(sleep_mode != SLEEPMGR_ACTIVE);
|
||||
#ifdef CONFIG_SLEEPMGR_ENABLE
|
||||
cpu_irq_disable();
|
||||
|
||||
// Atomically enable the global interrupts and enter the sleep mode.
|
||||
pmc_sleep(sleep_mode);
|
||||
#else
|
||||
UNUSED(sleep_mode);
|
||||
cpu_irq_enable();
|
||||
#endif /* CONFIG_SLEEPMGR_ENABLE */
|
||||
|
||||
}
|
||||
|
||||
//! @}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SAM_SLEEPMGR_INCLUDED */
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM3/SAM4 Sleep manager implementation.
|
||||
*
|
||||
* Copyright (c) 2012-2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* 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. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 4. This software may only be redistributed and used in connection with an
|
||||
* Atmel microcontroller product.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
|
||||
*/
|
||||
|
||||
#ifndef SAM_SLEEPMGR_INCLUDED
|
||||
#define SAM_SLEEPMGR_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <compiler.h>
|
||||
#include <conf_sleepmgr.h>
|
||||
#include <sleep.h>
|
||||
#include <interrupt.h>
|
||||
|
||||
/**
|
||||
* \weakgroup sleepmgr_group
|
||||
* @{
|
||||
*/
|
||||
#if (SAMG51 || SAMG53 || SAMG54)
|
||||
enum sleepmgr_mode {
|
||||
//! Active mode.
|
||||
SLEEPMGR_ACTIVE = 0,
|
||||
/*! Wait mode, wakeup fast (in 3ms).
|
||||
* Potential Wake Up sources: fast startup events */
|
||||
SLEEPMGR_WAIT_FAST,
|
||||
/*! Wait mode.
|
||||
* Potential Wake Up sources: fast startup events */
|
||||
SLEEPMGR_WAIT,
|
||||
|
||||
SLEEPMGR_NR_OF_MODES,
|
||||
};
|
||||
|
||||
#else
|
||||
enum sleepmgr_mode {
|
||||
//! Active mode.
|
||||
SLEEPMGR_ACTIVE = 0,
|
||||
/*! WFE sleep mode.
|
||||
* Potential Wake Up sources:
|
||||
* fast startup events (USB, RTC, RTT, WKUPs),
|
||||
* interrupt, and events. */
|
||||
SLEEPMGR_SLEEP_WFE,
|
||||
/*! WFI sleep mode.
|
||||
* Potential Wake Up sources: fast startup events and interrupt. */
|
||||
SLEEPMGR_SLEEP_WFI,
|
||||
/*! Wait mode, wakeup fast (in 3ms).
|
||||
* XTAL is not disabled when sleep.
|
||||
* Potential Wake Up sources: fast startup events */
|
||||
SLEEPMGR_WAIT_FAST,
|
||||
/*! Wait mode.
|
||||
* Potential Wake Up sources: fast startup events */
|
||||
SLEEPMGR_WAIT,
|
||||
//! Backup mode. Potential Wake Up sources: WKUPs, SM, RTT, RTC.
|
||||
SLEEPMGR_BACKUP,
|
||||
|
||||
SLEEPMGR_NR_OF_MODES,
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* \name Internal arrays
|
||||
* @{
|
||||
*/
|
||||
#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__)
|
||||
//! Sleep mode lock counters
|
||||
extern uint8_t sleepmgr_locks[];
|
||||
#endif /* CONFIG_SLEEPMGR_ENABLE */
|
||||
//! @}
|
||||
|
||||
|
||||
static inline void sleepmgr_sleep(const enum sleepmgr_mode sleep_mode)
|
||||
{
|
||||
Assert(sleep_mode != SLEEPMGR_ACTIVE);
|
||||
#ifdef CONFIG_SLEEPMGR_ENABLE
|
||||
cpu_irq_disable();
|
||||
|
||||
// Atomically enable the global interrupts and enter the sleep mode.
|
||||
pmc_sleep(sleep_mode);
|
||||
#else
|
||||
UNUSED(sleep_mode);
|
||||
cpu_irq_enable();
|
||||
#endif /* CONFIG_SLEEPMGR_ENABLE */
|
||||
|
||||
}
|
||||
|
||||
//! @}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SAM_SLEEPMGR_INCLUDED */
|
||||
|
||||
@@ -51,56 +51,56 @@
|
||||
* The file is automatically generated and will be re-written when
|
||||
* running the ASF driver selector tool. Any changes will be discarded.
|
||||
*/
|
||||
|
||||
// From module: Compiler abstraction layer and code utilities
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: FLASH Controller Double-Word (FLASHCDW)
|
||||
#include <flashcdw.h>
|
||||
|
||||
// From module: GPIO - General-Purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: Interrupt management - UC3 implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEMBAG Memory Bag Allocator
|
||||
#include <membag.h>
|
||||
|
||||
// From module: PM Power Manager - UC3 L0 implementation
|
||||
#include <power_clocks_lib.h>
|
||||
#include <sleep.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: SCIF System Control Interface - UC3L implementation
|
||||
#include <scif_uc3l.h>
|
||||
|
||||
// From module: Sleep manager - UC3 implementation
|
||||
#include <sleepmgr.h>
|
||||
#include <uc3/sleepmgr.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - UC3 implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - UC3 L0 implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: UC3-L0 Xplained
|
||||
#include <led.h>
|
||||
|
||||
// From module: USART - Serial interface - UC3 implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart.h>
|
||||
|
||||
// From module: Compiler abstraction layer and code utilities
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: FLASH Controller Double-Word (FLASHCDW)
|
||||
#include <flashcdw.h>
|
||||
|
||||
// From module: GPIO - General-Purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: Interrupt management - UC3 implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEMBAG Memory Bag Allocator
|
||||
#include <membag.h>
|
||||
|
||||
// From module: PM Power Manager - UC3 L0 implementation
|
||||
#include <power_clocks_lib.h>
|
||||
#include <sleep.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: SCIF System Control Interface - UC3L implementation
|
||||
#include <scif_uc3l.h>
|
||||
|
||||
// From module: Sleep manager - UC3 implementation
|
||||
#include <sleepmgr.h>
|
||||
#include <uc3/sleepmgr.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - UC3 implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - UC3 L0 implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: UC3-L0 Xplained
|
||||
#include <led.h>
|
||||
|
||||
// From module: USART - Serial interface - UC3 implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart.h>
|
||||
|
||||
#endif // ASF_H
|
||||
|
||||
@@ -51,56 +51,56 @@
|
||||
* The file is automatically generated and will be re-written when
|
||||
* running the ASF driver selector tool. Any changes will be discarded.
|
||||
*/
|
||||
|
||||
// From module: Compiler abstraction layer and code utilities
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: FLASH Controller Double-Word (FLASHCDW)
|
||||
#include <flashcdw.h>
|
||||
|
||||
// From module: GPIO - General-Purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: Interrupt management - UC3 implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEMBAG Memory Bag Allocator
|
||||
#include <membag.h>
|
||||
|
||||
// From module: PM Power Manager - UC3 L0 implementation
|
||||
#include <power_clocks_lib.h>
|
||||
#include <sleep.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: SCIF System Control Interface - UC3L implementation
|
||||
#include <scif_uc3l.h>
|
||||
|
||||
// From module: Sleep manager - UC3 implementation
|
||||
#include <sleepmgr.h>
|
||||
#include <uc3/sleepmgr.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - UC3 implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - UC3 L0 implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: UC3-L0 Xplained
|
||||
#include <led.h>
|
||||
|
||||
// From module: USART - Serial interface - UC3 implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart.h>
|
||||
|
||||
// From module: Compiler abstraction layer and code utilities
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: FLASH Controller Double-Word (FLASHCDW)
|
||||
#include <flashcdw.h>
|
||||
|
||||
// From module: GPIO - General-Purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: Interrupt management - UC3 implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEMBAG Memory Bag Allocator
|
||||
#include <membag.h>
|
||||
|
||||
// From module: PM Power Manager - UC3 L0 implementation
|
||||
#include <power_clocks_lib.h>
|
||||
#include <sleep.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: SCIF System Control Interface - UC3L implementation
|
||||
#include <scif_uc3l.h>
|
||||
|
||||
// From module: Sleep manager - UC3 implementation
|
||||
#include <sleepmgr.h>
|
||||
#include <uc3/sleepmgr.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - UC3 implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - UC3 L0 implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: UC3-L0 Xplained
|
||||
#include <led.h>
|
||||
|
||||
// From module: USART - Serial interface - UC3 implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart.h>
|
||||
|
||||
#endif // ASF_H
|
||||
|
||||
@@ -51,59 +51,59 @@
|
||||
* The file is automatically generated and will be re-written when
|
||||
* running the ASF driver selector tool. Any changes will be discarded.
|
||||
*/
|
||||
|
||||
// From module: CPU specific features
|
||||
#include <ccp.h>
|
||||
#include <xmega_reset_cause.h>
|
||||
|
||||
// From module: GPIO - General purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: IOPORT - General purpose I/O service
|
||||
#include <ioport.h>
|
||||
|
||||
// From module: Interrupt management - XMEGA implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEMBAG Memory Bag Allocator
|
||||
#include <membag.h>
|
||||
|
||||
// From module: PMIC - Programmable Multi-level Interrupt Controller
|
||||
#include <pmic.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: Sleep Controller driver
|
||||
#include <sleep.h>
|
||||
|
||||
// From module: Sleep manager - XMEGA A/AU/B/D implementation
|
||||
#include <sleepmgr.h>
|
||||
#include <xmega/sleepmgr.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - XMEGA implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - XMEGA A1/A3/A3B/A4/D/E implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: USART - Serial interface - XMEGA implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart.h>
|
||||
|
||||
// From module: XMEGA compiler driver
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: XMEGA-A1 Xplained LED support enabled
|
||||
#include <led.h>
|
||||
|
||||
// From module: CPU specific features
|
||||
#include <ccp.h>
|
||||
#include <xmega_reset_cause.h>
|
||||
|
||||
// From module: GPIO - General purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: IOPORT - General purpose I/O service
|
||||
#include <ioport.h>
|
||||
|
||||
// From module: Interrupt management - XMEGA implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEMBAG Memory Bag Allocator
|
||||
#include <membag.h>
|
||||
|
||||
// From module: PMIC - Programmable Multi-level Interrupt Controller
|
||||
#include <pmic.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: Sleep Controller driver
|
||||
#include <sleep.h>
|
||||
|
||||
// From module: Sleep manager - XMEGA A/AU/B/D implementation
|
||||
#include <sleepmgr.h>
|
||||
#include <xmega/sleepmgr.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - XMEGA implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - XMEGA A1/A3/A3B/A4/D/E implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: USART - Serial interface - XMEGA implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart.h>
|
||||
|
||||
// From module: XMEGA compiler driver
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: XMEGA-A1 Xplained LED support enabled
|
||||
#include <led.h>
|
||||
|
||||
#endif // ASF_H
|
||||
|
||||
@@ -51,59 +51,59 @@
|
||||
* The file is automatically generated and will be re-written when
|
||||
* running the ASF driver selector tool. Any changes will be discarded.
|
||||
*/
|
||||
|
||||
// From module: CPU specific features
|
||||
#include <ccp.h>
|
||||
#include <xmega_reset_cause.h>
|
||||
|
||||
// From module: GPIO - General purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: IOPORT - General purpose I/O service
|
||||
#include <ioport.h>
|
||||
|
||||
// From module: Interrupt management - XMEGA implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEMBAG Memory Bag Allocator
|
||||
#include <membag.h>
|
||||
|
||||
// From module: PMIC - Programmable Multi-level Interrupt Controller
|
||||
#include <pmic.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: Sleep Controller driver
|
||||
#include <sleep.h>
|
||||
|
||||
// From module: Sleep manager - XMEGA A/AU/B/D implementation
|
||||
#include <sleepmgr.h>
|
||||
#include <xmega/sleepmgr.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - XMEGA implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - XMEGA A1/A3/A3B/A4/D/E implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: USART - Serial interface - XMEGA implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart.h>
|
||||
|
||||
// From module: XMEGA compiler driver
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: XMEGA-A1 Xplained LED support enabled
|
||||
#include <led.h>
|
||||
|
||||
// From module: CPU specific features
|
||||
#include <ccp.h>
|
||||
#include <xmega_reset_cause.h>
|
||||
|
||||
// From module: GPIO - General purpose Input/Output
|
||||
#include <gpio.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Generic components of unit test framework
|
||||
#include <unit_test/suite.h>
|
||||
|
||||
// From module: IOPORT - General purpose I/O service
|
||||
#include <ioport.h>
|
||||
|
||||
// From module: Interrupt management - XMEGA implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: MEMBAG Memory Bag Allocator
|
||||
#include <membag.h>
|
||||
|
||||
// From module: PMIC - Programmable Multi-level Interrupt Controller
|
||||
#include <pmic.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: Sleep Controller driver
|
||||
#include <sleep.h>
|
||||
|
||||
// From module: Sleep manager - XMEGA A/AU/B/D implementation
|
||||
#include <sleepmgr.h>
|
||||
#include <xmega/sleepmgr.h>
|
||||
|
||||
// From module: Standard serial I/O (stdio) - XMEGA implementation
|
||||
#include <stdio_serial.h>
|
||||
|
||||
// From module: System Clock Control - XMEGA A1/A3/A3B/A4/D/E implementation
|
||||
#include <sysclk.h>
|
||||
|
||||
// From module: USART - Serial interface - XMEGA implementation
|
||||
#include <serial.h>
|
||||
|
||||
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
|
||||
#include <usart.h>
|
||||
|
||||
// From module: XMEGA compiler driver
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: XMEGA-A1 Xplained LED support enabled
|
||||
#include <led.h>
|
||||
|
||||
#endif // ASF_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,56 +1,56 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file board.h
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This empty heard file is included by Atmel library.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform_config.h"
|
||||
|
||||
/******************************************************
|
||||
* Macros
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Global Variables
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file board.h
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This empty heard file is included by Atmel library.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform_config.h"
|
||||
|
||||
/******************************************************
|
||||
* Macros
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Global Variables
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -1,180 +1,180 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_adc.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide ADC driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_logging.h"
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
static int8_t channel_num = 0;
|
||||
volatile bool initialized = false;
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
enum adc_channel{
|
||||
adc_channel_0 = 0,
|
||||
adc_channel_1,
|
||||
adc_channel_2,
|
||||
adc_channel_3,
|
||||
adc_channel_4,
|
||||
adc_channel_5,
|
||||
adc_channel_6,
|
||||
adc_channel_7,
|
||||
};
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
/**
|
||||
* \brief ADC interrupt callback function.
|
||||
*/
|
||||
static void adc_end_conversion(void)
|
||||
{
|
||||
switch(channel_num){
|
||||
case adc_channel_0:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_0);
|
||||
break;
|
||||
case adc_channel_1:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_1);
|
||||
break;
|
||||
case adc_channel_2:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_2);
|
||||
break;
|
||||
case adc_channel_3:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_3);
|
||||
break;
|
||||
case adc_channel_4:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_4);
|
||||
break;
|
||||
case adc_channel_5:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_5);
|
||||
break;
|
||||
case adc_channel_6:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_6);
|
||||
break;
|
||||
case adc_channel_7:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OSStatus platform_adc_init( const platform_adc_t* adc, uint32_t sample_cycle )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
struct adc_config adc_cfg;
|
||||
UNUSED_PARAMETER(sample_cycle);
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
require_action_quiet( adc != NULL, exit, err = kParamErr);
|
||||
|
||||
if( initialized != true )
|
||||
{
|
||||
adc_enable();
|
||||
|
||||
adc_select_clock_source_mck(ADC);
|
||||
|
||||
adc_get_config_defaults(&adc_cfg);
|
||||
|
||||
adc_init(ADC, &adc_cfg);
|
||||
|
||||
adc_set_trigger(ADC, ADC_TRIG_SW);
|
||||
|
||||
adc_set_resolution(ADC, adc->resolution);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_adc_take_sample( const platform_adc_t* adc, uint16_t* output )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
require_action_quiet( adc != NULL, exit, err = kParamErr);
|
||||
|
||||
channel_num = adc->channel;
|
||||
|
||||
adc_channel_enable(ADC, adc->channel);
|
||||
|
||||
adc_set_callback(ADC, adc->interrupt, adc_end_conversion, 1);
|
||||
|
||||
/* Start conversion */
|
||||
adc_start_software_conversion(ADC);
|
||||
adc_start_calibration(ADC);
|
||||
|
||||
while (adc_get_interrupt_status(ADC) & (1 << adc->channel));
|
||||
|
||||
*output = adc_channel_get_value(ADC, adc->channel);
|
||||
mico_thread_msleep(1);
|
||||
adc_channel_disable(ADC, adc->channel);
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_adc_take_sample_stream( const platform_adc_t* adc, void* buffer, uint16_t buffer_length )
|
||||
{
|
||||
UNUSED_PARAMETER(adc);
|
||||
UNUSED_PARAMETER(buffer);
|
||||
UNUSED_PARAMETER(buffer_length);
|
||||
platform_log("unimplemented");
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
OSStatus platform_adc_deinit( const platform_adc_t* adc )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
require_action_quiet( adc != NULL, exit, err = kParamErr);
|
||||
|
||||
adc_disable();
|
||||
|
||||
initialized = false;
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_adc.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide ADC driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_logging.h"
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
static int8_t channel_num = 0;
|
||||
volatile bool initialized = false;
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
enum adc_channel{
|
||||
adc_channel_0 = 0,
|
||||
adc_channel_1,
|
||||
adc_channel_2,
|
||||
adc_channel_3,
|
||||
adc_channel_4,
|
||||
adc_channel_5,
|
||||
adc_channel_6,
|
||||
adc_channel_7,
|
||||
};
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
/**
|
||||
* \brief ADC interrupt callback function.
|
||||
*/
|
||||
static void adc_end_conversion(void)
|
||||
{
|
||||
switch(channel_num){
|
||||
case adc_channel_0:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_0);
|
||||
break;
|
||||
case adc_channel_1:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_1);
|
||||
break;
|
||||
case adc_channel_2:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_2);
|
||||
break;
|
||||
case adc_channel_3:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_3);
|
||||
break;
|
||||
case adc_channel_4:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_4);
|
||||
break;
|
||||
case adc_channel_5:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_5);
|
||||
break;
|
||||
case adc_channel_6:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_6);
|
||||
break;
|
||||
case adc_channel_7:
|
||||
adc_channel_get_value(ADC, ADC_CHANNEL_7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OSStatus platform_adc_init( const platform_adc_t* adc, uint32_t sample_cycle )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
struct adc_config adc_cfg;
|
||||
UNUSED_PARAMETER(sample_cycle);
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
require_action_quiet( adc != NULL, exit, err = kParamErr);
|
||||
|
||||
if( initialized != true )
|
||||
{
|
||||
adc_enable();
|
||||
|
||||
adc_select_clock_source_mck(ADC);
|
||||
|
||||
adc_get_config_defaults(&adc_cfg);
|
||||
|
||||
adc_init(ADC, &adc_cfg);
|
||||
|
||||
adc_set_trigger(ADC, ADC_TRIG_SW);
|
||||
|
||||
adc_set_resolution(ADC, adc->resolution);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_adc_take_sample( const platform_adc_t* adc, uint16_t* output )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
require_action_quiet( adc != NULL, exit, err = kParamErr);
|
||||
|
||||
channel_num = adc->channel;
|
||||
|
||||
adc_channel_enable(ADC, adc->channel);
|
||||
|
||||
adc_set_callback(ADC, adc->interrupt, adc_end_conversion, 1);
|
||||
|
||||
/* Start conversion */
|
||||
adc_start_software_conversion(ADC);
|
||||
adc_start_calibration(ADC);
|
||||
|
||||
while (adc_get_interrupt_status(ADC) & (1 << adc->channel));
|
||||
|
||||
*output = adc_channel_get_value(ADC, adc->channel);
|
||||
mico_thread_msleep(1);
|
||||
adc_channel_disable(ADC, adc->channel);
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_adc_take_sample_stream( const platform_adc_t* adc, void* buffer, uint16_t buffer_length )
|
||||
{
|
||||
UNUSED_PARAMETER(adc);
|
||||
UNUSED_PARAMETER(buffer);
|
||||
UNUSED_PARAMETER(buffer_length);
|
||||
platform_log("unimplemented");
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
OSStatus platform_adc_deinit( const platform_adc_t* adc )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
require_action_quiet( adc != NULL, exit, err = kParamErr);
|
||||
|
||||
adc_disable();
|
||||
|
||||
initialized = false;
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1,349 +1,349 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_flash.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provides flash operation functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "platform_logging.h"
|
||||
#include "mico_platform.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include "stdio.h"
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
#include "spi_flash.h"
|
||||
#endif
|
||||
#include "flash_efc.h"
|
||||
|
||||
/* Private constants --------------------------------------------------------*/
|
||||
#define ADDR_FLASH_SECTOR_00 ((uint32_t)0x00400000) /* base @ of sector 0, 8 kbyte */
|
||||
#define ADDR_FLASH_SECTOR_01 ((uint32_t)0x00402000) /* base @ of sector 1, 8 kbyte */
|
||||
#define ADDR_FLASH_SECTOR_02 ((uint32_t)0x00404000) /* base @ of sector 2, 112 kbyte */
|
||||
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x00420000) /* base @ of sector 1, 128 kbyte */
|
||||
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x00440000) /* base @ of sector 2, 128 kbyte */
|
||||
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x00480000) /* base @ of sector 3, 128 kbyte */
|
||||
|
||||
/* End of the Flash address */
|
||||
#define FLASH_START_ADDRESS IFLASH_ADDR //internal flash
|
||||
#define FLASH_END_ADDRESS (IFLASH_ADDR + IFLASH_SIZE - 1)
|
||||
#define FLASH_SIZE IFLASH_SIZE
|
||||
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
|
||||
/* critical disable irq */
|
||||
#define mem_flash_op_enter() do {\
|
||||
__DSB(); __ISB(); \
|
||||
cpu_irq_disable(); \
|
||||
__DMB(); \
|
||||
} while (0)
|
||||
/* critical enable irq */
|
||||
#define mem_flash_op_exit() do { \
|
||||
__DMB(); __DSB(); __ISB();\
|
||||
cpu_irq_enable(); \
|
||||
} while (0)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SAMG55_FLASH_ERASE_4_PAGES = 0x04,
|
||||
SAMG55_FLASH_ERASE_8_PAGES = 0x08,
|
||||
SAMG55_FLASH_ERASE_16_PAGES = 0x10,
|
||||
SAMG55_FLASH_ERASE_32_PAGES = 0x20,
|
||||
} samg55_flash_erase_page_amount_t;
|
||||
|
||||
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
static sflash_handle_t sflash_handle = {0x0, 0x0, SFLASH_WRITE_NOT_ALLOWED};
|
||||
#endif
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static OSStatus internalFlashInitialize( void );
|
||||
static OSStatus internalFlashErase(uint32_t StartAddress, uint32_t EndAddress);
|
||||
static OSStatus internalFlashWrite(volatile uint32_t* FlashAddress, uint32_t* Data ,uint32_t DataLength);
|
||||
|
||||
#ifdef MCU_EBANLE_FLASH_PROTECT
|
||||
static OSStatus internalFlashProtect(uint32_t StartAddress, uint32_t EndAddress, bool enable);
|
||||
#endif
|
||||
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
static OSStatus spiFlashErase(uint32_t StartAddress, uint32_t EndAddress);
|
||||
#endif
|
||||
|
||||
OSStatus platform_flash_init( const platform_flash_t *peripheral )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( peripheral != NULL, exit, err = kParamErr);
|
||||
|
||||
if( peripheral->flash_type == FLASH_TYPE_EMBEDDED ){
|
||||
err = internalFlashInitialize();
|
||||
require_noerr(err, exit);
|
||||
}
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
else if( peripheral->flash_type == FLASH_TYPE_SPI ){
|
||||
err = init_sflash( &sflash_handle, 0, SFLASH_WRITE_ALLOWED );
|
||||
require_noerr(err, exit);
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
err = kTypeErr;
|
||||
goto exit;
|
||||
}
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_flash_erase( const platform_flash_t *peripheral, uint32_t start_address, uint32_t end_address )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( peripheral != NULL, exit, err = kParamErr);
|
||||
require_action( start_address >= peripheral->flash_start_addr
|
||||
&& end_address <= peripheral->flash_start_addr + peripheral->flash_length - 1, exit, err = kParamErr);
|
||||
|
||||
if( peripheral->flash_type == FLASH_TYPE_EMBEDDED ){
|
||||
err = internalFlashErase( start_address, end_address );
|
||||
require_noerr(err, exit);
|
||||
}
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
else if( peripheral->flash_type == FLASH_TYPE_SPI ){
|
||||
err = spiFlashErase( start_address, end_address );
|
||||
require_noerr(err, exit);
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
err = kTypeErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_flash_write( const platform_flash_t *peripheral, volatile uint32_t* start_address, uint8_t* data ,uint32_t length )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( peripheral != NULL, exit, err = kParamErr);
|
||||
require_action( *start_address >= peripheral->flash_start_addr
|
||||
&& *start_address + length <= peripheral->flash_start_addr + peripheral->flash_length, exit, err = kParamErr);
|
||||
|
||||
if( peripheral->flash_type == FLASH_TYPE_EMBEDDED ){
|
||||
err = internalFlashWrite( start_address, (uint32_t *)data, length);
|
||||
require_noerr(err, exit);
|
||||
}
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
else if( peripheral->flash_type == FLASH_TYPE_SPI ){
|
||||
err = sflash_write( &sflash_handle, *start_address, data, length );
|
||||
require_noerr(err, exit);
|
||||
*start_address += length;
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
err = kTypeErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_flash_read( const platform_flash_t *peripheral, volatile uint32_t* start_address, uint8_t* data ,uint32_t length )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( peripheral != NULL, exit, err = kParamErr);
|
||||
require_action( (*start_address >= peripheral->flash_start_addr)
|
||||
&& (*start_address + length) <= ( peripheral->flash_start_addr + peripheral->flash_length), exit, err = kParamErr);
|
||||
|
||||
if( peripheral->flash_type == FLASH_TYPE_EMBEDDED ){
|
||||
memcpy(data, (void *)(*start_address), length);
|
||||
*start_address += length;
|
||||
}
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
else if( peripheral->flash_type == FLASH_TYPE_SPI ){
|
||||
err = sflash_read( &sflash_handle, *start_address, data, length );
|
||||
require_noerr(err, exit);
|
||||
*start_address += length;
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
err = kTypeErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_flash_enable_protect( const platform_flash_t *peripheral, uint32_t start_address, uint32_t end_address )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( peripheral != NULL, exit, err = kParamErr);
|
||||
require_action( start_address >= peripheral->flash_start_addr
|
||||
&& end_address <= peripheral->flash_start_addr + peripheral->flash_length - 1, exit, err = kParamErr);
|
||||
|
||||
if( peripheral->flash_type == FLASH_TYPE_EMBEDDED ){
|
||||
#ifdef MCU_EBANLE_FLASH_PROTECT
|
||||
err = internalFlashProtect( start_address, end_address, true );
|
||||
#endif
|
||||
require_noerr(err, exit);
|
||||
}
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
else if( peripheral->flash_type == FLASH_TYPE_SPI ){
|
||||
err = kNoErr;
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
err = kTypeErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_flash_disable_protect( const platform_flash_t *peripheral, uint32_t start_address, uint32_t end_address )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( peripheral != NULL, exit, err = kParamErr);
|
||||
require_action( start_address >= peripheral->flash_start_addr
|
||||
&& end_address <= peripheral->flash_start_addr + peripheral->flash_length - 1, exit, err = kParamErr);
|
||||
|
||||
if( peripheral->flash_type == FLASH_TYPE_EMBEDDED ){
|
||||
#ifdef MCU_EBANLE_FLASH_PROTECT
|
||||
err = internalFlashProtect( start_address, end_address, false );
|
||||
#endif
|
||||
require_noerr(err, exit);
|
||||
}
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
else if( peripheral->flash_type == FLASH_TYPE_SPI ){
|
||||
err = kNoErr;
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
err = kTypeErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static OSStatus internalFlashInitialize( void )
|
||||
{
|
||||
platform_log_trace();
|
||||
OSStatus err = kNoErr;
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
require_action( flash_init(FLASH_ACCESS_MODE_128, 6) == FLASH_RC_OK, exit, err = kGeneralErr );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
OSStatus internalFlashErase(uint32_t start_address, uint32_t end_address)
|
||||
{
|
||||
platform_log_trace();
|
||||
uint32_t i;
|
||||
OSStatus err = kNoErr;
|
||||
uint32_t page_start_address, page_end_address;
|
||||
uint32_t page_start_number, page_end_number;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
require_action( flash_unlock( start_address, end_address, &page_start_address, &page_end_address ) == FLASH_RC_OK, exit, err = kGeneralErr );
|
||||
|
||||
page_start_number = page_start_address/512;
|
||||
page_end_number = page_end_address/512;
|
||||
require_action( page_end_number >= page_start_number + 16, exit, err = kUnsupportedErr);
|
||||
|
||||
for ( i = page_start_number; i <= page_end_number; i+=16 )
|
||||
{
|
||||
require_action( flash_erase_page( i * 512, IFLASH_ERASE_PAGES_16) == FLASH_RC_OK, exit, err = kGeneralErr );
|
||||
}
|
||||
|
||||
require_action( flash_lock( start_address, end_address, NULL, NULL ) == FLASH_RC_OK, exit, err = kGeneralErr );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
OSStatus internalFlashWrite(volatile uint32_t* flash_address, uint32_t* data ,uint32_t data_length)
|
||||
{
|
||||
platform_log_trace();
|
||||
OSStatus err = kNoErr;
|
||||
uint32_t start_address = * flash_address;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
//mem_flash_op_enter();
|
||||
require_action( flash_unlock( start_address, start_address + data_length - 1, NULL, NULL ) == FLASH_RC_OK, exit, err = kGeneralErr );
|
||||
|
||||
require_action( flash_write((*flash_address), data, data_length, false) == FLASH_RC_OK, exit, err = kGeneralErr );
|
||||
*flash_address += data_length;
|
||||
|
||||
require_action( flash_lock( start_address, start_address + data_length - 1, NULL, NULL ) == FLASH_RC_OK, exit, err = kGeneralErr );
|
||||
//mem_flash_op_exit();
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef MCU_EBANLE_FLASH_PROTECT
|
||||
OSStatus internalFlashProtect(uint32_t StartAddress, uint32_t EndAddress, bool enable)
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
UNUSED_PARAMETER( StartAddress );
|
||||
UNUSED_PARAMETER( EndAddress );
|
||||
UNUSED_PARAMETER( enable );
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
OSStatus spiFlashErase(uint32_t StartAddress, uint32_t EndAddress)
|
||||
{
|
||||
platform_log_trace();
|
||||
OSStatus err = kNoErr;
|
||||
uint32_t StartSector, EndSector, i = 0;
|
||||
|
||||
/* Get the sector where start the user flash area */
|
||||
StartSector = StartAddress>>12;
|
||||
EndSector = EndAddress>>12;
|
||||
|
||||
for(i = StartSector; i <= EndSector; i += 1)
|
||||
{
|
||||
require_action(sflash_sector_erase(&sflash_handle, i<<12) == kNoErr, exit, err = kWriteErr);
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_flash.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provides flash operation functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "platform_logging.h"
|
||||
#include "mico_platform.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include "stdio.h"
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
#include "spi_flash.h"
|
||||
#endif
|
||||
#include "flash_efc.h"
|
||||
|
||||
/* Private constants --------------------------------------------------------*/
|
||||
#define ADDR_FLASH_SECTOR_00 ((uint32_t)0x00400000) /* base @ of sector 0, 8 kbyte */
|
||||
#define ADDR_FLASH_SECTOR_01 ((uint32_t)0x00402000) /* base @ of sector 1, 8 kbyte */
|
||||
#define ADDR_FLASH_SECTOR_02 ((uint32_t)0x00404000) /* base @ of sector 2, 112 kbyte */
|
||||
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x00420000) /* base @ of sector 1, 128 kbyte */
|
||||
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x00440000) /* base @ of sector 2, 128 kbyte */
|
||||
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x00480000) /* base @ of sector 3, 128 kbyte */
|
||||
|
||||
/* End of the Flash address */
|
||||
#define FLASH_START_ADDRESS IFLASH_ADDR //internal flash
|
||||
#define FLASH_END_ADDRESS (IFLASH_ADDR + IFLASH_SIZE - 1)
|
||||
#define FLASH_SIZE IFLASH_SIZE
|
||||
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
|
||||
/* critical disable irq */
|
||||
#define mem_flash_op_enter() do {\
|
||||
__DSB(); __ISB(); \
|
||||
cpu_irq_disable(); \
|
||||
__DMB(); \
|
||||
} while (0)
|
||||
/* critical enable irq */
|
||||
#define mem_flash_op_exit() do { \
|
||||
__DMB(); __DSB(); __ISB();\
|
||||
cpu_irq_enable(); \
|
||||
} while (0)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SAMG55_FLASH_ERASE_4_PAGES = 0x04,
|
||||
SAMG55_FLASH_ERASE_8_PAGES = 0x08,
|
||||
SAMG55_FLASH_ERASE_16_PAGES = 0x10,
|
||||
SAMG55_FLASH_ERASE_32_PAGES = 0x20,
|
||||
} samg55_flash_erase_page_amount_t;
|
||||
|
||||
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
static sflash_handle_t sflash_handle = {0x0, 0x0, SFLASH_WRITE_NOT_ALLOWED};
|
||||
#endif
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static OSStatus internalFlashInitialize( void );
|
||||
static OSStatus internalFlashErase(uint32_t StartAddress, uint32_t EndAddress);
|
||||
static OSStatus internalFlashWrite(volatile uint32_t* FlashAddress, uint32_t* Data ,uint32_t DataLength);
|
||||
|
||||
#ifdef MCU_EBANLE_FLASH_PROTECT
|
||||
static OSStatus internalFlashProtect(uint32_t StartAddress, uint32_t EndAddress, bool enable);
|
||||
#endif
|
||||
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
static OSStatus spiFlashErase(uint32_t StartAddress, uint32_t EndAddress);
|
||||
#endif
|
||||
|
||||
OSStatus platform_flash_init( const platform_flash_t *peripheral )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( peripheral != NULL, exit, err = kParamErr);
|
||||
|
||||
if( peripheral->flash_type == FLASH_TYPE_EMBEDDED ){
|
||||
err = internalFlashInitialize();
|
||||
require_noerr(err, exit);
|
||||
}
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
else if( peripheral->flash_type == FLASH_TYPE_SPI ){
|
||||
err = init_sflash( &sflash_handle, 0, SFLASH_WRITE_ALLOWED );
|
||||
require_noerr(err, exit);
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
err = kTypeErr;
|
||||
goto exit;
|
||||
}
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_flash_erase( const platform_flash_t *peripheral, uint32_t start_address, uint32_t end_address )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( peripheral != NULL, exit, err = kParamErr);
|
||||
require_action( start_address >= peripheral->flash_start_addr
|
||||
&& end_address <= peripheral->flash_start_addr + peripheral->flash_length - 1, exit, err = kParamErr);
|
||||
|
||||
if( peripheral->flash_type == FLASH_TYPE_EMBEDDED ){
|
||||
err = internalFlashErase( start_address, end_address );
|
||||
require_noerr(err, exit);
|
||||
}
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
else if( peripheral->flash_type == FLASH_TYPE_SPI ){
|
||||
err = spiFlashErase( start_address, end_address );
|
||||
require_noerr(err, exit);
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
err = kTypeErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_flash_write( const platform_flash_t *peripheral, volatile uint32_t* start_address, uint8_t* data ,uint32_t length )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( peripheral != NULL, exit, err = kParamErr);
|
||||
require_action( *start_address >= peripheral->flash_start_addr
|
||||
&& *start_address + length <= peripheral->flash_start_addr + peripheral->flash_length, exit, err = kParamErr);
|
||||
|
||||
if( peripheral->flash_type == FLASH_TYPE_EMBEDDED ){
|
||||
err = internalFlashWrite( start_address, (uint32_t *)data, length);
|
||||
require_noerr(err, exit);
|
||||
}
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
else if( peripheral->flash_type == FLASH_TYPE_SPI ){
|
||||
err = sflash_write( &sflash_handle, *start_address, data, length );
|
||||
require_noerr(err, exit);
|
||||
*start_address += length;
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
err = kTypeErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_flash_read( const platform_flash_t *peripheral, volatile uint32_t* start_address, uint8_t* data ,uint32_t length )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( peripheral != NULL, exit, err = kParamErr);
|
||||
require_action( (*start_address >= peripheral->flash_start_addr)
|
||||
&& (*start_address + length) <= ( peripheral->flash_start_addr + peripheral->flash_length), exit, err = kParamErr);
|
||||
|
||||
if( peripheral->flash_type == FLASH_TYPE_EMBEDDED ){
|
||||
memcpy(data, (void *)(*start_address), length);
|
||||
*start_address += length;
|
||||
}
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
else if( peripheral->flash_type == FLASH_TYPE_SPI ){
|
||||
err = sflash_read( &sflash_handle, *start_address, data, length );
|
||||
require_noerr(err, exit);
|
||||
*start_address += length;
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
err = kTypeErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_flash_enable_protect( const platform_flash_t *peripheral, uint32_t start_address, uint32_t end_address )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( peripheral != NULL, exit, err = kParamErr);
|
||||
require_action( start_address >= peripheral->flash_start_addr
|
||||
&& end_address <= peripheral->flash_start_addr + peripheral->flash_length - 1, exit, err = kParamErr);
|
||||
|
||||
if( peripheral->flash_type == FLASH_TYPE_EMBEDDED ){
|
||||
#ifdef MCU_EBANLE_FLASH_PROTECT
|
||||
err = internalFlashProtect( start_address, end_address, true );
|
||||
#endif
|
||||
require_noerr(err, exit);
|
||||
}
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
else if( peripheral->flash_type == FLASH_TYPE_SPI ){
|
||||
err = kNoErr;
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
err = kTypeErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_flash_disable_protect( const platform_flash_t *peripheral, uint32_t start_address, uint32_t end_address )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( peripheral != NULL, exit, err = kParamErr);
|
||||
require_action( start_address >= peripheral->flash_start_addr
|
||||
&& end_address <= peripheral->flash_start_addr + peripheral->flash_length - 1, exit, err = kParamErr);
|
||||
|
||||
if( peripheral->flash_type == FLASH_TYPE_EMBEDDED ){
|
||||
#ifdef MCU_EBANLE_FLASH_PROTECT
|
||||
err = internalFlashProtect( start_address, end_address, false );
|
||||
#endif
|
||||
require_noerr(err, exit);
|
||||
}
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
else if( peripheral->flash_type == FLASH_TYPE_SPI ){
|
||||
err = kNoErr;
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
err = kTypeErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static OSStatus internalFlashInitialize( void )
|
||||
{
|
||||
platform_log_trace();
|
||||
OSStatus err = kNoErr;
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
require_action( flash_init(FLASH_ACCESS_MODE_128, 6) == FLASH_RC_OK, exit, err = kGeneralErr );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
OSStatus internalFlashErase(uint32_t start_address, uint32_t end_address)
|
||||
{
|
||||
platform_log_trace();
|
||||
uint32_t i;
|
||||
OSStatus err = kNoErr;
|
||||
uint32_t page_start_address, page_end_address;
|
||||
uint32_t page_start_number, page_end_number;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
require_action( flash_unlock( start_address, end_address, &page_start_address, &page_end_address ) == FLASH_RC_OK, exit, err = kGeneralErr );
|
||||
|
||||
page_start_number = page_start_address/512;
|
||||
page_end_number = page_end_address/512;
|
||||
require_action( page_end_number >= page_start_number + 16, exit, err = kUnsupportedErr);
|
||||
|
||||
for ( i = page_start_number; i <= page_end_number; i+=16 )
|
||||
{
|
||||
require_action( flash_erase_page( i * 512, IFLASH_ERASE_PAGES_16) == FLASH_RC_OK, exit, err = kGeneralErr );
|
||||
}
|
||||
|
||||
require_action( flash_lock( start_address, end_address, NULL, NULL ) == FLASH_RC_OK, exit, err = kGeneralErr );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
OSStatus internalFlashWrite(volatile uint32_t* flash_address, uint32_t* data ,uint32_t data_length)
|
||||
{
|
||||
platform_log_trace();
|
||||
OSStatus err = kNoErr;
|
||||
uint32_t start_address = * flash_address;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
//mem_flash_op_enter();
|
||||
require_action( flash_unlock( start_address, start_address + data_length - 1, NULL, NULL ) == FLASH_RC_OK, exit, err = kGeneralErr );
|
||||
|
||||
require_action( flash_write((*flash_address), data, data_length, false) == FLASH_RC_OK, exit, err = kGeneralErr );
|
||||
*flash_address += data_length;
|
||||
|
||||
require_action( flash_lock( start_address, start_address + data_length - 1, NULL, NULL ) == FLASH_RC_OK, exit, err = kGeneralErr );
|
||||
//mem_flash_op_exit();
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef MCU_EBANLE_FLASH_PROTECT
|
||||
OSStatus internalFlashProtect(uint32_t StartAddress, uint32_t EndAddress, bool enable)
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
UNUSED_PARAMETER( StartAddress );
|
||||
UNUSED_PARAMETER( EndAddress );
|
||||
UNUSED_PARAMETER( enable );
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_MICO_SPI_FLASH
|
||||
OSStatus spiFlashErase(uint32_t StartAddress, uint32_t EndAddress)
|
||||
{
|
||||
platform_log_trace();
|
||||
OSStatus err = kNoErr;
|
||||
uint32_t StartSector, EndSector, i = 0;
|
||||
|
||||
/* Get the sector where start the user flash area */
|
||||
StartSector = StartAddress>>12;
|
||||
EndSector = EndAddress>>12;
|
||||
|
||||
for(i = StartSector; i <= EndSector; i += 1)
|
||||
{
|
||||
require_action(sflash_sector_erase(&sflash_handle, i<<12) == kNoErr, exit, err = kWriteErr);
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,376 +1,376 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_gpio.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide GPIO driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include "mico.h"
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_peripheral.h"
|
||||
#include "platform_logging.h"
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
#define PINS_PER_PORT (32) /* Px00 to Px31 */
|
||||
#define TOTAL_PORTS ( 2) /* PIOA to B */
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/* Structure of runtime GPIO IRQ data */
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct
|
||||
{
|
||||
bool wakeup_pin;
|
||||
platform_gpio_irq_callback_t callback;
|
||||
void* arg;
|
||||
} samg5x_gpio_irq_data_t;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/* Runtime GPIO IRQ data */
|
||||
static samg5x_gpio_irq_data_t gpio_irq_data[TOTAL_PORTS][PINS_PER_PORT];
|
||||
|
||||
///* GPIO IRQ interrupt vectors */
|
||||
static const IRQn_Type irq_vectors[] =
|
||||
{
|
||||
[0] = PIOA_IRQn,
|
||||
[1] = PIOB_IRQn,
|
||||
};
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_gpio_init( const platform_gpio_t* gpio, platform_pin_config_t config )
|
||||
{
|
||||
ioport_mode_t mode;
|
||||
enum ioport_direction direction;
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
|
||||
switch ( config )
|
||||
{
|
||||
case INPUT_PULL_UP:
|
||||
{
|
||||
direction = IOPORT_DIR_INPUT;
|
||||
mode = IOPORT_MODE_PULLUP;
|
||||
break;
|
||||
}
|
||||
case INPUT_PULL_DOWN:
|
||||
{
|
||||
direction = IOPORT_DIR_INPUT;
|
||||
mode = IOPORT_MODE_PULLDOWN;
|
||||
break;
|
||||
}
|
||||
case INPUT_HIGH_IMPEDANCE:
|
||||
{
|
||||
direction = IOPORT_DIR_INPUT;
|
||||
mode = 0;
|
||||
break;
|
||||
}
|
||||
case OUTPUT_PUSH_PULL:
|
||||
{
|
||||
direction = IOPORT_DIR_OUTPUT;
|
||||
mode = 0;
|
||||
break;
|
||||
}
|
||||
case OUTPUT_OPEN_DRAIN_NO_PULL:
|
||||
{
|
||||
direction = IOPORT_DIR_OUTPUT;
|
||||
mode = IOPORT_MODE_OPEN_DRAIN;
|
||||
break;
|
||||
}
|
||||
case OUTPUT_OPEN_DRAIN_PULL_UP:
|
||||
{
|
||||
direction = IOPORT_DIR_OUTPUT;
|
||||
mode = IOPORT_MODE_OPEN_DRAIN | IOPORT_MODE_PULLUP;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
err = kParamErr;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
ioport_enable_pin ( gpio->pin );
|
||||
ioport_set_pin_mode( gpio->pin, mode );
|
||||
ioport_set_pin_dir ( gpio->pin, direction );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_gpio_peripheral_pin_init( const platform_gpio_t* gpio, ioport_mode_t pin_mode )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable( );
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
|
||||
/* Set pin mode and disable GPIO peripheral */
|
||||
ioport_set_pin_mode( gpio->pin, pin_mode );
|
||||
ioport_disable_pin( gpio->pin );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_gpio_deinit( const platform_gpio_t* gpio )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
|
||||
ioport_disable_pin( gpio->pin );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_gpio_output_high( const platform_gpio_t* gpio )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
ioport_set_pin_level( gpio->pin, IOPORT_PIN_LEVEL_HIGH );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_gpio_output_low( const platform_gpio_t* gpio )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
ioport_set_pin_level( gpio->pin, IOPORT_PIN_LEVEL_LOW );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_gpio_output_trigger( const platform_gpio_t* gpio )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
ioport_toggle_pin_level( gpio->pin );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
bool platform_gpio_input_get( const platform_gpio_t* gpio )
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
require_quiet( gpio != NULL, exit);
|
||||
|
||||
result = ( ioport_get_pin_level( gpio->pin ) == false ) ? false : true;
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus platform_gpio_irq_enable( const platform_gpio_t* gpio, platform_gpio_irq_trigger_t trigger, platform_gpio_irq_callback_t handler, void* arg )
|
||||
{
|
||||
ioport_port_mask_t mask = ioport_pin_to_mask( gpio->pin );
|
||||
ioport_port_t port = ioport_pin_to_port_id( gpio->pin );
|
||||
volatile Pio* port_register = arch_ioport_port_to_base( port );
|
||||
uint8_t pin_number = (gpio->pin) & 0x1F;
|
||||
uint32_t temp;
|
||||
uint8_t samg5x_irq_trigger;
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
|
||||
NVIC_DisableIRQ( irq_vectors[port] );
|
||||
NVIC_ClearPendingIRQ( irq_vectors[port] );
|
||||
|
||||
gpio_irq_data[port][pin_number].wakeup_pin = gpio->is_wakeup_pin;
|
||||
gpio_irq_data[port][pin_number].arg = arg;
|
||||
gpio_irq_data[port][pin_number].callback = handler;
|
||||
|
||||
switch ( trigger )
|
||||
{
|
||||
case IRQ_TRIGGER_RISING_EDGE: samg5x_irq_trigger = IOPORT_SENSE_RISING; break;
|
||||
case IRQ_TRIGGER_FALLING_EDGE: samg5x_irq_trigger = IOPORT_SENSE_FALLING; break;
|
||||
case IRQ_TRIGGER_BOTH_EDGES: samg5x_irq_trigger = IOPORT_SENSE_BOTHEDGES; break;
|
||||
default:
|
||||
err = kParamErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( gpio->is_wakeup_pin == true )
|
||||
{
|
||||
platform_powersave_enable_wakeup_pin( gpio );
|
||||
}
|
||||
|
||||
if ( samg5x_irq_trigger == IOPORT_SENSE_RISING || samg5x_irq_trigger == IOPORT_SENSE_BOTHEDGES )
|
||||
{
|
||||
port_register->PIO_AIMER |= mask;
|
||||
port_register->PIO_ESR |= mask;
|
||||
port_register->PIO_REHLSR |= mask;
|
||||
}
|
||||
|
||||
if ( samg5x_irq_trigger == IOPORT_SENSE_FALLING || samg5x_irq_trigger == IOPORT_SENSE_BOTHEDGES )
|
||||
{
|
||||
port_register->PIO_AIMER |= mask;
|
||||
port_register->PIO_ESR |= mask;
|
||||
port_register->PIO_FELLSR |= mask;
|
||||
}
|
||||
|
||||
/* Read ISR to clear residual interrupt status */
|
||||
temp = port_register->PIO_ISR;
|
||||
UNUSED_PARAMETER( temp );
|
||||
|
||||
/* Enable interrupt source */
|
||||
port_register->PIO_IER |= mask;
|
||||
|
||||
NVIC_EnableIRQ( irq_vectors[port] );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
OSStatus platform_gpio_irq_disable( const platform_gpio_t* gpio )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
ioport_port_mask_t mask = ioport_pin_to_mask ( gpio->pin );
|
||||
ioport_port_t port = ioport_pin_to_port_id( gpio->pin );
|
||||
volatile Pio* port_register = arch_ioport_port_to_base( port );
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
|
||||
/* Disable interrupt on pin */
|
||||
port_register->PIO_IDR = mask;
|
||||
|
||||
/* Disable Cortex-M interrupt vector as well if no pin interrupt is enabled */
|
||||
if ( port_register->PIO_IMR == 0 )
|
||||
{
|
||||
NVIC_DisableIRQ( irq_vectors[port] );
|
||||
}
|
||||
|
||||
gpio_irq_data[port][mask].wakeup_pin = false;
|
||||
gpio_irq_data[port][mask].arg = 0;
|
||||
gpio_irq_data[port][mask].callback = NULL;
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
* STM32F2xx Internal Function Definitions
|
||||
******************************************************/
|
||||
OSStatus platform_gpio_irq_manager_init( void )
|
||||
{
|
||||
memset( &gpio_irq_data, 0, sizeof( gpio_irq_data ) );
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* IRQ Handler Definitions
|
||||
******************************************************/
|
||||
|
||||
|
||||
void gpio_irq( ioport_port_t port )
|
||||
{
|
||||
volatile Pio* port_register = arch_ioport_port_to_base( port );
|
||||
uint32_t status = port_register->PIO_ISR; /* Get interrupt status. Read clears the interrupt */
|
||||
uint32_t mask = port_register->PIO_IMR;
|
||||
uint32_t iter = 0;
|
||||
|
||||
if ( ( status != 0 ) && ( mask != 0 ) )
|
||||
{
|
||||
/* Call the respective GPIO interrupt handler/callback */
|
||||
for ( iter = 0; iter < PINS_PER_PORT; iter++, status >>= 1, mask >>= 1 )
|
||||
{
|
||||
if ( ( ( mask & 0x1 ) != 0 ) && ( ( status & 0x1 ) != 0 ) && ( gpio_irq_data[port][iter].callback != NULL ) )
|
||||
{
|
||||
if ( gpio_irq_data[port][iter].wakeup_pin == true )
|
||||
{
|
||||
platform_mcu_powersave_exit_notify();
|
||||
}
|
||||
gpio_irq_data[port][iter].callback( gpio_irq_data[port][iter].arg );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* IRQ Handler Mapping
|
||||
******************************************************/
|
||||
MICO_RTOS_DEFINE_ISR( PIOA_Handler )
|
||||
{
|
||||
gpio_irq( (ioport_port_t)0 );
|
||||
}
|
||||
|
||||
MICO_RTOS_DEFINE_ISR( PIOB_Handler )
|
||||
{
|
||||
gpio_irq( (ioport_port_t)1 );
|
||||
}
|
||||
|
||||
MICO_RTOS_DEFINE_ISR( PIOC_Handler )
|
||||
{
|
||||
gpio_irq( (ioport_port_t)2 );
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_gpio.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide GPIO driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include "mico.h"
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_peripheral.h"
|
||||
#include "platform_logging.h"
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
#define PINS_PER_PORT (32) /* Px00 to Px31 */
|
||||
#define TOTAL_PORTS ( 2) /* PIOA to B */
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/* Structure of runtime GPIO IRQ data */
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct
|
||||
{
|
||||
bool wakeup_pin;
|
||||
platform_gpio_irq_callback_t callback;
|
||||
void* arg;
|
||||
} samg5x_gpio_irq_data_t;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/* Runtime GPIO IRQ data */
|
||||
static samg5x_gpio_irq_data_t gpio_irq_data[TOTAL_PORTS][PINS_PER_PORT];
|
||||
|
||||
///* GPIO IRQ interrupt vectors */
|
||||
static const IRQn_Type irq_vectors[] =
|
||||
{
|
||||
[0] = PIOA_IRQn,
|
||||
[1] = PIOB_IRQn,
|
||||
};
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_gpio_init( const platform_gpio_t* gpio, platform_pin_config_t config )
|
||||
{
|
||||
ioport_mode_t mode;
|
||||
enum ioport_direction direction;
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
|
||||
switch ( config )
|
||||
{
|
||||
case INPUT_PULL_UP:
|
||||
{
|
||||
direction = IOPORT_DIR_INPUT;
|
||||
mode = IOPORT_MODE_PULLUP;
|
||||
break;
|
||||
}
|
||||
case INPUT_PULL_DOWN:
|
||||
{
|
||||
direction = IOPORT_DIR_INPUT;
|
||||
mode = IOPORT_MODE_PULLDOWN;
|
||||
break;
|
||||
}
|
||||
case INPUT_HIGH_IMPEDANCE:
|
||||
{
|
||||
direction = IOPORT_DIR_INPUT;
|
||||
mode = 0;
|
||||
break;
|
||||
}
|
||||
case OUTPUT_PUSH_PULL:
|
||||
{
|
||||
direction = IOPORT_DIR_OUTPUT;
|
||||
mode = 0;
|
||||
break;
|
||||
}
|
||||
case OUTPUT_OPEN_DRAIN_NO_PULL:
|
||||
{
|
||||
direction = IOPORT_DIR_OUTPUT;
|
||||
mode = IOPORT_MODE_OPEN_DRAIN;
|
||||
break;
|
||||
}
|
||||
case OUTPUT_OPEN_DRAIN_PULL_UP:
|
||||
{
|
||||
direction = IOPORT_DIR_OUTPUT;
|
||||
mode = IOPORT_MODE_OPEN_DRAIN | IOPORT_MODE_PULLUP;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
err = kParamErr;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
ioport_enable_pin ( gpio->pin );
|
||||
ioport_set_pin_mode( gpio->pin, mode );
|
||||
ioport_set_pin_dir ( gpio->pin, direction );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_gpio_peripheral_pin_init( const platform_gpio_t* gpio, ioport_mode_t pin_mode )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable( );
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
|
||||
/* Set pin mode and disable GPIO peripheral */
|
||||
ioport_set_pin_mode( gpio->pin, pin_mode );
|
||||
ioport_disable_pin( gpio->pin );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_gpio_deinit( const platform_gpio_t* gpio )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
|
||||
ioport_disable_pin( gpio->pin );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_gpio_output_high( const platform_gpio_t* gpio )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
ioport_set_pin_level( gpio->pin, IOPORT_PIN_LEVEL_HIGH );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_gpio_output_low( const platform_gpio_t* gpio )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
ioport_set_pin_level( gpio->pin, IOPORT_PIN_LEVEL_LOW );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_gpio_output_trigger( const platform_gpio_t* gpio )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
ioport_toggle_pin_level( gpio->pin );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
bool platform_gpio_input_get( const platform_gpio_t* gpio )
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
require_quiet( gpio != NULL, exit);
|
||||
|
||||
result = ( ioport_get_pin_level( gpio->pin ) == false ) ? false : true;
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus platform_gpio_irq_enable( const platform_gpio_t* gpio, platform_gpio_irq_trigger_t trigger, platform_gpio_irq_callback_t handler, void* arg )
|
||||
{
|
||||
ioport_port_mask_t mask = ioport_pin_to_mask( gpio->pin );
|
||||
ioport_port_t port = ioport_pin_to_port_id( gpio->pin );
|
||||
volatile Pio* port_register = arch_ioport_port_to_base( port );
|
||||
uint8_t pin_number = (gpio->pin) & 0x1F;
|
||||
uint32_t temp;
|
||||
uint8_t samg5x_irq_trigger;
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
|
||||
NVIC_DisableIRQ( irq_vectors[port] );
|
||||
NVIC_ClearPendingIRQ( irq_vectors[port] );
|
||||
|
||||
gpio_irq_data[port][pin_number].wakeup_pin = gpio->is_wakeup_pin;
|
||||
gpio_irq_data[port][pin_number].arg = arg;
|
||||
gpio_irq_data[port][pin_number].callback = handler;
|
||||
|
||||
switch ( trigger )
|
||||
{
|
||||
case IRQ_TRIGGER_RISING_EDGE: samg5x_irq_trigger = IOPORT_SENSE_RISING; break;
|
||||
case IRQ_TRIGGER_FALLING_EDGE: samg5x_irq_trigger = IOPORT_SENSE_FALLING; break;
|
||||
case IRQ_TRIGGER_BOTH_EDGES: samg5x_irq_trigger = IOPORT_SENSE_BOTHEDGES; break;
|
||||
default:
|
||||
err = kParamErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( gpio->is_wakeup_pin == true )
|
||||
{
|
||||
platform_powersave_enable_wakeup_pin( gpio );
|
||||
}
|
||||
|
||||
if ( samg5x_irq_trigger == IOPORT_SENSE_RISING || samg5x_irq_trigger == IOPORT_SENSE_BOTHEDGES )
|
||||
{
|
||||
port_register->PIO_AIMER |= mask;
|
||||
port_register->PIO_ESR |= mask;
|
||||
port_register->PIO_REHLSR |= mask;
|
||||
}
|
||||
|
||||
if ( samg5x_irq_trigger == IOPORT_SENSE_FALLING || samg5x_irq_trigger == IOPORT_SENSE_BOTHEDGES )
|
||||
{
|
||||
port_register->PIO_AIMER |= mask;
|
||||
port_register->PIO_ESR |= mask;
|
||||
port_register->PIO_FELLSR |= mask;
|
||||
}
|
||||
|
||||
/* Read ISR to clear residual interrupt status */
|
||||
temp = port_register->PIO_ISR;
|
||||
UNUSED_PARAMETER( temp );
|
||||
|
||||
/* Enable interrupt source */
|
||||
port_register->PIO_IER |= mask;
|
||||
|
||||
NVIC_EnableIRQ( irq_vectors[port] );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
OSStatus platform_gpio_irq_disable( const platform_gpio_t* gpio )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
ioport_port_mask_t mask = ioport_pin_to_mask ( gpio->pin );
|
||||
ioport_port_t port = ioport_pin_to_port_id( gpio->pin );
|
||||
volatile Pio* port_register = arch_ioport_port_to_base( port );
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
require_action_quiet( gpio != NULL, exit, err = kParamErr);
|
||||
|
||||
/* Disable interrupt on pin */
|
||||
port_register->PIO_IDR = mask;
|
||||
|
||||
/* Disable Cortex-M interrupt vector as well if no pin interrupt is enabled */
|
||||
if ( port_register->PIO_IMR == 0 )
|
||||
{
|
||||
NVIC_DisableIRQ( irq_vectors[port] );
|
||||
}
|
||||
|
||||
gpio_irq_data[port][mask].wakeup_pin = false;
|
||||
gpio_irq_data[port][mask].arg = 0;
|
||||
gpio_irq_data[port][mask].callback = NULL;
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
* STM32F2xx Internal Function Definitions
|
||||
******************************************************/
|
||||
OSStatus platform_gpio_irq_manager_init( void )
|
||||
{
|
||||
memset( &gpio_irq_data, 0, sizeof( gpio_irq_data ) );
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* IRQ Handler Definitions
|
||||
******************************************************/
|
||||
|
||||
|
||||
void gpio_irq( ioport_port_t port )
|
||||
{
|
||||
volatile Pio* port_register = arch_ioport_port_to_base( port );
|
||||
uint32_t status = port_register->PIO_ISR; /* Get interrupt status. Read clears the interrupt */
|
||||
uint32_t mask = port_register->PIO_IMR;
|
||||
uint32_t iter = 0;
|
||||
|
||||
if ( ( status != 0 ) && ( mask != 0 ) )
|
||||
{
|
||||
/* Call the respective GPIO interrupt handler/callback */
|
||||
for ( iter = 0; iter < PINS_PER_PORT; iter++, status >>= 1, mask >>= 1 )
|
||||
{
|
||||
if ( ( ( mask & 0x1 ) != 0 ) && ( ( status & 0x1 ) != 0 ) && ( gpio_irq_data[port][iter].callback != NULL ) )
|
||||
{
|
||||
if ( gpio_irq_data[port][iter].wakeup_pin == true )
|
||||
{
|
||||
platform_mcu_powersave_exit_notify();
|
||||
}
|
||||
gpio_irq_data[port][iter].callback( gpio_irq_data[port][iter].arg );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* IRQ Handler Mapping
|
||||
******************************************************/
|
||||
MICO_RTOS_DEFINE_ISR( PIOA_Handler )
|
||||
{
|
||||
gpio_irq( (ioport_port_t)0 );
|
||||
}
|
||||
|
||||
MICO_RTOS_DEFINE_ISR( PIOB_Handler )
|
||||
{
|
||||
gpio_irq( (ioport_port_t)1 );
|
||||
}
|
||||
|
||||
MICO_RTOS_DEFINE_ISR( PIOC_Handler )
|
||||
{
|
||||
gpio_irq( (ioport_port_t)2 );
|
||||
}
|
||||
|
||||
|
||||
@@ -1,213 +1,213 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_i2c.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide I2C driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "platform_peripheral.h"
|
||||
#include "mico.h"
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
#define I2C_TRANSACTION_TIMEOUT (1000)
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mico_semaphore_t transfer_complete;
|
||||
uint32_t transfer_size;
|
||||
bool i2c_inited;
|
||||
const platform_i2c_t* peripheral;
|
||||
platform_i2c_message_t* current_message;
|
||||
uint16_t data_count;
|
||||
volatile int transfer_status;
|
||||
} g55_i2c_runtime_data_t;
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_i2c_init( const platform_i2c_t* i2c, const platform_i2c_config_t* config )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable( );
|
||||
require_action_quiet( i2c != NULL, exit, err = kParamErr);
|
||||
|
||||
twi_options_t twi_slave_config;
|
||||
|
||||
/* Setup SAMG pins */
|
||||
platform_gpio_peripheral_pin_init( i2c->sda_pin, ( i2c->sda_pin_mux_mode | IOPORT_MODE_OPEN_DRAIN ) );
|
||||
platform_gpio_peripheral_pin_init( i2c->scl_pin, ( i2c->scl_pin_mux_mode | IOPORT_MODE_OPEN_DRAIN ) );
|
||||
|
||||
/* Enable the peripheral and set I2C mode. */
|
||||
if( pmc_is_periph_clk_enabled( i2c->peripheral_id ) == 0 ){
|
||||
flexcom_enable( i2c->flexcom_base );
|
||||
}
|
||||
flexcom_set_opmode( i2c->flexcom_base, FLEXCOM_TWI );
|
||||
|
||||
twi_enable_master_mode( i2c->port );
|
||||
|
||||
require_action( config->address_width == I2C_ADDRESS_WIDTH_7BIT, exit, err = kParamErr);
|
||||
|
||||
twi_slave_config.chip = (uint8_t) config->address;
|
||||
switch ( config->speed_mode )
|
||||
{
|
||||
case I2C_LOW_SPEED_MODE : twi_slave_config.speed = 10000; break;
|
||||
case I2C_STANDARD_SPEED_MODE: twi_slave_config.speed = 100000; break;
|
||||
case I2C_HIGH_SPEED_MODE : twi_slave_config.speed = 100000; break;
|
||||
default : platform_log("Speed mode is not supported"); break;
|
||||
}
|
||||
|
||||
twi_slave_config.master_clk = CPU_CLOCK_HZ;
|
||||
twi_slave_config.smbus = 0;
|
||||
twi_master_init( i2c->port, &twi_slave_config );
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
bool platform_i2c_probe_device( const platform_i2c_t* i2c, const platform_i2c_config_t* config, int retries )
|
||||
{
|
||||
for ( ; retries != 0 ; --retries ){
|
||||
if( twi_probe( i2c->port, config->address ) == TWI_SUCCESS ){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
OSStatus platform_i2c_init_tx_message( platform_i2c_message_t* message, const void* tx_buffer, uint16_t tx_buffer_length, uint16_t retries )
|
||||
{
|
||||
memset( message, 0x00, sizeof(platform_i2c_message_t) );
|
||||
message->tx_buffer = tx_buffer;
|
||||
message->tx_length = tx_buffer_length;
|
||||
message->retries = retries;
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus platform_i2c_init_rx_message( platform_i2c_message_t* message, void* rx_buffer, uint16_t rx_buffer_length, uint16_t retries )
|
||||
{
|
||||
memset(message, 0x00, sizeof(platform_i2c_message_t));
|
||||
message->rx_buffer = rx_buffer;
|
||||
message->retries = retries;
|
||||
message->rx_length = rx_buffer_length;
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus platform_i2c_init_combined_message( platform_i2c_message_t* message, const void* tx_buffer, void* rx_buffer, uint16_t tx_buffer_length, uint16_t rx_buffer_length, uint16_t retries )
|
||||
{
|
||||
memset(message, 0x00, sizeof(platform_i2c_message_t));
|
||||
message->rx_buffer = rx_buffer;
|
||||
message->tx_buffer = tx_buffer;
|
||||
message->retries = retries;
|
||||
message->tx_length = tx_buffer_length;
|
||||
message->rx_length = rx_buffer_length;
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
|
||||
OSStatus platform_i2c_transfer( const platform_i2c_t* i2c, const platform_i2c_config_t* config, platform_i2c_message_t* messages, uint16_t number_of_messages )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
Twi* twi = ( Twi* )( i2c->port );
|
||||
int i;
|
||||
twi_packet_t packet;
|
||||
int retry_count;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
/* Check input arguments */
|
||||
require_action_quiet( (i2c != NULL) && ( config != NULL ) &&( messages != NULL ) && ( number_of_messages != 0 ), exit, err = kParamErr );
|
||||
|
||||
for ( i = 0; i < number_of_messages && err == kNoErr; i++ )
|
||||
{
|
||||
platform_i2c_message_t* message_pointer = &messages[i];
|
||||
check_string( message_pointer != NULL, "Message pointer shouldn't be null" );
|
||||
for ( retry_count = 0; retry_count < message_pointer->retries; retry_count++ )
|
||||
{
|
||||
err = kNoErr;
|
||||
|
||||
if ( message_pointer->tx_buffer != NULL )
|
||||
{
|
||||
/** Get the extension boards info */
|
||||
packet.chip = config->address;
|
||||
packet.addr_length = 0;
|
||||
packet.addr[0] = 0;
|
||||
packet.buffer = (void *)message_pointer->tx_buffer;
|
||||
packet.length = message_pointer->tx_length;
|
||||
if (twi_master_write(twi, &packet) != TWI_SUCCESS) {
|
||||
err = kGeneralErr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( message_pointer->rx_buffer != NULL )
|
||||
{
|
||||
/** Get the extension boards info */
|
||||
packet.chip = config->address;
|
||||
packet.addr_length = 0;
|
||||
packet.addr[0] = 0;
|
||||
packet.buffer = message_pointer->rx_buffer;
|
||||
packet.length = message_pointer->rx_length;
|
||||
if (twi_master_read(twi, &packet) != TWI_SUCCESS) {
|
||||
err = kGeneralErr;
|
||||
}
|
||||
}
|
||||
|
||||
if( err == kNoErr )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
OSStatus platform_i2c_deinit( const platform_i2c_t* i2c, const platform_i2c_config_t* config )
|
||||
{
|
||||
/* Disable the RX and TX PDC transfer requests */
|
||||
if( pmc_is_periph_clk_enabled( i2c->peripheral_id ) == 1 ){
|
||||
flexcom_disable( i2c->flexcom_base );
|
||||
}
|
||||
|
||||
twi_reset( i2c->port );
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_i2c.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide I2C driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "platform_peripheral.h"
|
||||
#include "mico.h"
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
#define I2C_TRANSACTION_TIMEOUT (1000)
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mico_semaphore_t transfer_complete;
|
||||
uint32_t transfer_size;
|
||||
bool i2c_inited;
|
||||
const platform_i2c_t* peripheral;
|
||||
platform_i2c_message_t* current_message;
|
||||
uint16_t data_count;
|
||||
volatile int transfer_status;
|
||||
} g55_i2c_runtime_data_t;
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_i2c_init( const platform_i2c_t* i2c, const platform_i2c_config_t* config )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable( );
|
||||
require_action_quiet( i2c != NULL, exit, err = kParamErr);
|
||||
|
||||
twi_options_t twi_slave_config;
|
||||
|
||||
/* Setup SAMG pins */
|
||||
platform_gpio_peripheral_pin_init( i2c->sda_pin, ( i2c->sda_pin_mux_mode | IOPORT_MODE_OPEN_DRAIN ) );
|
||||
platform_gpio_peripheral_pin_init( i2c->scl_pin, ( i2c->scl_pin_mux_mode | IOPORT_MODE_OPEN_DRAIN ) );
|
||||
|
||||
/* Enable the peripheral and set I2C mode. */
|
||||
if( pmc_is_periph_clk_enabled( i2c->peripheral_id ) == 0 ){
|
||||
flexcom_enable( i2c->flexcom_base );
|
||||
}
|
||||
flexcom_set_opmode( i2c->flexcom_base, FLEXCOM_TWI );
|
||||
|
||||
twi_enable_master_mode( i2c->port );
|
||||
|
||||
require_action( config->address_width == I2C_ADDRESS_WIDTH_7BIT, exit, err = kParamErr);
|
||||
|
||||
twi_slave_config.chip = (uint8_t) config->address;
|
||||
switch ( config->speed_mode )
|
||||
{
|
||||
case I2C_LOW_SPEED_MODE : twi_slave_config.speed = 10000; break;
|
||||
case I2C_STANDARD_SPEED_MODE: twi_slave_config.speed = 100000; break;
|
||||
case I2C_HIGH_SPEED_MODE : twi_slave_config.speed = 100000; break;
|
||||
default : platform_log("Speed mode is not supported"); break;
|
||||
}
|
||||
|
||||
twi_slave_config.master_clk = CPU_CLOCK_HZ;
|
||||
twi_slave_config.smbus = 0;
|
||||
twi_master_init( i2c->port, &twi_slave_config );
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
bool platform_i2c_probe_device( const platform_i2c_t* i2c, const platform_i2c_config_t* config, int retries )
|
||||
{
|
||||
for ( ; retries != 0 ; --retries ){
|
||||
if( twi_probe( i2c->port, config->address ) == TWI_SUCCESS ){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
OSStatus platform_i2c_init_tx_message( platform_i2c_message_t* message, const void* tx_buffer, uint16_t tx_buffer_length, uint16_t retries )
|
||||
{
|
||||
memset( message, 0x00, sizeof(platform_i2c_message_t) );
|
||||
message->tx_buffer = tx_buffer;
|
||||
message->tx_length = tx_buffer_length;
|
||||
message->retries = retries;
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus platform_i2c_init_rx_message( platform_i2c_message_t* message, void* rx_buffer, uint16_t rx_buffer_length, uint16_t retries )
|
||||
{
|
||||
memset(message, 0x00, sizeof(platform_i2c_message_t));
|
||||
message->rx_buffer = rx_buffer;
|
||||
message->retries = retries;
|
||||
message->rx_length = rx_buffer_length;
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus platform_i2c_init_combined_message( platform_i2c_message_t* message, const void* tx_buffer, void* rx_buffer, uint16_t tx_buffer_length, uint16_t rx_buffer_length, uint16_t retries )
|
||||
{
|
||||
memset(message, 0x00, sizeof(platform_i2c_message_t));
|
||||
message->rx_buffer = rx_buffer;
|
||||
message->tx_buffer = tx_buffer;
|
||||
message->retries = retries;
|
||||
message->tx_length = tx_buffer_length;
|
||||
message->rx_length = rx_buffer_length;
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
|
||||
OSStatus platform_i2c_transfer( const platform_i2c_t* i2c, const platform_i2c_config_t* config, platform_i2c_message_t* messages, uint16_t number_of_messages )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
Twi* twi = ( Twi* )( i2c->port );
|
||||
int i;
|
||||
twi_packet_t packet;
|
||||
int retry_count;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
/* Check input arguments */
|
||||
require_action_quiet( (i2c != NULL) && ( config != NULL ) &&( messages != NULL ) && ( number_of_messages != 0 ), exit, err = kParamErr );
|
||||
|
||||
for ( i = 0; i < number_of_messages && err == kNoErr; i++ )
|
||||
{
|
||||
platform_i2c_message_t* message_pointer = &messages[i];
|
||||
check_string( message_pointer != NULL, "Message pointer shouldn't be null" );
|
||||
for ( retry_count = 0; retry_count < message_pointer->retries; retry_count++ )
|
||||
{
|
||||
err = kNoErr;
|
||||
|
||||
if ( message_pointer->tx_buffer != NULL )
|
||||
{
|
||||
/** Get the extension boards info */
|
||||
packet.chip = config->address;
|
||||
packet.addr_length = 0;
|
||||
packet.addr[0] = 0;
|
||||
packet.buffer = (void *)message_pointer->tx_buffer;
|
||||
packet.length = message_pointer->tx_length;
|
||||
if (twi_master_write(twi, &packet) != TWI_SUCCESS) {
|
||||
err = kGeneralErr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( message_pointer->rx_buffer != NULL )
|
||||
{
|
||||
/** Get the extension boards info */
|
||||
packet.chip = config->address;
|
||||
packet.addr_length = 0;
|
||||
packet.addr[0] = 0;
|
||||
packet.buffer = message_pointer->rx_buffer;
|
||||
packet.length = message_pointer->rx_length;
|
||||
if (twi_master_read(twi, &packet) != TWI_SUCCESS) {
|
||||
err = kGeneralErr;
|
||||
}
|
||||
}
|
||||
|
||||
if( err == kNoErr )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
OSStatus platform_i2c_deinit( const platform_i2c_t* i2c, const platform_i2c_config_t* config )
|
||||
{
|
||||
/* Disable the RX and TX PDC transfer requests */
|
||||
if( pmc_is_periph_clk_enabled( i2c->peripheral_id ) == 1 ){
|
||||
flexcom_disable( i2c->flexcom_base );
|
||||
}
|
||||
|
||||
twi_reset( i2c->port );
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,260 +1,260 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_mcu_peripheral.h
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide all the headers of functions for stm32f2xx platform
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "samg55.h"
|
||||
#include "ioport.h"
|
||||
#include "usart.h"
|
||||
#include "spi.h"
|
||||
#include "twi.h"
|
||||
#include "efc.h"
|
||||
#include "pdc.h"
|
||||
#include "flexcom.h"
|
||||
#include "rtt.h"
|
||||
#include "supc.h"
|
||||
#include "matrix.h"
|
||||
#include "wdt.h"
|
||||
#include "adc2.h"
|
||||
|
||||
#include "mico_rtos.h"
|
||||
#include "RingBufferUtils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/******************************************************
|
||||
* Macros
|
||||
******************************************************/
|
||||
|
||||
#define CREATE_IOPORT_PIN(port, pin) ((port) * 32 + (pin))
|
||||
|
||||
#define PORTA IOPORT_PIOA
|
||||
#define PORTB IOPORT_PIOB
|
||||
|
||||
/**
|
||||
* \brief Set peripheral mode for IOPORT pins.
|
||||
* It will configure port mode and disable pin mode (but enable peripheral).
|
||||
* \param port IOPORT port to configure
|
||||
* \param masks IOPORT pin masks to configure
|
||||
* \param mode Mode masks to configure for the specified pin (\ref ioport_modes)
|
||||
*/
|
||||
#define ioport_set_port_peripheral_mode(port, masks, mode) \
|
||||
do {\
|
||||
ioport_set_port_mode(port, masks, mode);\
|
||||
ioport_disable_port(port, masks);\
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* \brief Set peripheral mode for one single IOPORT pin.
|
||||
* It will configure port mode and disable pin mode (but enable peripheral).
|
||||
* \param pin IOPORT pin to configure
|
||||
* \param mode Mode masks to configure for the specified pin (\ref ioport_modes)
|
||||
*/
|
||||
#define ioport_set_pin_peripheral_mode(pin, mode) \
|
||||
do {\
|
||||
ioport_set_pin_mode(pin, mode);\
|
||||
ioport_disable_pin(pin);\
|
||||
} while (0)
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
/* GPIOA to I */
|
||||
#define NUMBER_OF_GPIO_PORTS (8)
|
||||
|
||||
#define NUMBER_OF_GPIO_IRQ_LINES (7)
|
||||
|
||||
/* USART1 to 6 */
|
||||
#define NUMBER_OF_UART_PORTS (6)
|
||||
|
||||
|
||||
/* Invalid UART port number */
|
||||
#define INVALID_UART_PORT_NUMBER (0xff)
|
||||
|
||||
/* SPI1 to SPI3 */
|
||||
#define NUMBER_OF_SPI_PORTS (3)
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/* SPI port */
|
||||
typedef Spi platform_spi_port_t;
|
||||
typedef Adc platform_adc_port_t;
|
||||
typedef Twi platform_i2c_port_t;
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ioport_pin_t pin;
|
||||
bool is_wakeup_pin;
|
||||
uint8_t wakeup_pin_number; /* wakeup pin number: 0 .. 15 */
|
||||
uint8_t trigger; /* wakeup trigger: IOPORT_SENSE_FALLING or RISING */
|
||||
|
||||
} platform_gpio_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
enum adc_channel_num channel;
|
||||
enum adc_interrupt_source interrupt;
|
||||
enum adc_resolution resolution;
|
||||
} platform_adc_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t uart_id;
|
||||
void* port; /* Usart* or Uart* */
|
||||
Flexcom* flexcom_base;
|
||||
uint32_t peripheral_id;
|
||||
const platform_gpio_t* tx_pin; /* Tx pin */
|
||||
ioport_mode_t tx_pin_mux_mode; /* Tx pin mux mode */
|
||||
const platform_gpio_t* rx_pin; /* Rx pin */
|
||||
ioport_mode_t rx_pin_mux_mode; /* Tx pin mux mode */
|
||||
const platform_gpio_t* cts_pin; /* CTS pin */
|
||||
ioport_mode_t cts_pin_mux_mode; /* Tx pin mux mode */
|
||||
const platform_gpio_t* rts_pin; /* RTS pin */
|
||||
ioport_mode_t rts_pin_mux_mode; /* Tx pin mux mode */
|
||||
} platform_uart_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
platform_uart_t* peripheral;
|
||||
ring_buffer_t* rx_ring_buffer;
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_semaphore_t rx_complete;
|
||||
mico_semaphore_t tx_complete;
|
||||
mico_mutex_t tx_mutex;
|
||||
mico_semaphore_t sem_wakeup;
|
||||
#else
|
||||
volatile bool rx_complete;
|
||||
volatile bool tx_complete;
|
||||
#endif
|
||||
volatile uint32_t tx_size;
|
||||
volatile uint32_t rx_size;
|
||||
volatile OSStatus last_receive_result;
|
||||
volatile OSStatus last_transmit_result;
|
||||
} platform_uart_driver_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t spi_id;
|
||||
platform_spi_port_t* port; /* Peripheral */
|
||||
Flexcom* flexcom_base;
|
||||
uint32_t peripheral_id;
|
||||
const platform_gpio_t* mosi_pin; /* MOSI pin */
|
||||
ioport_mode_t mosi_pin_mux_mode; /* MOSI pin mux mode */
|
||||
const platform_gpio_t* miso_pin; /* MISO pin */
|
||||
ioport_mode_t miso_pin_mux_mode; /* MISO pin mux mode */
|
||||
const platform_gpio_t* clock_pin; /* CLOCK pin */
|
||||
ioport_mode_t clock_pin_mux_mode; /* CLOCK pin mux mode */
|
||||
} platform_spi_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
platform_spi_t* peripheral;
|
||||
mico_mutex_t spi_mutex;
|
||||
} platform_spi_driver_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t unimplemented;
|
||||
} platform_spi_slave_driver_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t unimplemented;
|
||||
} platform_pwm_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t i2c_id;
|
||||
platform_i2c_port_t* port;
|
||||
Flexcom* flexcom_base;
|
||||
uint32_t peripheral_id;
|
||||
const platform_gpio_t* sda_pin;
|
||||
ioport_mode_t sda_pin_mux_mode;
|
||||
const platform_gpio_t* scl_pin;
|
||||
ioport_mode_t scl_pin_mux_mode;
|
||||
} platform_i2c_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mico_mutex_t i2c_mutex;
|
||||
} platform_i2c_driver_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t flash_type;
|
||||
uint32_t flash_start_addr;
|
||||
uint32_t flash_length;
|
||||
uint32_t flash_protect_opt;
|
||||
} platform_flash_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const platform_flash_t* peripheral;
|
||||
mico_mutex_t flash_mutex;
|
||||
volatile bool initialized;
|
||||
} platform_flash_driver_t;
|
||||
|
||||
/******************************************************
|
||||
* Global Variables
|
||||
******************************************************/
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
OSStatus platform_gpio_irq_manager_init ( void );
|
||||
OSStatus platform_powersave_enable_wakeup_pin( const platform_gpio_t* gpio );
|
||||
|
||||
|
||||
OSStatus platform_mcu_powersave_init ( void );
|
||||
|
||||
OSStatus platform_rtc_init ( void );
|
||||
|
||||
OSStatus platform_gpio_peripheral_pin_init( const platform_gpio_t* gpio, ioport_mode_t pin_mode );
|
||||
|
||||
void platform_uart_irq ( platform_uart_driver_t* driver );
|
||||
void platform_uart_tx_dma_irq ( platform_uart_driver_t* driver );
|
||||
void platform_uart_rx_dma_irq ( platform_uart_driver_t* driver );
|
||||
void platform_i2c_irq ( uint8_t i2c_id );
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_mcu_peripheral.h
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide all the headers of functions for stm32f2xx platform
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "samg55.h"
|
||||
#include "ioport.h"
|
||||
#include "usart.h"
|
||||
#include "spi.h"
|
||||
#include "twi.h"
|
||||
#include "efc.h"
|
||||
#include "pdc.h"
|
||||
#include "flexcom.h"
|
||||
#include "rtt.h"
|
||||
#include "supc.h"
|
||||
#include "matrix.h"
|
||||
#include "wdt.h"
|
||||
#include "adc2.h"
|
||||
|
||||
#include "mico_rtos.h"
|
||||
#include "RingBufferUtils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/******************************************************
|
||||
* Macros
|
||||
******************************************************/
|
||||
|
||||
#define CREATE_IOPORT_PIN(port, pin) ((port) * 32 + (pin))
|
||||
|
||||
#define PORTA IOPORT_PIOA
|
||||
#define PORTB IOPORT_PIOB
|
||||
|
||||
/**
|
||||
* \brief Set peripheral mode for IOPORT pins.
|
||||
* It will configure port mode and disable pin mode (but enable peripheral).
|
||||
* \param port IOPORT port to configure
|
||||
* \param masks IOPORT pin masks to configure
|
||||
* \param mode Mode masks to configure for the specified pin (\ref ioport_modes)
|
||||
*/
|
||||
#define ioport_set_port_peripheral_mode(port, masks, mode) \
|
||||
do {\
|
||||
ioport_set_port_mode(port, masks, mode);\
|
||||
ioport_disable_port(port, masks);\
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* \brief Set peripheral mode for one single IOPORT pin.
|
||||
* It will configure port mode and disable pin mode (but enable peripheral).
|
||||
* \param pin IOPORT pin to configure
|
||||
* \param mode Mode masks to configure for the specified pin (\ref ioport_modes)
|
||||
*/
|
||||
#define ioport_set_pin_peripheral_mode(pin, mode) \
|
||||
do {\
|
||||
ioport_set_pin_mode(pin, mode);\
|
||||
ioport_disable_pin(pin);\
|
||||
} while (0)
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
/* GPIOA to I */
|
||||
#define NUMBER_OF_GPIO_PORTS (8)
|
||||
|
||||
#define NUMBER_OF_GPIO_IRQ_LINES (7)
|
||||
|
||||
/* USART1 to 6 */
|
||||
#define NUMBER_OF_UART_PORTS (6)
|
||||
|
||||
|
||||
/* Invalid UART port number */
|
||||
#define INVALID_UART_PORT_NUMBER (0xff)
|
||||
|
||||
/* SPI1 to SPI3 */
|
||||
#define NUMBER_OF_SPI_PORTS (3)
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/* SPI port */
|
||||
typedef Spi platform_spi_port_t;
|
||||
typedef Adc platform_adc_port_t;
|
||||
typedef Twi platform_i2c_port_t;
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ioport_pin_t pin;
|
||||
bool is_wakeup_pin;
|
||||
uint8_t wakeup_pin_number; /* wakeup pin number: 0 .. 15 */
|
||||
uint8_t trigger; /* wakeup trigger: IOPORT_SENSE_FALLING or RISING */
|
||||
|
||||
} platform_gpio_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
enum adc_channel_num channel;
|
||||
enum adc_interrupt_source interrupt;
|
||||
enum adc_resolution resolution;
|
||||
} platform_adc_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t uart_id;
|
||||
void* port; /* Usart* or Uart* */
|
||||
Flexcom* flexcom_base;
|
||||
uint32_t peripheral_id;
|
||||
const platform_gpio_t* tx_pin; /* Tx pin */
|
||||
ioport_mode_t tx_pin_mux_mode; /* Tx pin mux mode */
|
||||
const platform_gpio_t* rx_pin; /* Rx pin */
|
||||
ioport_mode_t rx_pin_mux_mode; /* Tx pin mux mode */
|
||||
const platform_gpio_t* cts_pin; /* CTS pin */
|
||||
ioport_mode_t cts_pin_mux_mode; /* Tx pin mux mode */
|
||||
const platform_gpio_t* rts_pin; /* RTS pin */
|
||||
ioport_mode_t rts_pin_mux_mode; /* Tx pin mux mode */
|
||||
} platform_uart_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
platform_uart_t* peripheral;
|
||||
ring_buffer_t* rx_ring_buffer;
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_semaphore_t rx_complete;
|
||||
mico_semaphore_t tx_complete;
|
||||
mico_mutex_t tx_mutex;
|
||||
mico_semaphore_t sem_wakeup;
|
||||
#else
|
||||
volatile bool rx_complete;
|
||||
volatile bool tx_complete;
|
||||
#endif
|
||||
volatile uint32_t tx_size;
|
||||
volatile uint32_t rx_size;
|
||||
volatile OSStatus last_receive_result;
|
||||
volatile OSStatus last_transmit_result;
|
||||
} platform_uart_driver_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t spi_id;
|
||||
platform_spi_port_t* port; /* Peripheral */
|
||||
Flexcom* flexcom_base;
|
||||
uint32_t peripheral_id;
|
||||
const platform_gpio_t* mosi_pin; /* MOSI pin */
|
||||
ioport_mode_t mosi_pin_mux_mode; /* MOSI pin mux mode */
|
||||
const platform_gpio_t* miso_pin; /* MISO pin */
|
||||
ioport_mode_t miso_pin_mux_mode; /* MISO pin mux mode */
|
||||
const platform_gpio_t* clock_pin; /* CLOCK pin */
|
||||
ioport_mode_t clock_pin_mux_mode; /* CLOCK pin mux mode */
|
||||
} platform_spi_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
platform_spi_t* peripheral;
|
||||
mico_mutex_t spi_mutex;
|
||||
} platform_spi_driver_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t unimplemented;
|
||||
} platform_spi_slave_driver_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t unimplemented;
|
||||
} platform_pwm_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t i2c_id;
|
||||
platform_i2c_port_t* port;
|
||||
Flexcom* flexcom_base;
|
||||
uint32_t peripheral_id;
|
||||
const platform_gpio_t* sda_pin;
|
||||
ioport_mode_t sda_pin_mux_mode;
|
||||
const platform_gpio_t* scl_pin;
|
||||
ioport_mode_t scl_pin_mux_mode;
|
||||
} platform_i2c_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mico_mutex_t i2c_mutex;
|
||||
} platform_i2c_driver_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t flash_type;
|
||||
uint32_t flash_start_addr;
|
||||
uint32_t flash_length;
|
||||
uint32_t flash_protect_opt;
|
||||
} platform_flash_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const platform_flash_t* peripheral;
|
||||
mico_mutex_t flash_mutex;
|
||||
volatile bool initialized;
|
||||
} platform_flash_driver_t;
|
||||
|
||||
/******************************************************
|
||||
* Global Variables
|
||||
******************************************************/
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
OSStatus platform_gpio_irq_manager_init ( void );
|
||||
OSStatus platform_powersave_enable_wakeup_pin( const platform_gpio_t* gpio );
|
||||
|
||||
|
||||
OSStatus platform_mcu_powersave_init ( void );
|
||||
|
||||
OSStatus platform_rtc_init ( void );
|
||||
|
||||
OSStatus platform_gpio_peripheral_pin_init( const platform_gpio_t* gpio, ioport_mode_t pin_mode );
|
||||
|
||||
void platform_uart_irq ( platform_uart_driver_t* driver );
|
||||
void platform_uart_tx_dma_irq ( platform_uart_driver_t* driver );
|
||||
void platform_uart_rx_dma_irq ( platform_uart_driver_t* driver );
|
||||
void platform_i2c_irq ( uint8_t i2c_id );
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,404 +1,404 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_mcu_powersave.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide functions called by MICO to drive stm32f2xx
|
||||
* platform: - e.g. power save, reboot, platform initialize
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
#include "platform_config.h"
|
||||
#include "platform_init.h"
|
||||
|
||||
/******************************************************
|
||||
* Macros
|
||||
******************************************************/
|
||||
|
||||
#define CYCLES_TO_MS( cycles ) ( ( ( cycles ) * 1000 * RTT_CLOCK_PRESCALER ) / RTT_CLOCK_HZ )
|
||||
#define MS_TO_CYCLES( ms ) ( ( ( ms ) * RTT_CLOCK_HZ ) / ( 1000 * RTT_CLOCK_PRESCALER ) )
|
||||
|
||||
#ifndef ENABLE_INTERRUPTS
|
||||
#define ENABLE_INTERRUPTS __asm("CPSIE i")
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_INTERRUPTS
|
||||
#define DISABLE_INTERRUPTS __asm("CPSID i") /**< Disable interrupts to stop task switching in MICO RTOS. */
|
||||
#endif
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
#define RTT_CLOCK_PRESCALER (4) /* */
|
||||
#define RTT_CLOCK_HZ (32768) /* 32K / prescaler */
|
||||
#define RTT_MAX_CYCLES (64000) /* 7.8125 seconds */
|
||||
#define RC_OSC_DELAY_CYCLES (15) /* Cycles required to stabilise clock after exiting WAIT mode */
|
||||
#define JTAG_DEBUG_SLEEP_DELAY_MS (3000) /* Delay in ms to give OpenOCD enough time to halt the CPU before the CPU enter WAIT mode */
|
||||
|
||||
#define WAIT_MODE_SUPPORT
|
||||
#define WAIT_MODE_ENTER_DELAY_CYCLES (3)
|
||||
#define WAIT_MODE_EXIT_DELAY_CYCLES (34)
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
static unsigned long wait_mode_power_down_hook( unsigned long sleep_ms );
|
||||
#else
|
||||
static unsigned long idle_power_down_hook( unsigned long sleep_ms );
|
||||
#endif
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
static volatile uint32_t system_io_backup_value = 0;
|
||||
static volatile uint32_t samg5x_clock_needed_counter = 0;
|
||||
static volatile bool wake_up_interrupt_triggered = false;
|
||||
#endif /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_mcu_powersave_init(void)
|
||||
{
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
#error Not working currently, uncomment MICO_DISABLE_MCU_POWERSAVE in platform_config.h
|
||||
/* Initialise all pins to be input pull-up to save power */
|
||||
ioport_enable_port( IOPORT_PIOA, 0xffffffffU );
|
||||
ioport_set_port_mode( IOPORT_PIOA, 0xffffffffU, IOPORT_MODE_PULLUP );
|
||||
ioport_set_port_dir( IOPORT_PIOA, 0xffffffffU, IOPORT_DIR_INPUT );
|
||||
|
||||
ioport_enable_port( IOPORT_PIOB, 0xffffffffU );
|
||||
ioport_set_port_mode( IOPORT_PIOB, 0xffffffffU, IOPORT_MODE_PULLUP );
|
||||
ioport_set_port_dir( IOPORT_PIOB, 0xffffffffU, IOPORT_DIR_INPUT );
|
||||
|
||||
NVIC_DisableIRQ( RTT_IRQn );
|
||||
NVIC_ClearPendingIRQ( RTT_IRQn );
|
||||
NVIC_EnableIRQ( RTT_IRQn );
|
||||
pmc_set_fast_startup_input( PMC_FSMR_RTTAL );
|
||||
|
||||
|
||||
rtt_init( RTT, RTT_CLOCK_PRESCALER );
|
||||
rtt_write_alarm_time( RTT, 64000 );
|
||||
|
||||
|
||||
#endif /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus platform_mcu_powersave_disable( void )
|
||||
{
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
|
||||
/* Atomic operation starts */
|
||||
DISABLE_INTERRUPTS;
|
||||
|
||||
/* Increment counter to indicate CPU clock is needed preventing CPU from entering WAIT mode */
|
||||
samg5x_clock_needed_counter++;
|
||||
|
||||
/* Atomic operation ends */
|
||||
ENABLE_INTERRUPTS;
|
||||
|
||||
#endif /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus platform_mcu_powersave_enable( void )
|
||||
{
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
/* Atomic operation starts */
|
||||
DISABLE_INTERRUPTS;
|
||||
|
||||
/* Decrement counter only if it's not 0 */
|
||||
samg5x_clock_needed_counter -= ( samg5x_clock_needed_counter > 0 ) ? 1 : 0;
|
||||
|
||||
/* Atomic operation ends */
|
||||
ENABLE_INTERRUPTS;
|
||||
#endif /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus platform_powersave_enable_wakeup_pin( const platform_gpio_t* gpio )
|
||||
{
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
if ( gpio->is_wakeup_pin == true )
|
||||
{
|
||||
/* Enable wake-up pin */
|
||||
pmc_set_fast_startup_input( 1 << gpio->wakeup_pin_number );
|
||||
|
||||
if ( gpio->trigger == IOPORT_SENSE_RISING )
|
||||
{
|
||||
/* Set polarity of corresponding wake-up pin bit to active-high */
|
||||
PMC->PMC_FSPR |= (uint32_t)( 1 << gpio->wakeup_pin_number );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set polarity of corresponding wake-up pin bit to active-low */
|
||||
PMC->PMC_FSPR &= ~(uint32_t)( 1 << gpio->wakeup_pin_number );
|
||||
}
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kGeneralErr;
|
||||
}
|
||||
#else /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
return kNoErr;
|
||||
#endif
|
||||
}
|
||||
|
||||
OSStatus platform_powersave_disable_wakeup_pin( const platform_gpio_t* gpio )
|
||||
{
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
if ( gpio->is_wakeup_pin == true )
|
||||
{
|
||||
pmc_clr_fast_startup_input( 1 << gpio->wakeup_pin_number );
|
||||
return kNoErr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kGeneralErr;
|
||||
}
|
||||
#else /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
return kNoErr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void platform_mcu_powersave_exit_notify( void )
|
||||
{
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
wake_up_interrupt_triggered = true;
|
||||
#endif /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* RTOS Powersave Hooks
|
||||
******************************************************/
|
||||
|
||||
void platform_idle_hook( void )
|
||||
{
|
||||
__asm("wfi");
|
||||
}
|
||||
|
||||
uint32_t platform_power_down_hook( uint32_t sleep_ms )
|
||||
{
|
||||
#ifdef MICO_DISABLE_MCU_POWERSAVE
|
||||
/* If MCU powersave feature is disabled, enter idle mode when powerdown hook is called by the RTOS */
|
||||
return idle_power_down_hook( sleep_ms );
|
||||
|
||||
#else
|
||||
/* If MCU powersave feature is enabled, enter STOP mode when powerdown hook is called by the RTOS */
|
||||
return wait_mode_power_down_hook( sleep_ms );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Static Function Definitions
|
||||
******************************************************/
|
||||
|
||||
#ifdef MICO_DISABLE_MCU_POWERSAVE
|
||||
/* MCU Powersave is disabled */
|
||||
static unsigned long idle_power_down_hook( unsigned long sleep_ms )
|
||||
{
|
||||
UNUSED_PARAMETER( sleep_ms );
|
||||
ENABLE_INTERRUPTS;;
|
||||
__asm("wfi");
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static unsigned long wait_mode_power_down_hook( unsigned long delay_ms )
|
||||
{
|
||||
bool jtag_enabled = ( ( CoreDebug ->DHCSR & CoreDebug_DEMCR_TRCENA_Msk ) != 0 ) ? true : false;
|
||||
bool jtag_delay_elapsed = ( mico_get_time() > JTAG_DEBUG_SLEEP_DELAY_MS ) ? true : false;
|
||||
uint32_t elapsed_cycles = 0;
|
||||
|
||||
/* Criteria to enter WAIT mode
|
||||
* 1. Clock needed counter is 0 and no JTAG debugging
|
||||
* 2. Clock needed counter is 0, in JTAG debugging session, and MiCO system tick has progressed over 3 seconds.
|
||||
* This is to give OpenOCD enough time to poke the JTAG tap before the CPU enters WAIT mode.
|
||||
*/
|
||||
if ( ( samg5x_clock_needed_counter == 0 ) && ( ( jtag_enabled == false ) || ( ( jtag_enabled == true ) && ( jtag_delay_elapsed == true ) ) ) )
|
||||
{
|
||||
uint32_t total_sleep_cycles;
|
||||
uint32_t total_delay_cycles;
|
||||
|
||||
/* Start real-time timer */
|
||||
rtt_init( RTT, RTT_CLOCK_PRESCALER );
|
||||
|
||||
/* Start atomic operation */
|
||||
DISABLE_INTERRUPTS;
|
||||
|
||||
/* Ensure deep sleep bit is enabled, otherwise system doesn't go into deep sleep */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
|
||||
/* Disable SysTick */
|
||||
SysTick->CTRL &= ( ~( SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk ) );
|
||||
|
||||
/* End atomic operation */
|
||||
ENABLE_INTERRUPTS;
|
||||
|
||||
/* Expected total time CPU executing in this function (including WAIT mode time) */
|
||||
total_sleep_cycles = MS_TO_CYCLES( delay_ms );
|
||||
|
||||
/* Total cycles in WAIT mode loop */
|
||||
total_delay_cycles = ( total_sleep_cycles / RTT_MAX_CYCLES + 1 ) * RC_OSC_DELAY_CYCLES + WAIT_MODE_ENTER_DELAY_CYCLES + WAIT_MODE_EXIT_DELAY_CYCLES;
|
||||
|
||||
if ( total_sleep_cycles > total_delay_cycles )
|
||||
{
|
||||
/* Adjust total sleep cycle to exclude exit delay */
|
||||
total_sleep_cycles -= WAIT_MODE_EXIT_DELAY_CYCLES;
|
||||
|
||||
/* Prepare platform specific settings before entering powersave */
|
||||
// platform_enter_powersave();
|
||||
|
||||
///* Prepare WLAN bus before entering powersave */
|
||||
//platform_bus_enter_powersave();
|
||||
|
||||
/* Disable brownout detector */
|
||||
supc_disable_brownout_detector( SUPC );
|
||||
|
||||
/* Backup system I/0 functions and set all to GPIO to save power */
|
||||
system_io_backup_value = matrix_get_system_io();
|
||||
matrix_set_system_io( 0x0CF0 );
|
||||
|
||||
/* Switch Master Clock to Main Clock (internal fast RC oscillator) */
|
||||
pmc_switch_mck_to_mainck( PMC_PCK_PRES_CLK_1 );
|
||||
|
||||
/* Switch on internal fast RC oscillator, switch Main Clock source to internal fast RC oscillator and disables external fast crystal */
|
||||
pmc_switch_mainck_to_fastrc( CKGR_MOR_MOSCRCF_8_MHz );
|
||||
|
||||
/* Disable external fast crystal */
|
||||
pmc_osc_disable_xtal( 0 );
|
||||
|
||||
/* Disable PLLA */
|
||||
pmc_disable_pllack( );
|
||||
|
||||
/* This above process introduces certain delay. Add delay to the elapsed cycles */
|
||||
elapsed_cycles += rtt_read_timer_value( RTT );
|
||||
|
||||
while ( wake_up_interrupt_triggered == false && elapsed_cycles < total_sleep_cycles )
|
||||
{
|
||||
uint32_t current_sleep_cycles = total_sleep_cycles - elapsed_cycles;
|
||||
|
||||
/* Start real-time timer and alarm */
|
||||
rtt_init( RTT, RTT_CLOCK_PRESCALER );
|
||||
rtt_write_alarm_time( RTT, ( current_sleep_cycles > RTT_MAX_CYCLES ) ? RTT_MAX_CYCLES - RC_OSC_DELAY_CYCLES : current_sleep_cycles - RC_OSC_DELAY_CYCLES );
|
||||
|
||||
__asm("wfi");
|
||||
/* Enter WAIT mode */
|
||||
//pmc_enable_waitmode();
|
||||
|
||||
/* Clear wake-up status */
|
||||
rtt_get_status( RTT );
|
||||
|
||||
/* Add sleep time to the elapsed cycles */
|
||||
elapsed_cycles += rtt_read_timer_value( RTT );
|
||||
}
|
||||
|
||||
/* Re-enable real-time timer to time clock reinitialisation delay */
|
||||
rtt_init( RTT, RTT_CLOCK_PRESCALER );
|
||||
|
||||
/* Reinit fast clock. This takes ~19ms, but the timing has been compensated */
|
||||
init_clocks();
|
||||
|
||||
/* Disable unused clock to save power */
|
||||
pmc_osc_disable_fastrc();
|
||||
|
||||
/* Restore system I/O pins */
|
||||
matrix_set_system_io( system_io_backup_value );
|
||||
|
||||
/* Restore WLAN bus */
|
||||
//platform_bus_exit_powersave();
|
||||
|
||||
// /* Restore platform-specific settings */
|
||||
// platform_exit_powersave();
|
||||
|
||||
/* Add clock reinitialisation delay to elapsed cycles */
|
||||
elapsed_cycles += rtt_read_timer_value( RTT );
|
||||
|
||||
/* Disable RTT to save power */
|
||||
RTT->RTT_MR = (uint32_t)( 1 << 20 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Start atomic operation */
|
||||
DISABLE_INTERRUPTS;
|
||||
|
||||
/* Switch SysTick back on */
|
||||
SysTick->CTRL |= ( SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk );
|
||||
|
||||
/* Clear flag indicating interrupt triggered by wake up pin */
|
||||
wake_up_interrupt_triggered = false;
|
||||
|
||||
/* End atomic operation */
|
||||
ENABLE_INTERRUPTS;
|
||||
|
||||
/* Return total time in milliseconds */
|
||||
return CYCLES_TO_MS( elapsed_cycles );
|
||||
}
|
||||
#endif /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
|
||||
|
||||
void platform_mcu_enter_standby(uint32_t secondsToWakeup)
|
||||
{
|
||||
platform_log("unimplemented");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
* IRQ Handlers Definition & Mapping
|
||||
******************************************************/
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Interrupt Service Routine Definitions
|
||||
******************************************************/
|
||||
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
MICO_RTOS_DEFINE_ISR(RTT_Handler)
|
||||
{
|
||||
// __set_PRIMASK( 1 );
|
||||
// rtt_get_status( RTT );
|
||||
// rtt_disable_interrupt( RTT, RTT_MR_ALMIEN );
|
||||
}
|
||||
#endif /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_mcu_powersave.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide functions called by MICO to drive stm32f2xx
|
||||
* platform: - e.g. power save, reboot, platform initialize
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
#include "platform_config.h"
|
||||
#include "platform_init.h"
|
||||
|
||||
/******************************************************
|
||||
* Macros
|
||||
******************************************************/
|
||||
|
||||
#define CYCLES_TO_MS( cycles ) ( ( ( cycles ) * 1000 * RTT_CLOCK_PRESCALER ) / RTT_CLOCK_HZ )
|
||||
#define MS_TO_CYCLES( ms ) ( ( ( ms ) * RTT_CLOCK_HZ ) / ( 1000 * RTT_CLOCK_PRESCALER ) )
|
||||
|
||||
#ifndef ENABLE_INTERRUPTS
|
||||
#define ENABLE_INTERRUPTS __asm("CPSIE i")
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_INTERRUPTS
|
||||
#define DISABLE_INTERRUPTS __asm("CPSID i") /**< Disable interrupts to stop task switching in MICO RTOS. */
|
||||
#endif
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
#define RTT_CLOCK_PRESCALER (4) /* */
|
||||
#define RTT_CLOCK_HZ (32768) /* 32K / prescaler */
|
||||
#define RTT_MAX_CYCLES (64000) /* 7.8125 seconds */
|
||||
#define RC_OSC_DELAY_CYCLES (15) /* Cycles required to stabilise clock after exiting WAIT mode */
|
||||
#define JTAG_DEBUG_SLEEP_DELAY_MS (3000) /* Delay in ms to give OpenOCD enough time to halt the CPU before the CPU enter WAIT mode */
|
||||
|
||||
#define WAIT_MODE_SUPPORT
|
||||
#define WAIT_MODE_ENTER_DELAY_CYCLES (3)
|
||||
#define WAIT_MODE_EXIT_DELAY_CYCLES (34)
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
static unsigned long wait_mode_power_down_hook( unsigned long sleep_ms );
|
||||
#else
|
||||
static unsigned long idle_power_down_hook( unsigned long sleep_ms );
|
||||
#endif
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
static volatile uint32_t system_io_backup_value = 0;
|
||||
static volatile uint32_t samg5x_clock_needed_counter = 0;
|
||||
static volatile bool wake_up_interrupt_triggered = false;
|
||||
#endif /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_mcu_powersave_init(void)
|
||||
{
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
#error Not working currently, uncomment MICO_DISABLE_MCU_POWERSAVE in platform_config.h
|
||||
/* Initialise all pins to be input pull-up to save power */
|
||||
ioport_enable_port( IOPORT_PIOA, 0xffffffffU );
|
||||
ioport_set_port_mode( IOPORT_PIOA, 0xffffffffU, IOPORT_MODE_PULLUP );
|
||||
ioport_set_port_dir( IOPORT_PIOA, 0xffffffffU, IOPORT_DIR_INPUT );
|
||||
|
||||
ioport_enable_port( IOPORT_PIOB, 0xffffffffU );
|
||||
ioport_set_port_mode( IOPORT_PIOB, 0xffffffffU, IOPORT_MODE_PULLUP );
|
||||
ioport_set_port_dir( IOPORT_PIOB, 0xffffffffU, IOPORT_DIR_INPUT );
|
||||
|
||||
NVIC_DisableIRQ( RTT_IRQn );
|
||||
NVIC_ClearPendingIRQ( RTT_IRQn );
|
||||
NVIC_EnableIRQ( RTT_IRQn );
|
||||
pmc_set_fast_startup_input( PMC_FSMR_RTTAL );
|
||||
|
||||
|
||||
rtt_init( RTT, RTT_CLOCK_PRESCALER );
|
||||
rtt_write_alarm_time( RTT, 64000 );
|
||||
|
||||
|
||||
#endif /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus platform_mcu_powersave_disable( void )
|
||||
{
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
|
||||
/* Atomic operation starts */
|
||||
DISABLE_INTERRUPTS;
|
||||
|
||||
/* Increment counter to indicate CPU clock is needed preventing CPU from entering WAIT mode */
|
||||
samg5x_clock_needed_counter++;
|
||||
|
||||
/* Atomic operation ends */
|
||||
ENABLE_INTERRUPTS;
|
||||
|
||||
#endif /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus platform_mcu_powersave_enable( void )
|
||||
{
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
/* Atomic operation starts */
|
||||
DISABLE_INTERRUPTS;
|
||||
|
||||
/* Decrement counter only if it's not 0 */
|
||||
samg5x_clock_needed_counter -= ( samg5x_clock_needed_counter > 0 ) ? 1 : 0;
|
||||
|
||||
/* Atomic operation ends */
|
||||
ENABLE_INTERRUPTS;
|
||||
#endif /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus platform_powersave_enable_wakeup_pin( const platform_gpio_t* gpio )
|
||||
{
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
if ( gpio->is_wakeup_pin == true )
|
||||
{
|
||||
/* Enable wake-up pin */
|
||||
pmc_set_fast_startup_input( 1 << gpio->wakeup_pin_number );
|
||||
|
||||
if ( gpio->trigger == IOPORT_SENSE_RISING )
|
||||
{
|
||||
/* Set polarity of corresponding wake-up pin bit to active-high */
|
||||
PMC->PMC_FSPR |= (uint32_t)( 1 << gpio->wakeup_pin_number );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set polarity of corresponding wake-up pin bit to active-low */
|
||||
PMC->PMC_FSPR &= ~(uint32_t)( 1 << gpio->wakeup_pin_number );
|
||||
}
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kGeneralErr;
|
||||
}
|
||||
#else /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
return kNoErr;
|
||||
#endif
|
||||
}
|
||||
|
||||
OSStatus platform_powersave_disable_wakeup_pin( const platform_gpio_t* gpio )
|
||||
{
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
if ( gpio->is_wakeup_pin == true )
|
||||
{
|
||||
pmc_clr_fast_startup_input( 1 << gpio->wakeup_pin_number );
|
||||
return kNoErr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kGeneralErr;
|
||||
}
|
||||
#else /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
return kNoErr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void platform_mcu_powersave_exit_notify( void )
|
||||
{
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
wake_up_interrupt_triggered = true;
|
||||
#endif /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* RTOS Powersave Hooks
|
||||
******************************************************/
|
||||
|
||||
void platform_idle_hook( void )
|
||||
{
|
||||
__asm("wfi");
|
||||
}
|
||||
|
||||
uint32_t platform_power_down_hook( uint32_t sleep_ms )
|
||||
{
|
||||
#ifdef MICO_DISABLE_MCU_POWERSAVE
|
||||
/* If MCU powersave feature is disabled, enter idle mode when powerdown hook is called by the RTOS */
|
||||
return idle_power_down_hook( sleep_ms );
|
||||
|
||||
#else
|
||||
/* If MCU powersave feature is enabled, enter STOP mode when powerdown hook is called by the RTOS */
|
||||
return wait_mode_power_down_hook( sleep_ms );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Static Function Definitions
|
||||
******************************************************/
|
||||
|
||||
#ifdef MICO_DISABLE_MCU_POWERSAVE
|
||||
/* MCU Powersave is disabled */
|
||||
static unsigned long idle_power_down_hook( unsigned long sleep_ms )
|
||||
{
|
||||
UNUSED_PARAMETER( sleep_ms );
|
||||
ENABLE_INTERRUPTS;;
|
||||
__asm("wfi");
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static unsigned long wait_mode_power_down_hook( unsigned long delay_ms )
|
||||
{
|
||||
bool jtag_enabled = ( ( CoreDebug ->DHCSR & CoreDebug_DEMCR_TRCENA_Msk ) != 0 ) ? true : false;
|
||||
bool jtag_delay_elapsed = ( mico_get_time() > JTAG_DEBUG_SLEEP_DELAY_MS ) ? true : false;
|
||||
uint32_t elapsed_cycles = 0;
|
||||
|
||||
/* Criteria to enter WAIT mode
|
||||
* 1. Clock needed counter is 0 and no JTAG debugging
|
||||
* 2. Clock needed counter is 0, in JTAG debugging session, and MiCO system tick has progressed over 3 seconds.
|
||||
* This is to give OpenOCD enough time to poke the JTAG tap before the CPU enters WAIT mode.
|
||||
*/
|
||||
if ( ( samg5x_clock_needed_counter == 0 ) && ( ( jtag_enabled == false ) || ( ( jtag_enabled == true ) && ( jtag_delay_elapsed == true ) ) ) )
|
||||
{
|
||||
uint32_t total_sleep_cycles;
|
||||
uint32_t total_delay_cycles;
|
||||
|
||||
/* Start real-time timer */
|
||||
rtt_init( RTT, RTT_CLOCK_PRESCALER );
|
||||
|
||||
/* Start atomic operation */
|
||||
DISABLE_INTERRUPTS;
|
||||
|
||||
/* Ensure deep sleep bit is enabled, otherwise system doesn't go into deep sleep */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
|
||||
/* Disable SysTick */
|
||||
SysTick->CTRL &= ( ~( SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk ) );
|
||||
|
||||
/* End atomic operation */
|
||||
ENABLE_INTERRUPTS;
|
||||
|
||||
/* Expected total time CPU executing in this function (including WAIT mode time) */
|
||||
total_sleep_cycles = MS_TO_CYCLES( delay_ms );
|
||||
|
||||
/* Total cycles in WAIT mode loop */
|
||||
total_delay_cycles = ( total_sleep_cycles / RTT_MAX_CYCLES + 1 ) * RC_OSC_DELAY_CYCLES + WAIT_MODE_ENTER_DELAY_CYCLES + WAIT_MODE_EXIT_DELAY_CYCLES;
|
||||
|
||||
if ( total_sleep_cycles > total_delay_cycles )
|
||||
{
|
||||
/* Adjust total sleep cycle to exclude exit delay */
|
||||
total_sleep_cycles -= WAIT_MODE_EXIT_DELAY_CYCLES;
|
||||
|
||||
/* Prepare platform specific settings before entering powersave */
|
||||
// platform_enter_powersave();
|
||||
|
||||
///* Prepare WLAN bus before entering powersave */
|
||||
//platform_bus_enter_powersave();
|
||||
|
||||
/* Disable brownout detector */
|
||||
supc_disable_brownout_detector( SUPC );
|
||||
|
||||
/* Backup system I/0 functions and set all to GPIO to save power */
|
||||
system_io_backup_value = matrix_get_system_io();
|
||||
matrix_set_system_io( 0x0CF0 );
|
||||
|
||||
/* Switch Master Clock to Main Clock (internal fast RC oscillator) */
|
||||
pmc_switch_mck_to_mainck( PMC_PCK_PRES_CLK_1 );
|
||||
|
||||
/* Switch on internal fast RC oscillator, switch Main Clock source to internal fast RC oscillator and disables external fast crystal */
|
||||
pmc_switch_mainck_to_fastrc( CKGR_MOR_MOSCRCF_8_MHz );
|
||||
|
||||
/* Disable external fast crystal */
|
||||
pmc_osc_disable_xtal( 0 );
|
||||
|
||||
/* Disable PLLA */
|
||||
pmc_disable_pllack( );
|
||||
|
||||
/* This above process introduces certain delay. Add delay to the elapsed cycles */
|
||||
elapsed_cycles += rtt_read_timer_value( RTT );
|
||||
|
||||
while ( wake_up_interrupt_triggered == false && elapsed_cycles < total_sleep_cycles )
|
||||
{
|
||||
uint32_t current_sleep_cycles = total_sleep_cycles - elapsed_cycles;
|
||||
|
||||
/* Start real-time timer and alarm */
|
||||
rtt_init( RTT, RTT_CLOCK_PRESCALER );
|
||||
rtt_write_alarm_time( RTT, ( current_sleep_cycles > RTT_MAX_CYCLES ) ? RTT_MAX_CYCLES - RC_OSC_DELAY_CYCLES : current_sleep_cycles - RC_OSC_DELAY_CYCLES );
|
||||
|
||||
__asm("wfi");
|
||||
/* Enter WAIT mode */
|
||||
//pmc_enable_waitmode();
|
||||
|
||||
/* Clear wake-up status */
|
||||
rtt_get_status( RTT );
|
||||
|
||||
/* Add sleep time to the elapsed cycles */
|
||||
elapsed_cycles += rtt_read_timer_value( RTT );
|
||||
}
|
||||
|
||||
/* Re-enable real-time timer to time clock reinitialisation delay */
|
||||
rtt_init( RTT, RTT_CLOCK_PRESCALER );
|
||||
|
||||
/* Reinit fast clock. This takes ~19ms, but the timing has been compensated */
|
||||
init_clocks();
|
||||
|
||||
/* Disable unused clock to save power */
|
||||
pmc_osc_disable_fastrc();
|
||||
|
||||
/* Restore system I/O pins */
|
||||
matrix_set_system_io( system_io_backup_value );
|
||||
|
||||
/* Restore WLAN bus */
|
||||
//platform_bus_exit_powersave();
|
||||
|
||||
// /* Restore platform-specific settings */
|
||||
// platform_exit_powersave();
|
||||
|
||||
/* Add clock reinitialisation delay to elapsed cycles */
|
||||
elapsed_cycles += rtt_read_timer_value( RTT );
|
||||
|
||||
/* Disable RTT to save power */
|
||||
RTT->RTT_MR = (uint32_t)( 1 << 20 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Start atomic operation */
|
||||
DISABLE_INTERRUPTS;
|
||||
|
||||
/* Switch SysTick back on */
|
||||
SysTick->CTRL |= ( SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk );
|
||||
|
||||
/* Clear flag indicating interrupt triggered by wake up pin */
|
||||
wake_up_interrupt_triggered = false;
|
||||
|
||||
/* End atomic operation */
|
||||
ENABLE_INTERRUPTS;
|
||||
|
||||
/* Return total time in milliseconds */
|
||||
return CYCLES_TO_MS( elapsed_cycles );
|
||||
}
|
||||
#endif /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
|
||||
|
||||
void platform_mcu_enter_standby(uint32_t secondsToWakeup)
|
||||
{
|
||||
platform_log("unimplemented");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
* IRQ Handlers Definition & Mapping
|
||||
******************************************************/
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Interrupt Service Routine Definitions
|
||||
******************************************************/
|
||||
|
||||
#ifndef MICO_DISABLE_MCU_POWERSAVE
|
||||
MICO_RTOS_DEFINE_ISR(RTT_Handler)
|
||||
{
|
||||
// __set_PRIMASK( 1 );
|
||||
// rtt_get_status( RTT );
|
||||
// rtt_disable_interrupt( RTT, RTT_MR_ALMIEN );
|
||||
}
|
||||
#endif /* MICO_DISABLE_MCU_POWERSAVE */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,75 +1,75 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_pwm.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide PWM driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_pwm_init( const platform_pwm_t* pwm, uint32_t frequency, float duty_cycle )
|
||||
{
|
||||
UNUSED_PARAMETER(pwm);
|
||||
UNUSED_PARAMETER(frequency);
|
||||
UNUSED_PARAMETER(duty_cycle);
|
||||
platform_log("unimplemented");
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
OSStatus platform_pwm_start( const platform_pwm_t* pwm )
|
||||
{
|
||||
UNUSED_PARAMETER(pwm);
|
||||
platform_log("unimplemented");
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
OSStatus platform_pwm_stop( const platform_pwm_t* pwm )
|
||||
{
|
||||
UNUSED_PARAMETER(pwm);
|
||||
platform_log("unimplemented");
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_pwm.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide PWM driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_pwm_init( const platform_pwm_t* pwm, uint32_t frequency, float duty_cycle )
|
||||
{
|
||||
UNUSED_PARAMETER(pwm);
|
||||
UNUSED_PARAMETER(frequency);
|
||||
UNUSED_PARAMETER(duty_cycle);
|
||||
platform_log("unimplemented");
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
OSStatus platform_pwm_start( const platform_pwm_t* pwm )
|
||||
{
|
||||
UNUSED_PARAMETER(pwm);
|
||||
platform_log("unimplemented");
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
OSStatus platform_pwm_stop( const platform_pwm_t* pwm )
|
||||
{
|
||||
UNUSED_PARAMETER(pwm);
|
||||
platform_log("unimplemented");
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,75 +1,75 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_rng.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide RNG driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
/******************************************************
|
||||
* Macros
|
||||
******************************************************/
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Variables
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_random_number_read( void *inBuffer, int inByteCount )
|
||||
{
|
||||
// PLATFORM_TO_DO
|
||||
// PLATFORM_TO_DO
|
||||
int idx;
|
||||
uint32_t *pWord = inBuffer;
|
||||
uint32_t tempRDM;
|
||||
uint8_t *pByte = NULL;
|
||||
int inWordCount;
|
||||
int remainByteCount;
|
||||
|
||||
inWordCount = inByteCount/4;
|
||||
remainByteCount = inByteCount%4;
|
||||
pByte = (uint8_t *)pWord+inWordCount*4;
|
||||
|
||||
for(idx = 0; idx<inWordCount; idx++, pWord++){
|
||||
srand(mico_rtos_get_time());
|
||||
*pWord = rand();
|
||||
}
|
||||
|
||||
if(remainByteCount){
|
||||
srand(mico_rtos_get_time());
|
||||
tempRDM = rand();
|
||||
memcpy(pByte, &tempRDM, (size_t)remainByteCount);
|
||||
}
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_rng.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide RNG driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
/******************************************************
|
||||
* Macros
|
||||
******************************************************/
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Variables
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_random_number_read( void *inBuffer, int inByteCount )
|
||||
{
|
||||
// PLATFORM_TO_DO
|
||||
// PLATFORM_TO_DO
|
||||
int idx;
|
||||
uint32_t *pWord = inBuffer;
|
||||
uint32_t tempRDM;
|
||||
uint8_t *pByte = NULL;
|
||||
int inWordCount;
|
||||
int remainByteCount;
|
||||
|
||||
inWordCount = inByteCount/4;
|
||||
remainByteCount = inByteCount%4;
|
||||
pByte = (uint8_t *)pWord+inWordCount*4;
|
||||
|
||||
for(idx = 0; idx<inWordCount; idx++, pWord++){
|
||||
srand(mico_rtos_get_time());
|
||||
*pWord = rand();
|
||||
}
|
||||
|
||||
if(remainByteCount){
|
||||
srand(mico_rtos_get_time());
|
||||
tempRDM = rand();
|
||||
memcpy(pByte, &tempRDM, (size_t)remainByteCount);
|
||||
}
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
@@ -1,106 +1,106 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_rtc.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide RTC driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "mico.h"
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_logging.h"
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
/******************************************************
|
||||
* Macros
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Static Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_rtc_init(void)
|
||||
{
|
||||
platform_log("unimplemented");
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function will return the value of time read from the on board CPU real time clock. Time value must be given in the format of
|
||||
* the structure mico_rtc_time_t
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
*/
|
||||
OSStatus platform_rtc_get_time( platform_rtc_time_t* time)
|
||||
{
|
||||
UNUSED_PARAMETER(time);
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set MCU RTC time to a new value. Time value must be given in the format of
|
||||
* the structure mico_rtc_time_t
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
*/
|
||||
OSStatus platform_rtc_set_time( const mico_rtc_time_t* time )
|
||||
{
|
||||
UNUSED_PARAMETER(time);
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_rtc.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide RTC driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "mico.h"
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_logging.h"
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
/******************************************************
|
||||
* Macros
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Static Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_rtc_init(void)
|
||||
{
|
||||
platform_log("unimplemented");
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function will return the value of time read from the on board CPU real time clock. Time value must be given in the format of
|
||||
* the structure mico_rtc_time_t
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
*/
|
||||
OSStatus platform_rtc_get_time( platform_rtc_time_t* time)
|
||||
{
|
||||
UNUSED_PARAMETER(time);
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set MCU RTC time to a new value. Time value must be given in the format of
|
||||
* the structure mico_rtc_time_t
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
*/
|
||||
OSStatus platform_rtc_set_time( const mico_rtc_time_t* time )
|
||||
{
|
||||
UNUSED_PARAMETER(time);
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,238 +1,238 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_spi.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide SPI driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_spi_init( platform_spi_driver_t* driver, const platform_spi_t* peripheral, const platform_spi_config_t* config )
|
||||
{
|
||||
pdc_packet_t pdc_spi_packet;
|
||||
Pdc* spi_pdc;
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable( );
|
||||
|
||||
require_action_quiet( ( driver != NULL ) && ( peripheral != NULL ) && ( config != NULL ), exit, err = kParamErr);
|
||||
|
||||
driver->peripheral = (platform_spi_t *)peripheral;
|
||||
|
||||
spi_pdc = spi_get_pdc_base( peripheral->port );
|
||||
|
||||
/* Setup chip select pin */
|
||||
platform_gpio_init( config->chip_select, OUTPUT_PUSH_PULL );
|
||||
platform_gpio_output_high( config->chip_select );
|
||||
|
||||
/* Setup other pins */
|
||||
platform_gpio_peripheral_pin_init( peripheral->mosi_pin, ( peripheral->mosi_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
platform_gpio_peripheral_pin_init( peripheral->miso_pin, ( peripheral->miso_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
platform_gpio_peripheral_pin_init( peripheral->clock_pin, ( peripheral->clock_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
|
||||
/* Enable the peripheral and set SPI mode. */
|
||||
if( pmc_is_periph_clk_enabled( driver->peripheral->peripheral_id ) == 0 ){
|
||||
flexcom_enable( driver->peripheral->flexcom_base );
|
||||
}
|
||||
flexcom_set_opmode( driver->peripheral->flexcom_base, FLEXCOM_SPI );
|
||||
|
||||
/* Init pdc, and clear RX TX. */
|
||||
pdc_spi_packet.ul_addr = 0;
|
||||
pdc_spi_packet.ul_size = 1;
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
/* Configure an SPI peripheral. */
|
||||
spi_disable( peripheral->port );
|
||||
spi_reset( peripheral->port );
|
||||
spi_set_lastxfer( peripheral->port );
|
||||
spi_set_master_mode( peripheral->port );
|
||||
spi_disable_mode_fault_detect( peripheral->port );
|
||||
spi_set_peripheral_chip_select_value( peripheral->port, 0 );
|
||||
|
||||
spi_set_clock_polarity( peripheral->port, 0, ( ( config->mode & SPI_CLOCK_IDLE_HIGH ) ? (1) : (0) ) );
|
||||
spi_set_clock_phase( peripheral->port, 0, ( ( config->mode & SPI_CLOCK_FALLING_EDGE ) ? (1) : (0) ) );
|
||||
|
||||
spi_set_bits_per_transfer( peripheral->port, 0, SPI_CSR_BITS_8_BIT );
|
||||
spi_set_baudrate_div( peripheral->port, 0, (uint8_t)( sysclk_get_cpu_hz() / config->speed ) );
|
||||
spi_set_transfer_delay( peripheral->port, 0, 0, 0 );
|
||||
spi_enable( peripheral->port );
|
||||
pdc_disable_transfer( spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable( );
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_spi_deinit( platform_spi_driver_t* driver )
|
||||
{
|
||||
/* Disable the RX and TX PDC transfer requests */
|
||||
if( pmc_is_periph_clk_enabled( driver->peripheral->peripheral_id ) == 1 ){
|
||||
flexcom_disable( driver->peripheral->flexcom_base );
|
||||
}
|
||||
|
||||
spi_disable( driver->peripheral->port );
|
||||
spi_reset( driver->peripheral->port );
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus samg5x_spi_transfer_internal( const platform_spi_t* spi, const uint8_t* data_out, uint8_t* data_in, uint32_t data_length )
|
||||
{
|
||||
Pdc* spi_pdc = spi_get_pdc_base( spi->port );
|
||||
pdc_packet_t pdc_spi_packet;
|
||||
uint8_t junk3;
|
||||
uint16_t junk2;
|
||||
|
||||
/* Send and read */
|
||||
if( data_in != NULL && data_out != NULL )
|
||||
{
|
||||
pdc_spi_packet.ul_addr = (uint32_t)data_in;
|
||||
pdc_spi_packet.ul_size = (uint32_t)data_length;
|
||||
pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
pdc_spi_packet.ul_addr = (uint32_t)data_out;
|
||||
pdc_spi_packet.ul_size = (uint32_t)data_length;
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
/* Enable the RX and TX PDC transfer requests */
|
||||
pdc_enable_transfer( spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN );
|
||||
|
||||
/* Waiting transfer done*/
|
||||
while ( ( spi_read_status( spi->port ) & SPI_SR_RXBUFF ) == 0 )
|
||||
{
|
||||
}
|
||||
|
||||
/* Disable the RX and TX PDC transfer requests */
|
||||
pdc_disable_transfer(spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
|
||||
|
||||
pdc_spi_packet.ul_addr = 0;
|
||||
pdc_spi_packet.ul_size = 1;
|
||||
pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
}
|
||||
/* Send Only */
|
||||
else if( data_in == NULL && data_out != NULL)
|
||||
{
|
||||
pdc_spi_packet.ul_addr = (uint32_t)data_out;
|
||||
pdc_spi_packet.ul_size = (uint32_t)data_length;
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
/* Enable the TX PDC transfer requests */
|
||||
pdc_enable_transfer( spi_pdc, PERIPH_PTCR_TXTEN );
|
||||
|
||||
/* Waiting transfer done*/
|
||||
while ( ( spi_read_status( spi->port ) & SPI_SR_ENDTX ) == 0 )
|
||||
{
|
||||
}
|
||||
|
||||
/* Disable the RX and TX PDC transfer requests */
|
||||
pdc_disable_transfer(spi_pdc, PERIPH_PTCR_TXTDIS);
|
||||
|
||||
pdc_spi_packet.ul_addr = 0;
|
||||
pdc_spi_packet.ul_size = 1;
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
spi_read( spi->port, &junk2, &junk3);
|
||||
}
|
||||
/* Read Only */
|
||||
else if( data_in != NULL && data_out == NULL)
|
||||
{
|
||||
pdc_spi_packet.ul_addr = (uint32_t)data_in;
|
||||
pdc_spi_packet.ul_size = (uint32_t)data_length;
|
||||
pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
pdc_spi_packet.ul_addr = (uint32_t)data_in;
|
||||
pdc_spi_packet.ul_size = (uint32_t)data_length;
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
/* Enable the RX and TX PDC transfer requests */
|
||||
pdc_enable_transfer( spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN );
|
||||
|
||||
/* Waiting transfer done*/
|
||||
while ( ( spi_read_status( spi->port ) & SPI_SR_RXBUFF ) == 0 )
|
||||
{
|
||||
}
|
||||
|
||||
/* Disable the RX and TX PDC transfer requests */
|
||||
pdc_disable_transfer(spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
|
||||
|
||||
pdc_spi_packet.ul_addr = 0;
|
||||
pdc_spi_packet.ul_size = 1;
|
||||
pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
}
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
|
||||
OSStatus platform_spi_transfer( platform_spi_driver_t* driver, const platform_spi_config_t* config, const platform_spi_message_segment_t* segments, uint16_t number_of_segments )
|
||||
{
|
||||
int i = 0;
|
||||
OSStatus result;
|
||||
platform_mcu_powersave_disable( );
|
||||
|
||||
platform_gpio_output_low( config->chip_select );
|
||||
|
||||
for ( i = 0; i < number_of_segments; i++ )
|
||||
{
|
||||
if( segments[i].length == 0)
|
||||
continue;
|
||||
result = samg5x_spi_transfer_internal( driver->peripheral, segments[i].tx_buffer, segments[i].rx_buffer, segments[i].length );
|
||||
|
||||
if ( result != kNoErr )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
platform_gpio_output_high( config->chip_select );
|
||||
|
||||
platform_mcu_powersave_enable( );
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_spi.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide SPI driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_spi_init( platform_spi_driver_t* driver, const platform_spi_t* peripheral, const platform_spi_config_t* config )
|
||||
{
|
||||
pdc_packet_t pdc_spi_packet;
|
||||
Pdc* spi_pdc;
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable( );
|
||||
|
||||
require_action_quiet( ( driver != NULL ) && ( peripheral != NULL ) && ( config != NULL ), exit, err = kParamErr);
|
||||
|
||||
driver->peripheral = (platform_spi_t *)peripheral;
|
||||
|
||||
spi_pdc = spi_get_pdc_base( peripheral->port );
|
||||
|
||||
/* Setup chip select pin */
|
||||
platform_gpio_init( config->chip_select, OUTPUT_PUSH_PULL );
|
||||
platform_gpio_output_high( config->chip_select );
|
||||
|
||||
/* Setup other pins */
|
||||
platform_gpio_peripheral_pin_init( peripheral->mosi_pin, ( peripheral->mosi_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
platform_gpio_peripheral_pin_init( peripheral->miso_pin, ( peripheral->miso_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
platform_gpio_peripheral_pin_init( peripheral->clock_pin, ( peripheral->clock_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
|
||||
/* Enable the peripheral and set SPI mode. */
|
||||
if( pmc_is_periph_clk_enabled( driver->peripheral->peripheral_id ) == 0 ){
|
||||
flexcom_enable( driver->peripheral->flexcom_base );
|
||||
}
|
||||
flexcom_set_opmode( driver->peripheral->flexcom_base, FLEXCOM_SPI );
|
||||
|
||||
/* Init pdc, and clear RX TX. */
|
||||
pdc_spi_packet.ul_addr = 0;
|
||||
pdc_spi_packet.ul_size = 1;
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
/* Configure an SPI peripheral. */
|
||||
spi_disable( peripheral->port );
|
||||
spi_reset( peripheral->port );
|
||||
spi_set_lastxfer( peripheral->port );
|
||||
spi_set_master_mode( peripheral->port );
|
||||
spi_disable_mode_fault_detect( peripheral->port );
|
||||
spi_set_peripheral_chip_select_value( peripheral->port, 0 );
|
||||
|
||||
spi_set_clock_polarity( peripheral->port, 0, ( ( config->mode & SPI_CLOCK_IDLE_HIGH ) ? (1) : (0) ) );
|
||||
spi_set_clock_phase( peripheral->port, 0, ( ( config->mode & SPI_CLOCK_FALLING_EDGE ) ? (1) : (0) ) );
|
||||
|
||||
spi_set_bits_per_transfer( peripheral->port, 0, SPI_CSR_BITS_8_BIT );
|
||||
spi_set_baudrate_div( peripheral->port, 0, (uint8_t)( sysclk_get_cpu_hz() / config->speed ) );
|
||||
spi_set_transfer_delay( peripheral->port, 0, 0, 0 );
|
||||
spi_enable( peripheral->port );
|
||||
pdc_disable_transfer( spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable( );
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_spi_deinit( platform_spi_driver_t* driver )
|
||||
{
|
||||
/* Disable the RX and TX PDC transfer requests */
|
||||
if( pmc_is_periph_clk_enabled( driver->peripheral->peripheral_id ) == 1 ){
|
||||
flexcom_disable( driver->peripheral->flexcom_base );
|
||||
}
|
||||
|
||||
spi_disable( driver->peripheral->port );
|
||||
spi_reset( driver->peripheral->port );
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus samg5x_spi_transfer_internal( const platform_spi_t* spi, const uint8_t* data_out, uint8_t* data_in, uint32_t data_length )
|
||||
{
|
||||
Pdc* spi_pdc = spi_get_pdc_base( spi->port );
|
||||
pdc_packet_t pdc_spi_packet;
|
||||
uint8_t junk3;
|
||||
uint16_t junk2;
|
||||
|
||||
/* Send and read */
|
||||
if( data_in != NULL && data_out != NULL )
|
||||
{
|
||||
pdc_spi_packet.ul_addr = (uint32_t)data_in;
|
||||
pdc_spi_packet.ul_size = (uint32_t)data_length;
|
||||
pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
pdc_spi_packet.ul_addr = (uint32_t)data_out;
|
||||
pdc_spi_packet.ul_size = (uint32_t)data_length;
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
/* Enable the RX and TX PDC transfer requests */
|
||||
pdc_enable_transfer( spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN );
|
||||
|
||||
/* Waiting transfer done*/
|
||||
while ( ( spi_read_status( spi->port ) & SPI_SR_RXBUFF ) == 0 )
|
||||
{
|
||||
}
|
||||
|
||||
/* Disable the RX and TX PDC transfer requests */
|
||||
pdc_disable_transfer(spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
|
||||
|
||||
pdc_spi_packet.ul_addr = 0;
|
||||
pdc_spi_packet.ul_size = 1;
|
||||
pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
}
|
||||
/* Send Only */
|
||||
else if( data_in == NULL && data_out != NULL)
|
||||
{
|
||||
pdc_spi_packet.ul_addr = (uint32_t)data_out;
|
||||
pdc_spi_packet.ul_size = (uint32_t)data_length;
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
/* Enable the TX PDC transfer requests */
|
||||
pdc_enable_transfer( spi_pdc, PERIPH_PTCR_TXTEN );
|
||||
|
||||
/* Waiting transfer done*/
|
||||
while ( ( spi_read_status( spi->port ) & SPI_SR_ENDTX ) == 0 )
|
||||
{
|
||||
}
|
||||
|
||||
/* Disable the RX and TX PDC transfer requests */
|
||||
pdc_disable_transfer(spi_pdc, PERIPH_PTCR_TXTDIS);
|
||||
|
||||
pdc_spi_packet.ul_addr = 0;
|
||||
pdc_spi_packet.ul_size = 1;
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
spi_read( spi->port, &junk2, &junk3);
|
||||
}
|
||||
/* Read Only */
|
||||
else if( data_in != NULL && data_out == NULL)
|
||||
{
|
||||
pdc_spi_packet.ul_addr = (uint32_t)data_in;
|
||||
pdc_spi_packet.ul_size = (uint32_t)data_length;
|
||||
pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
pdc_spi_packet.ul_addr = (uint32_t)data_in;
|
||||
pdc_spi_packet.ul_size = (uint32_t)data_length;
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
|
||||
/* Enable the RX and TX PDC transfer requests */
|
||||
pdc_enable_transfer( spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN );
|
||||
|
||||
/* Waiting transfer done*/
|
||||
while ( ( spi_read_status( spi->port ) & SPI_SR_RXBUFF ) == 0 )
|
||||
{
|
||||
}
|
||||
|
||||
/* Disable the RX and TX PDC transfer requests */
|
||||
pdc_disable_transfer(spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
|
||||
|
||||
pdc_spi_packet.ul_addr = 0;
|
||||
pdc_spi_packet.ul_size = 1;
|
||||
pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
|
||||
}
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
|
||||
OSStatus platform_spi_transfer( platform_spi_driver_t* driver, const platform_spi_config_t* config, const platform_spi_message_segment_t* segments, uint16_t number_of_segments )
|
||||
{
|
||||
int i = 0;
|
||||
OSStatus result;
|
||||
platform_mcu_powersave_disable( );
|
||||
|
||||
platform_gpio_output_low( config->chip_select );
|
||||
|
||||
for ( i = 0; i < number_of_segments; i++ )
|
||||
{
|
||||
if( segments[i].length == 0)
|
||||
continue;
|
||||
result = samg5x_spi_transfer_internal( driver->peripheral, segments[i].tx_buffer, segments[i].rx_buffer, segments[i].length );
|
||||
|
||||
if ( result != kNoErr )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
platform_gpio_output_high( config->chip_select );
|
||||
|
||||
platform_mcu_powersave_enable( );
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,420 +1,420 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_uart.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide UART driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_peripheral.h"
|
||||
#include "platform_logging.h"
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
#define DMA_INTERRUPT_FLAGS ( DMA_IT_TC | DMA_IT_TE | DMA_IT_DME | DMA_IT_FE )
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
static IRQn_Type platform_flexcom_irq_numbers[] =
|
||||
{
|
||||
[0] = FLEXCOM0_IRQn,
|
||||
[1] = FLEXCOM1_IRQn,
|
||||
[2] = FLEXCOM2_IRQn,
|
||||
[3] = FLEXCOM3_IRQn,
|
||||
[4] = FLEXCOM4_IRQn,
|
||||
[5] = FLEXCOM5_IRQn,
|
||||
[6] = FLEXCOM6_IRQn,
|
||||
[7] = FLEXCOM7_IRQn,
|
||||
};
|
||||
|
||||
/******************************************************
|
||||
* Static Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_uart_init( platform_uart_driver_t* driver, const platform_uart_t* peripheral, const platform_uart_config_t* config, ring_buffer_t* optional_ring_buffer )
|
||||
{
|
||||
pdc_packet_t pdc_uart_packet, pdc_uart_tx_packet;
|
||||
OSStatus err = kNoErr;
|
||||
sam_usart_opt_t settings;
|
||||
bool hardware_shaking = false;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
require_action_quiet( ( driver != NULL ) && ( peripheral != NULL ) && ( config != NULL ), exit, err = kParamErr);
|
||||
require_action_quiet( (optional_ring_buffer->buffer != NULL ) && (optional_ring_buffer->size != 0), exit, err = kUnsupportedErr);
|
||||
|
||||
driver->rx_size = 0;
|
||||
driver->tx_size = 0;
|
||||
driver->rx_ring_buffer = optional_ring_buffer;
|
||||
driver->last_transmit_result = kNoErr;
|
||||
driver->last_receive_result = kNoErr;
|
||||
driver->peripheral = (platform_uart_t*)peripheral;
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_init_semaphore( &driver->tx_complete, 1 );
|
||||
mico_rtos_init_semaphore( &driver->rx_complete, 1 );
|
||||
mico_rtos_init_semaphore( &driver->sem_wakeup, 1 );
|
||||
mico_rtos_init_mutex ( &driver->tx_mutex );
|
||||
#else
|
||||
driver->tx_complete = false;
|
||||
driver->rx_complete = false;
|
||||
#endif
|
||||
|
||||
/* Set Tx and Rx pin mode to UART peripheral */
|
||||
platform_gpio_peripheral_pin_init( peripheral->tx_pin, ( peripheral->tx_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
platform_gpio_peripheral_pin_init( peripheral->rx_pin, ( peripheral->rx_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
|
||||
/* Init CTS and RTS pins (if available) */
|
||||
if ( peripheral->cts_pin != NULL && (config->flow_control == FLOW_CONTROL_CTS || config->flow_control == FLOW_CONTROL_CTS_RTS) )
|
||||
{
|
||||
hardware_shaking = true;
|
||||
platform_gpio_peripheral_pin_init( peripheral->cts_pin, ( peripheral->cts_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
}
|
||||
|
||||
if ( peripheral->rts_pin != NULL && (config->flow_control == FLOW_CONTROL_CTS || config->flow_control == FLOW_CONTROL_CTS_RTS) )
|
||||
{
|
||||
hardware_shaking = true;
|
||||
platform_gpio_peripheral_pin_init( peripheral->rts_pin, ( peripheral->rts_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
}
|
||||
|
||||
/* Enable the clock. */
|
||||
if( pmc_is_periph_clk_enabled( peripheral->peripheral_id ) == 0 ){
|
||||
flexcom_enable( peripheral->flexcom_base );
|
||||
}
|
||||
flexcom_set_opmode( peripheral->flexcom_base, FLEXCOM_USART );
|
||||
|
||||
/* Enable the receiver and transmitter. */
|
||||
usart_reset_tx( peripheral->port );
|
||||
usart_reset_rx( peripheral->port );
|
||||
|
||||
/* Disable all the interrupts. */
|
||||
usart_disable_interrupt( peripheral->port, 0xffffffff );
|
||||
|
||||
switch ( config->parity ) {
|
||||
case NO_PARITY:
|
||||
settings.parity_type = US_MR_PAR_NO;
|
||||
break;
|
||||
case EVEN_PARITY:
|
||||
settings.parity_type = US_MR_PAR_EVEN;
|
||||
break;
|
||||
case ODD_PARITY:
|
||||
settings.parity_type = US_MR_PAR_ODD;
|
||||
break;
|
||||
default:
|
||||
err = kParamErr;
|
||||
goto exit;
|
||||
}
|
||||
switch ( config->data_width) {
|
||||
case DATA_WIDTH_5BIT:
|
||||
settings.char_length = US_MR_CHRL_5_BIT;
|
||||
break;
|
||||
case DATA_WIDTH_6BIT:
|
||||
settings.char_length = US_MR_CHRL_6_BIT;
|
||||
break;
|
||||
case DATA_WIDTH_7BIT:
|
||||
settings.char_length = US_MR_CHRL_7_BIT;
|
||||
break;
|
||||
case DATA_WIDTH_8BIT:
|
||||
settings.char_length = US_MR_CHRL_8_BIT;
|
||||
break;
|
||||
case DATA_WIDTH_9BIT:
|
||||
settings.char_length = US_MR_MODE9;
|
||||
break;
|
||||
default:
|
||||
err = kParamErr;
|
||||
goto exit;
|
||||
}
|
||||
settings.baudrate = config->baud_rate;
|
||||
settings.stop_bits = ( config->stop_bits == STOP_BITS_1 ) ? US_MR_NBSTOP_1_BIT : US_MR_NBSTOP_2_BIT;
|
||||
settings.channel_mode= US_MR_CHMODE_NORMAL;
|
||||
|
||||
/* Configure USART in serial mode. */
|
||||
if (!hardware_shaking) {
|
||||
usart_init_rs232( peripheral->port, &settings, sysclk_get_peripheral_hz());
|
||||
} else {
|
||||
usart_init_hw_handshaking( peripheral->port, &settings, sysclk_get_peripheral_hz());
|
||||
}
|
||||
|
||||
/* Enable uart interrupt */
|
||||
NVIC_SetPriority( platform_flexcom_irq_numbers[peripheral->uart_id], 0x06 );
|
||||
NVIC_EnableIRQ( platform_flexcom_irq_numbers[peripheral->uart_id] );
|
||||
|
||||
/* Enable PDC transmit */
|
||||
pdc_enable_transfer( usart_get_pdc_base( peripheral->port ), PERIPH_PTCR_TXTEN | PERIPH_PTCR_RXTEN );
|
||||
pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->port ), PERIPH_PTCR_TXTDIS );
|
||||
|
||||
pdc_uart_packet.ul_addr = (uint32_t)driver->rx_ring_buffer->buffer;
|
||||
pdc_uart_packet.ul_size = (uint32_t)driver->rx_ring_buffer->size;
|
||||
pdc_rx_init( usart_get_pdc_base( peripheral->port ), &pdc_uart_packet, &pdc_uart_packet );
|
||||
|
||||
pdc_uart_tx_packet.ul_addr = (uint32_t)0;
|
||||
pdc_uart_tx_packet.ul_size = (uint32_t)1;
|
||||
|
||||
pdc_tx_init( usart_get_pdc_base( driver->peripheral->port ), &pdc_uart_tx_packet, NULL );
|
||||
|
||||
usart_enable_interrupt( peripheral->port, US_IER_ENDRX | US_IER_RXBUFF | US_IER_RXRDY | US_IER_ENDTX );
|
||||
|
||||
/* Enable the receiver and transmitter. */
|
||||
usart_enable_tx( peripheral->port );
|
||||
usart_enable_rx( peripheral->port );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable( );
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_uart_deinit( platform_uart_driver_t* driver )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
require_action_quiet( ( driver != NULL ), exit, err = kParamErr);
|
||||
|
||||
usart_disable_interrupt( driver->peripheral->port, 0xffffffff );
|
||||
|
||||
NVIC_DisableIRQ( platform_flexcom_irq_numbers[driver->peripheral->uart_id] );
|
||||
|
||||
pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->port ), PERIPH_PTCR_TXTDIS | PERIPH_PTCR_RXTDIS );
|
||||
|
||||
usart_disable_tx( driver->peripheral->port );
|
||||
usart_disable_rx( driver->peripheral->port );
|
||||
|
||||
if( pmc_is_periph_clk_enabled( driver->peripheral->peripheral_id ) == 1 ){
|
||||
flexcom_disable( driver->peripheral->flexcom_base );
|
||||
}
|
||||
|
||||
platform_gpio_deinit( driver->peripheral->tx_pin );
|
||||
platform_gpio_deinit( driver->peripheral->rx_pin );
|
||||
|
||||
if ( driver->peripheral->cts_pin != NULL )
|
||||
{
|
||||
platform_gpio_deinit( driver->peripheral->cts_pin );
|
||||
}
|
||||
|
||||
if ( driver->peripheral->rts_pin != NULL )
|
||||
{
|
||||
platform_gpio_deinit( driver->peripheral->rts_pin );
|
||||
}
|
||||
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_deinit_semaphore(&driver->rx_complete);
|
||||
mico_rtos_deinit_semaphore(&driver->tx_complete);
|
||||
#endif
|
||||
|
||||
driver->peripheral = NULL;
|
||||
memset( driver, 0, sizeof(platform_uart_driver_t) );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_uart_transmit_bytes( platform_uart_driver_t* driver, const uint8_t* data_out, uint32_t size )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
pdc_packet_t pdc_uart_packet;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_lock_mutex( &driver->tx_mutex );
|
||||
#endif
|
||||
|
||||
require_action_quiet( ( driver != NULL ) && ( data_out != NULL ) && ( size != 0 ), exit, err = kParamErr);
|
||||
|
||||
/* reset DMA transmission result. the result is assigned in interrupt handler */
|
||||
driver->last_transmit_result = kGeneralErr;
|
||||
driver->tx_size = size;
|
||||
|
||||
pdc_uart_packet.ul_addr = (uint32_t) data_out;
|
||||
pdc_uart_packet.ul_size = size;
|
||||
pdc_tx_init( usart_get_pdc_base( driver->peripheral->port ), &pdc_uart_packet, NULL);
|
||||
|
||||
/* Enable Tx DMA transmission */
|
||||
pdc_enable_transfer( usart_get_pdc_base( driver->peripheral->port ), PERIPH_PTCR_TXTEN );
|
||||
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_get_semaphore( &driver->tx_complete, MICO_NEVER_TIMEOUT );
|
||||
#else
|
||||
while( driver->tx_complete == false);
|
||||
driver->tx_complete = false;
|
||||
#endif
|
||||
|
||||
exit:
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_unlock_mutex( &driver->tx_mutex );
|
||||
#endif
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_uart_receive_bytes( platform_uart_driver_t* driver, uint8_t* data_in, uint32_t expected_data_size, uint32_t timeout_ms )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
uint32_t transfer_size;
|
||||
|
||||
//platform_mcu_powersave_disable();
|
||||
|
||||
require_action_quiet( ( driver != NULL ) && ( data_in != NULL ) && ( expected_data_size != 0 ), exit, err = kParamErr);
|
||||
require_action_quiet( driver->rx_ring_buffer != NULL , exit, err = kUnsupportedErr);
|
||||
|
||||
while ( expected_data_size != 0 )
|
||||
{
|
||||
transfer_size = MIN(driver->rx_ring_buffer->size / 2, expected_data_size);
|
||||
|
||||
/* Check if ring buffer already contains the required amount of data. */
|
||||
if ( transfer_size > ring_buffer_used_space( driver->rx_ring_buffer ) )
|
||||
{
|
||||
/* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */
|
||||
driver->rx_size = transfer_size;
|
||||
|
||||
#ifndef NO_MICO_RTOS
|
||||
if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout_ms ) != kNoErr )
|
||||
{
|
||||
driver->rx_size = 0;
|
||||
err = kTimeoutErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Reset rx_size to prevent semaphore being set while nothing waits for the data */
|
||||
driver->rx_size = 0;
|
||||
#else
|
||||
driver->rx_complete = false;
|
||||
int delay_start = mico_rtos_get_time();
|
||||
while(driver->rx_complete == false){
|
||||
if(mico_rtos_get_time() >= delay_start + timeout_ms && timeout_ms != MICO_NEVER_TIMEOUT){
|
||||
driver->rx_size = 0;
|
||||
err = kTimeoutErr;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
driver->rx_size = 0;
|
||||
#endif
|
||||
}
|
||||
expected_data_size -= transfer_size;
|
||||
|
||||
// Grab data from the buffer
|
||||
do
|
||||
{
|
||||
uint8_t* available_data;
|
||||
uint32_t bytes_available;
|
||||
|
||||
ring_buffer_get_data( driver->rx_ring_buffer, &available_data, &bytes_available );
|
||||
bytes_available = MIN( bytes_available, transfer_size );
|
||||
memcpy( data_in, available_data, bytes_available );
|
||||
transfer_size -= bytes_available;
|
||||
data_in = ( (uint8_t*)data_in + bytes_available );
|
||||
ring_buffer_consume( driver->rx_ring_buffer, bytes_available );
|
||||
}
|
||||
while ( transfer_size != 0 );
|
||||
}
|
||||
|
||||
require_action( expected_data_size == 0, exit, err = kReadErr);
|
||||
|
||||
exit:
|
||||
//platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
uint32_t platform_uart_get_length_in_buffer( platform_uart_driver_t* driver )
|
||||
{
|
||||
return ring_buffer_used_space( driver->rx_ring_buffer );
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* Interrupt Service Routines
|
||||
******************************************************/
|
||||
|
||||
void platform_uart_irq( platform_uart_driver_t* driver )
|
||||
{
|
||||
uint32_t status = usart_get_status( driver->peripheral->port );
|
||||
uint32_t mask = usart_get_interrupt_mask( driver->peripheral->port );
|
||||
Pdc* pdc_register = usart_get_pdc_base( driver->peripheral->port );
|
||||
|
||||
/* ENDTX flag is set when Tx DMA transfer is done */
|
||||
if ( ( mask & US_IMR_ENDTX ) && ( status & US_CSR_ENDTX ) )
|
||||
{
|
||||
pdc_packet_t dma_packet;
|
||||
|
||||
/* ENDTX is cleared when TCR or TNCR is set to a non-zero value, which effectively
|
||||
* starts another Tx DMA transaction. To work around this, disable Tx before
|
||||
* performing a dummy Tx init.
|
||||
*/
|
||||
pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->port ), PERIPH_PTCR_TXTDIS );
|
||||
|
||||
dma_packet.ul_addr = (uint32_t)0;
|
||||
dma_packet.ul_size = (uint32_t)1;
|
||||
|
||||
pdc_tx_init( usart_get_pdc_base( driver->peripheral->port ), &dma_packet, NULL );
|
||||
|
||||
/* Notifies waiting thread that Tx DMA transfer is complete */
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_set_semaphore( &driver->tx_complete );
|
||||
#else
|
||||
driver->tx_complete = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ENDRX flag is set when RCR is 0. RNPR and RNCR values are then copied into
|
||||
* RPR and RCR, respectively, while the RX tranfer continues. We now need to
|
||||
* prepare RNPR and RNCR for the next iteration.
|
||||
*/
|
||||
if ( ( mask & US_IMR_ENDRX ) && ( status & US_CSR_ENDRX ) )
|
||||
{
|
||||
pdc_register->PERIPH_RNPR = (uint32_t)driver->rx_ring_buffer->buffer;
|
||||
pdc_register->PERIPH_RNCR = (uint32_t)driver->rx_ring_buffer->size;
|
||||
}
|
||||
|
||||
/* RXRDY interrupt is triggered and flag is set when a new character has been
|
||||
* received but not yet read from the US_RHR. When this interrupt executes,
|
||||
* the DMA engine already read the character out from the US_RHR and RXRDY flag
|
||||
* is no longer asserted. The code below updates the ring buffer parameters
|
||||
* to keep them current
|
||||
*/
|
||||
if ( ( mask & US_IMR_RXRDY ) )
|
||||
{
|
||||
driver->rx_ring_buffer->tail = driver->rx_ring_buffer->size - pdc_register->PERIPH_RCR;
|
||||
|
||||
// Notify thread if sufficient data are available
|
||||
if ( ( driver->rx_size > 0 ) && ( ring_buffer_used_space( driver->rx_ring_buffer ) >= driver->rx_size ) )
|
||||
{
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_set_semaphore( &driver->rx_complete );
|
||||
#else
|
||||
driver->rx_complete = true;
|
||||
#endif
|
||||
driver->rx_size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_uart.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide UART driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_peripheral.h"
|
||||
#include "platform_logging.h"
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
#define DMA_INTERRUPT_FLAGS ( DMA_IT_TC | DMA_IT_TE | DMA_IT_DME | DMA_IT_FE )
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
static IRQn_Type platform_flexcom_irq_numbers[] =
|
||||
{
|
||||
[0] = FLEXCOM0_IRQn,
|
||||
[1] = FLEXCOM1_IRQn,
|
||||
[2] = FLEXCOM2_IRQn,
|
||||
[3] = FLEXCOM3_IRQn,
|
||||
[4] = FLEXCOM4_IRQn,
|
||||
[5] = FLEXCOM5_IRQn,
|
||||
[6] = FLEXCOM6_IRQn,
|
||||
[7] = FLEXCOM7_IRQn,
|
||||
};
|
||||
|
||||
/******************************************************
|
||||
* Static Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_uart_init( platform_uart_driver_t* driver, const platform_uart_t* peripheral, const platform_uart_config_t* config, ring_buffer_t* optional_ring_buffer )
|
||||
{
|
||||
pdc_packet_t pdc_uart_packet, pdc_uart_tx_packet;
|
||||
OSStatus err = kNoErr;
|
||||
sam_usart_opt_t settings;
|
||||
bool hardware_shaking = false;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
require_action_quiet( ( driver != NULL ) && ( peripheral != NULL ) && ( config != NULL ), exit, err = kParamErr);
|
||||
require_action_quiet( (optional_ring_buffer->buffer != NULL ) && (optional_ring_buffer->size != 0), exit, err = kUnsupportedErr);
|
||||
|
||||
driver->rx_size = 0;
|
||||
driver->tx_size = 0;
|
||||
driver->rx_ring_buffer = optional_ring_buffer;
|
||||
driver->last_transmit_result = kNoErr;
|
||||
driver->last_receive_result = kNoErr;
|
||||
driver->peripheral = (platform_uart_t*)peripheral;
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_init_semaphore( &driver->tx_complete, 1 );
|
||||
mico_rtos_init_semaphore( &driver->rx_complete, 1 );
|
||||
mico_rtos_init_semaphore( &driver->sem_wakeup, 1 );
|
||||
mico_rtos_init_mutex ( &driver->tx_mutex );
|
||||
#else
|
||||
driver->tx_complete = false;
|
||||
driver->rx_complete = false;
|
||||
#endif
|
||||
|
||||
/* Set Tx and Rx pin mode to UART peripheral */
|
||||
platform_gpio_peripheral_pin_init( peripheral->tx_pin, ( peripheral->tx_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
platform_gpio_peripheral_pin_init( peripheral->rx_pin, ( peripheral->rx_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
|
||||
/* Init CTS and RTS pins (if available) */
|
||||
if ( peripheral->cts_pin != NULL && (config->flow_control == FLOW_CONTROL_CTS || config->flow_control == FLOW_CONTROL_CTS_RTS) )
|
||||
{
|
||||
hardware_shaking = true;
|
||||
platform_gpio_peripheral_pin_init( peripheral->cts_pin, ( peripheral->cts_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
}
|
||||
|
||||
if ( peripheral->rts_pin != NULL && (config->flow_control == FLOW_CONTROL_CTS || config->flow_control == FLOW_CONTROL_CTS_RTS) )
|
||||
{
|
||||
hardware_shaking = true;
|
||||
platform_gpio_peripheral_pin_init( peripheral->rts_pin, ( peripheral->rts_pin_mux_mode | IOPORT_MODE_PULLUP ) );
|
||||
}
|
||||
|
||||
/* Enable the clock. */
|
||||
if( pmc_is_periph_clk_enabled( peripheral->peripheral_id ) == 0 ){
|
||||
flexcom_enable( peripheral->flexcom_base );
|
||||
}
|
||||
flexcom_set_opmode( peripheral->flexcom_base, FLEXCOM_USART );
|
||||
|
||||
/* Enable the receiver and transmitter. */
|
||||
usart_reset_tx( peripheral->port );
|
||||
usart_reset_rx( peripheral->port );
|
||||
|
||||
/* Disable all the interrupts. */
|
||||
usart_disable_interrupt( peripheral->port, 0xffffffff );
|
||||
|
||||
switch ( config->parity ) {
|
||||
case NO_PARITY:
|
||||
settings.parity_type = US_MR_PAR_NO;
|
||||
break;
|
||||
case EVEN_PARITY:
|
||||
settings.parity_type = US_MR_PAR_EVEN;
|
||||
break;
|
||||
case ODD_PARITY:
|
||||
settings.parity_type = US_MR_PAR_ODD;
|
||||
break;
|
||||
default:
|
||||
err = kParamErr;
|
||||
goto exit;
|
||||
}
|
||||
switch ( config->data_width) {
|
||||
case DATA_WIDTH_5BIT:
|
||||
settings.char_length = US_MR_CHRL_5_BIT;
|
||||
break;
|
||||
case DATA_WIDTH_6BIT:
|
||||
settings.char_length = US_MR_CHRL_6_BIT;
|
||||
break;
|
||||
case DATA_WIDTH_7BIT:
|
||||
settings.char_length = US_MR_CHRL_7_BIT;
|
||||
break;
|
||||
case DATA_WIDTH_8BIT:
|
||||
settings.char_length = US_MR_CHRL_8_BIT;
|
||||
break;
|
||||
case DATA_WIDTH_9BIT:
|
||||
settings.char_length = US_MR_MODE9;
|
||||
break;
|
||||
default:
|
||||
err = kParamErr;
|
||||
goto exit;
|
||||
}
|
||||
settings.baudrate = config->baud_rate;
|
||||
settings.stop_bits = ( config->stop_bits == STOP_BITS_1 ) ? US_MR_NBSTOP_1_BIT : US_MR_NBSTOP_2_BIT;
|
||||
settings.channel_mode= US_MR_CHMODE_NORMAL;
|
||||
|
||||
/* Configure USART in serial mode. */
|
||||
if (!hardware_shaking) {
|
||||
usart_init_rs232( peripheral->port, &settings, sysclk_get_peripheral_hz());
|
||||
} else {
|
||||
usart_init_hw_handshaking( peripheral->port, &settings, sysclk_get_peripheral_hz());
|
||||
}
|
||||
|
||||
/* Enable uart interrupt */
|
||||
NVIC_SetPriority( platform_flexcom_irq_numbers[peripheral->uart_id], 0x06 );
|
||||
NVIC_EnableIRQ( platform_flexcom_irq_numbers[peripheral->uart_id] );
|
||||
|
||||
/* Enable PDC transmit */
|
||||
pdc_enable_transfer( usart_get_pdc_base( peripheral->port ), PERIPH_PTCR_TXTEN | PERIPH_PTCR_RXTEN );
|
||||
pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->port ), PERIPH_PTCR_TXTDIS );
|
||||
|
||||
pdc_uart_packet.ul_addr = (uint32_t)driver->rx_ring_buffer->buffer;
|
||||
pdc_uart_packet.ul_size = (uint32_t)driver->rx_ring_buffer->size;
|
||||
pdc_rx_init( usart_get_pdc_base( peripheral->port ), &pdc_uart_packet, &pdc_uart_packet );
|
||||
|
||||
pdc_uart_tx_packet.ul_addr = (uint32_t)0;
|
||||
pdc_uart_tx_packet.ul_size = (uint32_t)1;
|
||||
|
||||
pdc_tx_init( usart_get_pdc_base( driver->peripheral->port ), &pdc_uart_tx_packet, NULL );
|
||||
|
||||
usart_enable_interrupt( peripheral->port, US_IER_ENDRX | US_IER_RXBUFF | US_IER_RXRDY | US_IER_ENDTX );
|
||||
|
||||
/* Enable the receiver and transmitter. */
|
||||
usart_enable_tx( peripheral->port );
|
||||
usart_enable_rx( peripheral->port );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable( );
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_uart_deinit( platform_uart_driver_t* driver )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
require_action_quiet( ( driver != NULL ), exit, err = kParamErr);
|
||||
|
||||
usart_disable_interrupt( driver->peripheral->port, 0xffffffff );
|
||||
|
||||
NVIC_DisableIRQ( platform_flexcom_irq_numbers[driver->peripheral->uart_id] );
|
||||
|
||||
pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->port ), PERIPH_PTCR_TXTDIS | PERIPH_PTCR_RXTDIS );
|
||||
|
||||
usart_disable_tx( driver->peripheral->port );
|
||||
usart_disable_rx( driver->peripheral->port );
|
||||
|
||||
if( pmc_is_periph_clk_enabled( driver->peripheral->peripheral_id ) == 1 ){
|
||||
flexcom_disable( driver->peripheral->flexcom_base );
|
||||
}
|
||||
|
||||
platform_gpio_deinit( driver->peripheral->tx_pin );
|
||||
platform_gpio_deinit( driver->peripheral->rx_pin );
|
||||
|
||||
if ( driver->peripheral->cts_pin != NULL )
|
||||
{
|
||||
platform_gpio_deinit( driver->peripheral->cts_pin );
|
||||
}
|
||||
|
||||
if ( driver->peripheral->rts_pin != NULL )
|
||||
{
|
||||
platform_gpio_deinit( driver->peripheral->rts_pin );
|
||||
}
|
||||
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_deinit_semaphore(&driver->rx_complete);
|
||||
mico_rtos_deinit_semaphore(&driver->tx_complete);
|
||||
#endif
|
||||
|
||||
driver->peripheral = NULL;
|
||||
memset( driver, 0, sizeof(platform_uart_driver_t) );
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_uart_transmit_bytes( platform_uart_driver_t* driver, const uint8_t* data_out, uint32_t size )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
pdc_packet_t pdc_uart_packet;
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_lock_mutex( &driver->tx_mutex );
|
||||
#endif
|
||||
|
||||
require_action_quiet( ( driver != NULL ) && ( data_out != NULL ) && ( size != 0 ), exit, err = kParamErr);
|
||||
|
||||
/* reset DMA transmission result. the result is assigned in interrupt handler */
|
||||
driver->last_transmit_result = kGeneralErr;
|
||||
driver->tx_size = size;
|
||||
|
||||
pdc_uart_packet.ul_addr = (uint32_t) data_out;
|
||||
pdc_uart_packet.ul_size = size;
|
||||
pdc_tx_init( usart_get_pdc_base( driver->peripheral->port ), &pdc_uart_packet, NULL);
|
||||
|
||||
/* Enable Tx DMA transmission */
|
||||
pdc_enable_transfer( usart_get_pdc_base( driver->peripheral->port ), PERIPH_PTCR_TXTEN );
|
||||
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_get_semaphore( &driver->tx_complete, MICO_NEVER_TIMEOUT );
|
||||
#else
|
||||
while( driver->tx_complete == false);
|
||||
driver->tx_complete = false;
|
||||
#endif
|
||||
|
||||
exit:
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_unlock_mutex( &driver->tx_mutex );
|
||||
#endif
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_uart_receive_bytes( platform_uart_driver_t* driver, uint8_t* data_in, uint32_t expected_data_size, uint32_t timeout_ms )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
uint32_t transfer_size;
|
||||
|
||||
//platform_mcu_powersave_disable();
|
||||
|
||||
require_action_quiet( ( driver != NULL ) && ( data_in != NULL ) && ( expected_data_size != 0 ), exit, err = kParamErr);
|
||||
require_action_quiet( driver->rx_ring_buffer != NULL , exit, err = kUnsupportedErr);
|
||||
|
||||
while ( expected_data_size != 0 )
|
||||
{
|
||||
transfer_size = MIN(driver->rx_ring_buffer->size / 2, expected_data_size);
|
||||
|
||||
/* Check if ring buffer already contains the required amount of data. */
|
||||
if ( transfer_size > ring_buffer_used_space( driver->rx_ring_buffer ) )
|
||||
{
|
||||
/* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */
|
||||
driver->rx_size = transfer_size;
|
||||
|
||||
#ifndef NO_MICO_RTOS
|
||||
if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout_ms ) != kNoErr )
|
||||
{
|
||||
driver->rx_size = 0;
|
||||
err = kTimeoutErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Reset rx_size to prevent semaphore being set while nothing waits for the data */
|
||||
driver->rx_size = 0;
|
||||
#else
|
||||
driver->rx_complete = false;
|
||||
int delay_start = mico_rtos_get_time();
|
||||
while(driver->rx_complete == false){
|
||||
if(mico_rtos_get_time() >= delay_start + timeout_ms && timeout_ms != MICO_NEVER_TIMEOUT){
|
||||
driver->rx_size = 0;
|
||||
err = kTimeoutErr;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
driver->rx_size = 0;
|
||||
#endif
|
||||
}
|
||||
expected_data_size -= transfer_size;
|
||||
|
||||
// Grab data from the buffer
|
||||
do
|
||||
{
|
||||
uint8_t* available_data;
|
||||
uint32_t bytes_available;
|
||||
|
||||
ring_buffer_get_data( driver->rx_ring_buffer, &available_data, &bytes_available );
|
||||
bytes_available = MIN( bytes_available, transfer_size );
|
||||
memcpy( data_in, available_data, bytes_available );
|
||||
transfer_size -= bytes_available;
|
||||
data_in = ( (uint8_t*)data_in + bytes_available );
|
||||
ring_buffer_consume( driver->rx_ring_buffer, bytes_available );
|
||||
}
|
||||
while ( transfer_size != 0 );
|
||||
}
|
||||
|
||||
require_action( expected_data_size == 0, exit, err = kReadErr);
|
||||
|
||||
exit:
|
||||
//platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
uint32_t platform_uart_get_length_in_buffer( platform_uart_driver_t* driver )
|
||||
{
|
||||
return ring_buffer_used_space( driver->rx_ring_buffer );
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* Interrupt Service Routines
|
||||
******************************************************/
|
||||
|
||||
void platform_uart_irq( platform_uart_driver_t* driver )
|
||||
{
|
||||
uint32_t status = usart_get_status( driver->peripheral->port );
|
||||
uint32_t mask = usart_get_interrupt_mask( driver->peripheral->port );
|
||||
Pdc* pdc_register = usart_get_pdc_base( driver->peripheral->port );
|
||||
|
||||
/* ENDTX flag is set when Tx DMA transfer is done */
|
||||
if ( ( mask & US_IMR_ENDTX ) && ( status & US_CSR_ENDTX ) )
|
||||
{
|
||||
pdc_packet_t dma_packet;
|
||||
|
||||
/* ENDTX is cleared when TCR or TNCR is set to a non-zero value, which effectively
|
||||
* starts another Tx DMA transaction. To work around this, disable Tx before
|
||||
* performing a dummy Tx init.
|
||||
*/
|
||||
pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->port ), PERIPH_PTCR_TXTDIS );
|
||||
|
||||
dma_packet.ul_addr = (uint32_t)0;
|
||||
dma_packet.ul_size = (uint32_t)1;
|
||||
|
||||
pdc_tx_init( usart_get_pdc_base( driver->peripheral->port ), &dma_packet, NULL );
|
||||
|
||||
/* Notifies waiting thread that Tx DMA transfer is complete */
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_set_semaphore( &driver->tx_complete );
|
||||
#else
|
||||
driver->tx_complete = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ENDRX flag is set when RCR is 0. RNPR and RNCR values are then copied into
|
||||
* RPR and RCR, respectively, while the RX tranfer continues. We now need to
|
||||
* prepare RNPR and RNCR for the next iteration.
|
||||
*/
|
||||
if ( ( mask & US_IMR_ENDRX ) && ( status & US_CSR_ENDRX ) )
|
||||
{
|
||||
pdc_register->PERIPH_RNPR = (uint32_t)driver->rx_ring_buffer->buffer;
|
||||
pdc_register->PERIPH_RNCR = (uint32_t)driver->rx_ring_buffer->size;
|
||||
}
|
||||
|
||||
/* RXRDY interrupt is triggered and flag is set when a new character has been
|
||||
* received but not yet read from the US_RHR. When this interrupt executes,
|
||||
* the DMA engine already read the character out from the US_RHR and RXRDY flag
|
||||
* is no longer asserted. The code below updates the ring buffer parameters
|
||||
* to keep them current
|
||||
*/
|
||||
if ( ( mask & US_IMR_RXRDY ) )
|
||||
{
|
||||
driver->rx_ring_buffer->tail = driver->rx_ring_buffer->size - pdc_register->PERIPH_RCR;
|
||||
|
||||
// Notify thread if sufficient data are available
|
||||
if ( ( driver->rx_size > 0 ) && ( ring_buffer_used_space( driver->rx_ring_buffer ) >= driver->rx_size ) )
|
||||
{
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_set_semaphore( &driver->rx_complete );
|
||||
#else
|
||||
driver->rx_complete = true;
|
||||
#endif
|
||||
driver->rx_size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,70 +1,70 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_watchdog.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide WDG driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_logging.h"
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_watchdog_init( uint32_t timeout_ms )
|
||||
{
|
||||
UNUSED_PARAMETER( timeout_ms );
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
OSStatus MicoWdgFinalize( void )
|
||||
{
|
||||
// PLATFORM_TO_DO
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus platform_watchdog_kick( void )
|
||||
{
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
bool platform_watchdog_check_last_reset( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file platform_watchdog.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide WDG driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_logging.h"
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
OSStatus platform_watchdog_init( uint32_t timeout_ms )
|
||||
{
|
||||
UNUSED_PARAMETER( timeout_ms );
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
OSStatus MicoWdgFinalize( void )
|
||||
{
|
||||
// PLATFORM_TO_DO
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus platform_watchdog_kick( void )
|
||||
{
|
||||
return kUnsupportedErr;
|
||||
}
|
||||
|
||||
bool platform_watchdog_check_last_reset( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user