Merged master and slave

This commit is contained in:
Nicolas Trimborn 2021-09-06 22:12:59 +02:00
parent 7ed41be749
commit b4e74a5e72
26 changed files with 1931 additions and 406 deletions

View File

@ -51,6 +51,7 @@
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/quad_spi_dma.rst"/>
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/spi_master_dma.rst"/>
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/spi_master_sync.rst"/>
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/spi_slave_sync.rst"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_atomic.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_cache.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_custom_logic.h"/>
@ -65,6 +66,7 @@
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_sleep.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_spi_m_dma.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_spi_m_sync.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_spi_s_sync.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_adc_dma.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_cmcc.h"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_core.h"/>
@ -177,6 +179,7 @@
<file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_pwm.c"/>
<file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_spi_m_dma.c"/>
<file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_spi_m_sync.c"/>
<file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_spi_s_sync.c"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hal/utils/include/parts.h"/>
<file category="source" condition="ARMCC, GCC, IAR" name="hpl/adc/hpl_adc.c"/>
<file category="header" condition="ARMCC, GCC, IAR" name="hpl/adc/hpl_adc_base.h"/>

View File

@ -1822,8 +1822,8 @@ drivers:
configuration:
core_gclk_selection: Generic clock generator 0
slow_gclk_selection: Generic clock generator 3
SPI_1_MSIF:
user_label: SPI_1_MSIF
SPI_1_MSIF_M:
user_label: SPI_1_MSIF_M
definition: Atmel:SAMD51_Drivers:0.0.1::SAMD51J18A-MF::SERCOM1::driver_config_definition::SPI.Master::HAL:Driver:SPI.Master.DMA
functionality: SPI
api: HAL:Driver:SPI_Master_DMA
@ -1913,6 +1913,43 @@ drivers:
configuration:
core_gclk_selection: Generic clock generator 0
slow_gclk_selection: Generic clock generator 3
SPI_1_MSIF_S:
user_label: SPI_1_MSIF_S
definition: Atmel:SAMD51_Drivers:0.0.1::SAMD51J18A-MF::SERCOM3::driver_config_definition::SPI.Slave::HAL:Driver:SPI.Slave.Sync
functionality: SPI
api: HAL:Driver:SPI_Slave_Sync
configuration:
spi_slave_advanced: false
spi_slave_arch_addr: 0
spi_slave_arch_addrmask: 0
spi_slave_arch_amode: Address mask
spi_slave_arch_amode_en: false
spi_slave_arch_cpha: Sample input on trailing edge
spi_slave_arch_cpol: SCK is low when idle
spi_slave_arch_dbgstop: Keep running
spi_slave_arch_dord: MSB first
spi_slave_arch_ibon: In data stream
spi_slave_arch_ploaden: false
spi_slave_arch_runstdby: false
spi_slave_arch_ssde: false
spi_slave_character_size: 8 bits
spi_slave_rx_enable: true
optional_signals: []
variant: null
clocks:
domain_group:
nodes:
- name: Core
input: Generic clock generator 0
external: false
external_frequency: 0
- name: Slow
input: Generic clock generator 3
external: false
external_frequency: 0
configuration:
core_gclk_selection: Generic clock generator 0
slow_gclk_selection: Generic clock generator 3
SPI_3:
user_label: SPI_3
definition: Atmel:SAMD51_Drivers:0.0.1::SAMD51J18A-MF::SERCOM5::driver_config_definition::SPI.Master::HAL:Driver:SPI.Master.Sync

View File

@ -479,6 +479,154 @@
#define CONF_SERCOM_2_SPI_BAUD_RATE ((float)CONF_GCLK_SERCOM2_CORE_FREQUENCY / (float)(2 * CONF_SERCOM_2_SPI_BAUD)) - 1
#endif
// Enable configuration of module
#ifndef CONF_SERCOM_3_SPI_ENABLE
#define CONF_SERCOM_3_SPI_ENABLE 0
#endif
// Set module in SPI Slave mode
#ifndef CONF_SERCOM_3_SPI_MODE
#define CONF_SERCOM_3_SPI_MODE 0x02
#endif
// <h> Basic Configuration
// <q> Receive buffer enable
// <i> Enable receive buffer to receive data from slave. (RXEN)
// <id> spi_slave_rx_enable
#ifndef CONF_SERCOM_3_SPI_RXEN
#define CONF_SERCOM_3_SPI_RXEN 0x1
#endif
// <o> Character Size
// <i> Bit size for all characters sent over the SPI bus. (CHSIZE)
// <0x0=>8 bits
// <0x1=>9 bits
// <id> spi_slave_character_size
#ifndef CONF_SERCOM_3_SPI_CHSIZE
#define CONF_SERCOM_3_SPI_CHSIZE 0x0
#endif
// </h>
// <e> Advanced Configuration
// <id> spi_slave_advanced
#ifndef CONF_SERCOM_3_SPI_ADVANCED
#define CONF_SERCOM_3_SPI_ADVANCED 0
#endif
// <o> Data Order
// <0=>MSB first
// <1=>LSB first
// <i> I least significant or most significant bit is shifted out first. (DORD)
// <id> spi_slave_arch_dord
#ifndef CONF_SERCOM_3_SPI_DORD
#define CONF_SERCOM_3_SPI_DORD 0x0
#endif
// <o> Clock Polarity
// <0=>SCK is low when idle
// <1=>SCK is high when idle
// <i> Determines if the leading edge is rising or falling with a corresponding opposite edge at the trailing edge. (CPOL)
// <id> spi_slave_arch_cpol
#ifndef CONF_SERCOM_3_SPI_CPOL
#define CONF_SERCOM_3_SPI_CPOL 0x0
#endif
// <o> Clock Phase
// <0x0=>Sample input on leading edge
// <0x1=>Sample input on trailing edge
// <i> Determines if input data is sampled on leading or trailing SCK edge. (CPHA)
// <id> spi_slave_arch_cpha
#ifndef CONF_SERCOM_3_SPI_CPHA
#define CONF_SERCOM_3_SPI_CPHA 0x1
#endif
// <o> Immediate Buffer Overflow Notification
// <i> Controls when OVF is asserted. (IBON)
// <0x0=>In data stream
// <0x1=>On buffer overflow
// <id> spi_slave_arch_ibon
#ifndef CONF_SERCOM_3_SPI_IBON
#define CONF_SERCOM_3_SPI_IBON 0x0
#endif
// <q> Slave Select Low Detect Enable
// <i> This bit enables wake up when the slave select (_SS) pin transitions from high to low. (SSDE)
// <id> spi_slave_arch_ssde
#ifndef CONF_SERCOM_3_SPI_SSDE
#define CONF_SERCOM_3_SPI_SSDE 0
#endif
// <q> Slave Detect Preload Enable
// <i> Setting this bit will enable preloading of the slave shift register when there is no transfer in progress. (PLOADEN)
// <id> spi_slave_arch_ploaden
#ifndef CONF_SERCOM_3_SPI_PLOADEN
#define CONF_SERCOM_3_SPI_PLOADEN 0
#endif
// <q> Enable SPI address mode
// <i> This will enable SPI frames with address, first received character is treated as address. (FORM=SPI_ADDR)
// <id> spi_slave_arch_amode_en
#ifndef CONF_SERCOM_3_SPI_AMODE_EN
#define CONF_SERCOM_3_SPI_AMODE_EN 0
#endif
// <o> Address Mode
// <0x0=>Address mask
// <0x1=>Two unique addresses
// <0x2=>Address range
// <i> These bits set the slave addressing mode when the frame format with address is used. (AMODE)
// <id> spi_slave_arch_amode
#ifndef CONF_SERCOM_3_SPI_AMODE
#define CONF_SERCOM_3_SPI_AMODE 0
#endif
// <o> Address <0-255>
// <i> These bits hold the address when SPI address modes is enabled. (ADDR)
// <id> spi_slave_arch_addr
#ifndef CONF_SERCOM_3_SPI_ADDR
#define CONF_SERCOM_3_SPI_ADDR 0
#endif
// <o> Address mask <0-255>
// <i> These bits hold the address mask when SPI address mode is enabled. (ADDRMASK)
// <id> spi_slave_arch_addrmask
#ifndef CONF_SERCOM_3_SPI_ADDRMASK
#define CONF_SERCOM_3_SPI_ADDRMASK 0
#endif
// <q> Run in stand-by
// <i> Module stays active in stand-by sleep mode. (RUNSTDBY)
// <id> spi_slave_arch_runstdby
#ifndef CONF_SERCOM_3_SPI_RUNSTDBY
#define CONF_SERCOM_3_SPI_RUNSTDBY 0x0
#endif
// <o> Debug Stop Mode
// <i> Behavior of the baud-rate generator when CPU is halted by external debugger. (DBGSTOP)
// <0=>Keep running
// <1=>Halt
// <id> spi_slave_arch_dbgstop
#ifndef CONF_SERCOM_3_SPI_DBGSTOP
#define CONF_SERCOM_3_SPI_DBGSTOP 0
#endif
// </e>
// This bit is not applicable in slave mode
#ifndef CONF_SERCOM_3_SPI_MSSEN
#define CONF_SERCOM_3_SPI_MSSEN 0x0
#endif
#ifndef CONF_SERCOM_3_SPI_BAUD_RATE
#define CONF_SERCOM_3_SPI_BAUD_RATE 0
#endif
#ifndef CONF_SERCOM_3_SPI_DUMMYBYTE
#define CONF_SERCOM_3_SPI_DUMMYBYTE 0x0
#endif
#include <peripheral_clk_config.h>
// Enable configuration of module

View File

@ -931,6 +931,86 @@
// <GCLK_PCHCTRL_GEN_GCLK11_Val"> Generic clock generator 11
// <i> Select the clock source for CORE.
#ifndef CONF_GCLK_SERCOM3_CORE_SRC
#define CONF_GCLK_SERCOM3_CORE_SRC GCLK_PCHCTRL_GEN_GCLK0_Val
#endif
// <y> Slow Clock Source
// <id> slow_gclk_selection
// <GCLK_PCHCTRL_GEN_GCLK0_Val"> Generic clock generator 0
// <GCLK_PCHCTRL_GEN_GCLK1_Val"> Generic clock generator 1
// <GCLK_PCHCTRL_GEN_GCLK2_Val"> Generic clock generator 2
// <GCLK_PCHCTRL_GEN_GCLK3_Val"> Generic clock generator 3
// <GCLK_PCHCTRL_GEN_GCLK4_Val"> Generic clock generator 4
// <GCLK_PCHCTRL_GEN_GCLK5_Val"> Generic clock generator 5
// <GCLK_PCHCTRL_GEN_GCLK6_Val"> Generic clock generator 6
// <GCLK_PCHCTRL_GEN_GCLK7_Val"> Generic clock generator 7
// <GCLK_PCHCTRL_GEN_GCLK8_Val"> Generic clock generator 8
// <GCLK_PCHCTRL_GEN_GCLK9_Val"> Generic clock generator 9
// <GCLK_PCHCTRL_GEN_GCLK10_Val"> Generic clock generator 10
// <GCLK_PCHCTRL_GEN_GCLK11_Val"> Generic clock generator 11
// <i> Select the slow clock source.
#ifndef CONF_GCLK_SERCOM3_SLOW_SRC
#define CONF_GCLK_SERCOM3_SLOW_SRC GCLK_PCHCTRL_GEN_GCLK3_Val
#endif
/**
* \def CONF_GCLK_SERCOM3_CORE_FREQUENCY
* \brief SERCOM3's Core Clock frequency
*/
#ifndef CONF_GCLK_SERCOM3_CORE_FREQUENCY
#define CONF_GCLK_SERCOM3_CORE_FREQUENCY 100000000
#endif
/**
* \def CONF_GCLK_SERCOM3_SLOW_FREQUENCY
* \brief SERCOM3's Slow Clock frequency
*/
#ifndef CONF_GCLK_SERCOM3_SLOW_FREQUENCY
#define CONF_GCLK_SERCOM3_SLOW_FREQUENCY 32768
#endif
// <y> Core Clock Source
// <id> core_gclk_selection
// <GCLK_PCHCTRL_GEN_GCLK0_Val"> Generic clock generator 0
// <GCLK_PCHCTRL_GEN_GCLK1_Val"> Generic clock generator 1
// <GCLK_PCHCTRL_GEN_GCLK2_Val"> Generic clock generator 2
// <GCLK_PCHCTRL_GEN_GCLK3_Val"> Generic clock generator 3
// <GCLK_PCHCTRL_GEN_GCLK4_Val"> Generic clock generator 4
// <GCLK_PCHCTRL_GEN_GCLK5_Val"> Generic clock generator 5
// <GCLK_PCHCTRL_GEN_GCLK6_Val"> Generic clock generator 6
// <GCLK_PCHCTRL_GEN_GCLK7_Val"> Generic clock generator 7
// <GCLK_PCHCTRL_GEN_GCLK8_Val"> Generic clock generator 8
// <GCLK_PCHCTRL_GEN_GCLK9_Val"> Generic clock generator 9
// <GCLK_PCHCTRL_GEN_GCLK10_Val"> Generic clock generator 10
// <GCLK_PCHCTRL_GEN_GCLK11_Val"> Generic clock generator 11
// <i> Select the clock source for CORE.
#ifndef CONF_GCLK_SERCOM5_CORE_SRC
#define CONF_GCLK_SERCOM5_CORE_SRC GCLK_PCHCTRL_GEN_GCLK0_Val

