atmel-samd: Add support for SPI.
Also separate out the ASF config headers that are shared across all boards.
This commit is contained in:
parent
6986aa9aa2
commit
011056af15
@ -32,6 +32,7 @@ INC += -I..
|
||||
INC += -I../lib/mp-readline
|
||||
INC += -I../lib/timeutils
|
||||
INC += -Icommon-hal/modules/
|
||||
INC += -Iasf_conf/
|
||||
INC += -Iasf/common/boards/
|
||||
INC += -Iasf/common/services/sleepmgr/
|
||||
INC += -Iasf/common/services/storage/ctrl_access/
|
||||
@ -117,6 +118,7 @@ SRC_ASF = $(addprefix asf/sam0/,\
|
||||
drivers/sercom/i2c/i2c_sam0/i2c_master.c \
|
||||
drivers/sercom/sercom.c \
|
||||
drivers/sercom/sercom_interrupt.c \
|
||||
drivers/sercom/spi/spi.c \
|
||||
drivers/sercom/usart/usart.c \
|
||||
drivers/sercom/usart/usart_interrupt.c \
|
||||
drivers/system/clock/clock_samd21_r21_da/clock.c \
|
||||
|
@ -1,9 +1,9 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief Sleep manager configuration
|
||||
* \brief SAM D21 SPI configuration
|
||||
*
|
||||
* Copyright (c) 2014-2015 Atmel Corporation. All rights reserved.
|
||||
* Copyright (C) 2013-2016 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
@ -44,9 +44,11 @@
|
||||
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
|
||||
*/
|
||||
|
||||
#ifndef CONF_SLEEPMGR_H_INCLUDED
|
||||
#define CONF_SLEEPMGR_H_INCLUDED
|
||||
|
||||
#define CONFIG_SLEEPMGR_ENABLE
|
||||
#ifndef CONF_SPI_H_INCLUDED
|
||||
#define CONF_SPI_H_INCLUDED
|
||||
|
||||
#endif /* CONF_SLEEPMGR_H_INCLUDED */
|
||||
#define CONF_SPI_MASTER_ENABLE true
|
||||
#define CONF_SPI_SLAVE_ENABLE false
|
||||
|
||||
#endif /* CONF_SPI_H_INCLUDED */
|
@ -1,197 +0,0 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM D21 Clock configuration
|
||||
*
|
||||
* Copyright (C) 2014-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 <clock.h>
|
||||
|
||||
#ifndef CONF_CLOCKS_H_INCLUDED
|
||||
# define CONF_CLOCKS_H_INCLUDED
|
||||
|
||||
/* System clock bus configuration */
|
||||
# define CONF_CLOCK_CPU_CLOCK_FAILURE_DETECT false
|
||||
# define CONF_CLOCK_FLASH_WAIT_STATES 2
|
||||
# define CONF_CLOCK_CPU_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
|
||||
# define CONF_CLOCK_APBA_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
|
||||
# define CONF_CLOCK_APBB_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
|
||||
# define CONF_CLOCK_APBC_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_OSC8M configuration - Internal 8MHz oscillator */
|
||||
# define CONF_CLOCK_OSC8M_PRESCALER SYSTEM_OSC8M_DIV_1
|
||||
# define CONF_CLOCK_OSC8M_ON_DEMAND true
|
||||
# define CONF_CLOCK_OSC8M_RUN_IN_STANDBY false
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_XOSC configuration - External clock/oscillator */
|
||||
# define CONF_CLOCK_XOSC_ENABLE false
|
||||
# define CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL
|
||||
# define CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY 12000000UL
|
||||
# define CONF_CLOCK_XOSC_STARTUP_TIME SYSTEM_XOSC_STARTUP_32768
|
||||
# define CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL true
|
||||
# define CONF_CLOCK_XOSC_ON_DEMAND true
|
||||
# define CONF_CLOCK_XOSC_RUN_IN_STANDBY false
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_XOSC32K configuration - External 32KHz crystal/clock oscillator */
|
||||
# define CONF_CLOCK_XOSC32K_ENABLE true
|
||||
# define CONF_CLOCK_XOSC32K_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL
|
||||
# define CONF_CLOCK_XOSC32K_STARTUP_TIME SYSTEM_XOSC32K_STARTUP_65536
|
||||
# define CONF_CLOCK_XOSC32K_AUTO_AMPLITUDE_CONTROL false
|
||||
# define CONF_CLOCK_XOSC32K_ENABLE_1KHZ_OUPUT false
|
||||
# define CONF_CLOCK_XOSC32K_ENABLE_32KHZ_OUTPUT true
|
||||
# define CONF_CLOCK_XOSC32K_ON_DEMAND false
|
||||
# define CONF_CLOCK_XOSC32K_RUN_IN_STANDBY true
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_OSC32K configuration - Internal 32KHz oscillator */
|
||||
# define CONF_CLOCK_OSC32K_ENABLE false
|
||||
# define CONF_CLOCK_OSC32K_STARTUP_TIME SYSTEM_OSC32K_STARTUP_130
|
||||
# define CONF_CLOCK_OSC32K_ENABLE_1KHZ_OUTPUT true
|
||||
# define CONF_CLOCK_OSC32K_ENABLE_32KHZ_OUTPUT true
|
||||
# define CONF_CLOCK_OSC32K_ON_DEMAND true
|
||||
# define CONF_CLOCK_OSC32K_RUN_IN_STANDBY false
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop */
|
||||
# define CONF_CLOCK_DFLL_ENABLE true
|
||||
# define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED
|
||||
# define CONF_CLOCK_DFLL_ON_DEMAND true
|
||||
|
||||
/* DFLL open loop mode configuration */
|
||||
# define CONF_CLOCK_DFLL_FINE_VALUE (512)
|
||||
|
||||
/* DFLL closed loop mode configuration */
|
||||
# define CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR GCLK_GENERATOR_1
|
||||
# define CONF_CLOCK_DFLL_MULTIPLY_FACTOR (48000000 / 32768)
|
||||
# define CONF_CLOCK_DFLL_QUICK_LOCK true
|
||||
# define CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK true
|
||||
# define CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP true
|
||||
# define CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE true
|
||||
# define CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE (0x1f / 4)
|
||||
# define CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE (0xff / 4)
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_DPLL configuration - Digital Phase-Locked Loop */
|
||||
# define CONF_CLOCK_DPLL_ENABLE false
|
||||
# define CONF_CLOCK_DPLL_ON_DEMAND true
|
||||
# define CONF_CLOCK_DPLL_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_DPLL_LOCK_BYPASS false
|
||||
# define CONF_CLOCK_DPLL_WAKE_UP_FAST false
|
||||
# define CONF_CLOCK_DPLL_LOW_POWER_ENABLE false
|
||||
|
||||
# define CONF_CLOCK_DPLL_LOCK_TIME SYSTEM_CLOCK_SOURCE_DPLL_LOCK_TIME_DEFAULT
|
||||
# define CONF_CLOCK_DPLL_REFERENCE_CLOCK SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_XOSC32K
|
||||
# define CONF_CLOCK_DPLL_FILTER SYSTEM_CLOCK_SOURCE_DPLL_FILTER_DEFAULT
|
||||
|
||||
# define CONF_CLOCK_DPLL_REFERENCE_FREQUENCY 32768
|
||||
# define CONF_CLOCK_DPLL_REFERENCE_DIVIDER 1
|
||||
# define CONF_CLOCK_DPLL_OUTPUT_FREQUENCY 48000000
|
||||
|
||||
/* DPLL GCLK reference configuration */
|
||||
# define CONF_CLOCK_DPLL_REFERENCE_GCLK_GENERATOR GCLK_GENERATOR_1
|
||||
/* DPLL GCLK lock timer configuration */
|
||||
# define CONF_CLOCK_DPLL_LOCK_GCLK_GENERATOR GCLK_GENERATOR_1
|
||||
|
||||
/* Set this to true to configure the GCLK when running clocks_init. If set to
|
||||
* false, none of the GCLK generators will be configured in clocks_init(). */
|
||||
# define CONF_CLOCK_CONFIGURE_GCLK true
|
||||
|
||||
/* Configure GCLK generator 0 (Main Clock) */
|
||||
# define CONF_CLOCK_GCLK_0_ENABLE true
|
||||
# define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY true
|
||||
# define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_DFLL
|
||||
# define CONF_CLOCK_GCLK_0_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 1 */
|
||||
# define CONF_CLOCK_GCLK_1_ENABLE true
|
||||
# define CONF_CLOCK_GCLK_1_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_1_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_XOSC32K
|
||||
# define CONF_CLOCK_GCLK_1_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_1_OUTPUT_ENABLE true
|
||||
|
||||
/* Configure GCLK generator 2 (RTC) */
|
||||
# define CONF_CLOCK_GCLK_2_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_2_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_2_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC32K
|
||||
# define CONF_CLOCK_GCLK_2_PRESCALER 32
|
||||
# define CONF_CLOCK_GCLK_2_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 3 */
|
||||
# define CONF_CLOCK_GCLK_3_ENABLE true
|
||||
# define CONF_CLOCK_GCLK_3_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_3_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_3_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_3_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 4 */
|
||||
# define CONF_CLOCK_GCLK_4_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_4_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_4_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_4_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_4_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 5 */
|
||||
# define CONF_CLOCK_GCLK_5_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_5_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_5_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_5_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_5_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 6 */
|
||||
# define CONF_CLOCK_GCLK_6_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_6_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_6_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_6_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_6_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 7 */
|
||||
# define CONF_CLOCK_GCLK_7_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_7_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_7_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_7_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_7_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 8 */
|
||||
# define CONF_CLOCK_GCLK_8_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_8_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_8_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_8_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_8_OUTPUT_ENABLE false
|
||||
|
||||
#endif /* CONF_CLOCKS_H_INCLUDED */
|
@ -1,52 +0,0 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief Sleep manager configuration
|
||||
*
|
||||
* Copyright (c) 2014-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 CONF_SLEEPMGR_H_INCLUDED
|
||||
#define CONF_SLEEPMGR_H_INCLUDED
|
||||
|
||||
#define CONFIG_SLEEPMGR_ENABLE
|
||||
|
||||
#endif /* CONF_SLEEPMGR_H_INCLUDED */
|
@ -1,40 +0,0 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief User board definition template
|
||||
*
|
||||
*/
|
||||
|
||||
/* This file is intended to contain definitions and configuration details for
|
||||
* features and devices that are available on the board, e.g., frequency and
|
||||
* startup time for an external crystal, external memory devices, LED and USART
|
||||
* pins.
|
||||
*/
|
||||
/*
|
||||
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
|
||||
*/
|
||||
|
||||
#ifndef USER_BOARD_H
|
||||
#define USER_BOARD_H
|
||||
|
||||
#include <conf_board.h>
|
||||
|
||||
// External oscillator settings.
|
||||
// Uncomment and set correct values if external oscillator is used.
|
||||
|
||||
// External oscillator frequency
|
||||
//#define BOARD_XOSC_HZ 8000000
|
||||
|
||||
// External oscillator type.
|
||||
//!< External clock signal
|
||||
//#define BOARD_XOSC_TYPE XOSC_TYPE_EXTERNAL
|
||||
//!< 32.768 kHz resonator on TOSC
|
||||
//#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ
|
||||
//!< 0.4 to 16 MHz resonator on XTALS
|
||||
//#define BOARD_XOSC_TYPE XOSC_TYPE_XTAL
|
||||
|
||||
// External oscillator startup time
|
||||
//#define BOARD_XOSC_STARTUP_US 500000
|
||||
|
||||
|
||||
#endif // USER_BOARD_H
|
@ -1,197 +0,0 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM D21 Clock configuration
|
||||
*
|
||||
* Copyright (C) 2014-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 <clock.h>
|
||||
|
||||
#ifndef CONF_CLOCKS_H_INCLUDED
|
||||
# define CONF_CLOCKS_H_INCLUDED
|
||||
|
||||
/* System clock bus configuration */
|
||||
# define CONF_CLOCK_CPU_CLOCK_FAILURE_DETECT false
|
||||
# define CONF_CLOCK_FLASH_WAIT_STATES 2
|
||||
# define CONF_CLOCK_CPU_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
|
||||
# define CONF_CLOCK_APBA_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
|
||||
# define CONF_CLOCK_APBB_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
|
||||
# define CONF_CLOCK_APBC_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_OSC8M configuration - Internal 8MHz oscillator */
|
||||
# define CONF_CLOCK_OSC8M_PRESCALER SYSTEM_OSC8M_DIV_1
|
||||
# define CONF_CLOCK_OSC8M_ON_DEMAND true
|
||||
# define CONF_CLOCK_OSC8M_RUN_IN_STANDBY false
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_XOSC configuration - External clock/oscillator */
|
||||
# define CONF_CLOCK_XOSC_ENABLE false
|
||||
# define CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL
|
||||
# define CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY 12000000UL
|
||||
# define CONF_CLOCK_XOSC_STARTUP_TIME SYSTEM_XOSC_STARTUP_32768
|
||||
# define CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL true
|
||||
# define CONF_CLOCK_XOSC_ON_DEMAND true
|
||||
# define CONF_CLOCK_XOSC_RUN_IN_STANDBY false
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_XOSC32K configuration - External 32KHz crystal/clock oscillator */
|
||||
# define CONF_CLOCK_XOSC32K_ENABLE true
|
||||
# define CONF_CLOCK_XOSC32K_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL
|
||||
# define CONF_CLOCK_XOSC32K_STARTUP_TIME SYSTEM_XOSC32K_STARTUP_65536
|
||||
# define CONF_CLOCK_XOSC32K_AUTO_AMPLITUDE_CONTROL false
|
||||
# define CONF_CLOCK_XOSC32K_ENABLE_1KHZ_OUPUT false
|
||||
# define CONF_CLOCK_XOSC32K_ENABLE_32KHZ_OUTPUT true
|
||||
# define CONF_CLOCK_XOSC32K_ON_DEMAND false
|
||||
# define CONF_CLOCK_XOSC32K_RUN_IN_STANDBY true
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_OSC32K configuration - Internal 32KHz oscillator */
|
||||
# define CONF_CLOCK_OSC32K_ENABLE false
|
||||
# define CONF_CLOCK_OSC32K_STARTUP_TIME SYSTEM_OSC32K_STARTUP_130
|
||||
# define CONF_CLOCK_OSC32K_ENABLE_1KHZ_OUTPUT true
|
||||
# define CONF_CLOCK_OSC32K_ENABLE_32KHZ_OUTPUT true
|
||||
# define CONF_CLOCK_OSC32K_ON_DEMAND true
|
||||
# define CONF_CLOCK_OSC32K_RUN_IN_STANDBY false
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop */
|
||||
# define CONF_CLOCK_DFLL_ENABLE true
|
||||
# define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED
|
||||
# define CONF_CLOCK_DFLL_ON_DEMAND true
|
||||
|
||||
/* DFLL open loop mode configuration */
|
||||
# define CONF_CLOCK_DFLL_FINE_VALUE (512)
|
||||
|
||||
/* DFLL closed loop mode configuration */
|
||||
# define CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR GCLK_GENERATOR_1
|
||||
# define CONF_CLOCK_DFLL_MULTIPLY_FACTOR (48000000 / 32768)
|
||||
# define CONF_CLOCK_DFLL_QUICK_LOCK true
|
||||
# define CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK true
|
||||
# define CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP true
|
||||
# define CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE true
|
||||
# define CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE (0x1f / 4)
|
||||
# define CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE (0xff / 4)
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_DPLL configuration - Digital Phase-Locked Loop */
|
||||
# define CONF_CLOCK_DPLL_ENABLE false
|
||||
# define CONF_CLOCK_DPLL_ON_DEMAND true
|
||||
# define CONF_CLOCK_DPLL_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_DPLL_LOCK_BYPASS false
|
||||
# define CONF_CLOCK_DPLL_WAKE_UP_FAST false
|
||||
# define CONF_CLOCK_DPLL_LOW_POWER_ENABLE false
|
||||
|
||||
# define CONF_CLOCK_DPLL_LOCK_TIME SYSTEM_CLOCK_SOURCE_DPLL_LOCK_TIME_DEFAULT
|
||||
# define CONF_CLOCK_DPLL_REFERENCE_CLOCK SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_XOSC32K
|
||||
# define CONF_CLOCK_DPLL_FILTER SYSTEM_CLOCK_SOURCE_DPLL_FILTER_DEFAULT
|
||||
|
||||
# define CONF_CLOCK_DPLL_REFERENCE_FREQUENCY 32768
|
||||
# define CONF_CLOCK_DPLL_REFERENCE_DIVIDER 1
|
||||
# define CONF_CLOCK_DPLL_OUTPUT_FREQUENCY 48000000
|
||||
|
||||
/* DPLL GCLK reference configuration */
|
||||
# define CONF_CLOCK_DPLL_REFERENCE_GCLK_GENERATOR GCLK_GENERATOR_1
|
||||
/* DPLL GCLK lock timer configuration */
|
||||
# define CONF_CLOCK_DPLL_LOCK_GCLK_GENERATOR GCLK_GENERATOR_1
|
||||
|
||||
/* Set this to true to configure the GCLK when running clocks_init. If set to
|
||||
* false, none of the GCLK generators will be configured in clocks_init(). */
|
||||
# define CONF_CLOCK_CONFIGURE_GCLK true
|
||||
|
||||
/* Configure GCLK generator 0 (Main Clock) */
|
||||
# define CONF_CLOCK_GCLK_0_ENABLE true
|
||||
# define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY true
|
||||
# define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_DFLL
|
||||
# define CONF_CLOCK_GCLK_0_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 1 */
|
||||
# define CONF_CLOCK_GCLK_1_ENABLE true
|
||||
# define CONF_CLOCK_GCLK_1_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_1_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_XOSC32K
|
||||
# define CONF_CLOCK_GCLK_1_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_1_OUTPUT_ENABLE true
|
||||
|
||||
/* Configure GCLK generator 2 (RTC) */
|
||||
# define CONF_CLOCK_GCLK_2_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_2_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_2_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC32K
|
||||
# define CONF_CLOCK_GCLK_2_PRESCALER 32
|
||||
# define CONF_CLOCK_GCLK_2_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 3 */
|
||||
# define CONF_CLOCK_GCLK_3_ENABLE true
|
||||
# define CONF_CLOCK_GCLK_3_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_3_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_3_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_3_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 4 */
|
||||
# define CONF_CLOCK_GCLK_4_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_4_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_4_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_4_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_4_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 5 */
|
||||
# define CONF_CLOCK_GCLK_5_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_5_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_5_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_5_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_5_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 6 */
|
||||
# define CONF_CLOCK_GCLK_6_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_6_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_6_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_6_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_6_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 7 */
|
||||
# define CONF_CLOCK_GCLK_7_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_7_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_7_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_7_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_7_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 8 */
|
||||
# define CONF_CLOCK_GCLK_8_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_8_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_8_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_8_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_8_OUTPUT_ENABLE false
|
||||
|
||||
#endif /* CONF_CLOCKS_H_INCLUDED */
|
@ -121,7 +121,7 @@ PIN(PB10, false, NO_ADC_INPUT,
|
||||
PIN(PA12, false, NO_ADC_INPUT,
|
||||
TIMER(0, TCC2, 0, 0, PIN_PA12E_TCC2_WO0, MUX_PA12E_TCC2_WO0),
|
||||
TIMER(0, TCC0, 2, 6, PIN_PA12F_TCC0_WO6, MUX_PA12F_TCC0_WO6),
|
||||
SERCOM(SERCOM4, 0, PINMUX_PA12D_SERCOM4_PAD0),
|
||||
SERCOM(SERCOM4, 0, PINMUX_PA12D_SERCOM4_PAD0),
|
||||
SERCOM(SERCOM2, 0, PINMUX_PA12C_SERCOM2_PAD0));
|
||||
PIN(PA13, false, NO_ADC_INPUT,
|
||||
TIMER(0, TCC2, 1, 1, PIN_PA13E_TCC2_WO1, MUX_PA13E_TCC2_WO1),
|
||||
|
@ -1,40 +0,0 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief User board definition template
|
||||
*
|
||||
*/
|
||||
|
||||
/* This file is intended to contain definitions and configuration details for
|
||||
* features and devices that are available on the board, e.g., frequency and
|
||||
* startup time for an external crystal, external memory devices, LED and USART
|
||||
* pins.
|
||||
*/
|
||||
/*
|
||||
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
|
||||
*/
|
||||
|
||||
#ifndef USER_BOARD_H
|
||||
#define USER_BOARD_H
|
||||
|
||||
#include <conf_board.h>
|
||||
|
||||
// External oscillator settings.
|
||||
// Uncomment and set correct values if external oscillator is used.
|
||||
|
||||
// External oscillator frequency
|
||||
//#define BOARD_XOSC_HZ 8000000
|
||||
|
||||
// External oscillator type.
|
||||
//!< External clock signal
|
||||
//#define BOARD_XOSC_TYPE XOSC_TYPE_EXTERNAL
|
||||
//!< 32.768 kHz resonator on TOSC
|
||||
//#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ
|
||||
//!< 0.4 to 16 MHz resonator on XTALS
|
||||
//#define BOARD_XOSC_TYPE XOSC_TYPE_XTAL
|
||||
|
||||
// External oscillator startup time
|
||||
//#define BOARD_XOSC_STARTUP_US 500000
|
||||
|
||||
|
||||
#endif // USER_BOARD_H
|
@ -205,3 +205,63 @@ void mp_hal_i2c_read_mem(machine_i2c_obj_t *self, uint8_t addr, uint16_t memaddr
|
||||
mp_hal_i2c_read(self, addr, dest, len);
|
||||
return;
|
||||
}
|
||||
|
||||
void mp_hal_spi_construct(machine_spi_obj_t *self, const pin_obj_t * clock,
|
||||
const pin_obj_t * mosi, const pin_obj_t * miso,
|
||||
uint32_t baudrate) {
|
||||
struct spi_config config_spi_master;
|
||||
spi_get_config_defaults(&config_spi_master);
|
||||
|
||||
// Depends on where MOSI and CLK are.
|
||||
uint8_t dopo = 8;
|
||||
if (clock->primary_sercom.pad == 1) {
|
||||
if (mosi->primary_sercom.pad == 0) {
|
||||
dopo = 0;
|
||||
} else if (mosi->primary_sercom.pad == 3) {
|
||||
dopo = 2;
|
||||
}
|
||||
} else if (clock->primary_sercom.pad == 3) {
|
||||
if (mosi->primary_sercom.pad == 0) {
|
||||
dopo = 3;
|
||||
} else if (mosi->primary_sercom.pad == 2) {
|
||||
dopo = 1;
|
||||
}
|
||||
}
|
||||
if (dopo == 8) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "SPI MOSI and clock pins incompatible."));
|
||||
}
|
||||
|
||||
config_spi_master.mux_setting = (dopo << SERCOM_SPI_CTRLA_DOPO_Pos) |
|
||||
(miso->primary_sercom.pad << SERCOM_SPI_CTRLA_DIPO_Pos);
|
||||
|
||||
// Map pad to pinmux through a short array.
|
||||
uint32_t *pinmuxes[4] = {&config_spi_master.pinmux_pad0,
|
||||
&config_spi_master.pinmux_pad1,
|
||||
&config_spi_master.pinmux_pad2,
|
||||
&config_spi_master.pinmux_pad3};
|
||||
*pinmuxes[clock->primary_sercom.pad] = clock->primary_sercom.pinmux;
|
||||
*pinmuxes[mosi->primary_sercom.pad] = mosi->primary_sercom.pinmux;
|
||||
*pinmuxes[miso->primary_sercom.pad] = miso->primary_sercom.pinmux;
|
||||
|
||||
config_spi_master.mode_specific.master.baudrate = baudrate;
|
||||
|
||||
spi_init(&self->spi_master_instance, mosi->primary_sercom.sercom, &config_spi_master);
|
||||
}
|
||||
|
||||
void mp_hal_spi_init(machine_spi_obj_t *self) {
|
||||
spi_enable(&self->spi_master_instance);
|
||||
}
|
||||
|
||||
void mp_hal_spi_deinit(machine_spi_obj_t *self) {
|
||||
spi_disable(&self->spi_master_instance);
|
||||
}
|
||||
|
||||
void mp_hal_spi_transfer(machine_spi_obj_t *self, size_t len, const uint8_t *src,
|
||||
uint8_t *dest) {
|
||||
// TODO(tannewt): Don't cast away the const. Change ASF to respect it instead.
|
||||
enum status_code status = spi_transceive_buffer_wait(
|
||||
&self->spi_master_instance, (uint8_t *) src, dest, len);
|
||||
if (status != STATUS_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "SPI bus error"));
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "asf/sam0/drivers/adc/adc_sam_d_r/adc_feature.h"
|
||||
|
||||
#include "asf/sam0/drivers/sercom/i2c/i2c_master.h"
|
||||
#include "asf/sam0/drivers/sercom/spi/spi.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
@ -77,4 +78,9 @@ typedef struct _machine_i2c_obj_t {
|
||||
struct i2c_master_module i2c_master_instance;
|
||||
} machine_i2c_obj_t;
|
||||
|
||||
typedef struct _machine_spi_obj_t {
|
||||
mp_obj_base_t base;
|
||||
struct spi_module spi_master_instance;
|
||||
} machine_spi_obj_t;
|
||||
|
||||
#endif // __MICROPY_INCLUDED_ATMEL_SAMD_API_MACHINE_TYPES_H__
|
||||
|
@ -50,6 +50,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pin_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&pwm_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Flash), MP_ROM_PTR(&flash_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table);
|
||||
|
@ -45,8 +45,19 @@
|
||||
//|
|
||||
//| I2C objects are created attached to a specific bus. They can be initialised
|
||||
//| when created, or initialised later on.
|
||||
|
||||
STATIC void machine_i2c_obj_init_helper(machine_i2c_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
//|
|
||||
//| Constructors
|
||||
//| ------------
|
||||
//| .. class:: I2C(scl, sda, \*, freq=400000)
|
||||
//|
|
||||
//| Construct and return a new I2C object.
|
||||
//| See the init method below for a description of the arguments.
|
||||
STATIC mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
machine_i2c_obj_t *self = m_new_obj(machine_i2c_obj_t);
|
||||
self->base.type = &machine_i2c_type;
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
|
||||
enum { ARG_scl, ARG_sda, ARG_freq };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
@ -54,26 +65,11 @@ STATIC void machine_i2c_obj_init_helper(machine_i2c_obj_t *self, mp_uint_t n_arg
|
||||
{ MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
// TODO(tannewt): Replace pin_find with a unified version.
|
||||
const pin_obj_t* scl = pin_find(args[ARG_scl].u_obj);
|
||||
const pin_obj_t* sda = pin_find(args[ARG_sda].u_obj);
|
||||
mp_hal_i2c_construct(self, scl, sda, args[ARG_freq].u_int);
|
||||
}
|
||||
|
||||
//| Constructors
|
||||
//| ------------
|
||||
//| .. class:: I2C(scl, sda, \*, freq=400000)
|
||||
//|
|
||||
//| Construct and return a new I2C object.
|
||||
//| See the init method below for a description of the arguments.
|
||||
STATIC mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
machine_i2c_obj_t *self = m_new_obj(machine_i2c_obj_t);
|
||||
self->base.type = &machine_i2c_type;
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
machine_i2c_obj_init_helper(self, n_args, args, &kw_args);
|
||||
return (mp_obj_t)self;
|
||||
}
|
||||
|
||||
@ -281,6 +277,7 @@ STATIC const mp_rom_map_elem_t machine_i2c_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_writeto), MP_ROM_PTR(&machine_i2c_writeto_obj) },
|
||||
|
||||
// memory operations
|
||||
// TODO(tannewt): Move these into a separate loadable Python module.
|
||||
{ MP_ROM_QSTR(MP_QSTR_readfrom_mem), MP_ROM_PTR(&machine_i2c_readfrom_mem_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readfrom_mem_into), MP_ROM_PTR(&machine_i2c_readfrom_mem_into_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_writeto_mem), MP_ROM_PTR(&machine_i2c_writeto_mem_obj) },
|
||||
@ -294,3 +291,173 @@ const mp_obj_type_t machine_i2c_type = {
|
||||
.make_new = machine_i2c_make_new,
|
||||
.locals_dict = (mp_obj_dict_t*)&machine_i2c_locals_dict,
|
||||
};
|
||||
|
||||
//| class SPI -- a master-driven serial protocol
|
||||
//| ============================================
|
||||
//|
|
||||
//| SPI is a serial protocol that is driven by a master. This class only
|
||||
//| manages three of the four SPI lines: SCK, MOSI, MISO. Its up to the client
|
||||
//| to manage the appropriate slave select line.
|
||||
//|
|
||||
//| Constructors
|
||||
//| ------------
|
||||
//|
|
||||
//| .. class:: SPI(clock, MOSI, MISO, baudrate=1000000)
|
||||
//|
|
||||
//| Construct an SPI object on the given bus. ``id`` can be only 0.
|
||||
//| With no additional parameters, the SPI object is created but not
|
||||
//| initialised (it has the settings from the last initialisation of
|
||||
//| the bus, if any). If extra arguments are given, the bus is initialised.
|
||||
//| See ``init`` for parameters of initialisation.
|
||||
//|
|
||||
//| - ``clock`` is the pin to use for the clock.
|
||||
//| - ``MOSI`` is the Master Out Slave In pin.
|
||||
//| - ``MISO`` is the Master In Slave Out pin.
|
||||
//| - ``baudrate`` is the SCK clock rate.
|
||||
//|
|
||||
//| Methods
|
||||
//| -------
|
||||
//|
|
||||
|
||||
// TODO(tannewt): Support LSB SPI.
|
||||
// TODO(tannewt): Support phase, polarity and bit order.
|
||||
STATIC mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
machine_spi_obj_t *self = m_new_obj(machine_spi_obj_t);
|
||||
self->base.type = &machine_spi_type;
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
|
||||
enum { ARG_clock, ARG_MOSI, ARG_MISO, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_MOSI, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_MISO, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 100000} },
|
||||
{ MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} },
|
||||
{ MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} },
|
||||
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
// TODO(tannewt): Replace pin_find with a unified version.
|
||||
const pin_obj_t* clock = pin_find(args[ARG_clock].u_obj);
|
||||
const pin_obj_t* mosi = pin_find(args[ARG_MOSI].u_obj);
|
||||
const pin_obj_t* miso = pin_find(args[ARG_MISO].u_obj);
|
||||
mp_hal_spi_construct(self, clock, mosi, miso, args[ARG_baudrate].u_int);
|
||||
return (mp_obj_t)self;
|
||||
}
|
||||
|
||||
//| .. method:: SPI.init()
|
||||
//|
|
||||
//| Initialises the bus.
|
||||
STATIC mp_obj_t machine_spi_obj_init(mp_obj_t self_in) {
|
||||
machine_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_hal_spi_init(self);
|
||||
return self_in;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(machine_spi_init_obj, machine_spi_obj_init);
|
||||
|
||||
//| .. method:: SPI.deinit()
|
||||
//|
|
||||
//| Turn off the SPI bus.
|
||||
STATIC mp_obj_t machine_spi_obj_deinit(mp_obj_t self_in) {
|
||||
machine_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_hal_spi_deinit(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(machine_spi_deinit_obj, machine_spi_obj_deinit);
|
||||
|
||||
STATIC mp_obj_t machine_spi_obj___exit__(size_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
mp_hal_spi_deinit(args[0]);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_spi_obj___exit___obj, 4, 4, machine_spi_obj___exit__);
|
||||
|
||||
//| .. method:: SPI.write_readinto(write_buf, read_buf)
|
||||
//|
|
||||
//| Write from ``write_buf`` and read into ``read_buf``. Both buffers must have the
|
||||
//| same length. This is the same as a SPI transfer function on other platforms.
|
||||
//| Returns the number of bytes written
|
||||
STATIC mp_obj_t mp_machine_spi_write_readinto(mp_obj_t self_in, mp_obj_t wr_buf, mp_obj_t rd_buf) {
|
||||
mp_buffer_info_t src;
|
||||
mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ);
|
||||
mp_buffer_info_t dest;
|
||||
mp_get_buffer_raise(rd_buf, &dest, MP_BUFFER_WRITE);
|
||||
if (src.len != dest.len) {
|
||||
mp_raise_ValueError("buffers must be the same length");
|
||||
}
|
||||
machine_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_hal_spi_transfer(self, src.len, (uint8_t *) src.buf, (uint8_t *) dest.buf);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_3(mp_machine_spi_write_readinto_obj, mp_machine_spi_write_readinto);
|
||||
|
||||
//| Helper operations
|
||||
//| -----------------
|
||||
//| The below operations are finer grained operations based upon ``SPI.write_readinto``.
|
||||
//| They may be moved out of the core module later.
|
||||
//|
|
||||
//| .. method:: SPI.write(buf)
|
||||
//|
|
||||
//| Write the data contained in ``buf``.
|
||||
//| Returns the number of bytes written.
|
||||
STATIC mp_obj_t mp_machine_spi_write(mp_obj_t self_in, mp_obj_t wr_buf) {
|
||||
mp_buffer_info_t src;
|
||||
mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ);
|
||||
machine_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_hal_spi_transfer(self, src.len, (uint8_t *) src.buf, NULL);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(mp_machine_spi_write_obj, mp_machine_spi_write);
|
||||
|
||||
//| .. method:: SPI.read(nbytes, *, write=0x00)
|
||||
//|
|
||||
//| Read the ``nbytes`` while writing the data specified by ``write``.
|
||||
//| Return the number of bytes read.
|
||||
STATIC mp_obj_t mp_machine_spi_read(size_t n_args, const mp_obj_t *args) {
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, mp_obj_get_int(args[1]));
|
||||
memset(vstr.buf, n_args == 3 ? mp_obj_get_int(args[2]) : 0, vstr.len);
|
||||
mp_hal_spi_transfer(args[0], vstr.len, (uint8_t *) vstr.buf, (uint8_t *) vstr.buf);
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_read_obj, 2, 3, mp_machine_spi_read);
|
||||
|
||||
//| .. method:: SPI.readinto(buf, *, write=0x00)
|
||||
//|
|
||||
//| Read into the buffer specified by ``buf`` while writing the data specified by
|
||||
//| ``write``.
|
||||
//| Return the number of bytes read.
|
||||
STATIC mp_obj_t mp_machine_spi_readinto(size_t n_args, const mp_obj_t *args) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
|
||||
memset(bufinfo.buf, n_args == 3 ? mp_obj_get_int(args[2]) : 0, bufinfo.len);
|
||||
mp_hal_spi_transfer(args[0], bufinfo.len, (uint8_t *) bufinfo.buf, (uint8_t *) bufinfo.buf);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_readinto_obj, 2, 3, mp_machine_spi_readinto);
|
||||
|
||||
STATIC const mp_rom_map_elem_t machine_spi_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_spi_init_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_spi_deinit_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&machine_spi_init_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&machine_spi_obj___exit___obj) },
|
||||
|
||||
// Standard simultaneous read/write transfer.
|
||||
{ MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&mp_machine_spi_write_readinto_obj) },
|
||||
|
||||
// Helper methods.
|
||||
// TODO(tannewt): Move these into a helper Python class.
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_machine_spi_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_machine_spi_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_machine_spi_write_obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(machine_spi_locals_dict, machine_spi_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t machine_spi_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_SPI,
|
||||
.make_new = machine_spi_make_new,
|
||||
.locals_dict = (mp_obj_dict_t*)&machine_spi_locals_dict,
|
||||
};
|
||||
|
@ -49,6 +49,7 @@
|
||||
|
||||
// Type object used in Python. Should be shared between ports.
|
||||
extern const mp_obj_type_t machine_i2c_type;
|
||||
extern const mp_obj_type_t machine_spi_type;
|
||||
|
||||
// Initializes the hardware peripheral.
|
||||
extern void mp_hal_i2c_construct(machine_i2c_obj_t *self, const pin_obj_t * scl,
|
||||
@ -76,5 +77,16 @@ extern void mp_hal_i2c_write_mem(machine_i2c_obj_t *self, uint8_t addr,
|
||||
uint16_t memaddr, const uint8_t *src,
|
||||
size_t len);
|
||||
|
||||
// Construct an underlying SPI object.
|
||||
extern void mp_hal_spi_construct(machine_spi_obj_t *self, const pin_obj_t * clock,
|
||||
const pin_obj_t * mosi, const pin_obj_t * miso,
|
||||
uint32_t baudrate);
|
||||
|
||||
extern void mp_hal_spi_init(machine_spi_obj_t *self);
|
||||
extern void mp_hal_spi_deinit(machine_spi_obj_t *self);
|
||||
|
||||
// Concurrently write and read len bytes from the SPI port. Chip select is
|
||||
// handled externally.
|
||||
extern void mp_hal_spi_transfer(machine_spi_obj_t *self, size_t len, const uint8_t *src, uint8_t *dest);
|
||||
|
||||
#endif // __MICROPY_INCLUDED_API_MACHINE_H__
|
||||
|
Loading…
Reference in New Issue
Block a user