atmel-samd: Add support for SPI.

Also separate out the ASF config headers that are shared across all boards.
This commit is contained in:
Scott Shawcroft 2016-10-11 15:48:43 -07:00
parent 6986aa9aa2
commit 011056af15
16 changed files with 275 additions and 551 deletions

View File

@ -32,6 +32,7 @@ INC += -I..
INC += -I../lib/mp-readline INC += -I../lib/mp-readline
INC += -I../lib/timeutils INC += -I../lib/timeutils
INC += -Icommon-hal/modules/ INC += -Icommon-hal/modules/
INC += -Iasf_conf/
INC += -Iasf/common/boards/ INC += -Iasf/common/boards/
INC += -Iasf/common/services/sleepmgr/ INC += -Iasf/common/services/sleepmgr/
INC += -Iasf/common/services/storage/ctrl_access/ 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/i2c/i2c_sam0/i2c_master.c \
drivers/sercom/sercom.c \ drivers/sercom/sercom.c \
drivers/sercom/sercom_interrupt.c \ drivers/sercom/sercom_interrupt.c \
drivers/sercom/spi/spi.c \
drivers/sercom/usart/usart.c \ drivers/sercom/usart/usart.c \
drivers/sercom/usart/usart_interrupt.c \ drivers/sercom/usart/usart_interrupt.c \
drivers/system/clock/clock_samd21_r21_da/clock.c \ drivers/system/clock/clock_samd21_r21_da/clock.c \

View File

@ -1,9 +1,9 @@
/** /**
* \file * \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 * \asf_license_start
* *
@ -44,9 +44,11 @@
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> * 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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -121,7 +121,7 @@ PIN(PB10, false, NO_ADC_INPUT,
PIN(PA12, 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, TCC2, 0, 0, PIN_PA12E_TCC2_WO0, MUX_PA12E_TCC2_WO0),
TIMER(0, TCC0, 2, 6, PIN_PA12F_TCC0_WO6, MUX_PA12F_TCC0_WO6), 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)); SERCOM(SERCOM2, 0, PINMUX_PA12C_SERCOM2_PAD0));
PIN(PA13, false, NO_ADC_INPUT, PIN(PA13, false, NO_ADC_INPUT,
TIMER(0, TCC2, 1, 1, PIN_PA13E_TCC2_WO1, MUX_PA13E_TCC2_WO1), TIMER(0, TCC2, 1, 1, PIN_PA13E_TCC2_WO1, MUX_PA13E_TCC2_WO1),

View File

@ -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

View File

@ -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); mp_hal_i2c_read(self, addr, dest, len);
return; 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"));
}
}

View File

@ -42,6 +42,7 @@
#include "asf/sam0/drivers/adc/adc_sam_d_r/adc_feature.h" #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/i2c/i2c_master.h"
#include "asf/sam0/drivers/sercom/spi/spi.h"
#include "py/obj.h" #include "py/obj.h"
@ -77,4 +78,9 @@ typedef struct _machine_i2c_obj_t {
struct i2c_master_module i2c_master_instance; struct i2c_master_module i2c_master_instance;
} machine_i2c_obj_t; } 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__ #endif // __MICROPY_INCLUDED_ATMEL_SAMD_API_MACHINE_TYPES_H__

View File

@ -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_Pin), MP_ROM_PTR(&pin_type) },
{ MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&pwm_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_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); STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table);

View File

@ -45,8 +45,19 @@
//| //|
//| I2C objects are created attached to a specific bus. They can be initialised //| I2C objects are created attached to a specific bus. They can be initialised
//| when created, or initialised later on. //| 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 }; enum { ARG_scl, ARG_sda, ARG_freq };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
{ MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, { 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_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} },
}; };
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; 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. // 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* scl = pin_find(args[ARG_scl].u_obj);
const pin_obj_t* sda = pin_find(args[ARG_sda].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); 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; 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) }, { MP_ROM_QSTR(MP_QSTR_writeto), MP_ROM_PTR(&machine_i2c_writeto_obj) },
// memory operations // 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), 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_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) }, { 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, .make_new = machine_i2c_make_new,
.locals_dict = (mp_obj_dict_t*)&machine_i2c_locals_dict, .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,
};

View File

@ -49,6 +49,7 @@
// Type object used in Python. Should be shared between ports. // 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_i2c_type;
extern const mp_obj_type_t machine_spi_type;
// Initializes the hardware peripheral. // Initializes the hardware peripheral.
extern void mp_hal_i2c_construct(machine_i2c_obj_t *self, const pin_obj_t * scl, 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, uint16_t memaddr, const uint8_t *src,
size_t len); 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__ #endif // __MICROPY_INCLUDED_API_MACHINE_H__