View File

@ -0,0 +1,126 @@
<ArmGcc>
<armgcc.common.outputfiles.hex>True</armgcc.common.outputfiles.hex>
<armgcc.common.outputfiles.lss>True</armgcc.common.outputfiles.lss>
<armgcc.common.outputfiles.eep>True</armgcc.common.outputfiles.eep>
<armgcc.common.outputfiles.bin>True</armgcc.common.outputfiles.bin>
<armgcc.common.outputfiles.srec>True</armgcc.common.outputfiles.srec>
<armgcc.compiler.symbols.DefSymbols>
<ListValues>
<Value>DEBUG</Value>
<Value>ARM_MATH_CM4=1</Value>
</ListValues>
</armgcc.compiler.symbols.DefSymbols>
<armgcc.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\</Value>
<Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include</Value>
<Value>../Config</Value>
<Value>../</Value>
<Value>../examples</Value>
<Value>../hal/include</Value>
<Value>../hal/utils/include</Value>
<Value>../hpl/adc</Value>
<Value>../hpl/ccl</Value>
<Value>../hpl/cmcc</Value>
<Value>../hpl/core</Value>
<Value>../hpl/dmac</Value>
<Value>../hpl/eic</Value>
<Value>../hpl/evsys</Value>
<Value>../hpl/gclk</Value>
<Value>../hpl/mclk</Value>
<Value>../hpl/osc32kctrl</Value>
<Value>../hpl/oscctrl</Value>
<Value>../hpl/pm</Value>
<Value>../hpl/port</Value>
<Value>../hpl/qspi</Value>
<Value>../hpl/ramecc</Value>
<Value>../hpl/sercom</Value>
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
</ListValues>
</armgcc.compiler.directories.IncludePaths>
<armgcc.compiler.optimization.level>Optimize debugging experience (-Og)</armgcc.compiler.optimization.level>
<armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>
<armgcc.compiler.optimization.DebugLevel>Maximum (-g3)</armgcc.compiler.optimization.DebugLevel>
<armgcc.compiler.warnings.AllWarnings>True</armgcc.compiler.warnings.AllWarnings>
<armgcc.compiler.miscellaneous.OtherFlags>-std=gnu11 -mfloat-abi=hard -mfpu=fpv4-sp-d16</armgcc.compiler.miscellaneous.OtherFlags>
<armgcc.linker.general.UseNewlibNano>True</armgcc.linker.general.UseNewlibNano>
<armgcc.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
<Value>libarm_cortexM4lf_math.a</Value>
</ListValues>
</armgcc.linker.libraries.Libraries>
<armgcc.linker.libraries.LibrarySearchPaths>
<ListValues>
<Value>C:\Users\ge37vez\Documents\Git Repos\bldc_control_thesis\bldc_firmware_thesis\2_Motor_Master_D51\Two_Motor_D51\Two_Motor_D51\cmsis</Value>
<Value>%24(ProjectDir)\Device_Startup</Value>
</ListValues>
</armgcc.linker.libraries.LibrarySearchPaths>
<armgcc.linker.optimization.GarbageCollectUnusedSections>True</armgcc.linker.optimization.GarbageCollectUnusedSections>
<armgcc.linker.memorysettings.ExternalRAM />
<armgcc.linker.miscellaneous.LinkerFlags>-Tsamd51j18a_flash.ld -std=gnu99 -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mfp16-format=ieee</armgcc.linker.miscellaneous.LinkerFlags>
<armgcc.assembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\</Value>
<Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include</Value>
<Value>../Config</Value>
<Value>../</Value>
<Value>../examples</Value>
<Value>../hal/include</Value>
<Value>../hal/utils/include</Value>
<Value>../hpl/adc</Value>
<Value>../hpl/ccl</Value>
<Value>../hpl/cmcc</Value>
<Value>../hpl/core</Value>
<Value>../hpl/dmac</Value>
<Value>../hpl/eic</Value>
<Value>../hpl/evsys</Value>
<Value>../hpl/gclk</Value>
<Value>../hpl/mclk</Value>
<Value>../hpl/osc32kctrl</Value>
<Value>../hpl/oscctrl</Value>
<Value>../hpl/pm</Value>
<Value>../hpl/port</Value>
<Value>../hpl/qspi</Value>
<Value>../hpl/ramecc</Value>
<Value>../hpl/sercom</Value>
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
</ListValues>
</armgcc.assembler.general.IncludePaths>
<armgcc.assembler.debugging.DebugLevel>Default (-g)</armgcc.assembler.debugging.DebugLevel>
<armgcc.preprocessingassembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\</Value>
<Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include</Value>
<Value>../Config</Value>
<Value>../</Value>
<Value>../examples</Value>
<Value>../hal/include</Value>
<Value>../hal/utils/include</Value>
<Value>../hpl/adc</Value>
<Value>../hpl/ccl</Value>
<Value>../hpl/cmcc</Value>
<Value>../hpl/core</Value>
<Value>../hpl/dmac</Value>
<Value>../hpl/eic</Value>
<Value>../hpl/evsys</Value>
<Value>../hpl/gclk</Value>
<Value>../hpl/mclk</Value>
<Value>../hpl/osc32kctrl</Value>
<Value>../hpl/oscctrl</Value>
<Value>../hpl/pm</Value>
<Value>../hpl/port</Value>
<Value>../hpl/qspi</Value>
<Value>../hpl/ramecc</Value>
<Value>../hpl/sercom</Value>
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
</ListValues>
</armgcc.preprocessingassembler.general.IncludePaths>
<armgcc.preprocessingassembler.debugging.DebugLevel>Default (-Wa,-g)</armgcc.preprocessingassembler.debugging.DebugLevel>
</ArmGcc>

View File

