diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/.atmelstart/AtmelStart.gpdsc b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/.atmelstart/AtmelStart.gpdsc index 4f2fef4..f61ba3d 100644 --- a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/.atmelstart/AtmelStart.gpdsc +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/.atmelstart/AtmelStart.gpdsc @@ -51,6 +51,7 @@ + @@ -65,6 +66,7 @@ + @@ -177,6 +179,7 @@ + diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/.atmelstart/atmel_start_config.atstart b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/.atmelstart/atmel_start_config.atstart index 98ef807..3a4b4b1 100644 --- a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/.atmelstart/atmel_start_config.atstart +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/.atmelstart/atmel_start_config.atstart @@ -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 diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Config/hpl_sercom_config.h b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Config/hpl_sercom_config.h index 1d01fe3..7d87f2a 100644 --- a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Config/hpl_sercom_config.h +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Config/hpl_sercom_config.h @@ -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 + +// Basic Configuration + +// Receive buffer enable +// Enable receive buffer to receive data from slave. (RXEN) +// spi_slave_rx_enable +#ifndef CONF_SERCOM_3_SPI_RXEN +#define CONF_SERCOM_3_SPI_RXEN 0x1 +#endif + +// Character Size +// Bit size for all characters sent over the SPI bus. (CHSIZE) +// <0x0=>8 bits +// <0x1=>9 bits +// spi_slave_character_size +#ifndef CONF_SERCOM_3_SPI_CHSIZE +#define CONF_SERCOM_3_SPI_CHSIZE 0x0 +#endif + +// + +// Advanced Configuration +// spi_slave_advanced +#ifndef CONF_SERCOM_3_SPI_ADVANCED +#define CONF_SERCOM_3_SPI_ADVANCED 0 +#endif + +// Data Order +// <0=>MSB first +// <1=>LSB first +// I least significant or most significant bit is shifted out first. (DORD) +// spi_slave_arch_dord +#ifndef CONF_SERCOM_3_SPI_DORD +#define CONF_SERCOM_3_SPI_DORD 0x0 +#endif + +// Clock Polarity +// <0=>SCK is low when idle +// <1=>SCK is high when idle +// Determines if the leading edge is rising or falling with a corresponding opposite edge at the trailing edge. (CPOL) +// spi_slave_arch_cpol +#ifndef CONF_SERCOM_3_SPI_CPOL +#define CONF_SERCOM_3_SPI_CPOL 0x0 +#endif + +// Clock Phase +// <0x0=>Sample input on leading edge +// <0x1=>Sample input on trailing edge +// Determines if input data is sampled on leading or trailing SCK edge. (CPHA) +// spi_slave_arch_cpha +#ifndef CONF_SERCOM_3_SPI_CPHA +#define CONF_SERCOM_3_SPI_CPHA 0x1 +#endif + +// Immediate Buffer Overflow Notification +// Controls when OVF is asserted. (IBON) +// <0x0=>In data stream +// <0x1=>On buffer overflow +// spi_slave_arch_ibon +#ifndef CONF_SERCOM_3_SPI_IBON +#define CONF_SERCOM_3_SPI_IBON 0x0 +#endif + +// Slave Select Low Detect Enable +// This bit enables wake up when the slave select (_SS) pin transitions from high to low. (SSDE) +// spi_slave_arch_ssde +#ifndef CONF_SERCOM_3_SPI_SSDE +#define CONF_SERCOM_3_SPI_SSDE 0 +#endif + +// Slave Detect Preload Enable +// Setting this bit will enable preloading of the slave shift register when there is no transfer in progress. (PLOADEN) +// spi_slave_arch_ploaden +#ifndef CONF_SERCOM_3_SPI_PLOADEN +#define CONF_SERCOM_3_SPI_PLOADEN 0 +#endif + +// Enable SPI address mode +// This will enable SPI frames with address, first received character is treated as address. (FORM=SPI_ADDR) +// spi_slave_arch_amode_en +#ifndef CONF_SERCOM_3_SPI_AMODE_EN +#define CONF_SERCOM_3_SPI_AMODE_EN 0 +#endif + +// Address Mode +// <0x0=>Address mask +// <0x1=>Two unique addresses +// <0x2=>Address range +// These bits set the slave addressing mode when the frame format with address is used. (AMODE) +// spi_slave_arch_amode +#ifndef CONF_SERCOM_3_SPI_AMODE +#define CONF_SERCOM_3_SPI_AMODE 0 +#endif + +// Address <0-255> +// These bits hold the address when SPI address modes is enabled. (ADDR) +// spi_slave_arch_addr +#ifndef CONF_SERCOM_3_SPI_ADDR +#define CONF_SERCOM_3_SPI_ADDR 0 +#endif + +// Address mask <0-255> +// These bits hold the address mask when SPI address mode is enabled. (ADDRMASK) +// spi_slave_arch_addrmask +#ifndef CONF_SERCOM_3_SPI_ADDRMASK +#define CONF_SERCOM_3_SPI_ADDRMASK 0 +#endif + +// Run in stand-by +// Module stays active in stand-by sleep mode. (RUNSTDBY) +// spi_slave_arch_runstdby +#ifndef CONF_SERCOM_3_SPI_RUNSTDBY +#define CONF_SERCOM_3_SPI_RUNSTDBY 0x0 +#endif + +// Debug Stop Mode +// Behavior of the baud-rate generator when CPU is halted by external debugger. (DBGSTOP) +// <0=>Keep running +// <1=>Halt +// spi_slave_arch_dbgstop +#ifndef CONF_SERCOM_3_SPI_DBGSTOP +#define CONF_SERCOM_3_SPI_DBGSTOP 0 +#endif + +// + +// 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 // Enable configuration of module diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Config/peripheral_clk_config.h b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Config/peripheral_clk_config.h index 5fb0e21..756808f 100644 --- a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Config/peripheral_clk_config.h +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Config/peripheral_clk_config.h @@ -931,6 +931,86 @@ // Generic clock generator 11 +// Select the clock source for CORE. +#ifndef CONF_GCLK_SERCOM3_CORE_SRC +#define CONF_GCLK_SERCOM3_CORE_SRC GCLK_PCHCTRL_GEN_GCLK0_Val +#endif + +// Slow Clock Source +// slow_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// 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 + +// Core Clock Source +// core_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + // Select the clock source for CORE. #ifndef CONF_GCLK_SERCOM5_CORE_SRC #define CONF_GCLK_SERCOM5_CORE_SRC GCLK_PCHCTRL_GEN_GCLK0_Val diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Debug.xml b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Debug.xml new file mode 100644 index 0000000..f2260ea --- /dev/null +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Debug.xml @@ -0,0 +1,126 @@ + + True + True + True + True + True + + + DEBUG + ARM_MATH_CM4=1 + + + + + %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include + ../Config + ../ + ../examples + ../hal/include + ../hal/utils/include + ../hpl/adc + ../hpl/ccl + ../hpl/cmcc + ../hpl/core + ../hpl/dmac + ../hpl/eic + ../hpl/evsys + ../hpl/gclk + ../hpl/mclk + ../hpl/osc32kctrl + ../hpl/oscctrl + ../hpl/pm + ../hpl/port + ../hpl/qspi + ../hpl/ramecc + ../hpl/sercom + ../hpl/tc + ../hpl/tcc + ../hri + + + Optimize debugging experience (-Og) + True + Maximum (-g3) + True + -std=gnu11 -mfloat-abi=hard -mfpu=fpv4-sp-d16 + True + + + libm + libarm_cortexM4lf_math.a + + + + + C:\Users\ge37vez\Documents\Git Repos\bldc_control_thesis\bldc_firmware_thesis\2_Motor_Master_D51\Two_Motor_D51\Two_Motor_D51\cmsis + %24(ProjectDir)\Device_Startup + + + True + + -Tsamd51j18a_flash.ld -std=gnu99 -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mfp16-format=ieee + + + %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include + ../Config + ../ + ../examples + ../hal/include + ../hal/utils/include + ../hpl/adc + ../hpl/ccl + ../hpl/cmcc + ../hpl/core + ../hpl/dmac + ../hpl/eic + ../hpl/evsys + ../hpl/gclk + ../hpl/mclk + ../hpl/osc32kctrl + ../hpl/oscctrl + ../hpl/pm + ../hpl/port + ../hpl/qspi + ../hpl/ramecc + ../hpl/sercom + ../hpl/tc + ../hpl/tcc + ../hri + + + Default (-g) + + + %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include + ../Config + ../ + ../examples + ../hal/include + ../hal/utils/include + ../hpl/adc + ../hpl/ccl + ../hpl/cmcc + ../hpl/core + ../hpl/dmac + ../hpl/eic + ../hpl/evsys + ../hpl/gclk + ../hpl/mclk + ../hpl/osc32kctrl + ../hpl/oscctrl + ../hpl/pm + ../hpl/port + ../hpl/qspi + ../hpl/ramecc + ../hpl/sercom + ../hpl/tc + ../hpl/tcc + ../hri + + + Default (-Wa,-g) + \ No newline at end of file diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/MSIF_slave.h b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/MSIF_slave.h new file mode 100644 index 0000000..a81bf72 --- /dev/null +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/MSIF_slave.h @@ -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_ */ \ No newline at end of file diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Release.xml b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Release.xml new file mode 100644 index 0000000..084e2d1 --- /dev/null +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Release.xml @@ -0,0 +1,121 @@ + + True + True + True + True + True + + + NDEBUG + + + + + %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + ../Config + ../ + ../examples + ../hal/include + ../hal/utils/include + ../hpl/adc + ../hpl/ccl + ../hpl/cmcc + ../hpl/core + ../hpl/dmac + ../hpl/eic + ../hpl/evsys + ../hpl/gclk + ../hpl/mclk + ../hpl/osc32kctrl + ../hpl/oscctrl + ../hpl/pm + ../hpl/port + ../hpl/qspi + ../hpl/ramecc + ../hpl/sercom + ../hpl/tc + ../hpl/tcc + ../hri + %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include + + + Optimize for size (-Os) + True + True + -std=gnu99 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 + True + + + libm + libarm_cortexM4lf_math.a + + + + + C:\Users\ge37vez\Documents\Git Repos\bldc_control_thesis\bldc_firmware_thesis\2_Motor_Master_D51\Two_Motor_D51\Two_Motor_D51\cmsis + %24(ProjectDir)\Device_Startup + + + True + -Tsamd51j18a_flash.ld + + + %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + ../Config + ../ + ../examples + ../hal/include + ../hal/utils/include + ../hpl/adc + ../hpl/ccl + ../hpl/cmcc + ../hpl/core + ../hpl/dmac + ../hpl/eic + ../hpl/evsys + ../hpl/gclk + ../hpl/mclk + ../hpl/osc32kctrl + ../hpl/oscctrl + ../hpl/pm + ../hpl/port + ../hpl/qspi + ../hpl/ramecc + ../hpl/sercom + ../hpl/tc + ../hpl/tcc + ../hri + %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include + + + + + %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + ../Config + ../ + ../examples + ../hal/include + ../hal/utils/include + ../hpl/adc + ../hpl/ccl + ../hpl/cmcc + ../hpl/core + ../hpl/dmac + ../hpl/eic + ../hpl/evsys + ../hpl/gclk + ../hpl/mclk + ../hpl/osc32kctrl + ../hpl/oscctrl + ../hpl/pm + ../hpl/port + ../hpl/qspi + ../hpl/ramecc + ../hpl/sercom + ../hpl/tc + ../hpl/tcc + ../hri + %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include + + + \ No newline at end of file diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Two_Motor_D51.cproj b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Two_Motor_D51.cproj index f08b2bb..6c68523 100644 --- a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Two_Motor_D51.cproj +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/Two_Motor_D51.cproj @@ -65,6 +65,7 @@ + @@ -154,8 +155,8 @@ - - + + @@ -176,6 +177,7 @@ + @@ -216,9 +218,9 @@ - + - + @@ -243,256 +245,256 @@ - True - True - True - True - True - - - NDEBUG - - - - - %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ - ../Config - ../ - ../examples - ../hal/include - ../hal/utils/include - ../hpl/adc - ../hpl/ccl - ../hpl/cmcc - ../hpl/core - ../hpl/dmac - ../hpl/eic - ../hpl/evsys - ../hpl/gclk - ../hpl/mclk - ../hpl/osc32kctrl - ../hpl/oscctrl - ../hpl/pm - ../hpl/port - ../hpl/qspi - ../hpl/ramecc - ../hpl/sercom - ../hpl/tc - ../hpl/tcc - ../hri - %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include - - - Optimize for size (-Os) - True - True - -std=gnu99 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 - True - - - libm - libarm_cortexM4lf_math.a - - - - - C:\Users\ge37vez\Documents\Git Repos\bldc_control_thesis\bldc_firmware_thesis\2_Motor_Master_D51\Two_Motor_D51\Two_Motor_D51\cmsis - %24(ProjectDir)\Device_Startup - - - True - -Tsamd51j18a_flash.ld - - - %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ - ../Config - ../ - ../examples - ../hal/include - ../hal/utils/include - ../hpl/adc - ../hpl/ccl - ../hpl/cmcc - ../hpl/core - ../hpl/dmac - ../hpl/eic - ../hpl/evsys - ../hpl/gclk - ../hpl/mclk - ../hpl/osc32kctrl - ../hpl/oscctrl - ../hpl/pm - ../hpl/port - ../hpl/qspi - ../hpl/ramecc - ../hpl/sercom - ../hpl/tc - ../hpl/tcc - ../hri - %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include - - - - - %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ - ../Config - ../ - ../examples - ../hal/include - ../hal/utils/include - ../hpl/adc - ../hpl/ccl - ../hpl/cmcc - ../hpl/core - ../hpl/dmac - ../hpl/eic - ../hpl/evsys - ../hpl/gclk - ../hpl/mclk - ../hpl/osc32kctrl - ../hpl/oscctrl - ../hpl/pm - ../hpl/port - ../hpl/qspi - ../hpl/ramecc - ../hpl/sercom - ../hpl/tc - ../hpl/tcc - ../hri - %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include - - - + True + True + True + True + True + + + NDEBUG + + + + + %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + ../Config + ../ + ../examples + ../hal/include + ../hal/utils/include + ../hpl/adc + ../hpl/ccl + ../hpl/cmcc + ../hpl/core + ../hpl/dmac + ../hpl/eic + ../hpl/evsys + ../hpl/gclk + ../hpl/mclk + ../hpl/osc32kctrl + ../hpl/oscctrl + ../hpl/pm + ../hpl/port + ../hpl/qspi + ../hpl/ramecc + ../hpl/sercom + ../hpl/tc + ../hpl/tcc + ../hri + %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include + + + Optimize for size (-Os) + True + True + -std=gnu99 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 + True + + + libm + libarm_cortexM4lf_math.a + + + + + C:\Users\ge37vez\Documents\Git Repos\bldc_control_thesis\bldc_firmware_thesis\2_Motor_Master_D51\Two_Motor_D51\Two_Motor_D51\cmsis + %24(ProjectDir)\Device_Startup + + + True + -Tsamd51j18a_flash.ld + + + %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + ../Config + ../ + ../examples + ../hal/include + ../hal/utils/include + ../hpl/adc + ../hpl/ccl + ../hpl/cmcc + ../hpl/core + ../hpl/dmac + ../hpl/eic + ../hpl/evsys + ../hpl/gclk + ../hpl/mclk + ../hpl/osc32kctrl + ../hpl/oscctrl + ../hpl/pm + ../hpl/port + ../hpl/qspi + ../hpl/ramecc + ../hpl/sercom + ../hpl/tc + ../hpl/tcc + ../hri + %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include + + + + + %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + ../Config + ../ + ../examples + ../hal/include + ../hal/utils/include + ../hpl/adc + ../hpl/ccl + ../hpl/cmcc + ../hpl/core + ../hpl/dmac + ../hpl/eic + ../hpl/evsys + ../hpl/gclk + ../hpl/mclk + ../hpl/osc32kctrl + ../hpl/oscctrl + ../hpl/pm + ../hpl/port + ../hpl/qspi + ../hpl/ramecc + ../hpl/sercom + ../hpl/tc + ../hpl/tcc + ../hri + %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include + + + - True - True - True - True - True - - - DEBUG - ARM_MATH_CM4=1 - - - - - %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ - %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include - ../Config - ../ - ../examples - ../hal/include - ../hal/utils/include - ../hpl/adc - ../hpl/ccl - ../hpl/cmcc - ../hpl/core - ../hpl/dmac - ../hpl/eic - ../hpl/evsys - ../hpl/gclk - ../hpl/mclk - ../hpl/osc32kctrl - ../hpl/oscctrl - ../hpl/pm - ../hpl/port - ../hpl/qspi - ../hpl/ramecc - ../hpl/sercom - ../hpl/tc - ../hpl/tcc - ../hri - - - Optimize debugging experience (-Og) - True - Maximum (-g3) - True - -std=gnu99 -mfloat-abi=hard -mfpu=fpv4-sp-d16 - True - - - libm - libarm_cortexM4lf_math.a - - - - - C:\Users\ge37vez\Documents\Git Repos\bldc_control_thesis\bldc_firmware_thesis\2_Motor_Master_D51\Two_Motor_D51\Two_Motor_D51\cmsis - %24(ProjectDir)\Device_Startup - - - True - - -Tsamd51j18a_flash.ld -std=gnu99 -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mfp16-format=ieee - - - %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ - %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include - ../Config - ../ - ../examples - ../hal/include - ../hal/utils/include - ../hpl/adc - ../hpl/ccl - ../hpl/cmcc - ../hpl/core - ../hpl/dmac - ../hpl/eic - ../hpl/evsys - ../hpl/gclk - ../hpl/mclk - ../hpl/osc32kctrl - ../hpl/oscctrl - ../hpl/pm - ../hpl/port - ../hpl/qspi - ../hpl/ramecc - ../hpl/sercom - ../hpl/tc - ../hpl/tcc - ../hri - - - Default (-g) - - - %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ - %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include - ../Config - ../ - ../examples - ../hal/include - ../hal/utils/include - ../hpl/adc - ../hpl/ccl - ../hpl/cmcc - ../hpl/core - ../hpl/dmac - ../hpl/eic - ../hpl/evsys - ../hpl/gclk - ../hpl/mclk - ../hpl/osc32kctrl - ../hpl/oscctrl - ../hpl/pm - ../hpl/port - ../hpl/qspi - ../hpl/ramecc - ../hpl/sercom - ../hpl/tc - ../hpl/tcc - ../hri - - - Default (-Wa,-g) - + True + True + True + True + True + + + DEBUG + ARM_MATH_CM4=1 + + + + + %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + ../Config + ../ + ../examples + ../hal/include + ../hal/utils/include + ../hpl/adc + ../hpl/ccl + ../hpl/cmcc + ../hpl/core + ../hpl/dmac + ../hpl/eic + ../hpl/evsys + ../hpl/gclk + ../hpl/mclk + ../hpl/osc32kctrl + ../hpl/oscctrl + ../hpl/pm + ../hpl/port + ../hpl/qspi + ../hpl/ramecc + ../hpl/sercom + ../hpl/tc + ../hpl/tcc + ../hri + %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include + + + Optimize debugging experience (-Og) + True + Maximum (-g3) + True + -std=gnu99 -mfloat-abi=hard -mfpu=fpv4-sp-d16 + True + + + libm + libarm_cortexM4lf_math.a + + + + + C:\Users\ge37vez\Documents\Git Repos\bldc_control_thesis\bldc_firmware_thesis\2_Motor_Master_D51\Two_Motor_D51\Two_Motor_D51\cmsis + %24(ProjectDir)\Device_Startup + + + True + + -Tsamd51j18a_flash.ld -std=gnu99 -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mfp16-format=ieee + + + %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + ../Config + ../ + ../examples + ../hal/include + ../hal/utils/include + ../hpl/adc + ../hpl/ccl + ../hpl/cmcc + ../hpl/core + ../hpl/dmac + ../hpl/eic + ../hpl/evsys + ../hpl/gclk + ../hpl/mclk + ../hpl/osc32kctrl + ../hpl/oscctrl + ../hpl/pm + ../hpl/port + ../hpl/qspi + ../hpl/ramecc + ../hpl/sercom + ../hpl/tc + ../hpl/tcc + ../hri + %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include + + + Default (-g) + + + %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + ../Config + ../ + ../examples + ../hal/include + ../hal/utils/include + ../hpl/adc + ../hpl/ccl + ../hpl/cmcc + ../hpl/core + ../hpl/dmac + ../hpl/eic + ../hpl/evsys + ../hpl/gclk + ../hpl/mclk + ../hpl/osc32kctrl + ../hpl/oscctrl + ../hpl/pm + ../hpl/port + ../hpl/qspi + ../hpl/ramecc + ../hpl/sercom + ../hpl/tc + ../hpl/tcc + ../hri + %24(PackRepoDir)\atmel\SAMD51_DFP\1.2.139\samd51a\include + + + Default (-Wa,-g) + @@ -655,6 +657,9 @@ compile + + compile + compile @@ -814,6 +819,9 @@ compile + + compile + compile @@ -1051,6 +1059,9 @@ compile + + compile + compile @@ -1125,6 +1136,9 @@ compile + + compile + compile diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/configuration.h b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/configuration.h index ea10d7c..dec4c31 100644 --- a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/configuration.h +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/configuration.h @@ -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,51 +155,120 @@ 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) { - struct io_descriptor *io; - spi_m_dma_get_io_descriptor(&SPI_1_MSIF, &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; - //SERCOM1->SPI.LENGTH.bit.LEN = 64; + #ifdef _MASTER + struct io_descriptor *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; + //SERCOM1->SPI.LENGTH.bit.LEN = 64; - 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); + 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_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, + // Pull configuration + // pad_pull_config + // Off + // Pull-up + // Pull-down + GPIO_PULL_OFF); + + gpio_set_pin_function(SPI1_MOSI, PINMUX_PA00D_SERCOM1_PAD0); + + gpio_set_pin_level(SPI1_SCK, + // Initial level + // pad_initial_level + // Low + // 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, + // Pull configuration + // pad_pull_config + // Off + // Pull-up + // Pull-down + GPIO_PULL_OFF); + + gpio_set_pin_function(SPI1_CS, PINMUX_PB22C_SERCOM1_PAD2); + + gpio_set_pin_level(SPI1_MISO, + // Initial level + // pad_initial_level + // Low + // 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); +} + + +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); - _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); + _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_M_DMA_TX_CHANNEL]); - hri_dmacdescriptor_set_BTCTRL_VALID_bit(&_descriptor_section[CONF_SERCOM_1_SPI_M_DMA_RX_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; @@ -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_M_DMA_RX_CHANNEL, DMA_TRANSFER_ERROR_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_ */ \ No newline at end of file diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/driver_init.c b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/driver_init.c index 037d81d..06759c9 100644 --- a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/driver_init.c +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/driver_init.c @@ -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(); diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/driver_init.h b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/driver_init.h index bab8991..00edc6a 100644 --- a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/driver_init.h +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/driver_init.h @@ -37,6 +37,8 @@ extern "C" { #include #include + +#include #include #include #include @@ -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); diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/examples/driver_examples.c b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/examples/driver_examples.c index 2adbb38..98b7011 100644 --- a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/examples/driver_examples.c +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/examples/driver_examples.c @@ -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. */ diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/examples/driver_examples.h b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/examples/driver_examples.h index 9defce7..d009c83 100644 --- a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/examples/driver_examples.h +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/examples/driver_examples.h @@ -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); diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/hal/documentation/spi_slave_sync.rst b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/hal/documentation/spi_slave_sync.rst new file mode 100644 index 0000000..226eb8a --- /dev/null +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/hal/documentation/spi_slave_sync.rst @@ -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. + diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/hal/include/hal_spi_s_sync.h b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/hal/include/hal_spi_s_sync.h new file mode 100644 index 0000000..2cdc43d --- /dev/null +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/hal/include/hal_spi_s_sync.h @@ -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 */ diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/hal/src/hal_spi_s_sync.c b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/hal/src/hal_spi_s_sync.c new file mode 100644 index 0000000..0498769 --- /dev/null +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/hal/src/hal_spi_s_sync.c @@ -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 +#include + +#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 diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/interrupts.h b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/interrupts.h index cb1bb14..793ae58 100644 --- a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/interrupts.h +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/interrupts.h @@ -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) diff --git a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/main.c b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/main.c index 1aaae90..1a6ef50 100644 --- a/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/main.c +++ b/2_Motor_Master_D51/Two_Motor_D51/Two_Motor_D51/main.c @@ -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 */ - BldcInitStruct(&Motor1, &FH_22mm24BXTR); - BldcInitStruct(&Motor2, &FH_32mm12BXTR); - //Motor2.VdcBus_pu = 12.0; - //Motor2.VoneByDcBus_pu = 1.0/Motor2.VdcBus_pu; + #ifdef _MASTER + BldcInitStruct(&Motor1, &FH_22mm24BXTR); + BldcInitStruct(&Motor2, &FH_32mm12BXTR); + #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 */ - config_qspi(); + #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)) { + Motor1.timerflags.motor_telemetry_flag = false; + 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)) { - /* Enable */ - DMAC->Channel[CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE; - - } - + #ifdef _MASTER + if(!(DMAC->Channel[CONF_SERCOM_2_SPI_DMA_TX_CHANNEL].CHCTRLA.bit.ENABLE)) { + /* Enable */ + DMAC->Channel[CONF_SERCOM_2_SPI_DMA_TX_CHANNEL].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE; + } + #endif //MASTER update_telemetry(); update_setpoints(); } @@ -231,10 +244,10 @@ int main(void) exec_commutation(&Motor1); exec_commutation(&Motor2); } - - - + + #ifdef _MASTER if(run_ECAT) {ECAT_STATE_MACHINE();} + #endif // _MASTER } } diff --git a/Screenshots/Event Manual Config/CH0.PNG b/Screenshots/Event Manual Config/CH0.PNG new file mode 100644 index 0000000..dcc674b Binary files /dev/null and b/Screenshots/Event Manual Config/CH0.PNG differ diff --git a/Screenshots/Event Manual Config/CH1.PNG b/Screenshots/Event Manual Config/CH1.PNG new file mode 100644 index 0000000..1b4a9dd Binary files /dev/null and b/Screenshots/Event Manual Config/CH1.PNG differ diff --git a/Screenshots/Event Manual Config/CH11.PNG b/Screenshots/Event Manual Config/CH11.PNG new file mode 100644 index 0000000..563326f Binary files /dev/null and b/Screenshots/Event Manual Config/CH11.PNG differ diff --git a/Screenshots/Event Manual Config/CH12.PNG b/Screenshots/Event Manual Config/CH12.PNG new file mode 100644 index 0000000..c06bf72 Binary files /dev/null and b/Screenshots/Event Manual Config/CH12.PNG differ diff --git a/Screenshots/Event Manual Config/CH2.PNG b/Screenshots/Event Manual Config/CH2.PNG new file mode 100644 index 0000000..22229fd Binary files /dev/null and b/Screenshots/Event Manual Config/CH2.PNG differ diff --git a/Screenshots/Event Manual Config/CH3.PNG b/Screenshots/Event Manual Config/CH3.PNG new file mode 100644 index 0000000..eb290e7 Binary files /dev/null and b/Screenshots/Event Manual Config/CH3.PNG differ diff --git a/Screenshots/Event Manual Config/CH4.PNG b/Screenshots/Event Manual Config/CH4.PNG new file mode 100644 index 0000000..881c064 Binary files /dev/null and b/Screenshots/Event Manual Config/CH4.PNG differ diff --git a/Twincat/MotorData/.vs/MotorData/v15/.suo b/Twincat/MotorData/.vs/MotorData/v15/.suo index ef574d9..4438805 100644 Binary files a/Twincat/MotorData/.vs/MotorData/v15/.suo and b/Twincat/MotorData/.vs/MotorData/v15/.suo differ