diff --git a/2_Motor_Master/Motor_Master/Motor_Master/.atmelstart/AtmelStart.gpdsc b/2_Motor_Master/Motor_Master/Motor_Master/.atmelstart/AtmelStart.gpdsc index 0a6bfab..bb2e80e 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/.atmelstart/AtmelStart.gpdsc +++ b/2_Motor_Master/Motor_Master/Motor_Master/.atmelstart/AtmelStart.gpdsc @@ -49,6 +49,7 @@ + @@ -63,6 +64,7 @@ + @@ -176,6 +178,7 @@ + diff --git a/2_Motor_Master/Motor_Master/Motor_Master/.atmelstart/atmel_start_config.atstart b/2_Motor_Master/Motor_Master/Motor_Master/.atmelstart/atmel_start_config.atstart index 265b758..db2d737 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/.atmelstart/atmel_start_config.atstart +++ b/2_Motor_Master/Motor_Master/Motor_Master/.atmelstart/atmel_start_config.atstart @@ -393,7 +393,7 @@ drivers: the transaction dmac_blockact_9: Channel will be disabled if it is the last block transfer in the transaction - dmac_channel_0_settings: false + dmac_channel_0_settings: true dmac_channel_10_settings: false dmac_channel_11_settings: false dmac_channel_12_settings: false @@ -404,7 +404,7 @@ drivers: dmac_channel_17_settings: false dmac_channel_18_settings: false dmac_channel_19_settings: false - dmac_channel_1_settings: false + dmac_channel_1_settings: true dmac_channel_20_settings: false dmac_channel_21_settings: false dmac_channel_22_settings: false @@ -426,7 +426,7 @@ drivers: dmac_channel_8_settings: false dmac_channel_9_settings: false dmac_dbgrun: false - dmac_dstinc_0: false + dmac_dstinc_0: true dmac_dstinc_1: false dmac_dstinc_10: false dmac_dstinc_11: false @@ -599,7 +599,7 @@ drivers: dmac_lvl_17: Channel priority 0 dmac_lvl_18: Channel priority 0 dmac_lvl_19: Channel priority 0 - dmac_lvl_2: Channel priority 0 + dmac_lvl_2: Channel priority 1 dmac_lvl_20: Channel priority 0 dmac_lvl_21: Channel priority 0 dmac_lvl_22: Channel priority 0 @@ -610,7 +610,7 @@ drivers: dmac_lvl_27: Channel priority 0 dmac_lvl_28: Channel priority 0 dmac_lvl_29: Channel priority 0 - dmac_lvl_3: Channel priority 0 + dmac_lvl_3: Channel priority 1 dmac_lvl_30: Channel priority 0 dmac_lvl_31: Channel priority 0 dmac_lvl_4: Channel priority 0 @@ -624,7 +624,7 @@ drivers: dmac_lvlen2: true dmac_lvlen3: true dmac_lvlpri0: 0 - dmac_lvlpri1: 0 + dmac_lvlpri1: 1 dmac_lvlpri2: 0 dmac_lvlpri3: 0 dmac_rrlvlen0: Static arbitration scheme for channel with priority 0 @@ -664,7 +664,7 @@ drivers: dmac_runstdby_8: false dmac_runstdby_9: false dmac_srcinc_0: false - dmac_srcinc_1: false + dmac_srcinc_1: true dmac_srcinc_10: false dmac_srcinc_11: false dmac_srcinc_12: false @@ -696,7 +696,7 @@ drivers: dmac_srcinc_8: false dmac_srcinc_9: false dmac_stepsel_0: Step size settings apply to the destination address - dmac_stepsel_1: Step size settings apply to the destination address + dmac_stepsel_1: Step size settings apply to the source address dmac_stepsel_10: Step size settings apply to the destination address dmac_stepsel_11: Step size settings apply to the destination address dmac_stepsel_12: Step size settings apply to the destination address @@ -759,8 +759,8 @@ drivers: dmac_stepsize_7: Next ADDR = ADDR + (BEATSIZE + 1) * 1 dmac_stepsize_8: Next ADDR = ADDR + (BEATSIZE + 1) * 1 dmac_stepsize_9: Next ADDR = ADDR + (BEATSIZE + 1) * 1 - dmac_trifsrc_0: Only software/event triggers - dmac_trifsrc_1: Only software/event triggers + dmac_trifsrc_0: SERCOM1 RX Trigger + dmac_trifsrc_1: SERCOM1 TX Trigger dmac_trifsrc_10: Only software/event triggers dmac_trifsrc_11: Only software/event triggers dmac_trifsrc_12: Only software/event triggers @@ -791,8 +791,8 @@ drivers: dmac_trifsrc_7: Only software/event triggers dmac_trifsrc_8: Only software/event triggers dmac_trifsrc_9: Only software/event triggers - dmac_trigact_0: One trigger required for each block transfer - dmac_trigact_1: One trigger required for each block transfer + dmac_trigact_0: One trigger required for each beat transfer + dmac_trigact_1: One trigger required for each beat transfer dmac_trigact_10: One trigger required for each block transfer dmac_trigact_11: One trigger required for each block transfer dmac_trigact_12: One trigger required for each block transfer @@ -1800,22 +1800,25 @@ drivers: variant: null clocks: domain_group: null - SPI_1: - user_label: SPI_1 - definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::SERCOM1::driver_config_definition::SPI.Master::HAL:Driver:SPI.Master.Sync + SPI_1_MSIF: + user_label: SPI_1_MSIF + definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::SERCOM1::driver_config_definition::SPI.Master::HAL:Driver:SPI.Master.DMA functionality: SPI - api: HAL:Driver:SPI_Master_Sync + api: HAL:Driver:SPI_Master_DMA configuration: - spi_master_advanced: false + spi_master_advanced: true spi_master_arch_cpha: Sample input on leading edge spi_master_arch_cpol: SCK is low when idle spi_master_arch_dbgstop: Keep running spi_master_arch_dord: MSB first spi_master_arch_ibon: In data stream spi_master_arch_runstdby: false - spi_master_baud_rate: 50000 + spi_master_baud_rate: 8000000 spi_master_character_size: 8 bits + spi_master_dma_rx_channel: 0 + spi_master_dma_tx_channel: 1 spi_master_dummybyte: 511 + spi_master_rx_channel: true spi_master_rx_enable: true optional_signals: [] variant: @@ -2535,9 +2538,10 @@ pads: SPI1_CS: name: PB22 definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::pad::PB22 - mode: Peripheral IO + mode: Digital output user_label: SPI1_CS - configuration: null + configuration: + pad_initial_level: High SPI1_MISO: name: PB23 definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::pad::PB23 diff --git a/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_dmac_config.h b/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_dmac_config.h index 04a8d6b..c69200d 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_dmac_config.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_dmac_config.h @@ -51,7 +51,7 @@ // Level 1 Channel Priority Number <0x00-0xFF> // dmac_lvlpri1 #ifndef CONF_DMAC_LVLPRI1 -#define CONF_DMAC_LVLPRI1 0 +#define CONF_DMAC_LVLPRI1 1 #endif // Priority Level 2 // Indicates whether Priority Level 2 is enabled or not @@ -105,7 +105,7 @@ // Channel 0 settings // dmac_channel_0_settings #ifndef CONF_DMAC_CHANNEL_0_SETTINGS -#define CONF_DMAC_CHANNEL_0_SETTINGS 0 +#define CONF_DMAC_CHANNEL_0_SETTINGS 1 #endif // Channel Run in Standby @@ -122,7 +122,7 @@ // Defines the trigger action used for a transfer // dmac_trigact_0 #ifndef CONF_DMAC_TRIGACT_0 -#define CONF_DMAC_TRIGACT_0 0 +#define CONF_DMAC_TRIGACT_0 2 #endif // Trigger source @@ -214,7 +214,7 @@ // Defines the peripheral trigger which is source of the transfer // dmac_trifsrc_0 #ifndef CONF_DMAC_TRIGSRC_0 -#define CONF_DMAC_TRIGSRC_0 0 +#define CONF_DMAC_TRIGSRC_0 6 #endif // Channel Arbitration Level @@ -291,7 +291,7 @@ // Indicates whether the destination address incrementation is enabled or not // dmac_dstinc_0 #ifndef CONF_DMAC_DSTINC_0 -#define CONF_DMAC_DSTINC_0 0 +#define CONF_DMAC_DSTINC_0 1 #endif // Beat Size @@ -329,7 +329,7 @@ // Channel 1 settings // dmac_channel_1_settings #ifndef CONF_DMAC_CHANNEL_1_SETTINGS -#define CONF_DMAC_CHANNEL_1_SETTINGS 0 +#define CONF_DMAC_CHANNEL_1_SETTINGS 1 #endif // Channel Run in Standby @@ -346,7 +346,7 @@ // Defines the trigger action used for a transfer // dmac_trigact_1 #ifndef CONF_DMAC_TRIGACT_1 -#define CONF_DMAC_TRIGACT_1 0 +#define CONF_DMAC_TRIGACT_1 2 #endif // Trigger source @@ -438,7 +438,7 @@ // Defines the peripheral trigger which is source of the transfer // dmac_trifsrc_1 #ifndef CONF_DMAC_TRIGSRC_1 -#define CONF_DMAC_TRIGSRC_1 0 +#define CONF_DMAC_TRIGSRC_1 7 #endif // Channel Arbitration Level @@ -501,14 +501,14 @@ // Defines whether source or destination addresses are using the step size settings // dmac_stepsel_1 #ifndef CONF_DMAC_STEPSEL_1 -#define CONF_DMAC_STEPSEL_1 0 +#define CONF_DMAC_STEPSEL_1 1 #endif // Source Address Increment // Indicates whether the source address incrementation is enabled or not // dmac_srcinc_1 #ifndef CONF_DMAC_SRCINC_1 -#define CONF_DMAC_SRCINC_1 0 +#define CONF_DMAC_SRCINC_1 1 #endif // Destination Address Increment @@ -673,7 +673,7 @@ // Defines the arbitration level for this channel // dmac_lvl_2 #ifndef CONF_DMAC_LVL_2 -#define CONF_DMAC_LVL_2 0 +#define CONF_DMAC_LVL_2 1 #endif // Channel Event Output @@ -897,7 +897,7 @@ // Defines the arbitration level for this channel // dmac_lvl_3 #ifndef CONF_DMAC_LVL_3 -#define CONF_DMAC_LVL_3 0 +#define CONF_DMAC_LVL_3 1 #endif // Channel Event Output diff --git a/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_sercom_config.h b/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_sercom_config.h index 6112f6c..3ce0137 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_sercom_config.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_sercom_config.h @@ -11,6 +11,28 @@ #define CONF_SERCOM_1_SPI_ENABLE 1 #endif +// SPI DMA TX Channel <0-32> +// This defines DMA channel to be used +// spi_master_dma_tx_channel +#ifndef CONF_SERCOM_1_SPI_M_DMA_TX_CHANNEL +#define CONF_SERCOM_1_SPI_M_DMA_TX_CHANNEL 1 +#endif + +// SPI RX Channel Enable +// spi_master_rx_channel +#ifndef CONF_SERCOM_1_SPI_RX_CHANNEL +#define CONF_SERCOM_1_SPI_RX_CHANNEL 1 +#endif + +// DMA Channel <0-32> +// This defines DMA channel to be used +// spi_master_dma_rx_channel +#ifndef CONF_SERCOM_1_SPI_M_DMA_RX_CHANNEL +#define CONF_SERCOM_1_SPI_M_DMA_RX_CHANNEL 0 +#endif + +// + // Set module in SPI Master mode #ifndef CONF_SERCOM_1_SPI_MODE #define CONF_SERCOM_1_SPI_MODE 0x03 @@ -37,7 +59,7 @@ // The SPI data transfer rate // spi_master_baud_rate #ifndef CONF_SERCOM_1_SPI_BAUD -#define CONF_SERCOM_1_SPI_BAUD 50000 +#define CONF_SERCOM_1_SPI_BAUD 8000000 #endif // @@ -45,7 +67,7 @@ // Advanced Configuration // spi_master_advanced #ifndef CONF_SERCOM_1_SPI_ADVANCED -#define CONF_SERCOM_1_SPI_ADVANCED 0 +#define CONF_SERCOM_1_SPI_ADVANCED 1 #endif // Dummy byte <0x00-0x1ff> diff --git a/2_Motor_Master/Motor_Master/Motor_Master/EtherCAT_SlaveDef.h b/2_Motor_Master/Motor_Master/Motor_Master/EtherCAT_SlaveDef.h index ca22b89..0a5526c 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/EtherCAT_SlaveDef.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/EtherCAT_SlaveDef.h @@ -45,44 +45,51 @@ static volatile int16_t *EMG_CH5 = (((int16_t *)&QSPI_tx_buffer[12])); static volatile int16_t *EMG_CH6 = (((int16_t *)&QSPI_tx_buffer[12])+1); static volatile int16_t *EMG_CH7 = (((int16_t *)&QSPI_tx_buffer[13])); static volatile int16_t *EMG_CH8 = (((int16_t *)&QSPI_tx_buffer[13])+1); + +/* Reserved space */ +static volatile int16_t *Spare1_tx = (((int16_t *)&QSPI_tx_buffer[14])); +static volatile int16_t *Spare2_tx = (((int16_t *)&QSPI_tx_buffer[14])+1); +static volatile int16_t *Spare3_tx = (((int16_t *)&QSPI_tx_buffer[15])); +static volatile int16_t *Spare4_tx = (((int16_t *)&QSPI_tx_buffer[15])+1); + /* Motor 3*/ -static volatile uint8_t *M3_Status = (uint8_t *)&QSPI_tx_buffer[14]; -static volatile uint8_t *M3_Mode = (((uint8_t *)&QSPI_tx_buffer[14])+1); -static volatile int16_t *M3_Joint_rel_position = (((int16_t *)&QSPI_tx_buffer[14])+1); -static volatile int16_t *M3_Joint_abs_position = ((int16_t *)&QSPI_tx_buffer[15]); -static volatile int16_t *M3_Motor_speed = (((int16_t *)&QSPI_tx_buffer[15])+1); -static volatile int16_t *M3_Motor_current_bus = ((int16_t *)&QSPI_tx_buffer[16]); -static volatile int16_t *M3_Motor_currentPhA = (((int16_t *)&QSPI_tx_buffer[16])+1); -static volatile int16_t *M3_Motor_currentPhB = ((int16_t *)&QSPI_tx_buffer[17]); -static volatile int16_t *M3_Motor_currentPhC = (((int16_t *)&QSPI_tx_buffer[17])+1); -static volatile int16_t *M3_Motor__hallState = ((int16_t *)&QSPI_tx_buffer[18]); -static volatile int16_t *M3_Motor_dutyCycle = (((int16_t *)&QSPI_tx_buffer[18])+1); +static volatile uint8_t *M3_Status = (uint8_t *)&QSPI_tx_buffer[16]; +static volatile uint8_t *M3_Mode = (((uint8_t *)&QSPI_tx_buffer[16])+1); +static volatile int16_t *M3_Joint_rel_position = (((int16_t *)&QSPI_tx_buffer[16])+1); +static volatile int16_t *M3_Joint_abs_position = ((int16_t *)&QSPI_tx_buffer[17]); +static volatile int16_t *M3_Motor_speed = (((int16_t *)&QSPI_tx_buffer[17])+1); +static volatile int16_t *M3_Motor_current_bus = ((int16_t *)&QSPI_tx_buffer[18]); +static volatile int16_t *M3_Motor_currentPhA = (((int16_t *)&QSPI_tx_buffer[18])+1); +static volatile int16_t *M3_Motor_currentPhB = ((int16_t *)&QSPI_tx_buffer[19]); +static volatile int16_t *M3_Motor_currentPhC = (((int16_t *)&QSPI_tx_buffer[19])+1); +static volatile int16_t *M3_Motor__hallState = ((int16_t *)&QSPI_tx_buffer[20]); +static volatile int16_t *M3_Motor_dutyCycle = (((int16_t *)&QSPI_tx_buffer[20])+1); /* Motor 4*/ -static volatile uint8_t *M4_Status = (uint8_t *)&QSPI_tx_buffer[19]; -static volatile uint8_t *M4_Mode = (((uint8_t *)&QSPI_tx_buffer[19])+1); -static volatile int16_t *M4_Joint_rel_position = (((int16_t *)&QSPI_tx_buffer[19])+1); -static volatile int16_t *M4_Joint_abs_position = ((int16_t *)&QSPI_tx_buffer[20]); -static volatile int16_t *M4_Motor_speed = (((int16_t *)&QSPI_tx_buffer[20])+1); -static volatile int16_t *M4_Motor_current_bus = ((int16_t *)&QSPI_tx_buffer[21]); -static volatile int16_t *M4_Motor_currentPhA = (((int16_t *)&QSPI_tx_buffer[21])+1); -static volatile int16_t *M4_Motor_currentPhB = ((int16_t *)&QSPI_tx_buffer[22]); -static volatile int16_t *M4_Motor_currentPhC = (((int16_t *)&QSPI_tx_buffer[22])+1); -static volatile int16_t *M4_Motor__hallState = ((int16_t *)&QSPI_tx_buffer[23]); -static volatile int16_t *M4_Motor_dutyCycle = (((int16_t *)&QSPI_tx_buffer[23])+1); +static volatile uint8_t *M4_Status = (uint8_t *)&QSPI_tx_buffer[21]; +static volatile uint8_t *M4_Mode = (((uint8_t *)&QSPI_tx_buffer[21])+1); +static volatile int16_t *M4_Joint_rel_position = (((int16_t *)&QSPI_tx_buffer[21])+1); +static volatile int16_t *M4_Joint_abs_position = ((int16_t *)&QSPI_tx_buffer[22]); +static volatile int16_t *M4_Motor_speed = (((int16_t *)&QSPI_tx_buffer[22])+1); +static volatile int16_t *M4_Motor_current_bus = ((int16_t *)&QSPI_tx_buffer[23]); +static volatile int16_t *M4_Motor_currentPhA = (((int16_t *)&QSPI_tx_buffer[23])+1); +static volatile int16_t *M4_Motor_currentPhB = ((int16_t *)&QSPI_tx_buffer[24]); +static volatile int16_t *M4_Motor_currentPhC = (((int16_t *)&QSPI_tx_buffer[24])+1); +static volatile int16_t *M4_Motor__hallState = ((int16_t *)&QSPI_tx_buffer[25]); +static volatile int16_t *M4_Motor_dutyCycle = (((int16_t *)&QSPI_tx_buffer[25])+1); /* IMU */ -static volatile int16_t *q_x0 = (((int16_t *)&QSPI_tx_buffer[24])); -static volatile int16_t *q_y0 = (((int16_t *)&QSPI_tx_buffer[24])+1); -static volatile int16_t *q_z0 = (((int16_t *)&QSPI_tx_buffer[25])); -static volatile int16_t *q_w0 = (((int16_t *)&QSPI_tx_buffer[25])+1); +static volatile int16_t *q_x0 = (((int16_t *)&QSPI_tx_buffer[26])); +static volatile int16_t *q_y0 = (((int16_t *)&QSPI_tx_buffer[26])+1); +static volatile int16_t *q_z0 = (((int16_t *)&QSPI_tx_buffer[27])); +static volatile int16_t *q_w0 = (((int16_t *)&QSPI_tx_buffer[27])+1); /* EMG */ -static volatile int16_t *FSR_CH1 = (((int16_t *)&QSPI_tx_buffer[26])); -static volatile int16_t *FSR_CH2 = (((int16_t *)&QSPI_tx_buffer[26])+1); -static volatile int16_t *FSR_CH3 = (((int16_t *)&QSPI_tx_buffer[27])); -static volatile int16_t *FSR_CH4 = (((int16_t *)&QSPI_tx_buffer[27])+1); -static volatile int16_t *FSR_CH5 = (((int16_t *)&QSPI_tx_buffer[28])); -static volatile int16_t *Pressure_CH1 = (((int16_t *)&QSPI_tx_buffer[28])+1); -static volatile int16_t *Pressure_CH2 = (((int16_t *)&QSPI_tx_buffer[29])); -static volatile int16_t *Pressure_CH3 = (((int16_t *)&QSPI_tx_buffer[29])+1); +static volatile int16_t *FSR_CH1 = (((int16_t *)&QSPI_tx_buffer[28])); +static volatile int16_t *FSR_CH2 = (((int16_t *)&QSPI_tx_buffer[28])+1); +static volatile int16_t *FSR_CH3 = (((int16_t *)&QSPI_tx_buffer[29])); +static volatile int16_t *FSR_CH4 = (((int16_t *)&QSPI_tx_buffer[29])+1); +static volatile int16_t *FSR_CH5 = (((int16_t *)&QSPI_tx_buffer[30])); +static volatile int16_t *Pressure_CH1 = (((int16_t *)&QSPI_tx_buffer[30])+1); +static volatile int16_t *Pressure_CH2 = (((int16_t *)&QSPI_tx_buffer[31])); +static volatile int16_t *Pressure_CH3 = (((int16_t *)&QSPI_tx_buffer[31])+1); //Read From Ecat Total (XX Bytes) //QSPI_rx_buffer @@ -106,26 +113,46 @@ static volatile int16_t *M2_Max_pos = ((int16_t *)&QSPI_rx_buffer[6]); static volatile int16_t *M2_Max_velocity = ((int16_t *)&QSPI_rx_buffer[6]+1); static volatile int16_t *M2_Max_current = ((int16_t *)&QSPI_rx_buffer[7]); static volatile int16_t *M2_Desired_dc = ((int16_t *)&QSPI_rx_buffer[7]+1); //Spare + +/* Reserved space */ +/* 64 bytes reserved for each */ +static volatile int16_t *Spare1_rx = ((int16_t *)&QSPI_rx_buffer[8]); //Spare +static volatile int16_t *Spare2_rx = ((int16_t *)&QSPI_rx_buffer[8]+1); //Spare +static volatile int16_t *Spare3_rx = ((int16_t *)&QSPI_rx_buffer[9]); //Spare +static volatile int16_t *Spare4_rx = ((int16_t *)&QSPI_rx_buffer[9]+1); //Spare +static volatile int16_t *Spare5_rx = ((int16_t *)&QSPI_rx_buffer[10]); //Spare +static volatile int16_t *Spare6_rx = ((int16_t *)&QSPI_rx_buffer[10]+1); //Spare +static volatile int16_t *Spare7_rx = ((int16_t *)&QSPI_rx_buffer[11]); //Spare +static volatile int16_t *Spare8_rx = ((int16_t *)&QSPI_rx_buffer[11]+1); //Spare +static volatile int16_t *Spare9_rx = ((int16_t *)&QSPI_rx_buffer[12]); //Spare +static volatile int16_t *Spare10_rx = ((int16_t *)&QSPI_rx_buffer[12]+1); //Spare +static volatile int16_t *Spare11_rx = ((int16_t *)&QSPI_rx_buffer[13]); //Spare +static volatile int16_t *Spare12_rx = ((int16_t *)&QSPI_rx_buffer[13]+1); //Spare +static volatile int16_t *Spare13_rx = ((int16_t *)&QSPI_rx_buffer[14]); //Spare +static volatile int16_t *Spare14_rx = ((int16_t *)&QSPI_rx_buffer[14]+1); //Spare +static volatile int16_t *Spare15_rx = ((int16_t *)&QSPI_rx_buffer[15]); //Spare +static volatile int16_t *Spare16_rx = ((int16_t *)&QSPI_rx_buffer[15]+1); //Spare + ///* Motor 3*/ -static volatile uint8_t *M3_Control_mode = ((uint8_t *)&QSPI_rx_buffer[8]); -static volatile uint8_t *M3_Control_set = (((uint8_t *)&QSPI_rx_buffer[8])+1); -static volatile int16_t *M3_Desired_pos = ((int16_t *)&QSPI_rx_buffer[8]+1); -static volatile int16_t *M3_Desired_speed = ((int16_t *)&QSPI_rx_buffer[9]); -static volatile int16_t *M3_Desired_current = ((int16_t *)&QSPI_rx_buffer[9]+1); -static volatile int16_t *M3_Max_pos = ((int16_t *)&QSPI_rx_buffer[10]); -static volatile int16_t *M3_Max_velocity = ((int16_t *)&QSPI_rx_buffer[10]+1); -static volatile int16_t *M3_Max_current = ((int16_t *)&QSPI_rx_buffer[11]); -static volatile int16_t *M3_Spare = ((int16_t *)&QSPI_rx_buffer[11]+1); //Spare +static volatile uint8_t *M3_Control_mode = ((uint8_t *)&QSPI_rx_buffer[16]); +static volatile uint8_t *M3_Control_set = (((uint8_t *)&QSPI_rx_buffer[16])+1); +static volatile int16_t *M3_Desired_pos = ((int16_t *)&QSPI_rx_buffer[16]+1); +static volatile int16_t *M3_Desired_speed = ((int16_t *)&QSPI_rx_buffer[17]); +static volatile int16_t *M3_Desired_current = ((int16_t *)&QSPI_rx_buffer[17]+1); +static volatile int16_t *M3_Max_pos = ((int16_t *)&QSPI_rx_buffer[18]); +static volatile int16_t *M3_Max_velocity = ((int16_t *)&QSPI_rx_buffer[18]+1); +static volatile int16_t *M3_Max_current = ((int16_t *)&QSPI_rx_buffer[19]); +static volatile int16_t *M3_Spare = ((int16_t *)&QSPI_rx_buffer[19]+1); //Spare ///* Motor 4*/ -static volatile uint8_t *M4_Control_mode = ((uint8_t *)&QSPI_rx_buffer[12]); -static volatile uint8_t *M4_Control_set = (((uint8_t *)&QSPI_rx_buffer[12])+1); -static volatile int16_t *M4_Desired_pos = ((int16_t *)&QSPI_rx_buffer[12]+1); -static volatile int16_t *M4_Desired_speed = ((int16_t *)&QSPI_rx_buffer[13]); -static volatile int16_t *M4_Desired_current = ((int16_t *)&QSPI_rx_buffer[13]+1); -static volatile int16_t *M4_Max_pos = ((int16_t *)&QSPI_rx_buffer[14]); -static volatile int16_t *M4_Max_velocity = ((int16_t *)&QSPI_rx_buffer[14]+1); -static volatile int16_t *M4_Max_current = ((int16_t *)&QSPI_rx_buffer[15]); -static volatile int16_t *M4_Spare = ((int16_t *)&QSPI_rx_buffer[15]+1);//Spare +static volatile uint8_t *M4_Control_mode = ((uint8_t *)&QSPI_rx_buffer[20]); +static volatile uint8_t *M4_Control_set = (((uint8_t *)&QSPI_rx_buffer[20])+1); +static volatile int16_t *M4_Desired_pos = ((int16_t *)&QSPI_rx_buffer[20]+1); +static volatile int16_t *M4_Desired_speed = ((int16_t *)&QSPI_rx_buffer[21]); +static volatile int16_t *M4_Desired_current = ((int16_t *)&QSPI_rx_buffer[21]+1); +static volatile int16_t *M4_Max_pos = ((int16_t *)&QSPI_rx_buffer[22]); +static volatile int16_t *M4_Max_velocity = ((int16_t *)&QSPI_rx_buffer[22]+1); +static volatile int16_t *M4_Max_current = ((int16_t *)&QSPI_rx_buffer[23]); +static volatile int16_t *M4_Spare = ((int16_t *)&QSPI_rx_buffer[23]+1); //Spare static void update_telemetry(void) { diff --git a/2_Motor_Master/Motor_Master/Motor_Master/Ethercat_SlaveDef.h b/2_Motor_Master/Motor_Master/Motor_Master/Ethercat_SlaveDef.h index ca22b89..0a5526c 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/Ethercat_SlaveDef.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/Ethercat_SlaveDef.h @@ -45,44 +45,51 @@ static volatile int16_t *EMG_CH5 = (((int16_t *)&QSPI_tx_buffer[12])); static volatile int16_t *EMG_CH6 = (((int16_t *)&QSPI_tx_buffer[12])+1); static volatile int16_t *EMG_CH7 = (((int16_t *)&QSPI_tx_buffer[13])); static volatile int16_t *EMG_CH8 = (((int16_t *)&QSPI_tx_buffer[13])+1); + +/* Reserved space */ +static volatile int16_t *Spare1_tx = (((int16_t *)&QSPI_tx_buffer[14])); +static volatile int16_t *Spare2_tx = (((int16_t *)&QSPI_tx_buffer[14])+1); +static volatile int16_t *Spare3_tx = (((int16_t *)&QSPI_tx_buffer[15])); +static volatile int16_t *Spare4_tx = (((int16_t *)&QSPI_tx_buffer[15])+1); + /* Motor 3*/ -static volatile uint8_t *M3_Status = (uint8_t *)&QSPI_tx_buffer[14]; -static volatile uint8_t *M3_Mode = (((uint8_t *)&QSPI_tx_buffer[14])+1); -static volatile int16_t *M3_Joint_rel_position = (((int16_t *)&QSPI_tx_buffer[14])+1); -static volatile int16_t *M3_Joint_abs_position = ((int16_t *)&QSPI_tx_buffer[15]); -static volatile int16_t *M3_Motor_speed = (((int16_t *)&QSPI_tx_buffer[15])+1); -static volatile int16_t *M3_Motor_current_bus = ((int16_t *)&QSPI_tx_buffer[16]); -static volatile int16_t *M3_Motor_currentPhA = (((int16_t *)&QSPI_tx_buffer[16])+1); -static volatile int16_t *M3_Motor_currentPhB = ((int16_t *)&QSPI_tx_buffer[17]); -static volatile int16_t *M3_Motor_currentPhC = (((int16_t *)&QSPI_tx_buffer[17])+1); -static volatile int16_t *M3_Motor__hallState = ((int16_t *)&QSPI_tx_buffer[18]); -static volatile int16_t *M3_Motor_dutyCycle = (((int16_t *)&QSPI_tx_buffer[18])+1); +static volatile uint8_t *M3_Status = (uint8_t *)&QSPI_tx_buffer[16]; +static volatile uint8_t *M3_Mode = (((uint8_t *)&QSPI_tx_buffer[16])+1); +static volatile int16_t *M3_Joint_rel_position = (((int16_t *)&QSPI_tx_buffer[16])+1); +static volatile int16_t *M3_Joint_abs_position = ((int16_t *)&QSPI_tx_buffer[17]); +static volatile int16_t *M3_Motor_speed = (((int16_t *)&QSPI_tx_buffer[17])+1); +static volatile int16_t *M3_Motor_current_bus = ((int16_t *)&QSPI_tx_buffer[18]); +static volatile int16_t *M3_Motor_currentPhA = (((int16_t *)&QSPI_tx_buffer[18])+1); +static volatile int16_t *M3_Motor_currentPhB = ((int16_t *)&QSPI_tx_buffer[19]); +static volatile int16_t *M3_Motor_currentPhC = (((int16_t *)&QSPI_tx_buffer[19])+1); +static volatile int16_t *M3_Motor__hallState = ((int16_t *)&QSPI_tx_buffer[20]); +static volatile int16_t *M3_Motor_dutyCycle = (((int16_t *)&QSPI_tx_buffer[20])+1); /* Motor 4*/ -static volatile uint8_t *M4_Status = (uint8_t *)&QSPI_tx_buffer[19]; -static volatile uint8_t *M4_Mode = (((uint8_t *)&QSPI_tx_buffer[19])+1); -static volatile int16_t *M4_Joint_rel_position = (((int16_t *)&QSPI_tx_buffer[19])+1); -static volatile int16_t *M4_Joint_abs_position = ((int16_t *)&QSPI_tx_buffer[20]); -static volatile int16_t *M4_Motor_speed = (((int16_t *)&QSPI_tx_buffer[20])+1); -static volatile int16_t *M4_Motor_current_bus = ((int16_t *)&QSPI_tx_buffer[21]); -static volatile int16_t *M4_Motor_currentPhA = (((int16_t *)&QSPI_tx_buffer[21])+1); -static volatile int16_t *M4_Motor_currentPhB = ((int16_t *)&QSPI_tx_buffer[22]); -static volatile int16_t *M4_Motor_currentPhC = (((int16_t *)&QSPI_tx_buffer[22])+1); -static volatile int16_t *M4_Motor__hallState = ((int16_t *)&QSPI_tx_buffer[23]); -static volatile int16_t *M4_Motor_dutyCycle = (((int16_t *)&QSPI_tx_buffer[23])+1); +static volatile uint8_t *M4_Status = (uint8_t *)&QSPI_tx_buffer[21]; +static volatile uint8_t *M4_Mode = (((uint8_t *)&QSPI_tx_buffer[21])+1); +static volatile int16_t *M4_Joint_rel_position = (((int16_t *)&QSPI_tx_buffer[21])+1); +static volatile int16_t *M4_Joint_abs_position = ((int16_t *)&QSPI_tx_buffer[22]); +static volatile int16_t *M4_Motor_speed = (((int16_t *)&QSPI_tx_buffer[22])+1); +static volatile int16_t *M4_Motor_current_bus = ((int16_t *)&QSPI_tx_buffer[23]); +static volatile int16_t *M4_Motor_currentPhA = (((int16_t *)&QSPI_tx_buffer[23])+1); +static volatile int16_t *M4_Motor_currentPhB = ((int16_t *)&QSPI_tx_buffer[24]); +static volatile int16_t *M4_Motor_currentPhC = (((int16_t *)&QSPI_tx_buffer[24])+1); +static volatile int16_t *M4_Motor__hallState = ((int16_t *)&QSPI_tx_buffer[25]); +static volatile int16_t *M4_Motor_dutyCycle = (((int16_t *)&QSPI_tx_buffer[25])+1); /* IMU */ -static volatile int16_t *q_x0 = (((int16_t *)&QSPI_tx_buffer[24])); -static volatile int16_t *q_y0 = (((int16_t *)&QSPI_tx_buffer[24])+1); -static volatile int16_t *q_z0 = (((int16_t *)&QSPI_tx_buffer[25])); -static volatile int16_t *q_w0 = (((int16_t *)&QSPI_tx_buffer[25])+1); +static volatile int16_t *q_x0 = (((int16_t *)&QSPI_tx_buffer[26])); +static volatile int16_t *q_y0 = (((int16_t *)&QSPI_tx_buffer[26])+1); +static volatile int16_t *q_z0 = (((int16_t *)&QSPI_tx_buffer[27])); +static volatile int16_t *q_w0 = (((int16_t *)&QSPI_tx_buffer[27])+1); /* EMG */ -static volatile int16_t *FSR_CH1 = (((int16_t *)&QSPI_tx_buffer[26])); -static volatile int16_t *FSR_CH2 = (((int16_t *)&QSPI_tx_buffer[26])+1); -static volatile int16_t *FSR_CH3 = (((int16_t *)&QSPI_tx_buffer[27])); -static volatile int16_t *FSR_CH4 = (((int16_t *)&QSPI_tx_buffer[27])+1); -static volatile int16_t *FSR_CH5 = (((int16_t *)&QSPI_tx_buffer[28])); -static volatile int16_t *Pressure_CH1 = (((int16_t *)&QSPI_tx_buffer[28])+1); -static volatile int16_t *Pressure_CH2 = (((int16_t *)&QSPI_tx_buffer[29])); -static volatile int16_t *Pressure_CH3 = (((int16_t *)&QSPI_tx_buffer[29])+1); +static volatile int16_t *FSR_CH1 = (((int16_t *)&QSPI_tx_buffer[28])); +static volatile int16_t *FSR_CH2 = (((int16_t *)&QSPI_tx_buffer[28])+1); +static volatile int16_t *FSR_CH3 = (((int16_t *)&QSPI_tx_buffer[29])); +static volatile int16_t *FSR_CH4 = (((int16_t *)&QSPI_tx_buffer[29])+1); +static volatile int16_t *FSR_CH5 = (((int16_t *)&QSPI_tx_buffer[30])); +static volatile int16_t *Pressure_CH1 = (((int16_t *)&QSPI_tx_buffer[30])+1); +static volatile int16_t *Pressure_CH2 = (((int16_t *)&QSPI_tx_buffer[31])); +static volatile int16_t *Pressure_CH3 = (((int16_t *)&QSPI_tx_buffer[31])+1); //Read From Ecat Total (XX Bytes) //QSPI_rx_buffer @@ -106,26 +113,46 @@ static volatile int16_t *M2_Max_pos = ((int16_t *)&QSPI_rx_buffer[6]); static volatile int16_t *M2_Max_velocity = ((int16_t *)&QSPI_rx_buffer[6]+1); static volatile int16_t *M2_Max_current = ((int16_t *)&QSPI_rx_buffer[7]); static volatile int16_t *M2_Desired_dc = ((int16_t *)&QSPI_rx_buffer[7]+1); //Spare + +/* Reserved space */ +/* 64 bytes reserved for each */ +static volatile int16_t *Spare1_rx = ((int16_t *)&QSPI_rx_buffer[8]); //Spare +static volatile int16_t *Spare2_rx = ((int16_t *)&QSPI_rx_buffer[8]+1); //Spare +static volatile int16_t *Spare3_rx = ((int16_t *)&QSPI_rx_buffer[9]); //Spare +static volatile int16_t *Spare4_rx = ((int16_t *)&QSPI_rx_buffer[9]+1); //Spare +static volatile int16_t *Spare5_rx = ((int16_t *)&QSPI_rx_buffer[10]); //Spare +static volatile int16_t *Spare6_rx = ((int16_t *)&QSPI_rx_buffer[10]+1); //Spare +static volatile int16_t *Spare7_rx = ((int16_t *)&QSPI_rx_buffer[11]); //Spare +static volatile int16_t *Spare8_rx = ((int16_t *)&QSPI_rx_buffer[11]+1); //Spare +static volatile int16_t *Spare9_rx = ((int16_t *)&QSPI_rx_buffer[12]); //Spare +static volatile int16_t *Spare10_rx = ((int16_t *)&QSPI_rx_buffer[12]+1); //Spare +static volatile int16_t *Spare11_rx = ((int16_t *)&QSPI_rx_buffer[13]); //Spare +static volatile int16_t *Spare12_rx = ((int16_t *)&QSPI_rx_buffer[13]+1); //Spare +static volatile int16_t *Spare13_rx = ((int16_t *)&QSPI_rx_buffer[14]); //Spare +static volatile int16_t *Spare14_rx = ((int16_t *)&QSPI_rx_buffer[14]+1); //Spare +static volatile int16_t *Spare15_rx = ((int16_t *)&QSPI_rx_buffer[15]); //Spare +static volatile int16_t *Spare16_rx = ((int16_t *)&QSPI_rx_buffer[15]+1); //Spare + ///* Motor 3*/ -static volatile uint8_t *M3_Control_mode = ((uint8_t *)&QSPI_rx_buffer[8]); -static volatile uint8_t *M3_Control_set = (((uint8_t *)&QSPI_rx_buffer[8])+1); -static volatile int16_t *M3_Desired_pos = ((int16_t *)&QSPI_rx_buffer[8]+1); -static volatile int16_t *M3_Desired_speed = ((int16_t *)&QSPI_rx_buffer[9]); -static volatile int16_t *M3_Desired_current = ((int16_t *)&QSPI_rx_buffer[9]+1); -static volatile int16_t *M3_Max_pos = ((int16_t *)&QSPI_rx_buffer[10]); -static volatile int16_t *M3_Max_velocity = ((int16_t *)&QSPI_rx_buffer[10]+1); -static volatile int16_t *M3_Max_current = ((int16_t *)&QSPI_rx_buffer[11]); -static volatile int16_t *M3_Spare = ((int16_t *)&QSPI_rx_buffer[11]+1); //Spare +static volatile uint8_t *M3_Control_mode = ((uint8_t *)&QSPI_rx_buffer[16]); +static volatile uint8_t *M3_Control_set = (((uint8_t *)&QSPI_rx_buffer[16])+1); +static volatile int16_t *M3_Desired_pos = ((int16_t *)&QSPI_rx_buffer[16]+1); +static volatile int16_t *M3_Desired_speed = ((int16_t *)&QSPI_rx_buffer[17]); +static volatile int16_t *M3_Desired_current = ((int16_t *)&QSPI_rx_buffer[17]+1); +static volatile int16_t *M3_Max_pos = ((int16_t *)&QSPI_rx_buffer[18]); +static volatile int16_t *M3_Max_velocity = ((int16_t *)&QSPI_rx_buffer[18]+1); +static volatile int16_t *M3_Max_current = ((int16_t *)&QSPI_rx_buffer[19]); +static volatile int16_t *M3_Spare = ((int16_t *)&QSPI_rx_buffer[19]+1); //Spare ///* Motor 4*/ -static volatile uint8_t *M4_Control_mode = ((uint8_t *)&QSPI_rx_buffer[12]); -static volatile uint8_t *M4_Control_set = (((uint8_t *)&QSPI_rx_buffer[12])+1); -static volatile int16_t *M4_Desired_pos = ((int16_t *)&QSPI_rx_buffer[12]+1); -static volatile int16_t *M4_Desired_speed = ((int16_t *)&QSPI_rx_buffer[13]); -static volatile int16_t *M4_Desired_current = ((int16_t *)&QSPI_rx_buffer[13]+1); -static volatile int16_t *M4_Max_pos = ((int16_t *)&QSPI_rx_buffer[14]); -static volatile int16_t *M4_Max_velocity = ((int16_t *)&QSPI_rx_buffer[14]+1); -static volatile int16_t *M4_Max_current = ((int16_t *)&QSPI_rx_buffer[15]); -static volatile int16_t *M4_Spare = ((int16_t *)&QSPI_rx_buffer[15]+1);//Spare +static volatile uint8_t *M4_Control_mode = ((uint8_t *)&QSPI_rx_buffer[20]); +static volatile uint8_t *M4_Control_set = (((uint8_t *)&QSPI_rx_buffer[20])+1); +static volatile int16_t *M4_Desired_pos = ((int16_t *)&QSPI_rx_buffer[20]+1); +static volatile int16_t *M4_Desired_speed = ((int16_t *)&QSPI_rx_buffer[21]); +static volatile int16_t *M4_Desired_current = ((int16_t *)&QSPI_rx_buffer[21]+1); +static volatile int16_t *M4_Max_pos = ((int16_t *)&QSPI_rx_buffer[22]); +static volatile int16_t *M4_Max_velocity = ((int16_t *)&QSPI_rx_buffer[22]+1); +static volatile int16_t *M4_Max_current = ((int16_t *)&QSPI_rx_buffer[23]); +static volatile int16_t *M4_Spare = ((int16_t *)&QSPI_rx_buffer[23]+1); //Spare static void update_telemetry(void) { diff --git a/2_Motor_Master/Motor_Master/Motor_Master/MSIF_master.h b/2_Motor_Master/Motor_Master/Motor_Master/MSIF_master.h new file mode 100644 index 0000000..d64cfbf --- /dev/null +++ b/2_Motor_Master/Motor_Master/Motor_Master/MSIF_master.h @@ -0,0 +1,215 @@ +/* + * 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 MASTER_BUFFER_SIZE 64 +static uint8_t SPI_rx_buffer[MASTER_BUFFER_SIZE] = {0}; +static uint8_t SPI_tx_buffer[MASTER_BUFFER_SIZE] = {0}; + +//static uint8_t SPI_rx_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_rx_buffer[0]; //1 byte - 0 of 64 +static volatile uint8_t *M3_Mode = (uint8_t *)&SPI_rx_buffer[1]; //1 byte - 1 of 64 +static volatile int16_t *M3_Joint_rel_position = (int16_t *)&SPI_rx_buffer[2]; //2 byte - 2 of 64 +static volatile int16_t *M3_Joint_abs_position = (int16_t *)&SPI_rx_buffer[4]; //2 byte - 4 of 64 +static volatile int16_t *M3_Motor_speed = (int16_t *)&SPI_rx_buffer[6]; //2 byte - 6 of 64 +static volatile int16_t *M3_Motor_current_bus = (int16_t *)&SPI_rx_buffer[8]; //2 byte - 8 of 64 +static volatile int16_t *M3_Motor_currentPhA = (int16_t *)&SPI_rx_buffer[10]; //2 byte - 10 of 64 +static volatile int16_t *M3_Motor_currentPhB = (int16_t *)&SPI_rx_buffer[12]; //2 byte - 12 of 64 +static volatile int16_t *M3_Motor_currentPhC = (int16_t *)&SPI_rx_buffer[14]; //2 byte - 14 of 64 +static volatile int16_t *M3_Motor__hallState = (int16_t *)&SPI_rx_buffer[16]; //2 byte - 16 of 64 +static volatile int16_t *M3_Motor_dutyCycle = (int16_t *)&SPI_rx_buffer[18]; //2 byte - 18 of 64 +/* Motor 4*/ +static volatile uint8_t *M4_Status = (uint8_t *)&SPI_rx_buffer[20]; //1 byte - 20 of 64 +static volatile uint8_t *M4_Mode = (uint8_t *)&SPI_rx_buffer[21]; //1 byte - 21 of 64 +static volatile int16_t *M4_Joint_rel_position = (int16_t *)&SPI_rx_buffer[22]; //2 byte - 22 of 64 +static volatile int16_t *M4_Joint_abs_position = (int16_t *)&SPI_rx_buffer[24]; //2 byte - 24 of 64 +static volatile int16_t *M4_Motor_speed = (int16_t *)&SPI_rx_buffer[26]; //2 byte - 26 of 64 +static volatile int16_t *M4_Motor_current_bus = (int16_t *)&SPI_rx_buffer[28]; //2 byte - 28 of 64 +static volatile int16_t *M4_Motor_currentPhA = (int16_t *)&SPI_rx_buffer[30]; //2 byte - 30 of 64 +static volatile int16_t *M4_Motor_currentPhB = (int16_t *)&SPI_rx_buffer[32]; //2 byte - 32 of 64 +static volatile int16_t *M4_Motor_currentPhC = (int16_t *)&SPI_rx_buffer[34]; //2 byte - 34 of 64 +static volatile int16_t *M4_Motor__hallState = (int16_t *)&SPI_rx_buffer[36]; //2 byte - 36 of 64 +static volatile int16_t *M4_Motor_dutyCycle = (int16_t *)&SPI_rx_buffer[38]; //2 byte - 38 of 64 +/* IMU */ +static volatile int16_t *q_x0 = (int16_t *)&SPI_rx_buffer[40]; //2 byte - 40 of 64 +static volatile int16_t *q_y0 = (int16_t *)&SPI_rx_buffer[42]; //2 byte - 42 of 64 +static volatile int16_t *q_z0 = (int16_t *)&SPI_rx_buffer[44]; //2 byte - 44 of 64 +static volatile int16_t *q_w0 = (int16_t *)&SPI_rx_buffer[46]; //2 byte - 46 of 64 +/* EMG */ +static volatile int16_t *FSR_CH1 = (int16_t *)&SPI_rx_buffer[48]; //2 byte - 48 of 64 +static volatile int16_t *FSR_CH2 = (int16_t *)&SPI_rx_buffer[50]; //2 byte - 50 of 64 +static volatile int16_t *FSR_CH3 = (int16_t *)&SPI_rx_buffer[52]; //2 byte - 52 of 64 +static volatile int16_t *FSR_CH4 = (int16_t *)&SPI_rx_buffer[54]; //2 byte - 54 of 64 +static volatile int16_t *FSR_CH5 = (int16_t *)&SPI_rx_buffer[56]; //2 byte - 56 of 64 +static volatile int16_t *Pressure_CH1 = (int16_t *)&SPI_rx_buffer[58]; //2 byte - 58 of 64 +static volatile int16_t *Pressure_CH2 = (int16_t *)&SPI_rx_buffer[60]; //2 byte - 60 of 64 +static volatile int16_t *Pressure_CH3 = (int16_t *)&SPI_rx_buffer[62]; //2 byte - 62 of 64 + +//tx_buffer +///* Motor 3*/ +static volatile uint8_t *M3_Control_mode = (uint8_t *)&SPI_tx_buffer[0]; //1 byte - 0 of 32 +static volatile uint8_t *M3_Control_set = (uint8_t *)&SPI_tx_buffer[1]; //1 byte - 1 of 32 +static volatile int16_t *M3_Desired_pos = (int16_t *)&SPI_tx_buffer[2]; //2 byte - 2 of 32 +static volatile int16_t *M3_Desired_speed = (int16_t *)&SPI_tx_buffer[4]; //2 byte - 4 of 32 +static volatile int16_t *M3_Desired_current = (int16_t *)&SPI_tx_buffer[6]; //2 byte - 6 of 32 +static volatile int16_t *M3_Max_pos = (int16_t *)&SPI_tx_buffer[8]; //2 byte - 8 of 32 +static volatile int16_t *M3_Max_velocity = (int16_t *)&SPI_tx_buffer[10]; //2 byte - 10 of 32 +static volatile int16_t *M3_Max_current = (int16_t *)&SPI_tx_buffer[12]; //2 byte - 12 of 32 +static volatile int16_t *M3_Spare = (int16_t *)&SPI_tx_buffer[14]; //2 byte - 14 of 32 +///* Motor 4*/ +static volatile uint8_t *M4_Control_mode = (int16_t *)&SPI_tx_buffer[16]; //1 byte - 16 of 32 +static volatile uint8_t *M4_Control_set = (int16_t *)&SPI_tx_buffer[17]; //1 byte - 17 of 32 +static volatile int16_t *M4_Desired_pos = (int16_t *)&SPI_tx_buffer[18]; //2 byte - 18 of 32 +static volatile int16_t *M4_Desired_speed = (int16_t *)&SPI_tx_buffer[20]; //2 byte - 20 of 32 +static volatile int16_t *M4_Desired_current = (int16_t *)&SPI_tx_buffer[22]; //2 byte - 22 of 32 +static volatile int16_t *M4_Max_pos = (int16_t *)&SPI_tx_buffer[24]; //2 byte - 24 of 32 +static volatile int16_t *M4_Max_velocity = (int16_t *)&SPI_tx_buffer[26]; //2 byte - 26 of 32 +static volatile int16_t *M4_Max_current = (int16_t *)&SPI_tx_buffer[28]; //2 byte - 28 of 32 +static volatile int16_t *M4_Spare = (int16_t *)&SPI_tx_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.currentstate; + *M3_Joint_rel_position = Motor1.motor_status.Num_Steps; + //*M3_Joint_abs_position = ((int16_t *)&QSPI_rx_buffer[1]; + //*M3_Motor_speed = (((int16_t *)&QSPI_rx_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 = Motor1.motor_status.actualDirection; + /* Motor 2 */ + *M4_Status = Motor2.motor_state.currentstate; + *M4_Joint_rel_position = Motor2.motor_status.Num_Steps; + //*M3_Joint_abs_position = ((int16_t *)&QSPI_rx_buffer[1]; + //*M3_Motor_speed = (((int16_t *)&QSPI_rx_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 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/Motor_Master/Motor_Master/Motor_Master.cproj b/2_Motor_Master/Motor_Master/Motor_Master/Motor_Master.cproj index 3096d08..aa3b61d 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/Motor_Master.cproj +++ b/2_Motor_Master/Motor_Master/Motor_Master/Motor_Master.cproj @@ -63,6 +63,7 @@ + @@ -150,11 +151,11 @@ - - + + - - + + @@ -175,6 +176,7 @@ + @@ -198,7 +200,7 @@ - + @@ -210,7 +212,7 @@ - + @@ -219,7 +221,7 @@ - + @@ -648,6 +650,9 @@ compile + + compile + compile @@ -807,6 +812,9 @@ compile + + compile + compile @@ -1127,6 +1135,9 @@ compile + + compile + compile diff --git a/2_Motor_Master/Motor_Master/Motor_Master/bldc.c b/2_Motor_Master/Motor_Master/Motor_Master/bldc.c index d5f80fc..53768f4 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/bldc.c +++ b/2_Motor_Master/Motor_Master/Motor_Master/bldc.c @@ -35,11 +35,11 @@ void motor_StateMachine(BLDCMotor_t* const motor) case MOTOR_IDLE: //hri_tcc_write_PATTBUF_reg(motor->motor_param->pwm_desc->device.hw, DISABLE_PATTERN); motor->motor_state.previousstate = motor->motor_state.currentstate; - motor->motor_state.currentstate = MOTOR_PVI_CTRL_STATE; + motor->motor_state.currentstate = MOTOR_IDLE; break; case MOTOR_OPEN_LOOP_STATE: BLDC_runOpenLoop(motor, *M1_Desired_dc); - calculate_motor_speed(motor); + //calculate_motor_speed(motor); motor->motor_state.previousstate = motor->motor_state.currentstate; break; case MOTOR_V_CTRL_STATE: diff --git a/2_Motor_Master/Motor_Master/Motor_Master/configuration.h b/2_Motor_Master/Motor_Master/Motor_Master/configuration.h index d1654b2..02fb3ca 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/configuration.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/configuration.h @@ -16,13 +16,15 @@ #include "bldc.h" #include "interrupts.h" + + +// ---------------------------------------------------------------------- +// ADC DMA Initialization +// M1_IA=ADC1_AIN[9], M1_IB=ADC1_AIN[8], M2_IA=ADC1_AIN[7], M2_IB=ADC1_AIN[6] +// ---------------------------------------------------------------------- #define DMAC_CHANNEL_ADC_SEQ 2U #define DMAC_CHANNEL_ADC_SRAM 3U - -// ---------------------------------------------------------------------- -// M1_IA=ADC1_AIN[9], M1_IB=ADC1_AIN[8], M2_IA=ADC1_AIN[7], M2_IB=ADC1_AIN[6] -// ---------------------------------------------------------------------- /* Single Ended */ //const uint32_t adc_seq_regs[4] = {0x1807, 0x1806, 0x1809, 0x1808}; /* Differential */ @@ -32,6 +34,9 @@ volatile int16_t adc_res[4] = {0}; struct _dma_resource *adc_sram_dma_resource; struct _dma_resource *adc_dmac_sequence_resource; +// ---------------------------------------------------------------------- +// PWM Timer Initialization +// ---------------------------------------------------------------------- inline static void configure_tcc_pwm(void) { //gpio_set_pin_pull_mode(M1_HALLA, GPIO_PULL_UP); @@ -138,6 +143,19 @@ inline void adc_sram_dmac_init() _dma_enable_transaction(DMAC_CHANNEL_ADC_SRAM, false); } +// ---------------------------------------------------------------------- +// Init SPI DMA communication between Master & Slave Board +// ---------------------------------------------------------------------- + +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; + gpio_set_pin_level(SPI1_CS, true); + spi_m_dma_enable(&SPI_1_MSIF); +} #endif /* CONFIGURATION_H_ */ \ No newline at end of file diff --git a/2_Motor_Master/Motor_Master/Motor_Master/driver_init.c b/2_Motor_Master/Motor_Master/Motor_Master/driver_init.c index 1c22140..da2cb28 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/driver_init.c +++ b/2_Motor_Master/Motor_Master/Motor_Master/driver_init.c @@ -14,7 +14,6 @@ #include #include -struct spi_m_sync_descriptor SPI_1; struct spi_m_sync_descriptor SPI_3; struct timer_descriptor TIMER_0; @@ -24,6 +23,8 @@ struct adc_sync_descriptor ADC_1; struct qspi_dma_descriptor ECAT_QSPI; +struct spi_m_dma_descriptor SPI_1_MSIF; + struct spi_m_async_descriptor SPI_2; struct pwm_descriptor PWM_0; @@ -410,7 +411,7 @@ void ECAT_QSPI_init(void) ECAT_QSPI_PORT_init(); } -void SPI_1_PORT_init(void) +void SPI_1_MSIF_PORT_init(void) { gpio_set_pin_level(SPI1_MOSI, @@ -451,7 +452,7 @@ void SPI_1_PORT_init(void) gpio_set_pin_function(SPI1_MISO, PINMUX_PB23C_SERCOM1_PAD3); } -void SPI_1_CLOCK_init(void) +void SPI_1_MSIF_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)); @@ -459,11 +460,11 @@ void SPI_1_CLOCK_init(void) hri_mclk_set_APBAMASK_SERCOM1_bit(MCLK); } -void SPI_1_init(void) +void SPI_1_MSIF_init(void) { - SPI_1_CLOCK_init(); - spi_m_sync_init(&SPI_1, SERCOM1); - SPI_1_PORT_init(); + SPI_1_MSIF_CLOCK_init(); + spi_m_dma_init(&SPI_1_MSIF, SERCOM1); + SPI_1_MSIF_PORT_init(); } void SPI_2_PORT_init(void) @@ -716,6 +717,16 @@ void system_init(void) // GPIO on PB22 + gpio_set_pin_level(SPI1_CS, + // Initial level + // pad_initial_level + // Low + // High + true); + + // Set pin direction to output + gpio_set_pin_direction(SPI1_CS, GPIO_DIRECTION_OUT); + gpio_set_pin_function(SPI1_CS, GPIO_PIN_FUNCTION_OFF); ADC_0_init(); @@ -730,7 +741,7 @@ void system_init(void) ECAT_QSPI_init(); - SPI_1_init(); + SPI_1_MSIF_init(); SPI_2_init(); diff --git a/2_Motor_Master/Motor_Master/Motor_Master/driver_init.h b/2_Motor_Master/Motor_Master/Motor_Master/driver_init.h index b4af6ee..32bca4a 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/driver_init.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/driver_init.h @@ -33,7 +33,7 @@ extern "C" { #include -#include +#include #include #include @@ -52,8 +52,9 @@ extern struct adc_sync_descriptor ADC_0; extern struct adc_sync_descriptor ADC_1; -extern struct qspi_dma_descriptor ECAT_QSPI; -extern struct spi_m_sync_descriptor SPI_1; +extern struct qspi_dma_descriptor ECAT_QSPI; + +extern struct spi_m_dma_descriptor SPI_1_MSIF; extern struct spi_m_async_descriptor SPI_2; extern struct spi_m_sync_descriptor SPI_3; @@ -79,9 +80,9 @@ void ECAT_QSPI_PORT_init(void); void ECAT_QSPI_CLOCK_init(void); void ECAT_QSPI_init(void); -void SPI_1_PORT_init(void); -void SPI_1_CLOCK_init(void); -void SPI_1_init(void); +void SPI_1_MSIF_PORT_init(void); +void SPI_1_MSIF_CLOCK_init(void); +void SPI_1_MSIF_init(void); void SPI_2_PORT_init(void); void SPI_2_CLOCK_init(void); diff --git a/2_Motor_Master/Motor_Master/Motor_Master/examples/driver_examples.c b/2_Motor_Master/Motor_Master/Motor_Master/examples/driver_examples.c index 46fd6a9..80f3f55 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/examples/driver_examples.c +++ b/2_Motor_Master/Motor_Master/Motor_Master/examples/driver_examples.c @@ -101,17 +101,29 @@ void ECAT_QSPI_example(void) } /** - * Example of using SPI_1 to write "Hello World" using the IO abstraction. + * Example of using SPI_1_MSIF 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. + * + * Once transfer has been completed the tx_cb function will be called. */ -static uint8_t example_SPI_1[12] = "Hello World!"; -void SPI_1_example(void) +static uint8_t example_SPI_1_MSIF[12] = "Hello World!"; + +static void tx_complete_cb_SPI_1_MSIF(struct _dma_resource *resource) +{ + /* Transfer completed */ +} + +void SPI_1_MSIF_example(void) { struct io_descriptor *io; - spi_m_sync_get_io_descriptor(&SPI_1, &io); + spi_m_dma_get_io_descriptor(&SPI_1_MSIF, &io); - spi_m_sync_enable(&SPI_1); - io_write(io, example_SPI_1, 12); + 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); } /** diff --git a/2_Motor_Master/Motor_Master/Motor_Master/examples/driver_examples.h b/2_Motor_Master/Motor_Master/Motor_Master/examples/driver_examples.h index 7c59895..533f518 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/examples/driver_examples.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/examples/driver_examples.h @@ -22,6 +22,8 @@ void EXTERNAL_IRQ_0_example(void); void ECAT_QSPI_example(void); +void SPI_1_MSIF_example(void); + void SPI_2_example(void); void TIMER_0_example(void); diff --git a/2_Motor_Master/Motor_Master/Motor_Master/hal/documentation/spi_master_dma.rst b/2_Motor_Master/Motor_Master/Motor_Master/hal/documentation/spi_master_dma.rst new file mode 100644 index 0000000..475b317 --- /dev/null +++ b/2_Motor_Master/Motor_Master/Motor_Master/hal/documentation/spi_master_dma.rst @@ -0,0 +1,56 @@ +The SPI Master DMA Driver +================================== + +The serial peripheral interface (SPI) is a DMA serial communication +interface. + +The SPI Master DMA driver uses DMA system to transfer data from +a memory buffer to SPI (Memory to Peripheral), and receive data +from SPI to a memory buffer (Peripheral to Memory).User must configure +DMA system driver accordingly. A callback is called when all the data +is transfered or all the data is received, if it is registered via +spi_m_dma_register_callback function. + +Features +-------- + +* Initialization/de-initialization +* Enabling/disabling +* Control of the following settings: + + * Baudrate + * SPI mode + * Character size + * Data order +* Data transfer: transmission, reception and full-duplex +* Notifications about transfer completion and errors via callbacks + +Applications +------------ + +Send/receive/exchange data with a SPI slave device. E.g., serial flash, SD card, +LCD controller, etc. + +Dependencies +------------ + +SPI master capable hardware and DMA hardware, with data sent/received. + +Concurrency +----------- + +N/A + +Limitations +----------- + +When only uses DMA channel to receive data, the transfer channel must enable to +send dummy data to the slave. + +While read/write/transfer is in progress, the data buffer used must be kept +unchanged. + +Known issues and workarounds +---------------------------- + +N/A diff --git a/2_Motor_Master/Motor_Master/Motor_Master/hal/include/hal_spi_m_dma.h b/2_Motor_Master/Motor_Master/Motor_Master/hal/include/hal_spi_m_dma.h new file mode 100644 index 0000000..24e7b11 --- /dev/null +++ b/2_Motor_Master/Motor_Master/Motor_Master/hal/include/hal_spi_m_dma.h @@ -0,0 +1,257 @@ +/** + * \file + * + * \brief SPI DMA related functionality declaration. + * + * Copyright (c) 2016-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_M_DMA_H_INCLUDED +#define _HAL_SPI_M_DMA_H_INCLUDED + +#include +#include + +/** + * \addtogroup doc_driver_hal_spi_master_dma + * + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward declaration of spi_descriptor. */ +struct spi_m_dma_descriptor; + +/** The callback types */ +enum spi_m_dma_cb_type { + /** Callback type for DMA transfer buffer done */ + SPI_M_DMA_CB_TX_DONE, + /** Callback type for DMA receive buffer done */ + SPI_M_DMA_CB_RX_DONE, + /** Callback type for DMA errors */ + SPI_M_DMA_CB_ERROR, + SPI_M_DMA_CB_N +}; + +/** + * \brief SPI Master DMA callback type + */ +typedef void (*spi_m_dma_cb_t)(struct _dma_resource *resource); + +/** \brief SPI HAL driver struct for DMA access + */ +struct spi_m_dma_descriptor { + struct _spi_m_dma_hpl_interface *func; + /** Pointer to SPI device instance */ + struct _spi_m_dma_dev dev; + /** I/O read/write */ + struct io_descriptor io; + /** DMA resource */ + struct _dma_resource *resource; +}; + +/** \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_m_dma_set_func_ptr(struct spi_m_dma_descriptor *spi, void *const func); + +/** \brief Initialize the SPI HAL instance and hardware for DMA mode + * + * Initialize SPI HAL with dma mode. + * + * \param[in] spi Pointer to the HAL SPI instance. + * \param[in] hw Pointer to the hardware base. + * + * \return Operation status. + * \retval ERR_NONE Success. + * \retval ERR_INVALID_DATA Error, initialized. + */ +int32_t spi_m_dma_init(struct spi_m_dma_descriptor *spi, void *const hw); + +/** \brief Deinitialize the SPI HAL instance + * + * Abort transfer, disable and reset SPI, de-init software. + * + * \param[in] spi Pointer to the HAL SPI instance. + * + * \return Operation status. + * \retval ERR_NONE Success. + * \retval <0 Error code. + */ +void spi_m_dma_deinit(struct spi_m_dma_descriptor *spi); + +/** \brief Enable SPI + * + * \param[in] spi Pointer to the HAL SPI instance. + * + * \return Operation status. + * \retval ERR_NONE Success. + * \retval <0 Error code. + */ +void spi_m_dma_enable(struct spi_m_dma_descriptor *spi); + +/** \brief Disable SPI + * + * \param[in] spi Pointer to the HAL SPI instance. + * + * \return Operation status. + * \retval ERR_NONE Success. + * \retval <0 Error code. + */ +void spi_m_dma_disable(struct spi_m_dma_descriptor *spi); + +/** \brief Set SPI baudrate + * + * Works if SPI is initialized as master. + * In the function a sanity check is used to confirm it's called in the correct mode. + * + * \param[in] spi Pointer to the HAL SPI instance. + * \param[in] baud_val The target baudrate value + * (See "baudrate calculation" for calculating the value). + * + * \return Operation status. + * \retval ERR_NONE Success. + * \retval ERR_BUSY Busy. + * + * note: This api should be used to write the baudrate register with the given baud_val + * paramter, the user has to calculate the baud_val for required baud rate and pass it as + * argument(baud_val) to this api + */ +int32_t spi_m_dma_set_baudrate(struct spi_m_dma_descriptor *spi, const uint32_t baud_val); + +/** \brief Set SPI mode + * + * Set SPI transfer mode (\ref spi_transfer_mode), + * which controls 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. + * + * \param[in] spi Pointer to the HAL SPI instance. + * \param[in] mode The mode (\ref spi_transfer_mode). + * + * \return Operation status. + * \retval ERR_NONE Success. + * \retval ERR_BUSY Busy, CS activated. + */ +int32_t spi_m_dma_set_mode(struct spi_m_dma_descriptor *spi, const enum spi_transfer_mode mode); + +/** \brief Set the SPI transfer character size in number of bits + * + * The character size (\ref spi_char_size) 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. + * + * \param[in] spi Pointer to the HAL SPI instance. + * \param[in] char_size The char size (\ref spi_char_size). + * + * \return Operation status. + * \retval ERR_NONE Success. + * \retval ERR_BUSY Busy, CS activated. + * \retval ERR_INVALID_ARG The char size is not supported. + */ +int32_t spi_m_dma_set_char_size(struct spi_m_dma_descriptor *spi, const enum spi_char_size char_size); + +/** \brief Set SPI transfer data order + * + * \param[in] spi Pointer to the HAL SPI instance. + * \param[in] dord The data order: send LSB/MSB first. + * + * \return Operation status. + * \retval ERR_NONE Success. + * \retval ERR_BUSY Busy, CS activated. + * \retval ERR_INVALID The data order is not supported. + */ +int32_t spi_m_dma_set_data_order(struct spi_m_dma_descriptor *spi, const enum spi_data_order dord); + +/** \brief Perform the SPI data transfer (TX and RX) with the DMA + * + * \param[in] spi Pointer to the HAL SPI instance. + * \param[in] txbuf Pointer to the transfer information. + * \param[out] rxbuf Pointer to the receiver information. + * \param[in] length SPI transfer data length. + * + * \return Operation status. + * \retval ERR_NONE Success. + * \retval ERR_BUSY Busy. + */ +int32_t spi_m_dma_transfer(struct spi_m_dma_descriptor *spi, uint8_t const *txbuf, uint8_t *const rxbuf, + const uint16_t length); + +/** \brief Register a function as an SPI transfer completion callback + * + * Register a callback function specified by its \c type. + * - SPI_CB_COMPLETE: set the function that will be called on the SPI transfer + * completion including deactivating the CS. + * - SPI_CB_XFER: set the function that will be called on the SPI buffer transfer + * completion. + * Register a NULL function to not use the callback. + * + * \param[in] spi Pointer to the HAL SPI instance. + * \param[in] type Callback type (\ref spi_m_dma_cb_type). + * \param[in] func Pointer to callback function. + */ +void spi_m_dma_register_callback(struct spi_m_dma_descriptor *spi, const enum spi_m_dma_cb_type type, + spi_m_dma_cb_t func); + +/** + * \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 master descriptor, which is used to communicate through + * SPI + * \param[in, out] io A pointer to an I/O descriptor pointer type + * + * \retval ERR_NONE + */ +int32_t spi_m_dma_get_io_descriptor(struct spi_m_dma_descriptor *const spi, struct io_descriptor **io); + +/** \brief Retrieve the current driver version + * + * \return Current driver version. + */ +uint32_t spi_m_dma_get_version(void); + +#ifdef __cplusplus +} +#endif +/**@}*/ +#endif /* ifndef _HAL_SPI_M_DMA_H_INCLUDED */ diff --git a/2_Motor_Master/Motor_Master/Motor_Master/hal/src/hal_spi_m_dma.c b/2_Motor_Master/Motor_Master/Motor_Master/hal/src/hal_spi_m_dma.c new file mode 100644 index 0000000..976d0f8 --- /dev/null +++ b/2_Motor_Master/Motor_Master/Motor_Master/hal/src/hal_spi_m_dma.c @@ -0,0 +1,183 @@ +/** + * \file + * + * \brief I/O SPI DMA related functionality implementation. + * + * Copyright (c) 2016-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_m_dma.h" +#include +#include + +/** + * \brief Driver version + */ +#define SPI_DRIVER_VERSION 0x00000001u + +static int32_t _spi_m_dma_io_write(struct io_descriptor *const io, const uint8_t *const buf, const uint16_t length); +static int32_t _spi_m_dma_io_read(struct io_descriptor *const io, uint8_t *const buf, const uint16_t length); + +/** + * \brief Initialize the SPI HAL instance function pointer for HPL APIs. + */ +void spi_m_dma_set_func_ptr(struct spi_m_dma_descriptor *spi, void *const func) +{ + ASSERT(spi); + spi->func = (struct _spi_m_dma_hpl_interface *)func; +} + +int32_t spi_m_dma_init(struct spi_m_dma_descriptor *spi, void *const hw) +{ + int32_t rc = 0; + ASSERT(spi && hw); + spi->dev.prvt = (void *)hw; + rc = _spi_m_dma_init(&spi->dev, hw); + + if (rc) { + return rc; + } + + spi->io.read = _spi_m_dma_io_read; + spi->io.write = _spi_m_dma_io_write; + + return ERR_NONE; +} + +void spi_m_dma_deinit(struct spi_m_dma_descriptor *spi) +{ + ASSERT(spi); + _spi_m_dma_deinit(&spi->dev); +} + +void spi_m_dma_enable(struct spi_m_dma_descriptor *spi) +{ + ASSERT(spi); + _spi_m_dma_enable(&spi->dev); +} + +void spi_m_dma_disable(struct spi_m_dma_descriptor *spi) +{ + ASSERT(spi); + _spi_m_dma_disable(&spi->dev); +} + +int32_t spi_m_dma_set_baudrate(struct spi_m_dma_descriptor *spi, const uint32_t baud_val) +{ + ASSERT(spi); + return _spi_m_dma_set_baudrate(&spi->dev, baud_val); +} + +int32_t spi_m_dma_set_mode(struct spi_m_dma_descriptor *spi, const enum spi_transfer_mode mode) +{ + ASSERT(spi); + return _spi_m_dma_set_mode(&spi->dev, mode); +} + +int32_t spi_m_dma_set_char_size(struct spi_m_dma_descriptor *spi, const enum spi_char_size char_size) +{ + ASSERT(spi); + return _spi_m_dma_set_char_size(&spi->dev, char_size); +} + +int32_t spi_m_dma_set_data_order(struct spi_m_dma_descriptor *spi, const enum spi_data_order dord) +{ + ASSERT(spi); + return _spi_m_dma_set_data_order(&spi->dev, dord); +} + +/** \brief Do SPI read in background + * + * It never blocks and return quickly, user check status or set callback to + * know when data is ready to process. + * + * \param[in, out] spi Pointer to the HAL SPI instance. + * \param[out] p_buf Pointer to the buffer to store read data. + * \param[in] size Size of the data in number of characters. + * \return ERR_NONE on success, or an error code on failure. + * \retval ERR_NONE Success, transfer started. + * \retval ERR_BUSY Busy. + */ +static int32_t _spi_m_dma_io_read(struct io_descriptor *io, uint8_t *const buf, const uint16_t length) +{ + ASSERT(io); + + struct spi_m_dma_descriptor *spi = CONTAINER_OF(io, struct spi_m_dma_descriptor, io); + return _spi_m_dma_transfer(&spi->dev, NULL, buf, length); +} + +/** \brief Do SPI data write in background + * + * The data read back is discarded. + * + * It never blocks and return quickly, user check status or set callback to + * know when data is sent. + * + * \param[in, out] spi Pointer to the HAL SPI instance. + * \param[in] p_buf Pointer to the buffer to store data to write. + * \param[in] size Size of the data in number of characters. + * + * \return ERR_NONE on success, or an error code on failure. + * \retval ERR_NONE Success, transfer started. + * \retval ERR_BUSY Busy. + */ +static int32_t _spi_m_dma_io_write(struct io_descriptor *io, const uint8_t *const buf, const uint16_t length) +{ + ASSERT(io); + + struct spi_m_dma_descriptor *spi = CONTAINER_OF(io, struct spi_m_dma_descriptor, io); + return _spi_m_dma_transfer(&spi->dev, buf, NULL, length); +} + +int32_t spi_m_dma_transfer(struct spi_m_dma_descriptor *spi, uint8_t const *txbuf, uint8_t *const rxbuf, + const uint16_t length) +{ + ASSERT(spi); + return _spi_m_dma_transfer(&spi->dev, txbuf, rxbuf, length); +} + +void spi_m_dma_register_callback(struct spi_m_dma_descriptor *spi, const enum spi_m_dma_cb_type type, + spi_m_dma_cb_t func) +{ + ASSERT(spi); + _spi_m_dma_register_callback(&spi->dev, (enum _spi_dma_dev_cb_type)type, func); +} + +int32_t spi_m_dma_get_io_descriptor(struct spi_m_dma_descriptor *const spi, struct io_descriptor **io) +{ + ASSERT(spi && io); + *io = &spi->io; + + return 0; +} + +uint32_t spi_m_dma_get_version(void) +{ + return SPI_DRIVER_VERSION; +} diff --git a/2_Motor_Master/Motor_Master/Motor_Master/hpl/sercom/hpl_sercom.c b/2_Motor_Master/Motor_Master/Motor_Master/hpl/sercom/hpl_sercom.c index 66a059a..d81c840 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/hpl/sercom/hpl_sercom.c +++ b/2_Motor_Master/Motor_Master/Motor_Master/hpl/sercom/hpl_sercom.c @@ -31,6 +31,7 @@ * \asf_license_stop * */ +#include #include #include #include @@ -3018,3 +3019,428 @@ void _spi_s_async_set_irq_state(struct _spi_async_dev *const device, const enum { _spi_m_async_set_irq_state(device, type, state); } +#ifndef CONF_SERCOM_0_SPI_M_DMA_TX_CHANNEL +#define CONF_SERCOM_0_SPI_M_DMA_TX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_0_SPI_M_DMA_RX_CHANNEL +#define CONF_SERCOM_0_SPI_M_DMA_RX_CHANNEL 1 +#endif +#ifndef CONF_SERCOM_1_SPI_M_DMA_TX_CHANNEL +#define CONF_SERCOM_1_SPI_M_DMA_TX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_1_SPI_M_DMA_RX_CHANNEL +#define CONF_SERCOM_1_SPI_M_DMA_RX_CHANNEL 1 +#endif +#ifndef CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL +#define CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_2_SPI_M_DMA_RX_CHANNEL +#define CONF_SERCOM_2_SPI_M_DMA_RX_CHANNEL 1 +#endif +#ifndef CONF_SERCOM_3_SPI_M_DMA_TX_CHANNEL +#define CONF_SERCOM_3_SPI_M_DMA_TX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_3_SPI_M_DMA_RX_CHANNEL +#define CONF_SERCOM_3_SPI_M_DMA_RX_CHANNEL 1 +#endif +#ifndef CONF_SERCOM_4_SPI_M_DMA_TX_CHANNEL +#define CONF_SERCOM_4_SPI_M_DMA_TX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_4_SPI_M_DMA_RX_CHANNEL +#define CONF_SERCOM_4_SPI_M_DMA_RX_CHANNEL 1 +#endif +#ifndef CONF_SERCOM_5_SPI_M_DMA_TX_CHANNEL +#define CONF_SERCOM_5_SPI_M_DMA_TX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_5_SPI_M_DMA_RX_CHANNEL +#define CONF_SERCOM_5_SPI_M_DMA_RX_CHANNEL 1 +#endif +#ifndef CONF_SERCOM_6_SPI_M_DMA_TX_CHANNEL +#define CONF_SERCOM_6_SPI_M_DMA_TX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_6_SPI_M_DMA_RX_CHANNEL +#define CONF_SERCOM_6_SPI_M_DMA_RX_CHANNEL 1 +#endif +#ifndef CONF_SERCOM_7_SPI_M_DMA_TX_CHANNEL +#define CONF_SERCOM_7_SPI_M_DMA_TX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_7_SPI_M_DMA_RX_CHANNEL +#define CONF_SERCOM_7_SPI_M_DMA_RX_CHANNEL 1 +#endif + +#ifndef CONF_SERCOM_0_SPI_RX_CHANNEL +#define CONF_SERCOM_0_SPI_RX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_1_SPI_RX_CHANNEL +#define CONF_SERCOM_1_SPI_RX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_2_SPI_RX_CHANNEL +#define CONF_SERCOM_2_SPI_RX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_3_SPI_RX_CHANNEL +#define CONF_SERCOM_3_SPI_RX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_4_SPI_RX_CHANNEL +#define CONF_SERCOM_4_SPI_RX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_5_SPI_RX_CHANNEL +#define CONF_SERCOM_5_SPI_RX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_6_SPI_RX_CHANNEL +#define CONF_SERCOM_6_SPI_RX_CHANNEL 0 +#endif +#ifndef CONF_SERCOM_7_SPI_RX_CHANNEL +#define CONF_SERCOM_7_SPI_RX_CHANNEL 0 +#endif + +/** \internal Enable SERCOM SPI RX + * + * \param[in] hw Pointer to the hardware register base. + * + * \return Enabling status + */ +static int32_t _spi_sync_rx_enable(void *const hw) +{ + if (hri_sercomspi_is_syncing(hw, SERCOM_SPI_SYNCBUSY_CTRLB)) { + return ERR_BUSY; + } + + hri_sercomspi_set_CTRLB_RXEN_bit(hw); + + return ERR_NONE; +} + +/** \internal Disable SERCOM SPI RX + * + * \param[in] hw Pointer to the hardware register base. + * + * \return Disabling status + */ +static int32_t _spi_sync_rx_disable(void *const hw) +{ + if (hri_sercomspi_is_syncing(hw, SERCOM_SPI_SYNCBUSY_CTRLB)) { + return ERR_BUSY; + } + hri_sercomspi_clear_CTRLB_RXEN_bit(hw); + + return ERR_NONE; +} + +static int32_t _spi_m_dma_rx_enable(struct _spi_m_dma_dev *dev) +{ + ASSERT(dev && dev->prvt); + + return _spi_sync_rx_enable(dev->prvt); +} + +static int32_t _spi_m_dma_rx_disable(struct _spi_m_dma_dev *dev) +{ + ASSERT(dev && dev->prvt); + + return _spi_sync_rx_disable(dev->prvt); +} + +/** + * \brief Get the spi source address for DMA + * \param[in] dev Pointer to the SPI device instance + * + * \return The spi source address + */ +static uint32_t _spi_m_get_source_for_dma(void *const hw) +{ + return (uint32_t) & (((Sercom *)hw)->SPI.DATA); +} + +/** + * \brief Get the spi destination address for DMA + * \param[in] dev Pointer to the SPI device instance + * + * \return The spi destination address + */ +static uint32_t _spi_m_get_destination_for_dma(void *const hw) +{ + return (uint32_t) & (((Sercom *)hw)->SPI.DATA); +} + +/** + * \brief Return the SPI TX DMA channel index + * \param[in] hw_addr The hardware register base address + * + * \return SPI TX DMA channel index. + */ +static uint8_t _spi_get_tx_dma_channel(const void *const hw) +{ + uint8_t index = _sercom_get_hardware_index(hw); + + switch (index) { + case 0: + return CONF_SERCOM_0_SPI_M_DMA_TX_CHANNEL; + case 1: + return CONF_SERCOM_1_SPI_M_DMA_TX_CHANNEL; + case 2: + return CONF_SERCOM_2_SPI_M_DMA_TX_CHANNEL; + case 3: + return CONF_SERCOM_3_SPI_M_DMA_TX_CHANNEL; + case 4: + return CONF_SERCOM_4_SPI_M_DMA_TX_CHANNEL; + case 5: + return CONF_SERCOM_5_SPI_M_DMA_TX_CHANNEL; + case 6: + return CONF_SERCOM_6_SPI_M_DMA_TX_CHANNEL; + case 7: + return CONF_SERCOM_7_SPI_M_DMA_TX_CHANNEL; + default: + return CONF_SERCOM_0_SPI_M_DMA_TX_CHANNEL; + } +} + +/** + * \brief Return whether SPI RX DMA channel is enabled or not + * \param[in] hw_addr The hardware register base address + * + * \return one if enabled. + */ +static uint8_t _spi_is_rx_dma_channel_enabled(const void *const hw) +{ + uint8_t index = _sercom_get_hardware_index(hw); + + switch (index) { + case 0: + return CONF_SERCOM_0_SPI_RX_CHANNEL; + case 1: + return CONF_SERCOM_1_SPI_RX_CHANNEL; + case 2: + return CONF_SERCOM_2_SPI_RX_CHANNEL; + case 3: + return CONF_SERCOM_3_SPI_RX_CHANNEL; + case 4: + return CONF_SERCOM_4_SPI_RX_CHANNEL; + case 5: + return CONF_SERCOM_5_SPI_RX_CHANNEL; + case 6: + return CONF_SERCOM_6_SPI_RX_CHANNEL; + case 7: + return CONF_SERCOM_7_SPI_RX_CHANNEL; + default: + return false; + } +} + +/** + * \brief Return the SPI RX DMA channel index + * \param[in] hw_addr The hardware register base address + * + * \return SPI RX DMA channel index. + */ +static uint8_t _spi_get_rx_dma_channel(const void *const hw) +{ + uint8_t index = _sercom_get_hardware_index(hw); + + switch (index) { + case 0: + return CONF_SERCOM_0_SPI_M_DMA_RX_CHANNEL; + case 1: + return CONF_SERCOM_1_SPI_M_DMA_RX_CHANNEL; + case 2: + return CONF_SERCOM_2_SPI_M_DMA_RX_CHANNEL; + case 3: + return CONF_SERCOM_3_SPI_M_DMA_RX_CHANNEL; + case 4: + return CONF_SERCOM_4_SPI_M_DMA_RX_CHANNEL; + case 5: + return CONF_SERCOM_5_SPI_M_DMA_RX_CHANNEL; + case 6: + return CONF_SERCOM_6_SPI_M_DMA_RX_CHANNEL; + case 7: + return CONF_SERCOM_7_SPI_M_DMA_RX_CHANNEL; + default: + return CONF_SERCOM_0_SPI_M_DMA_TX_CHANNEL; + } +} + +/** + * \brief Callback for RX + * \param[in, out] dev Pointer to the DMA resource. + */ +static void _spi_dma_rx_complete(struct _dma_resource *resource) +{ + struct _spi_m_dma_dev *dev = (struct _spi_m_dma_dev *)resource->back; + + if (dev->callbacks.rx) { + dev->callbacks.rx(resource); + } +} + +/** + * \brief Callback for TX + * \param[in, out] dev Pointer to the DMA resource. + */ +static void _spi_dma_tx_complete(struct _dma_resource *resource) +{ + struct _spi_m_dma_dev *dev = (struct _spi_m_dma_dev *)resource->back; + + if (dev->callbacks.tx) { + dev->callbacks.tx(resource); + } +} + +/** + * \brief Callback for ERROR + * \param[in, out] dev Pointer to the DMA resource. + */ +static void _spi_dma_error_occured(struct _dma_resource *resource) +{ + struct _spi_m_dma_dev *dev = (struct _spi_m_dma_dev *)resource->back; + + if (dev->callbacks.error) { + dev->callbacks.error(resource); + } +} + +int32_t _spi_m_dma_init(struct _spi_m_dma_dev *dev, void *const hw) +{ + const struct sercomspi_regs_cfg *regs = _spi_get_regs((uint32_t)hw); + + ASSERT(dev && hw); + + if (regs == NULL) { + return ERR_INVALID_ARG; + } + + if (!hri_sercomspi_is_syncing(hw, SERCOM_SPI_SYNCBUSY_SWRST)) { + uint32_t mode = regs->ctrla & SERCOM_SPI_CTRLA_MODE_Msk; + if (hri_sercomspi_get_CTRLA_reg(hw, SERCOM_SPI_CTRLA_ENABLE)) { + hri_sercomspi_clear_CTRLA_ENABLE_bit(hw); + hri_sercomspi_wait_for_sync(hw, SERCOM_SPI_SYNCBUSY_ENABLE); + } + hri_sercomspi_write_CTRLA_reg(hw, SERCOM_SPI_CTRLA_SWRST | mode); + } + hri_sercomspi_wait_for_sync(hw, SERCOM_SPI_SYNCBUSY_SWRST); + + dev->prvt = hw; + + _spi_load_regs_master(hw, regs); + + /* If enabled, initialize DMA rx channel */ + if (_spi_is_rx_dma_channel_enabled(hw)) { + _dma_get_channel_resource(&dev->resource, _spi_get_rx_dma_channel(hw)); + dev->resource->back = dev; + dev->resource->dma_cb.transfer_done = _spi_dma_rx_complete; + dev->resource->dma_cb.error = _spi_dma_error_occured; + } + /* Initialize DMA tx channel */ + _dma_get_channel_resource(&dev->resource, _spi_get_tx_dma_channel(hw)); + dev->resource->back = dev; + dev->resource->dma_cb.transfer_done = _spi_dma_tx_complete; + dev->resource->dma_cb.error = _spi_dma_error_occured; + + return ERR_NONE; +} + +int32_t _spi_m_dma_deinit(struct _spi_m_dma_dev *dev) +{ + return _spi_deinit(dev->prvt); +} + +int32_t _spi_m_dma_enable(struct _spi_m_dma_dev *dev) +{ + ASSERT(dev && dev->prvt); + + return _spi_sync_enable(dev->prvt); +} + +int32_t _spi_m_dma_disable(struct _spi_m_dma_dev *dev) +{ + ASSERT(dev && dev->prvt); + + return _spi_sync_disable(dev->prvt); +} + +int32_t _spi_m_dma_set_mode(struct _spi_m_dma_dev *dev, const enum spi_transfer_mode mode) +{ + ASSERT(dev && dev->prvt); + + return _spi_set_mode(dev->prvt, mode); +} + +int32_t _spi_m_dma_set_baudrate(struct _spi_m_dma_dev *dev, const uint32_t baud_val) +{ + ASSERT(dev && dev->prvt); + + return _spi_set_baudrate(dev->prvt, baud_val); +} + +int32_t _spi_m_dma_set_data_order(struct _spi_m_dma_dev *dev, const enum spi_data_order dord) +{ + ASSERT(dev && dev->prvt); + + return _spi_set_data_order(dev->prvt, dord); +} + +int32_t _spi_m_dma_set_char_size(struct _spi_m_dma_dev *dev, const enum spi_char_size char_size) +{ + uint8_t size; + + ASSERT(dev && dev->prvt); + + _spi_set_char_size(dev->prvt, char_size, &size); + + return size; +} + +void _spi_m_dma_register_callback(struct _spi_m_dma_dev *dev, enum _spi_dma_dev_cb_type type, _spi_dma_cb_t func) +{ + switch (type) { + case SPI_DEV_CB_DMA_TX: + dev->callbacks.tx = func; + _dma_set_irq_state(_spi_get_tx_dma_channel(dev->prvt), DMA_TRANSFER_COMPLETE_CB, func != NULL); + break; + case SPI_DEV_CB_DMA_RX: + dev->callbacks.rx = func; + _dma_set_irq_state(_spi_get_rx_dma_channel(dev->prvt), DMA_TRANSFER_COMPLETE_CB, func != NULL); + break; + case SPI_DEV_CB_DMA_ERROR: + dev->callbacks.error = func; + _dma_set_irq_state(_spi_get_rx_dma_channel(dev->prvt), DMA_TRANSFER_ERROR_CB, func != NULL); + _dma_set_irq_state(_spi_get_tx_dma_channel(dev->prvt), DMA_TRANSFER_ERROR_CB, func != NULL); + break; + case SPI_DEV_CB_DMA_N: + break; + } +} + +int32_t _spi_m_dma_transfer(struct _spi_m_dma_dev *dev, uint8_t const *txbuf, uint8_t *const rxbuf, + const uint16_t length) +{ + const struct sercomspi_regs_cfg *regs = _spi_get_regs((uint32_t)dev->prvt); + uint8_t rx_ch = _spi_get_rx_dma_channel(dev->prvt); + uint8_t tx_ch = _spi_get_tx_dma_channel(dev->prvt); + + if (rxbuf) { + /* Enable spi rx */ + _spi_m_dma_rx_enable(dev); + _dma_set_source_address(rx_ch, (void *)_spi_m_get_source_for_dma(dev->prvt)); + _dma_set_destination_address(rx_ch, rxbuf); + _dma_set_data_amount(rx_ch, length); + _dma_enable_transaction(rx_ch, false); + } else { + /* Disable spi rx */ + _spi_m_dma_rx_disable(dev); + } + + if (txbuf) { + /* Enable spi tx */ + _dma_set_source_address(tx_ch, txbuf); + _dma_set_destination_address(tx_ch, (void *)_spi_m_get_destination_for_dma(dev->prvt)); + _dma_srcinc_enable(tx_ch, true); + _dma_set_data_amount(tx_ch, length); + } else { + _dma_set_source_address(tx_ch, ®s->dummy_byte); + _dma_set_destination_address(tx_ch, (void *)_spi_m_get_destination_for_dma(dev->prvt)); + _dma_srcinc_enable(tx_ch, false); + _dma_set_data_amount(tx_ch, length); + } + _dma_enable_transaction(tx_ch, false); + + return ERR_NONE; +} diff --git a/2_Motor_Master/Motor_Master/Motor_Master/interrupts.h b/2_Motor_Master/Motor_Master/Motor_Master/interrupts.h index df2f689..7a4ca8b 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/interrupts.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/interrupts.h @@ -9,6 +9,17 @@ #ifndef INTERRUPTS_H_ #define INTERRUPTS_H_ + +// ---------------------------------------------------------------------- +// Master/Slave IF Callback +// ---------------------------------------------------------------------- +static void b2bTransferComplete_cb(struct _dma_resource *resource) +{ + gpio_set_pin_level(SPI1_CS, true); +} + + + // ---------------------------------------------------------------------- // ADC Callback for Motor Phase Current Measurement. // Phase A & B Sampled and converted from LSB to Process Unit PU(Amps) diff --git a/2_Motor_Master/Motor_Master/Motor_Master/main.c b/2_Motor_Master/Motor_Master/Motor_Master/main.c index 2460a15..60e2351 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/main.c +++ b/2_Motor_Master/Motor_Master/Motor_Master/main.c @@ -7,10 +7,31 @@ #include "bldc_types.h" #include "EtherCAT_QSPI.h" #include "EtherCAT_SlaveDef.h" +//#include "MSIF_master.h" #include "configuration.h" #include "interrupts.h" #include "statemachine.h" +#define MASTER_BUFFER_SIZE 64 + + +struct SPI_slaveboard { + struct spi_m_dma_descriptor *SPI_Mn; + uint8_t state; + uint32_t SS_pin; + uint32_t *tx_buffer; + uint32_t *rx_buffer; +}; + +struct SPI_slaveboard Slave_1 = { + .SPI_Mn = &SPI_1_MSIF, + .state = 0, + .SS_pin = SPI1_CS, + .tx_buffer = &QSPI_tx_buffer[16], + .rx_buffer = &QSPI_rx_buffer[16], +}; + + void process_currents() { @@ -56,6 +77,13 @@ static void One_ms_cycle_callback(const struct timer_task *const timer_task) update_telemetry(); update_setpoints(); + + /*Master Slave Transfer */ + //tx_buffer[0] += 1; + //tx_buffer[31] += 1; + //gpio_set_pin_level(SPI1_CS, false); + //spi_m_dma_transfer(&SPI_1_MSIF, (uint8_t*)Slave_1.tx_buffer, (uint8_t*)Slave_1.rx_buffer, MASTER_BUFFER_SIZE); + //run_ECAT = true; } @@ -173,6 +201,7 @@ int main(void) configure_tcc_pwm(); adc_sync_enable_channel(&ADC_1, 6); adc_init_dma(); + boardToBoardTransferInit(); ECAT_STATE_MACHINE(); One_ms_timer_init(); custom_logic_enable(); diff --git a/2_Motor_Slave/Motor_Slave/Motor_Slave.atsln b/2_Motor_Slave/Motor_Slave/Motor_Slave.atsln new file mode 100644 index 0000000..4c3feaf --- /dev/null +++ b/2_Motor_Slave/Motor_Slave/Motor_Slave.atsln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Atmel Studio Solution File, Format Version 11.00 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "Motor_Slave", "Motor_Slave\Motor_Slave.cproj", "{DCE6C7E3-EE26-4D79-826B-08594B9AD897}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Release|ARM = Release|ARM + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|ARM.ActiveCfg = Debug|ARM + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|ARM.Build.0 = Debug|ARM + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|ARM.ActiveCfg = Release|ARM + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|ARM.Build.0 = Release|ARM + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/2_Motor_Slave/Motor_Slave/Motor_Slave/.atmelstart/AtmelStart.env_conf b/2_Motor_Slave/Motor_Slave/Motor_Slave/.atmelstart/AtmelStart.env_conf new file mode 100644 index 0000000..8010ebb --- /dev/null +++ b/2_Motor_Slave/Motor_Slave/Motor_Slave/.atmelstart/AtmelStart.env_conf @@ -0,0 +1,6 @@ + + + + + + diff --git a/2_Motor_Slave/Motor_Slave/Motor_Slave/.atmelstart/AtmelStart.gpdsc b/2_Motor_Slave/Motor_Slave/Motor_Slave/.atmelstart/AtmelStart.gpdsc new file mode 100644 index 0000000..87d5533 --- /dev/null +++ b/2_Motor_Slave/Motor_Slave/Motor_Slave/.atmelstart/AtmelStart.gpdsc @@ -0,0 +1,258 @@ + + Atmel + Motor_Slave + Project generated by Atmel Start + http://start.atmel.com/ + + Initial version + + + Configuration Files generated by Atmel Start + + + + Atmel Start +