@ -0,0 +1,285 @@
/*
* master_slave_IF.h
*
* Created: 8/18/2021 4:32:19 PM
* Author: ge37vez
*/
#ifndef MASTER_SLAVE_IF_H_
#define MASTER_SLAVE_IF_H_
#define SLAVE_BUFFER_SIZE_BYTES 64
#define SLAVE_BUFFER_SIZE_LONG SLAVE_BUFFER_SIZE_BYTES/4
static uint32_t SPI_rx_buffer[SLAVE_BUFFER_SIZE_LONG] = {0};
static uint32_t SPI_tx_buffer[SLAVE_BUFFER_SIZE_LONG] = {0};
//static uint8_t SPI_tx_buffer[SLAVE_BUFFER_SIZE] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,
//18,19,20,21,22,23,24,25,26,27,28,29,30,31};
//tx_buffer
/* Motor 3*/
static volatile uint8_t *M3_Status = (uint8_t *)&SPI_tx_buffer[0];
static volatile uint8_t *M3_Mode = (((uint8_t *)&SPI_tx_buffer[0])+1);
static volatile int16_t *M3_Joint_rel_position = (((int16_t *)&SPI_tx_buffer[0])+1);
static volatile int16_t *M3_Joint_abs_position = ((int16_t *)&SPI_tx_buffer[1]);
static volatile int16_t *M3_Motor_speed = (((int16_t *)&SPI_tx_buffer[1])+1);
static volatile int16_t *M3_Motor_current_bus = ((int16_t *)&SPI_tx_buffer[2]);
static volatile int16_t *M3_Motor_currentPhA = (((int16_t *)&SPI_tx_buffer[2])+1);
static volatile int16_t *M3_Motor_currentPhB = ((int16_t *)&SPI_tx_buffer[3]);
static volatile int16_t *M3_Motor_currentPhC = (((int16_t *)&SPI_tx_buffer[3])+1);
static volatile int16_t *M3_Motor__hallState = ((int16_t *)&SPI_tx_buffer[4]);
static volatile int16_t *M3_Motor_dutyCycle = (((int16_t *)&SPI_tx_buffer[4])+1);
/* Motor 4*/
static volatile uint8_t *M4_Status = (uint8_t *)&SPI_tx_buffer[5];
static volatile uint8_t *M4_Mode = (((uint8_t *)&SPI_tx_buffer[5])+1);
static volatile int16_t *M4_Joint_rel_position = (((int16_t *)&SPI_tx_buffer[5])+1);
static volatile int16_t *M4_Joint_abs_position = ((int16_t *)&SPI_tx_buffer[6]);
static volatile int16_t *M4_Motor_speed = (((int16_t *)&SPI_tx_buffer[6])+1);
static volatile int16_t *M4_Motor_current_bus = ((int16_t *)&SPI_tx_buffer[7]);
static volatile int16_t *M4_Motor_currentPhA = (((int16_t *)&SPI_tx_buffer[7])+1);
static volatile int16_t *M4_Motor_currentPhB = ((int16_t *)&SPI_tx_buffer[8]);
static volatile int16_t *M4_Motor_currentPhC = (((int16_t *)&SPI_tx_buffer[8])+1);
static volatile int16_t *M4_Motor__hallState = ((int16_t *)&SPI_tx_buffer[9]);
static volatile int16_t *M4_Motor_dutyCycle = (((int16_t *)&SPI_tx_buffer[9])+1);
/* IMU */
static volatile int16_t *q_x0 = (int16_t *)&SPI_tx_buffer[10];
static volatile int16_t *q_y0 = (((int16_t *)&SPI_tx_buffer[10])+1);
static volatile int16_t *q_z0 = (int16_t *)&SPI_tx_buffer[11];
static volatile int16_t *q_w0 = (((int16_t *)&SPI_tx_buffer[11])+1);
/* EMG */
static volatile int16_t *FSR_CH1 = (int16_t *)&SPI_tx_buffer[12]; //2 byte - 48 of 64
static volatile int16_t *FSR_CH2 = (((int16_t *)&SPI_tx_buffer[12])+1);
static volatile int16_t *FSR_CH3 = (int16_t *)&SPI_tx_buffer[13]; //2 byte - 52 of 64
static volatile int16_t *FSR_CH4 = (((int16_t *)&SPI_tx_buffer[13])+1);
static volatile int16_t *FSR_CH5 = (int16_t *)&SPI_tx_buffer[14]; //2 byte - 56 of 64
static volatile int16_t *Pressure_CH1 = (((int16_t *)&SPI_tx_buffer[14])+1);
static volatile int16_t *Pressure_CH2 = (int16_t *)&SPI_tx_buffer[15]; //2 byte - 60 of 64
static volatile int16_t *Pressure_CH3 = (((int16_t *)&SPI_tx_buffer[15])+1);
//rx_buffer
///* Motor 3*/
static volatile uint8_t *M3_Control_mode = (uint8_t *)&SPI_rx_buffer[0]; //1 byte - 0 of 32
static volatile uint8_t *M3_Control_set = (((uint8_t *)&SPI_rx_buffer[0])+1); //1 byte - 1 of 32
static volatile int16_t *M3_Desired_pos = ((int16_t *)&SPI_rx_buffer[0]+1); //2 byte - 2 of 32
static volatile int16_t *M3_Desired_speed = (int16_t *)&SPI_rx_buffer[1]; //2 byte - 4 of 32
static volatile int16_t *M3_Desired_current = ((int16_t *)&SPI_rx_buffer[1]+1); //2 byte - 6 of 32
static volatile int16_t *M3_Max_pos = (int16_t *)&SPI_rx_buffer[2]; //2 byte - 8 of 32
static volatile int16_t *M3_Max_velocity = ((int16_t *)&SPI_rx_buffer[2]+1); //2 byte - 10 of 32
static volatile int16_t *M3_Max_current = (int16_t *)&SPI_rx_buffer[3]; //2 byte - 12 of 32
static volatile int16_t *M3_Spare = ((int16_t *)&SPI_rx_buffer[3]+1); //2 byte - 14 of 32
///* Motor 4*/
static volatile uint8_t *M4_Control_mode = (uint8_t *)&SPI_rx_buffer[4]; //1 byte - 16 of 32
static volatile uint8_t *M4_Control_set = (((uint8_t *)&SPI_rx_buffer[4])+1); //1 byte - 17 of 32
static volatile int16_t *M4_Desired_pos = ((int16_t *)&SPI_rx_buffer[4]+1); //2 byte - 18 of 32
static volatile int16_t *M4_Desired_speed = (int16_t *)&SPI_rx_buffer[5]; //2 byte - 20 of 32
static volatile int16_t *M4_Desired_current = ((int16_t *)&SPI_rx_buffer[5]+1); //2 byte - 22 of 32
static volatile int16_t *M4_Max_pos = (int16_t *)&SPI_rx_buffer[6]; //2 byte - 24 of 32
static volatile int16_t *M4_Max_velocity = ((int16_t *)&SPI_rx_buffer[6]+1); //2 byte - 26 of 32
static volatile int16_t *M4_Max_current = (int16_t *)&SPI_rx_buffer[7]; //2 byte - 28 of 32
static volatile int16_t *M4_Spare = ((int16_t *)&SPI_rx_buffer[7]+1); //2 byte - 30 of 32
////tx_buffer
///* Motor 3*/
//static volatile uint8_t *M3_Status = (uint8_t *)&SPI_tx_buffer[0]; //1 byte - 0 of 64
//static volatile uint8_t *M3_Mode = (uint8_t *)&SPI_tx_buffer[1]; //1 byte - 1 of 64
//static volatile int16_t *M3_Joint_rel_position = (int16_t *)&SPI_tx_buffer[2]; //2 byte - 2 of 64
//static volatile int16_t *M3_Joint_abs_position = (int16_t *)&SPI_tx_buffer[4]; //2 byte - 4 of 64
//static volatile int16_t *M3_Motor_speed = (int16_t *)&SPI_tx_buffer[6]; //2 byte - 6 of 64
//static volatile int16_t *M3_Motor_current_bus = (int16_t *)&SPI_tx_buffer[8]; //2 byte - 8 of 64
//static volatile int16_t *M3_Motor_currentPhA = (int16_t *)&SPI_tx_buffer[10]; //2 byte - 10 of 64
//static volatile int16_t *M3_Motor_currentPhB = (int16_t *)&SPI_tx_buffer[12]; //2 byte - 12 of 64
//static volatile int16_t *M3_Motor_currentPhC = (int16_t *)&SPI_tx_buffer[14]; //2 byte - 14 of 64
//static volatile int16_t *M3_Motor__hallState = (int16_t *)&SPI_tx_buffer[16]; //2 byte - 16 of 64
//static volatile int16_t *M3_Motor_dutyCycle = (int16_t *)&SPI_tx_buffer[18]; //2 byte - 18 of 64
///* Motor 4*/
//static volatile uint8_t *M4_Status = (uint8_t *)&SPI_tx_buffer[20]; //1 byte - 20 of 64
//static volatile uint8_t *M4_Mode = (uint8_t *)&SPI_tx_buffer[21]; //1 byte - 21 of 64
//static volatile int16_t *M4_Joint_rel_position = (int16_t *)&SPI_tx_buffer[22]; //2 byte - 22 of 64
//static volatile int16_t *M4_Joint_abs_position = (int16_t *)&SPI_tx_buffer[24]; //2 byte - 24 of 64
//static volatile int16_t *M4_Motor_speed = (int16_t *)&SPI_tx_buffer[26]; //2 byte - 26 of 64
//static volatile int16_t *M4_Motor_current_bus = (int16_t *)&SPI_tx_buffer[28]; //2 byte - 28 of 64
//static volatile int16_t *M4_Motor_currentPhA = (int16_t *)&SPI_tx_buffer[30]; //2 byte - 30 of 64
//static volatile int16_t *M4_Motor_currentPhB = (int16_t *)&SPI_tx_buffer[32]; //2 byte - 32 of 64
//static volatile int16_t *M4_Motor_currentPhC = (int16_t *)&SPI_tx_buffer[34]; //2 byte - 34 of 64
//static volatile int16_t *M4_Motor__hallState = (int16_t *)&SPI_tx_buffer[36]; //2 byte - 36 of 64
//static volatile int16_t *M4_Motor_dutyCycle = (int16_t *)&SPI_tx_buffer[38]; //2 byte - 38 of 64
///* IMU */
//static volatile int16_t *q_x0 = (int16_t *)&SPI_tx_buffer[40]; //2 byte - 40 of 64
//static volatile int16_t *q_y0 = (int16_t *)&SPI_tx_buffer[42]; //2 byte - 42 of 64
//static volatile int16_t *q_z0 = (int16_t *)&SPI_tx_buffer[44]; //2 byte - 44 of 64
//static volatile int16_t *q_w0 = (int16_t *)&SPI_tx_buffer[46]; //2 byte - 46 of 64
///* EMG */
//static volatile int16_t *FSR_CH1 = (int16_t *)&SPI_tx_buffer[48]; //2 byte - 48 of 64
//static volatile int16_t *FSR_CH2 = (int16_t *)&SPI_tx_buffer[50]; //2 byte - 50 of 64
//static volatile int16_t *FSR_CH3 = (int16_t *)&SPI_tx_buffer[52]; //2 byte - 52 of 64
//static volatile int16_t *FSR_CH4 = (int16_t *)&SPI_tx_buffer[54]; //2 byte - 54 of 64
//static volatile int16_t *FSR_CH5 = (int16_t *)&SPI_tx_buffer[56]; //2 byte - 56 of 64
//static volatile int16_t *Pressure_CH1 = (int16_t *)&SPI_tx_buffer[58]; //2 byte - 58 of 64
//static volatile int16_t *Pressure_CH2 = (int16_t *)&SPI_tx_buffer[60]; //2 byte - 60 of 64
//static volatile int16_t *Pressure_CH3 = (int16_t *)&SPI_tx_buffer[62]; //2 byte - 62 of 64
//
////rx_buffer
/////* Motor 3*/
//static volatile uint8_t *M3_Control_mode = (uint8_t *)&SPI_rx_buffer[0]; //1 byte - 0 of 32
//static volatile uint8_t *M3_Control_set = (uint8_t *)&SPI_rx_buffer[1]; //1 byte - 1 of 32
//static volatile int16_t *M3_Desired_pos = (int16_t *)&SPI_rx_buffer[2]; //2 byte - 2 of 32
//static volatile int16_t *M3_Desired_speed = (int16_t *)&SPI_rx_buffer[4]; //2 byte - 4 of 32
//static volatile int16_t *M3_Desired_current = (int16_t *)&SPI_rx_buffer[6]; //2 byte - 6 of 32
//static volatile int16_t *M3_Max_pos = (int16_t *)&SPI_rx_buffer[8]; //2 byte - 8 of 32
//static volatile int16_t *M3_Max_velocity = (int16_t *)&SPI_rx_buffer[10]; //2 byte - 10 of 32
//static volatile int16_t *M3_Max_current = (int16_t *)&SPI_rx_buffer[12]; //2 byte - 12 of 32
//static volatile int16_t *M3_Spare = (int16_t *)&SPI_rx_buffer[14]; //2 byte - 14 of 32
/////* Motor 4*/
//static volatile uint8_t *M4_Control_mode = (int16_t *)&SPI_rx_buffer[16]; //1 byte - 16 of 32
//static volatile uint8_t *M4_Control_set = (int16_t *)&SPI_rx_buffer[17]; //1 byte - 17 of 32
//static volatile int16_t *M4_Desired_pos = (int16_t *)&SPI_rx_buffer[18]; //2 byte - 18 of 32
//static volatile int16_t *M4_Desired_speed = (int16_t *)&SPI_rx_buffer[20]; //2 byte - 20 of 32
//static volatile int16_t *M4_Desired_current = (int16_t *)&SPI_rx_buffer[22]; //2 byte - 22 of 32
//static volatile int16_t *M4_Max_pos = (int16_t *)&SPI_rx_buffer[24]; //2 byte - 24 of 32
//static volatile int16_t *M4_Max_velocity = (int16_t *)&SPI_rx_buffer[26]; //2 byte - 26 of 32
//static volatile int16_t *M4_Max_current = (int16_t *)&SPI_rx_buffer[28]; //2 byte - 28 of 32
//static volatile int16_t *M4_Spare = (int16_t *)&SPI_rx_buffer[30]; //2 byte - 30 of 32
static void update_telemetry(void)
{
inline int16_t convert_to_mA(volatile float32_t current_PU)
{
return (int16_t)(current_PU*1000.0f);
}
//
//*M3_Status = 0;
//*M3_Mode = 0;
/* Motor 1 */
*M3_Status = Motor1.motor_state.fault;
*M3_Mode = Motor1.motor_state.currentstate;
*M3_Joint_rel_position = Motor1.motor_status.Num_Steps;
*M3_Joint_abs_position = Motor1.motor_setpoints.desired_position + 1 ;
//*M3_Motor_speed = (((int16_t *)&QSPI_tx_buffer[1]+1);
*M3_Motor_current_bus = convert_to_mA(Motor1.Iphase_pu.Bus);
*M3_Motor_currentPhA = convert_to_mA(Motor1.Iphase_pu.A);
*M3_Motor_currentPhB = convert_to_mA(Motor1.Iphase_pu.B);
*M3_Motor_currentPhC = convert_to_mA(Motor1.Iphase_pu.C);
*M3_Motor__hallState = Motor1.motor_status.currentHallPattern;
*M3_Motor_dutyCycle = Motor1.motor_status.duty_cycle;
*M3_Motor_speed = (int16_t)Motor1.motor_status.calc_rpm;
//*M3_Joint_abs_position = ;
/* Motor 2 */
*M4_Status = Motor2.motor_state.fault;
*M4_Mode = Motor2.motor_state.currentstate;
*M4_Joint_rel_position = Motor2.motor_status.Num_Steps;
*M4_Joint_abs_position = Motor2.motor_setpoints.desired_position + 1 ;
//*M3_Motor_speed = (((int16_t *)&QSPI_tx_buffer[1]+1);
*M4_Motor_current_bus = convert_to_mA( Motor2.Iphase_pu.Bus);
*M4_Motor_currentPhA = convert_to_mA( Motor2.Iphase_pu.A);
*M4_Motor_currentPhB = convert_to_mA( Motor2.Iphase_pu.B);
*M4_Motor_currentPhC = convert_to_mA(Motor2.Iphase_pu.C);
*M4_Motor__hallState = Motor2.motor_status.currentHallPattern;
*M4_Motor_dutyCycle = Motor2.motor_status.duty_cycle;
*M4_Motor_speed = (int16_t)Motor2.motor_status.calc_rpm;
//*M4_Joint_abs_position = Motor2.motor_status.actualDirection;
}
static void update_setpoints(void)
{
Motor1.motor_setpoints.desired_position = *M3_Desired_pos;
Motor1.motor_setpoints.desired_speed = *M3_Desired_speed;
Motor1.motor_setpoints.desired_torque = *M3_Desired_current;
Motor1.motor_setpoints.max_current = *M3_Max_current;
Motor1.motor_setpoints.max_torque = *M3_Max_current;
Motor1.motor_setpoints.max_velocity = *M3_Max_velocity;
Motor2.motor_setpoints.desired_position = *M4_Desired_pos;
Motor2.motor_setpoints.desired_speed = *M4_Desired_speed;
Motor2.motor_setpoints.desired_torque = *M4_Desired_current;
Motor2.motor_setpoints.max_current = *M4_Max_current;
Motor2.motor_setpoints.max_torque = *M4_Max_current;
Motor2.motor_setpoints.max_velocity = *M4_Max_velocity;
volatile int y = 0;
//volatile uint8_t a = *M3_Control_mode;
//volatile uint8_t b = *M3_Control_set;
//volatile int16_t c = *M3_Desired_pos;
//volatile int16_t d = *M3_Desired_speed;
//volatile int16_t e = *M3_Desired_current;
//volatile int16_t f = *M3_Max_pos;
//volatile int16_t g = *M3_Max_velocity;
//volatile int16_t h = *M3_Max_current;
//volatile int16_t i = *M3_Spare;
//inline float32_t convert_int_to_PU(volatile int16_t input)
//{
//return ((float32_t)(input/1000.0f));
//}
////Motor1.des_mode = 0;
////Motor1.set = 0;
//Motor1.motor_setpoints.desired_position = *desired_position;
//Motor1.motor_setpoints.desired_speed = *desired_speed;
////Motor1.desired_speed = 1500;
//Motor1.motor_setpoints.desired_torque = convert_int_to_PU(*desired_torque);
////Motor1.controllerParam.I_kp = 0;
////Motor1.controllerParam.I_ki = 0;
////Motor1.controllerParam.V_kp = 0;
////Motor1.controllerParam.V_kd = 0;
////Motor1.controllerParam.V_kd = 0;
////Motor1.controllerParam.P_kp = 0;
////Motor1.controllerParam.P_ki = 0;
////Motor1.reductionRatio = 0;
//Motor1.motor_setpoints.max_velocity = *max_velocity;
//Motor1.motor_setpoints.max_current = convert_int_to_PU(*max_current);
//Motor1.motor_setpoints.max_torque = convert_int_to_PU(*max_torque);
////Motor1.Spare1 = 0;
////Motor1.Spare2 = 0;
////Motor1.Spare3 = 0;
////Motor1.Spare4 = 0;
}
static inline void comms_check(void)
{
/* Motor 1*/
*M3_Status = 1;
*M3_Mode = 2;
*M3_Joint_rel_position = -3;
*M3_Joint_abs_position = 4;
*M3_Motor_speed = -5;
*M3_Motor_current_bus = 6;
*M3_Motor_currentPhA = -7;
*M3_Motor_currentPhB = 8;
*M3_Motor_currentPhC = -9;
*M3_Motor__hallState = 10;
*M3_Motor_dutyCycle = -11;
/* Motor 2*/
*M4_Status = 12;
*M4_Mode = 13;
*M4_Joint_rel_position = 14;
*M4_Joint_abs_position = -15;
*M4_Motor_speed = 16;
*M4_Motor_current_bus = -17;
*M4_Motor_currentPhA = 18;
*M4_Motor_currentPhB = -19;
*M4_Motor_currentPhC = 20;
*M4_Motor__hallState = -21;
*M4_Motor_dutyCycle = 22;
/* IMU */
*q_x0 = 23;
*q_y0 = -24;
*q_z0 = 25;
*q_w0 = -26;
/* EMG */
*FSR_CH1 = 27;
*FSR_CH2 = -28;
*FSR_CH3 = 29;
*FSR_CH4 = -30;
*FSR_CH5 = 31;
*Pressure_CH1 = -32;
*Pressure_CH2 = 33;
*Pressure_CH3 = -34;
}
#endif /* MASTER_SLAVE_IF_H_ */

View File

@ -0,0 +1,121 @@
<ArmGcc>
<armgcc.common.outputfiles.hex>True</armgcc.common.outputfiles.hex>
<armgcc.common.outputfiles.lss>True</armgcc.common.outputfiles.lss>
<armgcc.common.outputfiles.eep>True</armgcc.common.outputfiles.eep>
<armgcc.common.outputfiles.bin>True</armgcc.common.outputfiles.bin>
<armgcc.common.outputfiles.srec>True</armgcc.common.outputfiles.srec>
<armgcc.compiler.symbols.DefSymbols>
<ListValues>
<Value>NDEBUG</Value>
</ListValues>
</armgcc.compiler.symbols.DefSymbols>
<armgcc.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\</Value>
<Value>../Config</Value>
<Value>../</Value>
<Value>../examples</Value>
<Value>../hal/include</Value>
<Value>../hal/utils/include</Value>
<Value>../hpl/adc</Value>
<Value>../hpl/ccl</Value>
<Value>../hpl/cmcc</Value>
<Value>../hpl/core</Value>
<Value>../hpl/dmac</Value>
<Value>../hpl/eic</Value>
<Value>../hpl/evsys</Value>
<Value>../hpl/gclk</Value>
<Value>../hpl/mclk</Value>
<Value>../hpl/osc32kctrl</Value>
<Value>../hpl/oscctrl</Value>
<Value>../hpl/pm</Value>
<Value>../hpl/port</Value>
<Value>../hpl/qspi</Value>
<Value>../hpl/ramecc</Value>
<Value>../hpl/sercom</Value>
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
<Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include</Value>
</ListValues>
</armgcc.compiler.directories.IncludePaths>
<armgcc.compiler.optimization.level>Optimize for size (-Os)</armgcc.compiler.optimization.level>
<armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>
<armgcc.compiler.warnings.AllWarnings>True</armgcc.compiler.warnings.AllWarnings>
<armgcc.compiler.miscellaneous.OtherFlags>-std=gnu99 -mfloat-abi=softfp -mfpu=fpv4-sp-d16</armgcc.compiler.miscellaneous.OtherFlags>
<armgcc.linker.general.UseNewlibNano>True</armgcc.linker.general.UseNewlibNano>
<armgcc.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
<Value>libarm_cortexM4lf_math.a</Value>
</ListValues>
</armgcc.linker.libraries.Libraries>
<armgcc.linker.libraries.LibrarySearchPaths>
<ListValues>
<Value>C:\Users\ge37vez\Documents\Git Repos\bldc_control_thesis\bldc_firmware_thesis\2_Motor_Master_D51\Two_Motor_D51\Two_Motor_D51\cmsis</Value>
<Value>%24(ProjectDir)\Device_Startup</Value>
</ListValues>
</armgcc.linker.libraries.LibrarySearchPaths>
<armgcc.linker.optimization.GarbageCollectUnusedSections>True</armgcc.linker.optimization.GarbageCollectUnusedSections>
<armgcc.linker.miscellaneous.LinkerFlags>-Tsamd51j18a_flash.ld</armgcc.linker.miscellaneous.LinkerFlags>
<armgcc.assembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\</Value>
<Value>../Config</Value>
<Value>../</Value>
<Value>../examples</Value>
<Value>../hal/include</Value>
<Value>../hal/utils/include</Value>
<Value>../hpl/adc</Value>
<Value>../hpl/ccl</Value>
<Value>../hpl/cmcc</Value>
<Value>../hpl/core</Value>
<Value>../hpl/dmac</Value>
<Value>../hpl/eic</Value>
<Value>../hpl/evsys</Value>
<Value>../hpl/gclk</Value>
<Value>../hpl/mclk</Value>
<Value>../hpl/osc32kctrl</Value>
<Value>../hpl/oscctrl</Value>
<Value>../hpl/pm</Value>
<Value>../hpl/port</Value>
<Value>../hpl/qspi</Value>
<Value>../hpl/ramecc</Value>
<Value>../hpl/sercom</Value>
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
<Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include</Value>
</ListValues>
</armgcc.assembler.general.IncludePaths>
<armgcc.preprocessingassembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\</Value>
<Value>../Config</Value>
<Value>../</Value>
<Value>../examples</Value>
<Value>../hal/include</Value>
<Value>../hal/utils/include</Value>
<Value>../hpl/adc</Value>
<Value>../hpl/ccl</Value>
<Value>../hpl/cmcc</Value>
<Value>../hpl/core</Value>
<Value>../hpl/dmac</Value>
<Value>../hpl/eic</Value>
<Value>../hpl/evsys</Value>
<Value>../hpl/gclk</Value>
<Value>../hpl/mclk</Value>
<Value>../hpl/osc32kctrl</Value>
<Value>../hpl/oscctrl</Value>
<Value>../hpl/pm</Value>
<Value>../hpl/port</Value>
<Value>../hpl/qspi</Value>
<Value>../hpl/ramecc</Value>
<Value>../hpl/sercom</Value>
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
<Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include</Value>
</ListValues>
</armgcc.preprocessingassembler.general.IncludePaths>
</ArmGcc>

View File

@ -65,6 +65,7 @@
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_sleep.h" IsConfig="false" Hash="KuZDwgrLdU+fuMG82ZFTqg" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_spi_m_dma.h" IsConfig="false" Hash="MRP9iaBaY97VrZIf+yI+nQ" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_spi_m_sync.h" IsConfig="false" Hash="2oma6hRMCcowUy2wVveqMg" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_spi_s_sync.h" IsConfig="false" Hash="BcDifFYXDI6EDQ8wmawMBw" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_adc_dma.h" IsConfig="false" Hash="ZNWJ5APLfPqPLqI7LDqlMA" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_cmcc.h" IsConfig="false" Hash="mDAHEzTxsniAe2HtqO43oA" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_core.h" IsConfig="false" Hash="XeEtUlBSwXUmLA41hFYYWg" />
@ -154,8 +155,8 @@
<AcmeProjectActionInfo Action="File" Source="driver_init.c" IsConfig="false" Hash="hFsI0KNGnASX+ATI26NJbQ" />
<AcmeProjectActionInfo Action="File" Source="driver_init.h" IsConfig="false" Hash="ZKqx201YiRi6ZiHSKlGz3Q" />
<AcmeProjectActionInfo Action="File" Source="atmel_start_pins.h" IsConfig="false" Hash="+wCcCLhKgMbl0si1M3P8dw" />
<AcmeProjectActionInfo Action="File" Source="examples/driver_examples.h" IsConfig="false" Hash="oqvcKPd0QTLLlbjHQia2RA" />
<AcmeProjectActionInfo Action="File" Source="examples/driver_examples.c" IsConfig="false" Hash="hmEZxj87UJ+w+jNPwsyZ8Q" />
<AcmeProjectActionInfo Action="File" Source="examples/driver_examples.h" IsConfig="false" Hash="ku+cJerLpmCXiUs6zVK4Hw" />
<AcmeProjectActionInfo Action="File" Source="examples/driver_examples.c" IsConfig="false" Hash="Ouvfc1KEvPIeiJoyFZEwxw" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_adc_sync.h" IsConfig="false" Hash="ez1X5T9kpYwT+1+5x4Pxqg" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_pwm.h" IsConfig="false" Hash="RXcBZcci/7vXKRJKNIq/Kw" />
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_adc_async.h" IsConfig="false" Hash="kKbVmqgGDUkuWZYErBwgVA" />
@ -176,6 +177,7 @@
<AcmeProjectActionInfo Action="File" Source="hal/src/hal_pwm.c" IsConfig="false" Hash="ZFJmg7/0rhQ6JMKyxuk9kw" />
<AcmeProjectActionInfo Action="File" Source="hal/src/hal_spi_m_dma.c" IsConfig="false" Hash="KMrinO/3xx7qWxy2PsJB7g" />
<AcmeProjectActionInfo Action="File" Source="hal/src/hal_spi_m_sync.c" IsConfig="false" Hash="Q0IudnTEWeoIkfQIoYIqxA" />
<AcmeProjectActionInfo Action="File" Source="hal/src/hal_spi_s_sync.c" IsConfig="false" Hash="ieqBjH0Vtuy9FaOaSw71oQ" />
<AcmeProjectActionInfo Action="File" Source="hal/utils/include/parts.h" IsConfig="false" Hash="iNmlmHpRV6XXv+ujHdORcQ" />
<AcmeProjectActionInfo Action="File" Source="hpl/adc/hpl_adc.c" IsConfig="false" Hash="zpNRk8aViOSavv+cy054MA" />
<AcmeProjectActionInfo Action="File" Source="hpl/adc/hpl_adc_base.h" IsConfig="false" Hash="19A6ERNtsVVhqvnpGbR3Lg" />
@ -216,9 +218,9 @@
<AcmeProjectActionInfo Action="File" Source="config/hpl_oscctrl_config.h" IsConfig="true" Hash="Xe5v62bijwZLOPLD+rPcrA" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_port_config.h" IsConfig="true" Hash="t2a7bSchW8m+1AA7WkNKWw" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_qspi_config.h" IsConfig="true" Hash="CwZ360eeEYs7T9SYFSvDug" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_sercom_config.h" IsConfig="true" Hash="z3+LxZ23I/55LvX2h+956g" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_sercom_config.h" IsConfig="true" Hash="vFkdNF0nx5i77+SQuUidMg" />
<AcmeProjectActionInfo Action="File" Source="config/hpl_tcc_config.h" IsConfig="true" Hash="zZZRHMWHMW27lOSGyjdBeg" />
<AcmeProjectActionInfo Action="File" Source="config/peripheral_clk_config.h" IsConfig="true" Hash="yN8Uael2Zk5Hh7j12sfU4w" />
<AcmeProjectActionInfo Action="File" Source="config/peripheral_clk_config.h" IsConfig="true" Hash="s49yApqTTX3OvfWWN3Bbtg" />
</AcmeActionInfos>
<NonsecureFilesInfo />
</AcmeProjectConfig>
@ -382,7 +384,6 @@
<armgcc.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\</Value>
<Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include</Value>
<Value>../Config</Value>
<Value>../</Value>
<Value>../examples</Value>
@ -407,6 +408,7 @@
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
<Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include</Value>
</ListValues>
</armgcc.compiler.directories.IncludePaths>
<armgcc.compiler.optimization.level>Optimize debugging experience (-Og)</armgcc.compiler.optimization.level>
@ -433,7 +435,6 @@
<armgcc.assembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\</Value>
<Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include</Value>
<Value>../Config</Value>
<Value>../</Value>
<Value>../examples</Value>
@ -458,13 +459,13 @@
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
<Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include</Value>
</ListValues>
</armgcc.assembler.general.IncludePaths>
<armgcc.assembler.debugging.DebugLevel>Default (-g)</armgcc.assembler.debugging.DebugLevel>
<armgcc.preprocessingassembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\</Value>
<Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include</Value>
<Value>../Config</Value>
<Value>../</Value>
<Value>../examples</Value>
@ -489,6 +490,7 @@
<Value>../hpl/tc</Value>
<Value>../hpl/tcc</Value>
<Value>../hri</Value>
<Value>%24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include</Value>
</ListValues>
</armgcc.preprocessingassembler.general.IncludePaths>
<armgcc.preprocessingassembler.debugging.DebugLevel>Default (-Wa,-g)</armgcc.preprocessingassembler.debugging.DebugLevel>
@ -655,6 +657,9 @@
<Compile Include="hal\include\hal_spi_m_sync.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="hal\include\hal_spi_s_sync.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="hal\include\hpl_adc_async.h">
<SubType>compile</SubType>
</Compile>
@ -814,6 +819,9 @@
<Compile Include="hal\src\hal_spi_m_sync.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="hal\src\hal_spi_s_sync.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="hal\utils\include\compiler.h">
<SubType>compile</SubType>
</Compile>
@ -1051,6 +1059,9 @@
<Compile Include="motorparameters.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="MSIF_slave.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="statemachine.h">
<SubType>compile</SubType>
</Compile>
@ -1125,6 +1136,9 @@
<None Include="hal\documentation\spi_master_sync.rst">
<SubType>compile</SubType>
</None>
<None Include="hal\documentation\spi_slave_sync.rst">
<SubType>compile</SubType>
</None>
<None Include="hpl\doc_lite\tc.rst">
<SubType>compile</SubType>
</None>

View File

@ -5,10 +5,17 @@
* Author: Nick-XMG
*/
#ifndef CONFIGURATION_H_
#define CONFIGURATION_H_
// Conditional Inclusion Only Select One
#define _MASTER
//#define _SLAVE
#ifdef _MASTER
#include "EtherCAT_QSPI.h"
#endif // MASTER
// ----------------------------------------------------------------------
// Header Files
// ----------------------------------------------------------------------
@ -19,6 +26,31 @@
#include "ADS1299.h"
#include "hpl_spi_m_dma.h"
#ifdef _SLAVE
#include "hal_spi_s_sync.h"
#include "hpl_spi_s_sync.h"
#endif // SLAVE
/* DMA channel Descriptor */
extern DmacDescriptor _descriptor_section[DMAC_CH_NUM];
extern DmacDescriptor _write_back_section[DMAC_CH_NUM];
// ----------------------------------------------------------------------
// DMA CHANNEL NUMBER CONFIGURATION
// ----------------------------------------------------------------------
#define CONF_SERCOM_1_SPI_DMA_RX_CHANNEL 0U
#define CONF_SERCOM_1_SPI_DMA_TX_CHANNEL 7U
#define CONF_ADC_1_ADC_RES_READY_CHANNEL 3U
#define CONF_ADC_1_SEQUENCER_CHANNEL 4U
#ifdef _MASTER
#define CONF_SERCOM_2_SPI_DMA_RX_CHANNEL 2U
#define CONF_SERCOM_2_SPI_DMA_TX_CHANNEL 5U
#else
#define CONF_ADC_0_ADC_RES_READY_CHANNEL 2U
#define CONF_ADC_0_SEQUENCER_CHANNEL 5U
#endif
// ----------------------------------------------------------------------
// PWM Timer Initialization
// ----------------------------------------------------------------------
@ -76,12 +108,6 @@ static void configure_tcc_pwm(void)
// ADC DMA Initialization
// M1_IA=ADC1_AIN[9], M1_IB=ADC1_AIN[8], M2_IA=ADC1_AIN[7], M2_IB=ADC1_AIN[6]
// ----------------------------------------------------------------------
//#define CONF_ADC_0_ADC_RES_READY_CHANNEL 4U
#define CONF_ADC_1_ADC_RES_READY_CHANNEL 3U
//#define CONF_ADC_0_SEQUENCER_CHANNEL 6U
#define CONF_ADC_1_SEQUENCER_CHANNEL 4U
const uint32_t adc0_seq_regs[4] = {0};
const uint32_t adc1_seq_regs[4] = {0x0089, 0x0088, 0x0087, 0x0086}; /* Differential */
//const uint32_t adc1_seq_regs[4] = {0x1807, 0x1806, 0x1809, 0x1808}; /* Single Ended */
@ -91,8 +117,6 @@ volatile int16_t adc1_res[4] = {0};
struct _dma_resource *adc_sram_dma_resource;
struct _dma_resource *adc_dmac_sequence_resource;
static void adc_dmac_sequence_init()
{
/* Configure the DMAC source address, destination address,
@ -122,7 +146,7 @@ static void adc_sram_dmac_init()
// ----------------------------------------------------------------------
// ADC Initialization
// ----------------------------------------------------------------------
static void adc_init_dma_descriptors(void)
static void adc1_init_dma_descriptors(void)
{
adc_sram_dmac_init();
adc_dmac_sequence_init();
@ -131,21 +155,18 @@ static void adc_init_dma_descriptors(void)
}
// ----------------------------------------------------------------------
// SPI DMA communication between Master & Slave Board
// ----------------------------------------------------------------------
#define MASTER_BUFFER_SIZE 64
#define MASTER_BUFFER_SIZE_LONG MASTER_BUFFER_SIZE/4
/* DMA channel Descriptor */
extern DmacDescriptor _descriptor_section[DMAC_CH_NUM];
extern DmacDescriptor _write_back_section[DMAC_CH_NUM];
#define MASTER_SLAVE_BUFFER_SIZE 64
#define MASTER_SLAVE_BUFFER_SIZE_LONG MASTER_SLAVE_BUFFER_SIZE/4
static void boardToBoardTransferInit(void)
{
#ifdef _MASTER
struct io_descriptor *io;
spi_m_dma_get_io_descriptor(&SPI_1_MSIF, &io);
spi_m_dma_get_io_descriptor(&SPI_1_MSIF_M, &io);
//spi_m_dma_register_callback(&SPI_1_MSIF, SPI_M_DMA_CB_RX_DONE, b2bTransferComplete_cb);
//SERCOM4->SPI.CTRLC.bit.DATA32B = true;
//SERCOM1->SPI.LENGTH.bit.LENEN = true;
@ -154,29 +175,101 @@ static void boardToBoardTransferInit(void)
SERCOM1->SPI.CTRLC.bit.ICSPACE = 4;
SERCOM1->SPI.CTRLC.bit.DATA32B= true;
gpio_set_pin_level(SPI1_CS, true);
spi_m_dma_enable(&SPI_1_MSIF);
spi_m_dma_enable(&SPI_1_MSIF_M);
#endif //MASTER
#ifdef _SLAVE
spi_m_dma_deinit(&SPI_1_MSIF_M);
spi_s_sync_init(&SPI_1_MSIF_S, SERCOM1);
SPI_1_MSIF_Slave_PORT_init();
SERCOM1->SPI.CTRLC.bit.DATA32B = true;
hri_sercomspi_set_CTRLB_PLOADEN_bit(SERCOM1);
hri_sercomspi_write_CTRLA_MODE_bf(SERCOM1, 0x02);
hri_sercomspi_write_CTRLB_MSSEN_bit(SERCOM1, true);
spi_s_sync_enable(&SPI_1_MSIF_S);
NVIC_DisableIRQ((IRQn_Type)SERCOM1_1_IRQn);
NVIC_ClearPendingIRQ((IRQn_Type)SERCOM1_1_IRQn);
NVIC_EnableIRQ((IRQn_Type)SERCOM1_1_IRQn);
hri_sercomspi_set_INTEN_TXC_bit(SERCOM1);
hri_sercomspi_set_INTEN_SSL_bit(SERCOM1);
#endif //SLAVE
}
static void spi_master_init_dma_descriptors()
void SPI_1_MSIF_Slave_PORT_init(void)
{
_dma_set_source_address(CONF_SERCOM_1_SPI_M_DMA_RX_CHANNEL,
(uint32_t *)&(((SercomSpi *)(SPI_1_MSIF.dev.prvt))->DATA.reg));
_dma_set_destination_address(CONF_SERCOM_1_SPI_M_DMA_RX_CHANNEL, &QSPI_tx_buffer[16]);
_dma_set_data_amount(CONF_SERCOM_1_SPI_M_DMA_RX_CHANNEL, MASTER_BUFFER_SIZE_LONG);
_dma_set_next_descriptor(CONF_SERCOM_1_SPI_M_DMA_RX_CHANNEL, CONF_SERCOM_1_SPI_M_DMA_RX_CHANNEL);
// Set pin direction to input
gpio_set_pin_direction(SPI1_MOSI, GPIO_DIRECTION_IN);
gpio_set_pin_pull_mode(SPI1_MOSI,
// <y> Pull configuration
// <id> pad_pull_config
// <GPIO_PULL_OFF"> Off
// <GPIO_PULL_UP"> Pull-up
// <GPIO_PULL_DOWN"> Pull-down
GPIO_PULL_OFF);
gpio_set_pin_function(SPI1_MOSI, PINMUX_PA00D_SERCOM1_PAD0);
gpio_set_pin_level(SPI1_SCK,
// <y> Initial level
// <id> pad_initial_level
// <false"> Low
// <true"> High
false);
// Set pin direction to output
gpio_set_pin_direction(SPI1_SCK, GPIO_DIRECTION_OUT);
gpio_set_pin_function(SPI1_SCK, PINMUX_PA01D_SERCOM1_PAD1);
// Set pin direction to input
gpio_set_pin_direction(SPI1_CS, GPIO_DIRECTION_IN);
gpio_set_pin_pull_mode(SPI1_CS,
// <y> Pull configuration
// <id> pad_pull_config
// <GPIO_PULL_OFF"> Off
// <GPIO_PULL_UP"> Pull-up
// <GPIO_PULL_DOWN"> Pull-down
GPIO_PULL_OFF);
gpio_set_pin_function(SPI1_CS, PINMUX_PB22C_SERCOM1_PAD2);
gpio_set_pin_level(SPI1_MISO,
// <y> Initial level
// <id> pad_initial_level
// <false"> Low
// <true"> High
false);
// Set pin direction to output
gpio_set_pin_direction(SPI1_MISO, GPIO_DIRECTION_OUT);
gpio_set_pin_function(SPI1_MISO, PINMUX_PB23C_SERCOM1_PAD3);
}
_dma_set_source_address(CONF_SERCOM_1_SPI_M_DMA_TX_CHANNEL, &QSPI_rx_buffer[16]);
_dma_set_destination_address(CONF_SERCOM_1_SPI_M_DMA_TX_CHANNEL,
(uint32_t *)&(((SercomSpi *)(SPI_1_MSIF.dev.prvt))->DATA.reg));
_dma_set_data_amount(CONF_SERCOM_1_SPI_M_DMA_TX_CHANNEL, MASTER_BUFFER_SIZE_LONG);
_dma_set_next_descriptor(CONF_SERCOM_1_SPI_M_DMA_TX_CHANNEL, CONF_SERCOM_1_SPI_M_DMA_TX_CHANNEL);
static void spi_master_slave_if_dma_descriptor_init()
{
#ifdef _MASTER
_dma_set_source_address(CONF_SERCOM_1_SPI_DMA_RX_CHANNEL,
(uint32_t *)&(((SercomSpi *)(SPI_1_MSIF_M.dev.prvt))->DATA.reg));
_dma_set_destination_address(CONF_SERCOM_1_SPI_DMA_RX_CHANNEL, &QSPI_tx_buffer[16]);
_dma_set_data_amount(CONF_SERCOM_1_SPI_DMA_RX_CHANNEL, MASTER_SLAVE_BUFFER_SIZE_LONG);
_dma_set_next_descriptor(CONF_SERCOM_1_SPI_DMA_RX_CHANNEL, CONF_SERCOM_1_SPI_DMA_RX_CHANNEL);
hri_dmacdescriptor_set_BTCTRL_VALID_bit(&_descriptor_section[CONF_SERCOM_1_SPI_M_DMA_TX_CHANNEL]);
hri_dmacdescriptor_set_BTCTRL_VALID_bit(&_descriptor_section[CONF_SERCOM_1_SPI_M_DMA_RX_CHANNEL]);
_dma_set_source_address(CONF_SERCOM_1_SPI_DMA_TX_CHANNEL, &QSPI_rx_buffer[16]);
_dma_set_destination_address(CONF_SERCOM_1_SPI_DMA_TX_CHANNEL,
(uint32_t *)&(((SercomSpi *)(SPI_1_MSIF_M.dev.prvt))->DATA.reg));
_dma_set_data_amount(CONF_SERCOM_1_SPI_DMA_TX_CHANNEL, MASTER_SLAVE_BUFFER_SIZE_LONG);
_dma_set_next_descriptor(CONF_SERCOM_1_SPI_DMA_TX_CHANNEL, CONF_SERCOM_1_SPI_DMA_TX_CHANNEL);
hri_dmacdescriptor_set_BTCTRL_VALID_bit(&_descriptor_section[CONF_SERCOM_1_SPI_DMA_TX_CHANNEL]);
hri_dmacdescriptor_set_BTCTRL_VALID_bit(&_descriptor_section[CONF_SERCOM_1_SPI_DMA_RX_CHANNEL]);
/* callback */
//struct _dma_resource *resource_rx, *resource_tx;
//_dma_get_channel_resource(&resource_rx, CONF_SERCOM_1_SPI_M_DMA_RX_CHANNEL);
@ -186,18 +279,12 @@ static void spi_master_init_dma_descriptors()
/* Enable DMA transfer complete interrupt */
//_dma_set_irq_state(DMAC_CHANNEL_CONF_SERCOM_1_RECEIVE, DMA_TRANSFER_COMPLETE_CB, true);
#endif //MASTER
}
// ----------------------------------------------------------------------
// SPI DMA communication ADS1299
// ----------------------------------------------------------------------
//
#define CONF_SERCOM_2_SPI_M_DMA_RX_CHANNEL 2U
#define CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL 5U
#ifdef _MASTER
/* 219 Bites total
* Number format is 24 bit
* 7 (uint_32) - 24 bits
@ -206,47 +293,43 @@ extern volatile uint32_t ads1299_buffer[ADS_BUFFER_SIZE];
//
static void spi_ads1299_init_dma_descriptors()
{
_dma_set_source_address(CONF_SERCOM_2_SPI_M_DMA_RX_CHANNEL,
_dma_set_source_address(CONF_SERCOM_2_SPI_DMA_RX_CHANNEL,
(uint32_t *)&(((SercomSpi *)(SPI_2.dev.prvt))->DATA.reg));
_dma_set_destination_address(CONF_SERCOM_2_SPI_M_DMA_RX_CHANNEL, &_ads1299_channel_data[0]);
_dma_set_data_amount(CONF_SERCOM_2_SPI_M_DMA_RX_CHANNEL, ADS_BUFFER_SIZE);
_dma_set_next_descriptor(CONF_SERCOM_2_SPI_M_DMA_RX_CHANNEL, CONF_SERCOM_2_SPI_M_DMA_RX_CHANNEL);
_dma_set_destination_address(CONF_SERCOM_2_SPI_DMA_RX_CHANNEL, &_ads1299_channel_data[0]);
_dma_set_data_amount(CONF_SERCOM_2_SPI_DMA_RX_CHANNEL, ADS_BUFFER_SIZE);
_dma_set_next_descriptor(CONF_SERCOM_2_SPI_DMA_RX_CHANNEL, CONF_SERCOM_2_SPI_DMA_RX_CHANNEL);
_dma_set_source_address(CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL, &ads1299_buffer[0]);
_dma_set_destination_address(CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL,
_dma_set_source_address(CONF_SERCOM_2_SPI_DMA_TX_CHANNEL, &ads1299_buffer[0]);
_dma_set_destination_address(CONF_SERCOM_2_SPI_DMA_TX_CHANNEL,
(uint32_t *)&(((SercomSpi *)(SPI_2.dev.prvt))->DATA.reg));
_dma_set_data_amount(CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL, ADS_BUFFER_SIZE);
_dma_set_next_descriptor(CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL, CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL);
_dma_set_data_amount(CONF_SERCOM_2_SPI_DMA_TX_CHANNEL, ADS_BUFFER_SIZE);
_dma_set_next_descriptor(CONF_SERCOM_2_SPI_DMA_TX_CHANNEL, CONF_SERCOM_2_SPI_DMA_TX_CHANNEL);
hri_dmacdescriptor_set_BTCTRL_VALID_bit(&_descriptor_section[CONF_SERCOM_2_SPI_M_DMA_RX_CHANNEL]);
hri_dmacdescriptor_set_BTCTRL_VALID_bit(&_descriptor_section[CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL]);
hri_dmacdescriptor_set_BTCTRL_VALID_bit(&_descriptor_section[CONF_SERCOM_2_SPI_DMA_RX_CHANNEL]);
hri_dmacdescriptor_set_BTCTRL_VALID_bit(&_descriptor_section[CONF_SERCOM_2_SPI_DMA_TX_CHANNEL]);
/* callback */
struct _dma_resource *resource_rx, *resource_tx;
_dma_get_channel_resource(&resource_rx, CONF_SERCOM_2_SPI_M_DMA_RX_CHANNEL);
_dma_get_channel_resource(&resource_tx, CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL);
_dma_get_channel_resource(&resource_rx, CONF_SERCOM_2_SPI_DMA_RX_CHANNEL);
_dma_get_channel_resource(&resource_tx, CONF_SERCOM_2_SPI_DMA_TX_CHANNEL);
resource_rx->dma_cb.transfer_done = ADS1299_Transfer_Complete_cb;
resource_rx->dma_cb.error = ADS1299_Transfer_error_cb;
resource_tx->dma_cb.transfer_done = ADS1299_Transfer_Complete_cb;
/* Enable DMA transfer complete interrupt */
_dma_set_irq_state(CONF_SERCOM_2_SPI_M_DMA_RX_CHANNEL, DMA_TRANSFER_COMPLETE_CB, true);
_dma_set_irq_state(CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL, DMA_TRANSFER_COMPLETE_CB, true);
_dma_set_irq_state(CONF_SERCOM_2_SPI_DMA_RX_CHANNEL, DMA_TRANSFER_COMPLETE_CB, true);
_dma_set_irq_state(CONF_SERCOM_2_SPI_DMA_TX_CHANNEL, DMA_TRANSFER_COMPLETE_CB, true);
//_dma_set_irq_state(CONF_SERCOM_2_SPI_M_DMA_RX_CHANNEL, DMA_TRANSFER_ERROR_CB, true);
}
#endif //MASTER
// ----------------------------------------------------------------------
// Overall DMA Init
// ----------------------------------------------------------------------
/* Peripherals should be configured before interacting with dma
/* MASTER
* CH0 - SERCOM1_RX(SPI1) - Master-Slave IF - Beat Transfer Event Drives CS Pin
* CH1 - SERCOM5_RX(SPI3) - Angle Sensor
* CH2 - SERCOM2_RX(SPI2) - Expansion IF (EMG) - Beat Transfer Event Drives CS Pin
@ -257,12 +340,24 @@ static void spi_ads1299_init_dma_descriptors()
* CH7 - SERCOM1_TX(SPI1) - Master-Slave IF
*/
/* SLAVE
* CH0 - SERCOM1_RX(SPI1) - Master-Slave IF - Beat Transfer Event Drives CS Pin
* CH1 - SERCOM5_RX(SPI3) - Angle Sensor
* CH2 - ADC0 - Result Ready
* CH3 - ADC1 - Result Ready
* CH4 - ADC1 - Sequencer - Triggered by TCC0 overflow event
* CH5 - ADC0 - Sequencer
* CH6 - SERCOM5_TX(SPI3) - Angle Sensor
* CH7 - SERCOM1_TX(SPI1) - Master-Slave IF
*/
static void init_dma(void)
{
spi_master_init_dma_descriptors();
spi_master_slave_if_dma_descriptor_init();
adc1_init_dma_descriptors();
#ifdef _MASTER
spi_ads1299_init_dma_descriptors();
adc_init_dma_descriptors();
#endif // _MASTER
}
@ -270,19 +365,48 @@ static void init_dma(void)
// Overall DMA Init
// ----------------------------------------------------------------------
/* Peripherals should be configured before interacting with dma
* CH0 - QSPI_RX - For ECAT DMA Mode - Currently Disabled in ASTART
* CH1 - SERCOM1_RX(SPI1) - Master-Slave IF - Beat Transfer Event Drives CS Pin
* CH2 - SERCOM2_RX(SPI2) - Expansion IF (EMG) - Beat Transfer Event Drives CS Pin
* CH3 - SERCOM5_RX(SPI3) - Angle Sensor
* CH4 - ADC0 - Result Ready (Unused on master) - Currently Disabled in ASTART
* CH5 - ADC1 - Result Ready
* CH6 - ADC0 - Sequencer (Unused on master) - Currently Disabled in ASTART
* CH7 - ADC1 - Sequencer - Triggered by TCC0 overflow event
* CH8 - SERCOM2_TX(SPI2) - Expansion IF (EMG)
* CH9 - SERCOM5_TX(SPI3) - Angle Sensor
* CH10 - SERCOM1_TX(SPI1) - Master-Slave IF
* CH11 - QSPI_TX - For ECAT DMA Mode - Currently Disabled in ASTART
/* Master Event System Configured in ATMEL START. Slave retains some of
the same events which are reconfigured and enabled
* CH0 - TCC0 OVF
* CH1 - TC0 OVF (1ms) - telemetry
* CH2 - TC1 OVF (1ms) - Angle Sensor
* CH3 - CCL output 0
* CH4 - CCL output 2
*/
void slave_event_system_config(void)
{
event_system_deinit();
uint16_t slave_channel_confs[5] =
{
0x0229, /* EVGEN = 29(TCC0_OVF) , Path = 2(ASYNCHRONOUS), Edgesel = 0(NO_EVT_OUTPUT)*/
0x0000, //0x0649, /* EVGEN = 49(TC0_OVF) , Path = 2(ASYNCHRONOUS), Edgesel = 1(RISING_EDGE) */
0x0000, //0x044C, /* EVGEN = 4C(TC1_OVF) , Path = 2(ASYNCHRONOUS), Edgesel = 1(RISING_EDGE) */
0x0674, /* EVGEN = 74(CCL_LUTOUT0) , Path = 2(ASYNCHRONOUS), Edgesel = 1(RISING_EDGE) */
0x0276 /* EVGEN = 76(CCL_LUTOUT2), Path = 2(ASYNCHRONOUS), Edgesel = 1(RISING_EDGE) */
};
uint32_t slave_interrupt_cfg[5] =
{
0x00 /* The Event Detected Channel interrupt is disabled, The Overrun Channel interrupt is disabled. */
};
/* USER_ID, Channel n-1 */
//hri_evsys_write_USER_reg(EVSYS, 0x01, 0x02); /*PORT_EV0 - CH1*/
//hri_evsys_write_USER_reg(EVSYS, 0x02, 0x07); /*PORT_EV1 - CH6*/
//hri_evsys_write_USER_reg(EVSYS, 0x03, 0x06); /*PORT_EV2 - CH5*/
//hri_evsys_write_USER_reg(EVSYS, 0x04, 0x09); /*PORT_EV3 - CH8*/
hri_evsys_write_USER_reg(EVSYS, 0x09, 0x01); /*DMAC_CH4 - CH0 */
//hri_evsys_write_USER_reg(EVSYS, 0x10, 0x06); /*DMAC_CH5 - CH1*/
//hri_evsys_write_USER_reg(EVSYS, 0x12, 0x03); /*DMAC_CH7 - CH2*/
hri_evsys_write_USER_reg(EVSYS, 0x46, 0x0c); /*TC2 - CH11*/
hri_evsys_write_USER_reg(EVSYS, 0x48, 0x0d); /*TC4 - CH12 */
uint8_t i;
for (i = 0; i < 5; i++) {
hri_evsys_write_CHANNEL_reg(EVSYS, i, slave_channel_confs[i]);
hri_evsys_write_CHINTEN_reg(EVSYS, i, slave_interrupt_cfg[i]);
}
}
#endif /* CONFIGURATION_H_ */

View File

@ -25,7 +25,9 @@ struct qspi_dma_descriptor ECAT_QSPI;
struct i2c_m_async_desc I2C_0;
struct spi_m_dma_descriptor SPI_1_MSIF;
struct spi_m_dma_descriptor SPI_1_MSIF_M;
struct spi_s_sync_descriptor SPI_1_MSIF_S;
struct pwm_descriptor PWM_0;
@ -439,7 +441,7 @@ void I2C_0_init(void)
I2C_0_PORT_init();
}
void SPI_1_MSIF_PORT_init(void)
void SPI_1_MSIF_M_PORT_init(void)
{
gpio_set_pin_level(SPI1_MOSI,
@ -480,7 +482,7 @@ void SPI_1_MSIF_PORT_init(void)
gpio_set_pin_function(SPI1_MISO, PINMUX_PB23C_SERCOM1_PAD3);
}
void SPI_1_MSIF_CLOCK_init(void)
void SPI_1_MSIF_M_CLOCK_init(void)
{
hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM1_GCLK_ID_CORE, CONF_GCLK_SERCOM1_CORE_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos));
hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM1_GCLK_ID_SLOW, CONF_GCLK_SERCOM1_SLOW_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos));
@ -488,11 +490,11 @@ void SPI_1_MSIF_CLOCK_init(void)
hri_mclk_set_APBAMASK_SERCOM1_bit(MCLK);
}
void SPI_1_MSIF_init(void)
void SPI_1_MSIF_M_init(void)
{
SPI_1_MSIF_CLOCK_init();
spi_m_dma_init(&SPI_1_MSIF, SERCOM1);
SPI_1_MSIF_PORT_init();
SPI_1_MSIF_M_CLOCK_init();
spi_m_dma_init(&SPI_1_MSIF_M, SERCOM1);
SPI_1_MSIF_M_PORT_init();
}
void SPI_2_PORT_init(void)
@ -551,6 +553,25 @@ void SPI_2_init(void)
SPI_2_PORT_init();
}
void SPI_1_MSIF_S_PORT_init(void)
{
}
void SPI_1_MSIF_S_CLOCK_init(void)
{
hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM3_GCLK_ID_CORE, CONF_GCLK_SERCOM3_CORE_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos));
hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM3_GCLK_ID_SLOW, CONF_GCLK_SERCOM3_SLOW_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos));
hri_mclk_set_APBBMASK_SERCOM3_bit(MCLK);
}
void SPI_1_MSIF_S_init(void)
{
//SPI_1_MSIF_S_CLOCK_init();
//spi_s_sync_init(&SPI_1_MSIF_S, SERCOM3);
//SPI_1_MSIF_S_PORT_init();
}
void SPI_3_PORT_init(void)
{
@ -805,10 +826,12 @@ void system_init(void)
I2C_0_init();
SPI_1_MSIF_init();
SPI_1_MSIF_M_init();
SPI_2_init();
SPI_1_MSIF_S_init();
SPI_3_init();
TIMER_0_CLOCK_init();

View File

@ -37,6 +37,8 @@ extern "C" {
#include <hal_spi_m_dma.h>
#include <hal_spi_m_sync.h>
#include <hal_spi_s_sync.h>
#include <hal_spi_m_sync.h>
#include <tc_lite.h>
#include <tc_lite.h>
@ -57,8 +59,10 @@ extern struct qspi_dma_descriptor ECAT_QSPI;
extern struct i2c_m_async_desc I2C_0;
extern struct spi_m_dma_descriptor SPI_1_MSIF;
extern struct spi_m_dma_descriptor SPI_1_MSIF_M;
extern struct spi_m_sync_descriptor SPI_2;
extern struct spi_s_sync_descriptor SPI_1_MSIF_S;
extern struct spi_m_sync_descriptor SPI_3;
extern struct pwm_descriptor PWM_0;
@ -85,14 +89,19 @@ void I2C_0_PORT_init(void);
void I2C_0_CLOCK_init(void);
void I2C_0_init(void);
void SPI_1_MSIF_PORT_init(void);
void SPI_1_MSIF_CLOCK_init(void);
void SPI_1_MSIF_init(void);
void SPI_1_MSIF_M_PORT_init(void);
void SPI_1_MSIF_M_CLOCK_init(void);
void SPI_1_MSIF_M_init(void);
void SPI_2_PORT_init(void);
void SPI_2_CLOCK_init(void);
void SPI_2_init(void);
void SPI_1_MSIF_S_PORT_init(void);
void SPI_1_MSIF_S_CLOCK_init(void);
void SPI_1_MSIF_S_init(void);
void SPI_1_MSIF_S_example(void);
void SPI_3_PORT_init(void);
void SPI_3_CLOCK_init(void);
void SPI_3_init(void);

View File

@ -124,7 +124,7 @@ void I2C_0_example(void)
}
/**
* Example of using SPI_1_MSIF to write "Hello World" using the IO abstraction.
* Example of using SPI_1_MSIF_M to write "Hello World" using the IO abstraction.
*
* Since the driver is asynchronous we need to use statically allocated memory for string
* because driver initiates transfer and then returns before the transmission is completed.
@ -132,21 +132,21 @@ void I2C_0_example(void)
* Once transfer has been completed the tx_cb function will be called.
*/
static uint8_t example_SPI_1_MSIF[12] = "Hello World!";
static uint8_t example_SPI_1_MSIF_M[12] = "Hello World!";
static void tx_complete_cb_SPI_1_MSIF(struct _dma_resource *resource)
static void tx_complete_cb_SPI_1_MSIF_M(struct _dma_resource *resource)
{
/* Transfer completed */
}
void SPI_1_MSIF_example(void)
void SPI_1_MSIF_M_example(void)
{
struct io_descriptor *io;
spi_m_dma_get_io_descriptor(&SPI_1_MSIF, &io);
spi_m_dma_get_io_descriptor(&SPI_1_MSIF_M, &io);
spi_m_dma_register_callback(&SPI_1_MSIF, SPI_M_DMA_CB_TX_DONE, tx_complete_cb_SPI_1_MSIF);
spi_m_dma_enable(&SPI_1_MSIF);
io_write(io, example_SPI_1_MSIF, 12);
spi_m_dma_register_callback(&SPI_1_MSIF_M, SPI_M_DMA_CB_TX_DONE, tx_complete_cb_SPI_1_MSIF_M);
spi_m_dma_enable(&SPI_1_MSIF_M);
io_write(io, example_SPI_1_MSIF_M, 12);
}
/**
@ -163,6 +163,20 @@ void SPI_2_example(void)
io_write(io, example_SPI_2, 12);
}
/**
* Example of using SPI_1_MSIF_S to write "Hello World" using the IO abstraction.
*/
static uint8_t example_SPI_1_MSIF_S[12] = "Hello World!";
void SPI_1_MSIF_S_example(void)
{
struct io_descriptor *io;
spi_s_sync_get_io_descriptor(&SPI_1_MSIF_S, &io);
spi_s_sync_enable(&SPI_1_MSIF_S);
io_write(io, example_SPI_1_MSIF_S, 12);
}
/**
* Example of using SPI_3 to write "Hello World" using the IO abstraction.
*/

View File

@ -24,7 +24,7 @@ void ECAT_QSPI_example(void);
void I2C_0_example(void);
void SPI_1_MSIF_example(void);
void SPI_1_MSIF_M_example(void);
void PWM_0_example(void);

View File

@ -0,0 +1,60 @@
The SPI Slave Synchronous Driver
================================
The serial peripheral interface (SPI) is a synchronous serial communication
interface.
SPI devices communicate in full duplex mode using a master-slave
architecture with a single master. The slave device uses the control signal
and clocks from master for reading and writing. Slave device is selected through
slave select (SS) line.
When data is read or written through the I/O writing function, the driver keeps
polling until amount of characters achieved. Also it's possible to perform
full-duplex read and write through transfer function, which process read and
write at the same time.
When SS detection is considered, a "break on SS detection" option can be enabled
to make it possible to terminate the read/write/transfer on SS desertion.
Features
--------
* Initialization/de-initialization
* Enabling/disabling
* Control of the following settings:
* SPI mode
* Character size
* Data order
* Data transfer: transmission, reception and full-duplex
Applications
------------
* SPI to I2C bridge that bridges SPI commands to I2C interface.
Dependencies
------------
SPI slave capable hardware
Concurrency
-----------
N/A
Limitations
-----------
N/A
Known issues and workarounds
----------------------------
When writing data through SPI slave, the time that the data appears on data line
depends on the SPI hardware, and previous writing state, since there can be
data in output fifo filled by previous broken transmitting. The number of such
dummy/broken characters is limited by hardware. Whether these dummy/broken
characters can be flushed is also limited by hardware.

View File

@ -0,0 +1,204 @@
/**
* \file
*
* \brief SPI Slave functionality declaration.
*
* Copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef _HAL_SPI_S_SYNC_H_INCLUDED
#define _HAL_SPI_S_SYNC_H_INCLUDED
#include "hpl_spi_s_sync.h"
#include "utils.h"
#include "hal_io.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \addtogroup doc_driver_hal_spi_slave_sync
*
* @{
*/
/** \brief SPI Slave HAL driver struct for synchronous access
*/
struct spi_s_sync_descriptor {
struct _spi_s_sync_hpl_interface *func;
/** SPI device instance */
struct _spi_sync_dev dev;
/** I/O read/write */
struct io_descriptor io;
/** Break on SS desert detection. */
uint8_t break_on_ss_det;
};
/** \brief Set the SPI HAL instance function pointer for HPL APIs.
*
* Set SPI HAL instance function pointer for HPL APIs.
*
* \param[in] spi Pointer to the HAL SPI instance.
* \param[in] func Pointer to the HPL api structure.
*
*/
void spi_s_sync_set_func_ptr(struct spi_s_sync_descriptor *spi, void *const func);
/** \brief Initialize the SPI Slave HAL instance and hardware
*
* Initialize SPI Slave HAL with polling mode.
*
* \param[in, out] spi Pointer to the SPI Slave HAL instance.
* \param[in] hw Pointer to the hardware base.
*
* \return Operation status.
* \retval 0 Success.
* \retval <0 Error.
*/
int32_t spi_s_sync_init(struct spi_s_sync_descriptor *spi, void *const hw);
/** \brief Deinitialize the SPI HAL instance
*
* Disable and reset SPI, de-init software.
*
* \param[in,out] spi Pointer to the SPI Slave HAL instance.
*/
void spi_s_sync_deinit(struct spi_s_sync_descriptor *spi);
/** \brief Enable SPI
*
* \param[in,out] spi Pointer to the SPI Slave HAL instance.
*/
void spi_s_sync_enable(struct spi_s_sync_descriptor *spi);
/** \brief Disable SPI
*
* \param[in,out] spi Pointer to the SPI Slave HAL instance.
*/
void spi_s_sync_disable(struct spi_s_sync_descriptor *spi);
/** \brief Set SPI mode
*
* Set the SPI transfer mode (\ref spi_transfer_mode_t),
* which controls the clock polarity and clock phase:
* - Mode 0: leading edge is rising edge, data sample on leading edge.
* - Mode 1: leading edge is rising edge, data sample on trailing edge.
* - Mode 2: leading edge is falling edge, data sample on leading edge.
* - Mode 3: leading edge is falling edge, data sample on trailing edge.
* Note that SPI must be disabled to change mode.
*
* \param[in,out] spi Pointer to the HAL SPI instance.
* \param[in] mode The mode (\ref spi_transfer_mode_t).
*
* \return Operation status.
* \retval 0 Success.
* \retval <0 Error.
*/
int32_t spi_s_sync_set_mode(struct spi_s_sync_descriptor *spi, const enum spi_transfer_mode mode);
/** \brief Set SPI transfer character size in number of bits
*
* The character size (\ref spi_char_size_t) influence the way the data is
* sent/received.
* For char size <= 8-bit, data is stored byte by byte.
* For char size between 9-bit ~ 16-bit, data is stored in 2-byte length.
* Note that the default and recommended char size is 8-bit since it's
* supported by all system.
* Note that the SPI must be disabled to change character size. Also it affects
* buffer accessing, the ring buffer should be flushed before changing it to
* avoid conflicts.
*
* \param[in,out] spi Pointer to the HAL SPI instance.
* \param[in] char_size The char size (~32, recommended 8).
*
* \return Operation status.
* \retval 0 Success.
* \retval <0 Error.
*/
int32_t spi_s_sync_set_char_size(struct spi_s_sync_descriptor *spi, const enum spi_char_size char_size);
/** \brief Set SPI transfer data order
*
* Note that the SPI must be disabled to change data order.
*
* \param[in,out] spi Pointer to the HAL SPI instance.
* \param[in] dord The data order: send LSB/MSB first.
*
* \return Operation status.
* \retval 0 Success.
* \retval <0 Error.
*/
int32_t spi_s_sync_set_data_order(struct spi_s_sync_descriptor *spi, const enum spi_data_order dord);
/** \brief Enable/disable break on SS desert detection
*
* \param[in,out] spi Pointer to the HAL SPI instance.
* \param[in] enable Set to \c true to break R/W loop on SS desert.
*/
void spi_s_sync_break_on_ss_detect(struct spi_s_sync_descriptor *spi, const bool enable);
/** \brief Write/read at the same time
*
* \param[in,out] spi Pointer to the HAL SPI instance.
* \param[in] xfer Pointer to the transfer information (\ref spi_xfer).
*
* \return Operation result.
* \retval <0 Error.
* \retval >=0 Number of characters transferred.
*/
int32_t spi_s_sync_transfer(struct spi_s_sync_descriptor *spi, const struct spi_xfer *xfer);
/**
* \brief Return I/O descriptor for this SPI instance
*
* This function will return an I/O instance for this SPI driver instance
*
* \param[in] spi An SPI slave descriptor, which is used to communicate through
* SPI
* \param[in] io A pointer to an I/O descriptor pointer type
*
* \return Error code.
* \retval 0 No error detected
* \retval <0 Error code
*/
int32_t spi_s_sync_get_io_descriptor(struct spi_s_sync_descriptor *spi, struct io_descriptor **io);
/** \brief Retrieve the current driver version
*
* \return Current driver version.
*/
uint32_t spi_s_sync_get_version(void);
/**@}*/
#ifdef __cplusplus
}
#endif
#endif /* _HAL_SPI_S_SYNC_H_INCLUDED */

View File

@ -0,0 +1,262 @@
/**
* \file
*
* \brief I/O SPI related functionality implementation.
*
* Copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "hal_atomic.h"
#include "hal_spi_s_sync.h"
#include <utils_assert.h>
#include <utils.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Driver version
*/
#define SPI_S_SYNC_DRIVER_VERSION 0x00000001u
/** Enable TX in transfer. */
#define SPI_XFER_TX_EN (1u << 0)
/** Enable RX in transfer. */
#define SPI_XFER_RX_EN (1u << 1)
/**
* \brief Transfer data
* \param[in, out] dev Pointer to the SPI device instance.
* \param[in] xfer Pointer to the transfer struct instance.
* \param[in] flags control options.
* \return Error or number of characters transferred.
* \retval <0 Error.
* \retval >=0 Number of characters transferred.
*/
static int32_t _spi_s_sync_xfer(struct spi_s_sync_descriptor *spi, const struct spi_xfer *xfer, const uint8_t flags)
{
uint32_t txcnt, rxcnt;
union {
uint16_t u16;
uint8_t u8[4];
} tmp;
uint32_t n_bytes;
ASSERT(spi && xfer);
if (xfer->size == 0) {
return 0;
}
n_bytes = xfer->size;
if (spi->dev.char_size > 1) {
n_bytes <<= 1;
}
tmp.u16 = 0;
for (txcnt = 0, rxcnt = 0; txcnt < n_bytes && rxcnt < n_bytes;) {
if (_spi_s_sync_is_error(&spi->dev)) {
return ERR_IO;
}
if ((flags & SPI_XFER_TX_EN) && _spi_s_sync_is_tx_ready(&spi->dev)) {
tmp.u8[0] = xfer->txbuf[txcnt++];
if (spi->dev.char_size > 1) {
tmp.u8[1] = xfer->txbuf[txcnt++];
}
_spi_s_sync_write_one(&spi->dev, tmp.u16);
}
if ((flags & SPI_XFER_RX_EN) && _spi_s_sync_is_rx_ready(&spi->dev)) {
tmp.u16 = _spi_s_sync_read_one(&spi->dev);
if (xfer->rxbuf) {
xfer->rxbuf[rxcnt++] = tmp.u8[0];
if (spi->dev.char_size > 1) {
xfer->rxbuf[rxcnt++] = tmp.u8[1];
}
}
}
if (spi->break_on_ss_det && _spi_s_sync_is_ss_deactivated(&spi->dev)) {
break;
}
}
if (spi->dev.char_size <= 1) {
return (flags & SPI_XFER_RX_EN) ? rxcnt : txcnt;
}
return ((flags & SPI_XFER_RX_EN) ? rxcnt : txcnt) >> 1;
}
/** \brief Do SPI data write
*
* Register background buffer to transmit data.
*
* It never blocks and return quickly, user check status or set callback to
* know when data is sent.
*
* \param[in] io Pointer to the I/O descriptor.
* \param[in] buf Pointer to the buffer to store data to write.
* \param[in] size Size of the data in number of characters.
* \return Operation status.
* \retval 0 Success.
* \retval -1 Busy, transfer in progress.
* \retval -3 Parameter error.
*/
static int32_t _spi_s_sync_io_write(struct io_descriptor *const io, const uint8_t *const buf, const uint16_t size)
{
struct spi_s_sync_descriptor *spi;
struct spi_xfer xfer;
ASSERT(io);
spi = CONTAINER_OF(io, struct spi_s_sync_descriptor, io);
xfer.txbuf = (uint8_t *)buf;
xfer.size = size;
return _spi_s_sync_xfer(spi, &xfer, SPI_XFER_TX_EN);
}
/** \brief Do SPI read from ring-buffer (asynchronously)
*
* Read available characters from ring-buffer and return number of characters
* read.
*
* It never blocks and return quickly, user check status or set callback to
* know when data is ready.
*
* \param[in] io Pointer to the I/O descriptor.
* \param[out] buf Pointer to the buffer to store read data,
NULL to discard data.
* \param[in] size Size of the data in number of characters.
* \return Read result.
* \retval n Number of characters read.
* \retval <0 Error.
*/
static int32_t _spi_s_sync_io_read(struct io_descriptor *const io, uint8_t *const buf, const uint16_t size)
{
struct spi_s_sync_descriptor *spi;
struct spi_xfer xfer;
ASSERT(io);
spi = CONTAINER_OF(io, struct spi_s_sync_descriptor, io);
xfer.rxbuf = (uint8_t *)buf;
xfer.size = size;
return _spi_s_sync_xfer(spi, &xfer, SPI_XFER_RX_EN);
}
/**
* \brief Initialize the SPI HAL instance function pointer for HPL APIs.
*/
void spi_s_sync_set_func_ptr(struct spi_s_sync_descriptor *spi, void *const func)
{
ASSERT(spi);
spi->func = (struct _spi_s_sync_hpl_interface *)func;
}
int32_t spi_s_sync_init(struct spi_s_sync_descriptor *spi, void *const hw)
{
int32_t rc;
ASSERT(spi && hw);
rc = _spi_s_sync_init(&spi->dev, hw);
if (rc < 0) {
return rc;
}
spi->io.read = _spi_s_sync_io_read;
spi->io.write = _spi_s_sync_io_write;
return ERR_NONE;
}
void spi_s_sync_deinit(struct spi_s_sync_descriptor *spi)
{
ASSERT(spi);
_spi_s_sync_deinit(&spi->dev);
}
void spi_s_sync_enable(struct spi_s_sync_descriptor *spi)
{
ASSERT(spi);
_spi_s_sync_enable(&spi->dev);
}
void spi_s_sync_disable(struct spi_s_sync_descriptor *spi)
{
ASSERT(spi);
_spi_s_sync_disable(&spi->dev);
}
int32_t spi_s_sync_set_mode(struct spi_s_sync_descriptor *spi, const enum spi_transfer_mode mode)
{
ASSERT(spi);
return _spi_s_sync_set_mode(&spi->dev, mode);
}
int32_t spi_s_sync_set_char_size(struct spi_s_sync_descriptor *spi, const enum spi_char_size char_size)
{
ASSERT(spi);
return _spi_s_sync_set_char_size(&spi->dev, char_size);
}
int32_t spi_s_sync_set_data_order(struct spi_s_sync_descriptor *spi, const enum spi_data_order dord)
{
ASSERT(spi);
return _spi_s_sync_set_data_order(&spi->dev, dord);
}
void spi_s_sync_break_on_ss_detect(struct spi_s_sync_descriptor *spi, const bool enable)
{
ASSERT(spi);
spi->break_on_ss_det = enable;
}
int32_t spi_s_sync_transfer(struct spi_s_sync_descriptor *spi, const struct spi_xfer *xfer)
{
return _spi_s_sync_xfer(spi, xfer, SPI_XFER_RX_EN | SPI_XFER_TX_EN);
}
int32_t spi_s_sync_get_io_descriptor(struct spi_s_sync_descriptor *spi, struct io_descriptor **io)
{
ASSERT(spi && io);
*io = &spi->io;
return ERR_NONE;
}
uint32_t spi_s_sync_get_version(void)
{
return SPI_S_SYNC_DRIVER_VERSION;
}
#ifdef __cplusplus
}
#endif

View File

@ -19,11 +19,13 @@ void TC0_Handler( void ){
if (TC0->COUNT8.INTFLAG.bit.OVF && TC0->COUNT8.INTENSET.bit.OVF)
{
TC0->COUNT8.INTFLAG.bit.OVF = 0x01;
#ifdef _MASTER
if ((ecat_state == wait2)|(ecat_state == wait))
{
ecat_state= write_fifo;
run_ECAT =true;
}
#endif //MASTER
Motor1.timerflags.motor_telemetry_flag = true;
}
if (TC0->COUNT8.INTFLAG.bit.MC0 && TC0->COUNT8.INTENSET.bit.MC0)

View File

@ -4,21 +4,23 @@
// Header Files
// ----------------------------------------------------------------------
#include "EtherCAT_QSPI.h"
//#include "MSIF_master.h"
#include "configuration.h"
#include "interrupts.h"
#include "bldc.h"
#include "bldc_types.h"
#include "EtherCAT_SlaveDef.h"
#include "statemachine.h"
#include "angle_sensors.h"
#ifdef _MASTER
#include "EtherCAT_SlaveDef.h"
#include "ADS1299.h"
#endif // MASTER
#ifdef _SLAVE
#include "MSIF_slave.h"
#endif // SLAVE
@ -83,13 +85,6 @@ void enable_NVIC_IRQ(void)
//NVIC_SetPriority(TCC0_0_IRQn, 3);
//NVIC_EnableIRQ(EIC_5_IRQn);
/* Reset Latch Interrupt */
ext_irq_register(PIN_PB30, M1_RESET_BAR);
ext_irq_register(PIN_PB31, M2_RESET_BAR);
NVIC_EnableIRQ(EIC_14_IRQn);
NVIC_EnableIRQ(EIC_15_IRQn);
}
void APPLICATION_StateMachine(void)
@ -107,9 +102,18 @@ void APPLICATION_StateMachine(void)
case SYSTEM_INIT:
/* Toggle driver reset Latch */
gpio_set_pin_level(M1_RST, true);
delay_us(100);
gpio_set_pin_level(M1_RST, false);
delay_us(100);
gpio_set_pin_level(M2_RST, true);
delay_us(100);
gpio_set_pin_level(M2_RST, false);
delay_us(100);
/*/* Reset Latch Interrupt */
ext_irq_register(PIN_PB30, M1_RESET_BAR);
ext_irq_register(PIN_PB31, M2_RESET_BAR);
NVIC_EnableIRQ(EIC_14_IRQn);
NVIC_EnableIRQ(EIC_15_IRQn);
/* Update State Variables */
applicationStatus.previousstate = applicationStatus.currentstate;
applicationStatus.currentstate = SYSTEM_IDLE;
@ -154,10 +158,14 @@ int main(void)
__disable_irq();
/* BLDC INIT */
#ifdef _MASTER
BldcInitStruct(&Motor1, &FH_22mm24BXTR);
BldcInitStruct(&Motor2, &FH_32mm12BXTR);
//Motor2.VdcBus_pu = 12.0;
//Motor2.VoneByDcBus_pu = 1.0/Motor2.VdcBus_pu;
#else
BldcInitStruct(&Motor1, &FH_22mm24BXTR);
BldcInitStruct(&Motor2, &FH_22mm24BXTR);
#endif //
Motor1.readHall = &readHallSensorM1;
Motor2.readHall = &readHallSensorM2;
@ -165,38 +173,47 @@ int main(void)
read_zero_current_offset_value(&Motor1, &Motor2);
/* Configure Hardware */
#ifdef _MASTER
config_qspi();
/* ECAT State Machine First run */
ECAT_STATE_MACHINE();
#else
slave_event_system_config();
#endif // _MASTER
configure_tcc_pwm();
adc_sync_enable_channel(&ADC_1, 6);
/* SPI Config */
/* Master Slave Interface init */
boardToBoardTransferInit();
/* DMA Configs */
init_dma();
/* ECAT State Machine First run */
ECAT_STATE_MACHINE();
//angle_sensor_init();
initialize_ads();
/* External IRQ Config */
custom_logic_enable();
delay_us(20);
/* ADS1299 Initialisation */
#ifdef _MASTER
initialize_ads();
delay_us(100);
ADS1299_START();
delay_us(20);
delay_us(100);
#endif // _MASTER
/* ADS Result Ready Interrupt, active low */
__enable_irq();
/* Enable Reception
* Enable RX channels at startup, Linked to itself so never ends
*/
_dma_enable_transaction(CONF_SERCOM_1_SPI_M_DMA_RX_CHANNEL, false);
_dma_enable_transaction(CONF_SERCOM_2_SPI_M_DMA_RX_CHANNEL, false);
_dma_enable_transaction(CONF_SERCOM_1_SPI_DMA_RX_CHANNEL, false);
#ifdef _MASTER
_dma_enable_transaction(CONF_SERCOM_2_SPI_DMA_RX_CHANNEL, false);
#endif //MASTER
/* Clear Exint Flag */
//EIC->INTFLAG.bit.EXTINT = (1<<2);
EIC->INTFLAG.bit.EXTINT = (1<<2);
//ext_irq_register(GPIO_PIN(ADS_DATA_RDY), ADS1299_dataReadyISR);
enable_NVIC_IRQ();
@ -206,21 +223,17 @@ int main(void)
if (Motor1.timerflags.adc_readings_ready_tic) {process_currents();}
if (Motor1.timerflags.motor_telemetry_flag) {
Motor1.timerflags.motor_telemetry_flag = false;
//DMAC->Channel[CONF_SERCOM_1_SPI_M_DMA_RX_CHANNEL].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE;
if (!(DMAC->Channel[CONF_SERCOM_1_SPI_M_DMA_TX_CHANNEL].CHCTRLA.bit.ENABLE)) {
if (!(DMAC->Channel[CONF_SERCOM_1_SPI_DMA_TX_CHANNEL].CHCTRLA.bit.ENABLE)) {
/* Enable */
DMAC->Channel[CONF_SERCOM_1_SPI_M_DMA_TX_CHANNEL].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE;
DMAC->Channel[CONF_SERCOM_1_SPI_DMA_TX_CHANNEL].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE;
}
if(!(DMAC->Channel[CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL].CHCTRLA.bit.ENABLE)) {
#ifdef _MASTER
if(!(DMAC->Channel[CONF_SERCOM_2_SPI_DMA_TX_CHANNEL].CHCTRLA.bit.ENABLE)) {
/* Enable */
DMAC->Channel[CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE;
DMAC->Channel[CONF_SERCOM_2_SPI_DMA_TX_CHANNEL].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE;
}
#endif //MASTER
update_telemetry();
update_setpoints();
}
@ -232,9 +245,9 @@ int main(void)
exec_commutation(&Motor2);
}
#ifdef _MASTER
if(run_ECAT) {ECAT_STATE_MACHINE();}
#endif // _MASTER
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB