From 65e1957d2ae0826c8d690b5a029a44e588c6f53d Mon Sep 17 00:00:00 2001 From: Nicolas Trimborn Date: Sun, 22 Aug 2021 17:40:44 +0200 Subject: [PATCH] started on ads1299 port --- .gitmodules | 3 + .../Motor_Master/.atmelstart/AtmelStart.gpdsc | 3 - .../.atmelstart/atmel_start_config.atstart | 102 ++--- .../Motor_Master/Motor_Master/ADS1299.c | 196 +++++++++ .../Motor_Master/Motor_Master/ADS1299.h | 106 +++++ .../Motor_Master/Config/hpl_adc_config.h | 293 -------------- .../Motor_Master/Config/hpl_eic_config.h | 8 +- .../Motor_Master/Config/hpl_sercom_config.h | 8 +- .../Config/peripheral_clk_config.h | 40 -- .../Motor_Master/Motor_Master.cproj | 47 +-- .../Motor_Master/Motor_Master/angle_sensors.c | 6 +- .../Motor_Master/atmel_start_pins.h | 4 +- .../Motor_Master/Motor_Master/driver_init.c | 64 ++- .../Motor_Master/Motor_Master/driver_init.h | 20 +- .../Motor_Master/examples/driver_examples.c | 35 +- .../Motor_Master/examples/driver_examples.h | 4 - .../hal/documentation/spi_master_async.rst | 55 --- .../hal/include/hal_spi_m_async.h | 334 --------------- .../Motor_Master/hal/src/hal_ext_irq.c | 2 +- .../Motor_Master/hal/src/hal_spi_m_async.c | 379 ------------------ .../Motor_Master/hpl/eic/hpl_eic.c | 12 +- .../Motor_Master/hpl/sercom/hpl_sercom.c | 61 --- .../Motor_Master/Motor_Master/main.c | 14 +- .../Motor_Master/motorparameters.h | 4 + .../.atmelstart/atmel_start_config.atstart | 6 +- .../Motor_Slave/Config/hpl_dmac_config.h | 6 +- .../Motor_Slave/Motor_Slave/Motor_Slave.cproj | 4 +- 2_Motor_Slave/Motor_Slave/Motor_Slave/main.c | 38 +- Examples/OpenBCI_Cyton_Library | 1 + 29 files changed, 458 insertions(+), 1397 deletions(-) create mode 100644 2_Motor_Master/Motor_Master/Motor_Master/ADS1299.c create mode 100644 2_Motor_Master/Motor_Master/Motor_Master/ADS1299.h delete mode 100644 2_Motor_Master/Motor_Master/Motor_Master/hal/documentation/spi_master_async.rst delete mode 100644 2_Motor_Master/Motor_Master/Motor_Master/hal/include/hal_spi_m_async.h delete mode 100644 2_Motor_Master/Motor_Master/Motor_Master/hal/src/hal_spi_m_async.c create mode 160000 Examples/OpenBCI_Cyton_Library diff --git a/.gitmodules b/.gitmodules index 1fdf999..2e44cd2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "Arduino-FOC"] path = Arduino-FOC url = https://github.com/simplefoc/Arduino-FOC.git +[submodule "Examples/OpenBCI_Cyton_Library"] + path = Examples/OpenBCI_Cyton_Library + url = https://github.com/OpenBCI/OpenBCI_Cyton_Library.git 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 bb2e80e..bdbf8e2 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/.atmelstart/AtmelStart.gpdsc +++ b/2_Motor_Master/Motor_Master/Motor_Master/.atmelstart/AtmelStart.gpdsc @@ -48,7 +48,6 @@ - @@ -63,7 +62,6 @@ - @@ -177,7 +175,6 @@ - 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 46fdc49..5ce51a4 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 @@ -20,68 +20,6 @@ details: null application: null middlewares: {} drivers: - ADC_0: - user_label: ADC_0 - definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::ADC0::driver_config_definition::ADC::HAL:Driver:ADC.Sync - functionality: ADC - api: HAL:Driver:ADC_Sync - configuration: - adc_advanced_settings: false - adc_arch_adjres: 0 - adc_arch_corren: false - adc_arch_dbgrun: false - adc_arch_event_settings: false - adc_arch_flushei: false - adc_arch_flushinv: false - adc_arch_gaincorr: 0 - adc_arch_leftadj: false - adc_arch_offcomp: false - adc_arch_offsetcorr: 0 - adc_arch_ondemand: false - adc_arch_refcomp: false - adc_arch_resrdyeo: false - adc_arch_runstdby: false - adc_arch_samplen: 0 - adc_arch_samplenum: 1 sample - adc_arch_seqen: 0 - adc_arch_startei: false - adc_arch_startinv: false - adc_arch_winlt: 0 - adc_arch_winmode: No window mode - adc_arch_winmoneo: false - adc_arch_winut: 0 - adc_differential_mode: true - adc_freerunning_mode: false - adc_pinmux_negative: ADC AIN2 pin - adc_pinmux_positive: ADC AIN0 pin - adc_prescaler: Peripheral clock divided by 2 - adc_reference: External reference A - adc_resolution: 12-bit - optional_signals: - - identifier: ADC_0:AIN/0 - pad: PA02 - mode: Enabled - configuration: null - definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::optional_signal_definition::ADC0.AIN.0 - name: ADC0/AIN/0 - label: AIN/0 - - identifier: ADC_0:AIN/3 - pad: PB09 - mode: Enabled - configuration: null - definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::optional_signal_definition::ADC0.AIN.3 - name: ADC0/AIN/3 - label: AIN/3 - variant: null - clocks: - domain_group: - nodes: - - name: ADC - input: Generic clock generator 0 - external: false - external_frequency: 0 - configuration: - adc_gclk_selection: Generic clock generator 0 ADC_1: user_label: ADC_1 definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::ADC1::driver_config_definition::ADC::HAL:Driver:ADC.Sync @@ -841,7 +779,7 @@ drivers: eic_arch_asynch13: false eic_arch_asynch14: true eic_arch_asynch15: true - eic_arch_asynch2: false + eic_arch_asynch2: true eic_arch_asynch3: false eic_arch_asynch4: false eic_arch_asynch5: false @@ -874,7 +812,7 @@ drivers: eic_arch_enable_irq_setting13: false eic_arch_enable_irq_setting14: true eic_arch_enable_irq_setting15: true - eic_arch_enable_irq_setting2: false + eic_arch_enable_irq_setting2: true eic_arch_enable_irq_setting3: false eic_arch_enable_irq_setting4: false eic_arch_enable_irq_setting5: false @@ -928,7 +866,7 @@ drivers: eic_arch_sense13: No detection eic_arch_sense14: Both-edges detection eic_arch_sense15: Both-edges detection - eic_arch_sense2: No detection + eic_arch_sense2: Falling-edge detection eic_arch_sense3: No detection eic_arch_sense4: No detection eic_arch_sense5: No detection @@ -940,6 +878,13 @@ drivers: eic_arch_states1: '3' eic_arch_tickon: The sampling rate is EIC clock optional_signals: + - identifier: EXTERNAL_IRQ_0:EXTINT/2 + pad: PA02 + mode: Enabled + configuration: null + definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::optional_signal_definition::EIC.EXTINT.2 + name: EIC/EXTINT/2 + label: EXTINT/2 - identifier: EXTERNAL_IRQ_0:EXTINT/7 pad: PA07 mode: Enabled @@ -1849,18 +1794,18 @@ drivers: slow_gclk_selection: Generic clock generator 3 SPI_2: user_label: SPI_2 - definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::SERCOM2::driver_config_definition::SPI.Master::HAL:Driver:SPI.Master.Async + definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::SERCOM2::driver_config_definition::SPI.Master::HAL:Driver:SPI.Master.Sync functionality: SPI - api: HAL:Driver:SPI_Master_Async + api: HAL:Driver:SPI_Master_Sync configuration: - spi_master_advanced: false - spi_master_arch_cpha: Sample input on leading edge + spi_master_advanced: true + spi_master_arch_cpha: Sample input on trailing 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: 4000000 spi_master_character_size: 8 bits spi_master_dummybyte: 511 spi_master_rx_enable: true @@ -1904,7 +1849,7 @@ drivers: spi_master_arch_dord: MSB first spi_master_arch_ibon: In data stream spi_master_arch_runstdby: false - spi_master_baud_rate: 1000000 + spi_master_baud_rate: 8000000 spi_master_character_size: 8 bits spi_master_dummybyte: 511 spi_master_rx_enable: true @@ -2307,11 +2252,11 @@ pads: mode: Digital output user_label: SPI1_SCK configuration: null - ALOG_0: + ADS_DATA_RDY: name: PA02 definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::pad::PA02 - mode: Analog - user_label: ALOG_0 + mode: Digital input + user_label: ADS_DATA_RDY configuration: null ANAREF_2V48: name: PA03 @@ -2349,12 +2294,13 @@ pads: mode: Analog user_label: half_VREF configuration: null - ALOG_2: + ADS_RESET: name: PB09 definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::pad::PB09 - mode: Analog - user_label: ALOG_2 - configuration: null + mode: Digital output + user_label: ADS_RESET + configuration: + pad_initial_level: High M1_HALLA: name: PA04 definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::pad::PA04 diff --git a/2_Motor_Master/Motor_Master/Motor_Master/ADS1299.c b/2_Motor_Master/Motor_Master/Motor_Master/ADS1299.c new file mode 100644 index 0000000..6bb7a1b --- /dev/null +++ b/2_Motor_Master/Motor_Master/Motor_Master/ADS1299.c @@ -0,0 +1,196 @@ +/* + * ADS1299.c + * + * Created: 8/22/2021 3:25:55 PM + * Author: ge37vez + */ + +#include "ADS1299.h" + +void initialize_ads() +{ + spi_m_sync_disable(ADS1299.SPI_descr); + /* Set Mode 1 */ + hri_sercomspi_write_CTRLA_CPOL_bit((SercomSpi *)(ADS1299.SPI_descr->dev.prvt), false); + hri_sercomspi_write_CTRLA_CPHA_bit((SercomSpi *)(ADS1299.SPI_descr->dev.prvt), true); + /* Init SPI*/ + spi_m_sync_enable(ADS1299.SPI_descr); + gpio_set_pin_level(ADS1299.SS_pin, true); + + /* Reset ADS1299 - Reset Active Low*/ + gpio_set_pin_level(ADS1299.reset_pin, false); + delay_us(5); + gpio_set_pin_level(ADS1299.reset_pin, true); + delay_us(20); +} + +uint8_t getDeviceID() +{ + uint8_t data = RREG(0x00); + return data; +} + +// ---------------------------------------------------------------------- +// AS5048 Registers & Commands +// ---------------------------------------------------------------------- + +void WAKEUP() { + gpio_set_pin_level(ADS1299.SS_pin, false); + transfer_byte(ADS1299.SPI_descr, _WAKEUP); + gpio_set_pin_level(ADS1299.SS_pin, true); + delay_us(3); //must wait 4 tCLK cycles before sending another command (Datasheet, pg. 35) +} + +void STANDBY() { // only allowed to send WAKEUP after sending STANDBY + gpio_set_pin_level(ADS1299.SS_pin, false); + transfer_byte(ADS1299.SPI_descr, _STANDBY); + gpio_set_pin_level(ADS1299.SS_pin, true); +} + +void RESET() { // reset all the registers to default settings + gpio_set_pin_level(ADS1299.SS_pin, false); + transfer_byte(ADS1299.SPI_descr, _RESET); + delay_us(12); //must wait 18 tCLK cycles to execute this command (Datasheet, pg. 35) + gpio_set_pin_level(ADS1299.SS_pin, true); +} + +void START() { //start data conversion + gpio_set_pin_level(ADS1299.SS_pin, false); + transfer_byte(ADS1299.SPI_descr, _START); + gpio_set_pin_level(ADS1299.SS_pin, true); +} + +void STOP() { //stop data conversion + gpio_set_pin_level(ADS1299.SS_pin, false); + transfer_byte(ADS1299.SPI_descr, _STOP); + gpio_set_pin_level(ADS1299.SS_pin, true); +} + +void RDATAC() { + gpio_set_pin_level(ADS1299.SS_pin, false); + transfer_byte(ADS1299.SPI_descr, _RDATAC); + gpio_set_pin_level(ADS1299.SS_pin, true); + delay_us(3); +} +void SDATAC() { + gpio_set_pin_level(ADS1299.SS_pin, false); + transfer_byte(ADS1299.SPI_descr, _SDATAC); + gpio_set_pin_level(ADS1299.SS_pin, true); + delay_us(3); //must wait 4 tCLK cycles after executing this command (Datasheet, pg. 37) +} + + +// ---------------------------------------------------------------------- +// SPI register Related Commands +// ---------------------------------------------------------------------- + + +// reads ONE register at _address +uint8_t RREG(uint8_t _address) +{ + uint8_t opcode1 = _address + 0x20; // RREG expects 001rrrrr where rrrrr = _address + gpio_set_pin_level(ADS1299.SS_pin, false); + transfer_byte(ADS1299.SPI_descr, opcode1); + transfer_byte(ADS1299.SPI_descr, 0x00); + ADS1299.regData[_address] = transfer_byte(ADS1299.SPI_descr, 0x00); + gpio_set_pin_level(ADS1299.SS_pin, true); + return ADS1299.regData[_address]; +} + +// Read more than one register starting at _address +void RREGS(uint8_t _address, uint8_t _numRegistersMinusOne) +{ + uint8_t opcode1 = _address + 0x20; // RREG expects 001rrrrr where rrrrr = _address + gpio_set_pin_level(ADS1299.SS_pin, false); + transfer_byte(ADS1299.SPI_descr, opcode1); + transfer_byte(ADS1299.SPI_descr, _numRegistersMinusOne); + for(int i = 0; i <= _numRegistersMinusOne; i++){ + ADS1299.regData[_address + i] = transfer_byte(ADS1299.SPI_descr, 0x00); // add register uint8_t to mirror array + } + ADS1299.regData[_address] = transfer_byte(ADS1299.SPI_descr, 0x00); + gpio_set_pin_level(ADS1299.SS_pin, true); +} + +void WREG(uint8_t _address, uint8_t _value) { // Write ONE register at _address + uint8_t opcode1 = _address + 0x40; // WREG expects 010rrrrr where rrrrr = _address + gpio_set_pin_level(ADS1299.SS_pin, false); // open SPI + transfer_byte(ADS1299.SPI_descr, opcode1); // Send WREG command & address + transfer_byte(ADS1299.SPI_descr, 0x00); // Send number of registers to read -1 + transfer_byte(ADS1299.SPI_descr, _value); // Write the value to the register + gpio_set_pin_level(ADS1299.SS_pin, true); // close SPI + ADS1299.regData[_address] = _value; // update the mirror array +} + +void WREGS(uint8_t _address, uint8_t _numRegistersMinusOne) { + uint8_t opcode1 = _address + 0x40; // WREG expects 010rrrrr where rrrrr = _address + gpio_set_pin_level(ADS1299.SS_pin, false); // open SPI + transfer_byte(ADS1299.SPI_descr, opcode1); // Send WREG command & address + transfer_byte(ADS1299.SPI_descr, _numRegistersMinusOne); // Send number of registers to read -1 + for (int i=_address; i <=(_address + _numRegistersMinusOne); i++){ + transfer_byte(ADS1299.SPI_descr, ADS1299.regData[i]); // Write to the registers + } + gpio_set_pin_level(ADS1299.SS_pin, true); // close SPI +} + +void updateChannelData() +{ + uint8_t inByte; + int nchan=4; //assume 8 channel. If needed, it automatically changes to 16 automatically in a later block. + gpio_set_pin_level(ADS1299.SS_pin, false); // open SPI + + // READ CHANNEL DATA FROM FIRST ADS IN DAISY LINE + for(int i=0; i<3; i++){ // read 3 byte status register from ADS 1 (1100+LOFF_STATP+LOFF_STATN+GPIO[7:4]) + inByte = transfer_byte(ADS1299.SPI_descr,0x00); + ADS1299.stat_1 = (ADS1299.stat_1<<8) | inByte; + } + + for(int i = 0; i<8; i++){ + for(int j=0; j<3; j++){ // read 24 bits of channel data from 1st ADS in 8 3 byte chunks + inByte = transfer_byte(ADS1299.SPI_descr, 0x00); + ADS1299.channel_data[i] = (ADS1299.channel_data[i]<<8) | inByte; + } + } + + gpio_set_pin_level(ADS1299.SS_pin, true); // close SPI + + //reformat the numbers + for(int i=0; i> 8 ) & 0xFF; + struct spi_xfer xfer; + xfer.rxbuf = in_buf; + xfer.txbuf = (uint8_t *)out_buf; + xfer.size = 2; + spi_m_sync_transfer(ADS1299.SPI_descr, &xfer); + wordRead = (uint16_t)((in_buf[0] << 8) | in_buf[1]); + return (wordRead); +} diff --git a/2_Motor_Master/Motor_Master/Motor_Master/ADS1299.h b/2_Motor_Master/Motor_Master/Motor_Master/ADS1299.h new file mode 100644 index 0000000..3705f1c --- /dev/null +++ b/2_Motor_Master/Motor_Master/Motor_Master/ADS1299.h @@ -0,0 +1,106 @@ +/* + * ADS1299.h + * + * Created: 8/22/2021 3:25:39 PM + * Author: ge37vez + */ + + +#ifndef ADS1299_H_ +#define ADS1299_H_ + +#include "atmel_start.h" + +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet(value, bit) : bitClear(value, bit)) + +//SPI Command Definition Byte Assignments (Datasheet, p35) +#define _WAKEUP 0x02 // Wake-up from standby mode +#define _STANDBY 0x04 // Enter Standby mode +#define _RESET 0x06 // Reset the device registers to default +#define _START 0x08 // Start and restart (synchronize) conversions +#define _STOP 0x0A // Stop conversion +#define _RDATAC 0x10 // Enable Read Data Continuous mode (default mode at power-up) +#define _SDATAC 0x11 // Stop Read Data Continuous mode +#define _RDATA 0x12 // Read data by command; supports multiple read back + +//Register Addresses +#define ID 0x00 +#define CONFIG1 0x01 +#define CONFIG2 0x02 +#define CONFIG3 0x03 +#define LOFF 0x04 +#define CH1SET 0x05 +#define CH2SET 0x06 +#define CH3SET 0x07 +#define CH4SET 0x08 +#define CH5SET 0x09 +#define CH6SET 0x0A +#define CH7SET 0x0B +#define CH8SET 0x0C +#define BIAS_SENSP 0x0D +#define BIAS_SENSN 0x0E +#define LOFF_SENSP 0x0F +#define LOFF_SENSN 0x10 +#define LOFF_FLIP 0x11 +#define LOFF_STATP 0x12 +#define LOFF_STATN 0x13 +#define GPIO_REG 0x14 +#define MISC1 0x15 +#define MISC2 0x16 +#define CONFIG4 0x17 + +/* Struct Definitions */ +struct SPI_ADS1299 { + struct spi_m_sync_descriptor *SPI_descr; + uint8_t flags; + uint32_t SS_pin; + uint32_t reset_pin; + uint8_t regData [24]; + int16_t channel_data[16]; // Must Equal n_dev + int16_t stat_1; +}; + +static struct SPI_ADS1299 ADS1299 = { + .SPI_descr = &SPI_2, + .flags = 0, + .SS_pin = SPI2_SS, + .reset_pin = ADS_RESET, + .regData = {0}, + .channel_data = {0}, +}; + +void initialize_ads(); + +//ADS1299 SPI Command Definitions (Datasheet, p35) +//System Commands +void WAKEUP(); +void STANDBY(); +void RESET(); +void START(); +void STOP(); + +//Data Read Commands +void RDATAC(); +void SDATAC(); +void RDATA(); + +//Register Read/Write Commands +uint8_t getDeviceID(); +uint8_t RREG(uint8_t _address); +void RREGS(uint8_t _address, uint8_t _numRegistersMinusOne); +void printRegisterName(uint8_t _address); +void WREG(uint8_t _address, uint8_t _value); +void WREGS(uint8_t _address, uint8_t _numRegistersMinusOne); +void printHex(uint8_t _data); +void updateChannelData(); + +uint8_t transfer_byte(struct spi_m_sync_descriptor *spi, uint8_t command); +uint16_t transfer_word(struct spi_m_sync_descriptor *spi, uint16_t command); +//SPI Transfer function + + + +#endif /* ADS1299_H_ */ \ No newline at end of file diff --git a/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_adc_config.h b/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_adc_config.h index 82de8c4..55aa07c 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_adc_config.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_adc_config.h @@ -4,299 +4,6 @@ // <<< Use Configuration Wizard in Context Menu >>> -#ifndef CONF_ADC_0_ENABLE -#define CONF_ADC_0_ENABLE 1 -#endif - -// Basic Configuration - -// Conversion Result Resolution -// <0x0=>12-bit -// <0x1=>16-bit (averaging must be enabled) -// <0x2=>10-bit -// <0x3=>8-bit -// Defines the bit resolution for the ADC sample values (RESSEL) -// adc_resolution -#ifndef CONF_ADC_0_RESSEL -#define CONF_ADC_0_RESSEL 0x0 -#endif - -// Reference Selection -// <0x0=>Internal bandgap reference -// <0x2=>1/2 VDDANA (only for VDDANA > 2.0V) -// <0x3=>VDDANA -// <0x4=>External reference A -// <0x5=>External reference B -// <0x6=>External reference C -// Select the reference for the ADC (REFSEL) -// adc_reference -#ifndef CONF_ADC_0_REFSEL -#define CONF_ADC_0_REFSEL 0x4 -#endif - -// Prescaler configuration -// <0x0=>Peripheral clock divided by 2 -// <0x1=>Peripheral clock divided by 4 -// <0x2=>Peripheral clock divided by 8 -// <0x3=>Peripheral clock divided by 16 -// <0x4=>Peripheral clock divided by 32 -// <0x5=>Peripheral clock divided by 64 -// <0x6=>Peripheral clock divided by 128 -// <0x7=>Peripheral clock divided by 256 -// These bits define the ADC clock relative to the peripheral clock (PRESCALER) -// adc_prescaler -#ifndef CONF_ADC_0_PRESCALER -#define CONF_ADC_0_PRESCALER 0x0 -#endif - -// Free Running Mode -// When enabled, the ADC is in free running mode and a new conversion will be initiated when a previous conversion completes. (FREERUN) -// adc_freerunning_mode -#ifndef CONF_ADC_0_FREERUN -#define CONF_ADC_0_FREERUN 0 -#endif - -// Differential Mode -// In differential mode, the voltage difference between the MUXPOS and MUXNEG inputs will be converted by the ADC. (DIFFMODE) -// adc_differential_mode -#ifndef CONF_ADC_0_DIFFMODE -#define CONF_ADC_0_DIFFMODE 1 -#endif - -// Positive Mux Input Selection -// <0x00=>ADC AIN0 pin -// <0x01=>ADC AIN1 pin -// <0x02=>ADC AIN2 pin -// <0x03=>ADC AIN3 pin -// <0x04=>ADC AIN4 pin -// <0x05=>ADC AIN5 pin -// <0x06=>ADC AIN6 pin -// <0x07=>ADC AIN7 pin -// <0x08=>ADC AIN8 pin -// <0x09=>ADC AIN9 pin -// <0x0A=>ADC AIN10 pin -// <0x0B=>ADC AIN11 pin -// <0x0C=>ADC AIN12 pin -// <0x0D=>ADC AIN13 pin -// <0x0E=>ADC AIN14 pin -// <0x0F=>ADC AIN15 pin -// <0x18=>1/4 scaled core supply -// <0x19=>1/4 Scaled VBAT Supply -// <0x1A=>1/4 scaled I/O supply -// <0x1B=>Bandgap voltage -// <0x1C=>Temperature reference (PTAT) -// <0x1D=>Temperature reference (CTAT) -// <0x1E=>DAC Output -// These bits define the Mux selection for the positive ADC input. (MUXPOS) -// adc_pinmux_positive -#ifndef CONF_ADC_0_MUXPOS -#define CONF_ADC_0_MUXPOS 0x0 -#endif - -// Negative Mux Input Selection -// <0x00=>ADC AIN0 pin -// <0x01=>ADC AIN1 pin -// <0x02=>ADC AIN2 pin -// <0x03=>ADC AIN3 pin -// <0x04=>ADC AIN4 pin -// <0x05=>ADC AIN5 pin -// <0x06=>ADC AIN6 pin -// <0x07=>ADC AIN7 pin -// <0x18=>Internal ground -// These bits define the Mux selection for the negative ADC input. (MUXNEG) -// adc_pinmux_negative -#ifndef CONF_ADC_0_MUXNEG -#define CONF_ADC_0_MUXNEG 0x2 -#endif - -// - -// Advanced Configuration -// adc_advanced_settings -#ifndef CONF_ADC_0_ADVANCED -#define CONF_ADC_0_ADVANCED 0 -#endif - -// Run in standby -// Indicates whether the ADC will continue running in standby sleep mode or not (RUNSTDBY) -// adc_arch_runstdby -#ifndef CONF_ADC_0_RUNSTDBY -#define CONF_ADC_0_RUNSTDBY 0 -#endif - -// Debug Run -// If enabled, the ADC is running if the CPU is halted by an external debugger. (DBGRUN) -// adc_arch_dbgrun -#ifndef CONF_ADC_0_DBGRUN -#define CONF_ADC_0_DBGRUN 0 -#endif - -// On Demand Control -// Will keep the ADC peripheral running if requested by other peripherals (ONDEMAND) -// adc_arch_ondemand -#ifndef CONF_ADC_0_ONDEMAND -#define CONF_ADC_0_ONDEMAND 0 -#endif - -// Left-Adjusted Result -// When enabled, the ADC conversion result is left-adjusted in the RESULT register. The high byte of the 12-bit result will be present in the upper part of the result register. (LEFTADJ) -// adc_arch_leftadj -#ifndef CONF_ADC_0_LEFTADJ -#define CONF_ADC_0_LEFTADJ 0 -#endif - -// Reference Buffer Offset Compensation Enable -// The accuracy of the gain stage can be increased by enabling the reference buffer offset compensation. This will decrease the input impedance and thus increase the start-up time of the reference. (REFCOMP) -// adc_arch_refcomp -#ifndef CONF_ADC_0_REFCOMP -#define CONF_ADC_0_REFCOMP 0 -#endif - -// Comparator Offset Compensation Enable -// This bit indicates whether the Comparator Offset Compensation is enabled or not (OFFCOMP) -// adc_arch_offcomp -#ifndef CONF_ADC_0_OFFCOMP -#define CONF_ADC_0_OFFCOMP 0 -#endif - -// Digital Correction Logic Enabled -// When enabled, the ADC conversion result in the RESULT register is then corrected for gain and offset based on the values in the GAINCAL and OFFSETCAL registers. (CORREN) -// adc_arch_corren -#ifndef CONF_ADC_0_CORREN -#define CONF_ADC_0_CORREN 0 -#endif - -// Offset Correction Value <0-4095> -// If the digital correction logic is enabled (CTRLB.CORREN = 1), these bits define how the ADC conversion result is compensated for offset error before being written to the Result register. (OFFSETCORR) -// adc_arch_offsetcorr -#ifndef CONF_ADC_0_OFFSETCORR -#define CONF_ADC_0_OFFSETCORR 0 -#endif - -// Gain Correction Value <0-4095> -// If the digital correction logic is enabled (CTRLB.CORREN = 1), these bits define how the ADC conversion result is compensated for gain error before being written to the result register. (GAINCORR) -// adc_arch_gaincorr -#ifndef CONF_ADC_0_GAINCORR -#define CONF_ADC_0_GAINCORR 0 -#endif - -// Adjusting Result / Division Coefficient <0-7> -// These bits define the division coefficient in 2n steps. (ADJRES) -// adc_arch_adjres -#ifndef CONF_ADC_0_ADJRES -#define CONF_ADC_0_ADJRES 0x0 -#endif - -// Number of Samples to be Collected -// <0x0=>1 sample -// <0x1=>2 samples -// <0x2=>4 samples -// <0x3=>8 samples -// <0x4=>16 samples -// <0x5=>32 samples -// <0x6=>64 samples -// <0x7=>128 samples -// <0x8=>256 samples -// <0x9=>512 samples -// <0xA=>1024 samples -// Define how many samples should be added together.The result will be available in the Result register (SAMPLENUM) -// adc_arch_samplenum -#ifndef CONF_ADC_0_SAMPLENUM -#define CONF_ADC_0_SAMPLENUM 0x0 -#endif - -// Sampling Time Length <0-63> -// These bits control the ADC sampling time in number of CLK_ADC cycles, depending of the prescaler value, thus controlling the ADC input impedance. (SAMPLEN) -// adc_arch_samplen -#ifndef CONF_ADC_0_SAMPLEN -#define CONF_ADC_0_SAMPLEN 0 -#endif - -// Window Monitor Mode -// <0x0=>No window mode -// <0x1=>Mode 1: RESULT above lower threshold -// <0x2=>Mode 2: RESULT beneath upper threshold -// <0x3=>Mode 3: RESULT inside lower and upper threshold -// <0x4=>Mode 4: RESULT outside lower and upper threshold -// These bits enable and define the window monitor mode. (WINMODE) -// adc_arch_winmode -#ifndef CONF_ADC_0_WINMODE -#define CONF_ADC_0_WINMODE 0x0 -#endif - -// Window Monitor Lower Threshold <0-65535> -// If the window monitor is enabled, these bits define the lower threshold value. (WINLT) -// adc_arch_winlt -#ifndef CONF_ADC_0_WINLT -#define CONF_ADC_0_WINLT 0 -#endif - -// Window Monitor Upper Threshold <0-65535> -// If the window monitor is enabled, these bits define the lower threshold value. (WINUT) -// adc_arch_winut -#ifndef CONF_ADC_0_WINUT -#define CONF_ADC_0_WINUT 0 -#endif - -// Bitmask for positive input sequence <0-4294967295> -// Use this parameter to input the bitmask for positive input sequence control (refer to datasheet for the device). -// adc_arch_seqen -#ifndef CONF_ADC_0_SEQEN -#define CONF_ADC_0_SEQEN 0x0 -#endif - -// - -// Event Control -// adc_arch_event_settings -#ifndef CONF_ADC_0_EVENT_CONTROL -#define CONF_ADC_0_EVENT_CONTROL 0 -#endif - -// Window Monitor Event Out -// Enables event output on window event (WINMONEO) -// adc_arch_winmoneo -#ifndef CONF_ADC_0_WINMONEO -#define CONF_ADC_0_WINMONEO 0 -#endif - -// Result Ready Event Out -// Enables event output on result ready event (RESRDEO) -// adc_arch_resrdyeo -#ifndef CONF_ADC_0_RESRDYEO -#define CONF_ADC_0_RESRDYEO 0 -#endif - -// Invert flush Event Signal -// Invert the flush event input signal (FLUSHINV) -// adc_arch_flushinv -#ifndef CONF_ADC_0_FLUSHINV -#define CONF_ADC_0_FLUSHINV 0 -#endif - -// Trigger Flush On Event -// Trigger an ADC pipeline flush on event (FLUSHEI) -// adc_arch_flushei -#ifndef CONF_ADC_0_FLUSHEI -#define CONF_ADC_0_FLUSHEI 0 -#endif - -// Invert Start Conversion Event Signal -// Invert the start conversion event input signal (STARTINV) -// adc_arch_startinv -#ifndef CONF_ADC_0_STARTINV -#define CONF_ADC_0_STARTINV 0 -#endif - -// Trigger Conversion On Event -// Trigger a conversion on event. (STARTEI) -// adc_arch_startei -#ifndef CONF_ADC_0_STARTEI -#define CONF_ADC_0_STARTEI 0 -#endif - -// - #ifndef CONF_ADC_1_ENABLE #define CONF_ADC_1_ENABLE 1 #endif diff --git a/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_eic_config.h b/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_eic_config.h index 059b167..058f1e7 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_eic_config.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_eic_config.h @@ -161,7 +161,7 @@ // Interrupt 2 Settings // eic_arch_enable_irq_setting2 #ifndef CONF_EIC_ENABLE_IRQ_SETTING2 -#define CONF_EIC_ENABLE_IRQ_SETTING2 0 +#define CONF_EIC_ENABLE_IRQ_SETTING2 1 #endif // External Interrupt 2 Filter Enable @@ -195,14 +195,14 @@ // This defines input sense trigger // eic_arch_sense2 #ifndef CONF_EIC_SENSE2 -#define CONF_EIC_SENSE2 EIC_NMICTRL_NMISENSE_NONE_Val +#define CONF_EIC_SENSE2 EIC_NMICTRL_NMISENSE_FALL_Val #endif // External Interrupt 2 Asynchronous Edge Detection Mode // Indicates the external interrupt 2 detection mode operated synchronously or asynchronousl // eic_arch_asynch2 #ifndef CONF_EIC_ASYNCH2 -#define CONF_EIC_ASYNCH2 0 +#define CONF_EIC_ASYNCH2 1 #endif // @@ -906,7 +906,7 @@ // -#define CONFIG_EIC_EXTINT_MAP {7, PIN_PA07}, {14, PIN_PB30}, {15, PIN_PB31}, +#define CONFIG_EIC_EXTINT_MAP {2, PIN_PA02}, {7, PIN_PA07}, {14, PIN_PB30}, {15, PIN_PB31}, // <<< end of configuration section >>> 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 27176cc..42009f6 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 @@ -218,7 +218,7 @@ // The SPI data transfer rate // spi_master_baud_rate #ifndef CONF_SERCOM_2_SPI_BAUD -#define CONF_SERCOM_2_SPI_BAUD 50000 +#define CONF_SERCOM_2_SPI_BAUD 4000000 #endif // @@ -226,7 +226,7 @@ // Advanced Configuration // spi_master_advanced #ifndef CONF_SERCOM_2_SPI_ADVANCED -#define CONF_SERCOM_2_SPI_ADVANCED 0 +#define CONF_SERCOM_2_SPI_ADVANCED 1 #endif // Dummy byte <0x00-0x1ff> @@ -260,7 +260,7 @@ // Determines if input data is sampled on leading or trailing SCK edge. (CPHA) // spi_master_arch_cpha #ifndef CONF_SERCOM_2_SPI_CPHA -#define CONF_SERCOM_2_SPI_CPHA 0x0 +#define CONF_SERCOM_2_SPI_CPHA 0x1 #endif // Immediate Buffer Overflow Notification @@ -377,7 +377,7 @@ // The SPI data transfer rate // spi_master_baud_rate #ifndef CONF_SERCOM_5_SPI_BAUD -#define CONF_SERCOM_5_SPI_BAUD 1000000 +#define CONF_SERCOM_5_SPI_BAUD 8000000 #endif // diff --git a/2_Motor_Master/Motor_Master/Motor_Master/Config/peripheral_clk_config.h b/2_Motor_Master/Motor_Master/Motor_Master/Config/peripheral_clk_config.h index 13499d1..69adb5c 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/Config/peripheral_clk_config.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/Config/peripheral_clk_config.h @@ -31,46 +31,6 @@ // Generic clock generator 11 -// Select the clock source for ADC. -#ifndef CONF_GCLK_ADC0_SRC -#define CONF_GCLK_ADC0_SRC GCLK_PCHCTRL_GEN_GCLK0_Val -#endif - -/** - * \def CONF_GCLK_ADC0_FREQUENCY - * \brief ADC0's Clock frequency - */ -#ifndef CONF_GCLK_ADC0_FREQUENCY -#define CONF_GCLK_ADC0_FREQUENCY 120000000 -#endif - -// ADC Clock Source -// adc_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 ADC. #ifndef CONF_GCLK_ADC1_SRC #define CONF_GCLK_ADC1_SRC GCLK_PCHCTRL_GEN_GCLK0_Val 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 211dacf..8cc331f 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/Motor_Master.cproj +++ b/2_Motor_Master/Motor_Master/Motor_Master/Motor_Master.cproj @@ -62,7 +62,6 @@ - @@ -151,11 +150,11 @@ - - - - - + + + + + @@ -173,9 +172,8 @@ - + - @@ -188,7 +186,7 @@ - + @@ -200,7 +198,7 @@ - + @@ -209,11 +207,11 @@ - + - + @@ -221,10 +219,10 @@ - + - + @@ -389,6 +387,7 @@ %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + %24(PackRepoDir)\atmel\SAME51_DFP\1.1.139\include ../Config ../ ../examples @@ -413,7 +412,6 @@ ../hpl/tc ../hpl/tcc ../hri - %24(PackRepoDir)\atmel\SAME51_DFP\1.1.139\include True @@ -440,6 +438,7 @@ %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + %24(PackRepoDir)\atmel\SAME51_DFP\1.1.139\include ../Config ../ ../examples @@ -464,13 +463,13 @@ ../hpl/tc ../hpl/tcc ../hri - %24(PackRepoDir)\atmel\SAME51_DFP\1.1.139\include Default (-g) %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ + %24(PackRepoDir)\atmel\SAME51_DFP\1.1.139\include ../Config ../ ../examples @@ -495,7 +494,6 @@ ../hpl/tc ../hpl/tcc ../hri - %24(PackRepoDir)\atmel\SAME51_DFP\1.1.139\include Default (-Wa,-g) @@ -503,6 +501,12 @@ + + compile + + + compile + compile @@ -653,9 +657,6 @@ compile - - compile - compile @@ -815,9 +816,6 @@ compile - - compile - compile @@ -1138,9 +1136,6 @@ compile - - compile - compile diff --git a/2_Motor_Master/Motor_Master/Motor_Master/angle_sensors.c b/2_Motor_Master/Motor_Master/Motor_Master/angle_sensors.c index 6500eae..61b2507 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/angle_sensors.c +++ b/2_Motor_Master/Motor_Master/Motor_Master/angle_sensors.c @@ -49,7 +49,7 @@ int16_t* _read(ASCommand command) // Give command to start reading the angle gpio_set_pin_level(ANGLESENSOR.SS_pin, false); uint16_t temp = _spi_transfer16(&ANGLESENSOR, command); - ANGLESENSOR._readBuffer[0] = (temp); + ANGLESENSOR._readBuffer[0] = (int16_t)(temp & AS_MASK); gpio_set_pin_level(ANGLESENSOR.SS_pin, true); //delay_us(1); // Wait at least 350ns after chip select } else { @@ -59,7 +59,7 @@ int16_t* _read(ASCommand command) for(int i = 0; i < ANGLESENSOR.n_dev; ++i) { uint16_t temp = _spi_transfer16(&ANGLESENSOR, command); - ANGLESENSOR._readBuffer[i] = (temp); + ANGLESENSOR._readBuffer[i] = (int16_t)(temp & AS_MASK); } gpio_set_pin_level(ANGLESENSOR.SS_pin, true); //delay_us(1); // Wait at least 350ns after chip select @@ -88,7 +88,7 @@ int16_t degrees(int16_t sensor_result) #ifdef AS5048 - rotation = (int16_t)(sensor_result); //- static_cast(this->position); + rotation = (int16_t)(sensor_result & AS_MASK); //- static_cast(this->position); if (rotation > AS5048A_MAX_VALUE) { rotation = -((0x3FFF) - rotation); //more than -180 } diff --git a/2_Motor_Master/Motor_Master/Motor_Master/atmel_start_pins.h b/2_Motor_Master/Motor_Master/Motor_Master/atmel_start_pins.h index c60e09d..932e4fe 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/atmel_start_pins.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/atmel_start_pins.h @@ -29,7 +29,7 @@ #define SPI1_MOSI GPIO(GPIO_PORTA, 0) #define SPI1_SCK GPIO(GPIO_PORTA, 1) -#define ALOG_0 GPIO(GPIO_PORTA, 2) +#define ADS_DATA_RDY GPIO(GPIO_PORTA, 2) #define ANAREF_2V48 GPIO(GPIO_PORTA, 3) #define M1_HALLA GPIO(GPIO_PORTA, 4) #define M1_HALLB GPIO(GPIO_PORTA, 5) @@ -63,7 +63,7 @@ #define M2_IA GPIO(GPIO_PORTB, 6) #define M2_IB GPIO(GPIO_PORTB, 7) #define half_VREF GPIO(GPIO_PORTB, 8) -#define ALOG_2 GPIO(GPIO_PORTB, 9) +#define ADS_RESET GPIO(GPIO_PORTB, 9) #define ECAT_QSPI_SCK GPIO(GPIO_PORTB, 10) #define ECAT_QSPI_CS GPIO(GPIO_PORTB, 11) #define M1_PWMA GPIO(GPIO_PORTB, 12) 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 cf01c37..f3a2693 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/driver_init.c +++ b/2_Motor_Master/Motor_Master/Motor_Master/driver_init.c @@ -11,53 +11,22 @@ #include #include -#include #include +struct spi_m_sync_descriptor SPI_2; struct spi_m_sync_descriptor SPI_3; struct timer_descriptor TIMER_0; -struct adc_sync_descriptor ADC_0; - 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; struct pwm_descriptor PWM_1; -void ADC_0_PORT_init(void) -{ - - // Disable digital pin circuitry - gpio_set_pin_direction(ALOG_0, GPIO_DIRECTION_OFF); - - gpio_set_pin_function(ALOG_0, PINMUX_PA02B_ADC0_AIN0); - - // Disable digital pin circuitry - gpio_set_pin_direction(ALOG_2, GPIO_DIRECTION_OFF); - - gpio_set_pin_function(ALOG_2, PINMUX_PB09B_ADC0_AIN3); -} - -void ADC_0_CLOCK_init(void) -{ - hri_mclk_set_APBDMASK_ADC0_bit(MCLK); - hri_gclk_write_PCHCTRL_reg(GCLK, ADC0_GCLK_ID, CONF_GCLK_ADC0_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos)); -} - -void ADC_0_init(void) -{ - ADC_0_CLOCK_init(); - ADC_0_PORT_init(); - adc_sync_init(&ADC_0, ADC0, (void *)NULL); -} - void ADC_1_PORT_init(void) { @@ -134,6 +103,19 @@ void EXTERNAL_IRQ_0_init(void) hri_gclk_write_PCHCTRL_reg(GCLK, EIC_GCLK_ID, CONF_GCLK_EIC_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos)); hri_mclk_set_APBAMASK_EIC_bit(MCLK); + // Set pin direction to input + gpio_set_pin_direction(ADS_DATA_RDY, GPIO_DIRECTION_IN); + + gpio_set_pin_pull_mode(ADS_DATA_RDY, + // Pull configuration + // pad_pull_config + // Off + // Pull-up + // Pull-down + GPIO_PULL_OFF); + + gpio_set_pin_function(ADS_DATA_RDY, PINMUX_PA02A_EIC_EXTINT2); + // Set pin direction to input gpio_set_pin_direction(ECAT_SYNC, GPIO_DIRECTION_IN); @@ -519,7 +501,7 @@ void SPI_2_CLOCK_init(void) void SPI_2_init(void) { SPI_2_CLOCK_init(); - spi_m_async_init(&SPI_2, SERCOM2); + spi_m_sync_init(&SPI_2, SERCOM2); SPI_2_PORT_init(); } @@ -725,6 +707,20 @@ void system_init(void) gpio_set_pin_function(SPI3_SS, GPIO_PIN_FUNCTION_OFF); + // GPIO on PB09 + + gpio_set_pin_level(ADS_RESET, + // Initial level + // pad_initial_level + // Low + // High + true); + + // Set pin direction to output + gpio_set_pin_direction(ADS_RESET, GPIO_DIRECTION_OUT); + + gpio_set_pin_function(ADS_RESET, GPIO_PIN_FUNCTION_OFF); + // GPIO on PB22 gpio_set_pin_level(SPI1_CS, @@ -739,8 +735,6 @@ void system_init(void) gpio_set_pin_function(SPI1_CS, GPIO_PIN_FUNCTION_OFF); - ADC_0_init(); - ADC_1_init(); DIGITAL_GLUE_LOGIC_0_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 32bca4a..0922178 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/driver_init.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/driver_init.h @@ -23,8 +23,6 @@ extern "C" { #include -#include - #include #include @@ -34,8 +32,7 @@ extern "C" { #include #include - -#include +#include #include #include #include @@ -48,26 +45,19 @@ extern "C" { #include #include -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_dma_descriptor SPI_1_MSIF; - -extern struct spi_m_async_descriptor SPI_2; -extern struct spi_m_sync_descriptor SPI_3; -extern struct timer_descriptor TIMER_0; +extern struct spi_m_dma_descriptor SPI_1_MSIF; +extern struct spi_m_sync_descriptor SPI_2; +extern struct spi_m_sync_descriptor SPI_3; +extern struct timer_descriptor TIMER_0; extern struct pwm_descriptor PWM_0; extern struct pwm_descriptor PWM_1; -void ADC_0_PORT_init(void); -void ADC_0_CLOCK_init(void); -void ADC_0_init(void); - void ADC_1_PORT_init(void); void ADC_1_CLOCK_init(void); void ADC_1_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 80f3f55..e5619cb 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 @@ -10,20 +10,6 @@ #include "driver_init.h" #include "utils.h" -/** - * Example of using ADC_0 to generate waveform. - */ -void ADC_0_example(void) -{ - uint8_t buffer[2]; - - adc_sync_enable_channel(&ADC_0, 0); - - while (1) { - adc_sync_read_channel(&ADC_0, 0, buffer, 2); - } -} - /** * Example of using ADC_1 to generate waveform. */ @@ -47,6 +33,10 @@ void DIGITAL_GLUE_LOGIC_0_example(void) /* Customer logic now works. */ } +static void button_on_PA02_pressed(void) +{ +} + static void button_on_PA07_pressed(void) { } @@ -65,6 +55,7 @@ static void button_on_PB31_pressed(void) void EXTERNAL_IRQ_0_example(void) { + ext_irq_register(PIN_PA02, button_on_PA02_pressed); ext_irq_register(PIN_PA07, button_on_PA07_pressed); ext_irq_register(PIN_PB30, button_on_PB30_pressed); ext_irq_register(PIN_PB31, button_on_PB31_pressed); @@ -128,27 +119,15 @@ void SPI_1_MSIF_example(void) /** * Example of using SPI_2 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_2[12] = "Hello World!"; -static void complete_cb_SPI_2(const struct spi_m_async_descriptor *const io_descr) -{ - /* Transfer completed */ -} - void SPI_2_example(void) { struct io_descriptor *io; - spi_m_async_get_io_descriptor(&SPI_2, &io); + spi_m_sync_get_io_descriptor(&SPI_2, &io); - spi_m_async_register_callback(&SPI_2, SPI_M_ASYNC_CB_XFER, (FUNC_PTR)complete_cb_SPI_2); - spi_m_async_enable(&SPI_2); + spi_m_sync_enable(&SPI_2); io_write(io, example_SPI_2, 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 533f518..70830e6 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 @@ -12,8 +12,6 @@ extern "C" { #endif -void ADC_0_example(void); - void ADC_1_example(void); void DIGITAL_GLUE_LOGIC_0_example(void); @@ -24,8 +22,6 @@ void ECAT_QSPI_example(void); void SPI_1_MSIF_example(void); -void SPI_2_example(void); - void TIMER_0_example(void); void PWM_0_example(void); diff --git a/2_Motor_Master/Motor_Master/Motor_Master/hal/documentation/spi_master_async.rst b/2_Motor_Master/Motor_Master/Motor_Master/hal/documentation/spi_master_async.rst deleted file mode 100644 index d726894..0000000 --- a/2_Motor_Master/Motor_Master/Motor_Master/hal/documentation/spi_master_async.rst +++ /dev/null @@ -1,55 +0,0 @@ -The SPI Master Asynchronous 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 master device originates the frame for -reading and writing. Multiple slave devices are supported through selection -with individual slave select (SS) lines. - -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 -* Status information with busy state and transfer count - -Applications ------------- - -Send/receive/exchange data with a SPI slave device. E.g., serial flash, SD card, -LCD controller, etc. - -Dependencies ------------- - -SPI master capable hardware, with interrupt on each character sent/received. - -Concurrency ------------ - -N/A - -Limitations ------------ - -The slave select (SS) is not automatically inserted during read/write/transfer, -user must use I/O to control the devices' SS. - -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_async.h b/2_Motor_Master/Motor_Master/Motor_Master/hal/include/hal_spi_m_async.h deleted file mode 100644 index 737e5b9..0000000 --- a/2_Motor_Master/Motor_Master/Motor_Master/hal/include/hal_spi_m_async.h +++ /dev/null @@ -1,334 +0,0 @@ -/** - * \file - * - * \brief SPI related functionality declaration. - * - * Copyright (c) 2014-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_ASYNC_H_INCLUDED -#define _HAL_SPI_M_ASYNC_H_INCLUDED - -#include -#include - -/** - * \addtogroup doc_driver_hal_spi_master_async - * - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** \brief SPI status - * - * Status descriptor holds the current status of transfer. - * - * \c txcnt and \c rxcnt are always the status of progress in current TX/RX - * transfer buffer. - * - * For R/W/Transfer, simply check \c SPI_M_ASYNC_STATUS_BUSY to know that the - * transfer is in progress, check \c SPI_M_ASYNC_STATUS_TX_DONE and - * \c SPI_M_ASYNC_STATUS_RX_DONE to know that TX or RX is completed (since TX - * and RX happen in different clock edge the time stamp of completion is - * different), check \c SPI_M_ASYNC_STATUS_COMPLETE to confirm that CS has been - * deactivate. - */ -struct spi_m_async_status { - /** Status flags */ - uint32_t flags; - /** Number of characters transmitted */ - uint32_t xfercnt; -}; -/** SPI is busy (read/write/transfer, with CS activated) */ -#define SPI_M_ASYNC_STATUS_BUSY 0x0010 -/** SPI finished transmit buffer */ -#define SPI_M_ASYNC_STATUS_TX_DONE 0x0020 -/** SPI finished receive buffer */ -#define SPI_M_ASYNC_STATUS_RX_DONE 0x0040 -/** SPI finished everything including CS deactivate */ -#define SPI_M_ASYNC_STATUS_COMPLETE 0x0080 -#define SPI_M_ASYNC_STATUS_ERR_MASK 0x000F -#define SPI_M_ASYNC_STATUS_ERR_POS 0 -#define SPI_M_ASYNC_STATUS_ERR_OVRF ((-ERR_OVERFLOW) << SPI_M_ASYNC_STATUS_ERR_POS) -#define SPI_M_ASYNC_STATUS_ERR_ABORT ((-ERR_ABORTED) << SPI_M_ASYNC_STATUS_ERR_POS) -#define SPI_M_ASYNC_STATUS_ERR_EXTRACT(st) (((st) >> SPI_M_ASYNC_STATUS_ERR_POS) & SPI_M_ASYNC_STATUS_ERR_MASK) - -/* Forward declaration of spi_descriptor. */ -struct spi_m_async_descriptor; - -/** The callback types */ -enum spi_m_async_cb_type { - /** Callback type for read/write/transfer buffer done, - * see \ref spi_m_async_cb_xfer_t. */ - SPI_M_ASYNC_CB_XFER, - /** Callback type for CS deactivate, error, or abort, - * see \ref spi_m_async_cb_error_t. */ - SPI_M_ASYNC_CB_ERROR, - SPI_M_ASYNC_CB_N -}; - -/** \brief Prototype of callback on SPI transfer errors - * - * Invoked on transfer errors - * invoke \ref spi_get_status. - */ -typedef void (*spi_m_async_cb_error_t)(struct spi_m_async_descriptor *, const int32_t status); - -/** \brief Prototype of callback on SPI read/write/transfer buffer completion - * - * Invoked on transfer completion, which means the transfer buffer has been - * completed, including all TX/RX data (TX and RX happen in different clock - * edges, but the callback is invoked after all TX and RX have been done). - */ -typedef void (*spi_m_async_cb_xfer_t)(struct spi_m_async_descriptor *); - -/** \brief SPI HAL callbacks - * - */ -struct spi_m_callbacks { - /** Callback invoked when the buffer read/write/transfer done. */ - spi_m_async_cb_xfer_t cb_xfer; - /** Callback invoked when the CS deactivates, goes wrong, or aborts. */ - spi_m_async_cb_error_t cb_error; -}; - -/** \brief SPI HAL driver struct for asynchronous access - */ -struct spi_m_async_descriptor { - struct _spi_m_async_hpl_interface *func; - /** Pointer to the SPI device instance */ - struct _spi_m_async_dev dev; - /** I/O read/write */ - struct io_descriptor io; - - /** SPI transfer status */ - uint8_t stat; - - /** Callbacks for asynchronous transfer */ - struct spi_m_callbacks callbacks; - /** Transfer information copy, for R/W/Transfer */ - struct spi_xfer xfer; - /** Character count in current transfer */ - uint32_t xfercnt; -}; - -/** \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_async_set_func_ptr(struct spi_m_async_descriptor *spi, void *const func); - -/** \brief Initialize the SPI HAL instance and hardware for callback mode - * - * Initialize SPI HAL with interrupt mode (uses callbacks). - * - * \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_async_init(struct spi_m_async_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_async_deinit(struct spi_m_async_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_async_enable(struct spi_m_async_descriptor *spi); - -/** \brief Disable the SPI and abort any pending transfer in progress - * - * If there is any pending transfer, the complete callback is invoked - * with the \c ERR_ABORTED status. - * - * \param[in] spi Pointer to the HAL SPI instance. - * - * \return Operation status. - * \retval ERR_NONE Success. - * \retval <0 Error code. - */ -void spi_m_async_disable(struct spi_m_async_descriptor *spi); - -/** \brief Set SPI baudrate - * - * Works if the 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. - */ -int32_t spi_m_async_set_baudrate(struct spi_m_async_descriptor *spi, const uint32_t baud_val); - -/** \brief Set SPI mode - * - * Set the SPI transfer mode (\ref spi_transfer_mode), - * 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. - * - * \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_async_set_mode(struct spi_m_async_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) 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_async_set_char_size(struct spi_m_async_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_async_set_data_order(struct spi_m_async_descriptor *spi, const enum spi_data_order dord); - -/** \brief Perform the SPI data transfer (TX and RX) asynchronously - * - * Log the TX and RX buffers and transfer them in the background. It never blocks. - * - * \param[in] spi Pointer to the HAL SPI instance. - * \param[in] txbuf Pointer to the transfer information (\ref spi_transfer). - * \param[out] rxbuf Pointer to the receiver information (\ref spi_receive). - * \param[in] length SPI transfer data length. - * - * \return Operation status. - * \retval ERR_NONE Success. - * \retval ERR_BUSY Busy. - */ -int32_t spi_m_async_transfer(struct spi_m_async_descriptor *spi, uint8_t const *txbuf, uint8_t *const rxbuf, - const uint16_t length); - -/** \brief Get the SPI transfer status - * - * Get transfer status, transfer counts in a structured way. - * - * \param[in] spi Pointer to the HAL SPI instance. - * \param[out] stat Pointer to the detailed status descriptor, set to NULL - * to not return details. - * - * \return Status. - * \retval ERR_NONE Not busy. - * \retval ERR_BUSY Busy. - */ -int32_t spi_m_async_get_status(struct spi_m_async_descriptor *spi, struct spi_m_async_status *stat); - -/** \brief Register a function as SPI transfer completion callback - * - * Register 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 NULL function to not use the callback. - * - * \param[in] spi Pointer to the HAL SPI instance. - * \param[in] type Callback type (\ref spi_m_async_cb_type). - * \param[in] func Pointer to callback function. - */ -void spi_m_async_register_callback(struct spi_m_async_descriptor *spi, const enum spi_m_async_cb_type type, - FUNC_PTR 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_async_get_io_descriptor(struct spi_m_async_descriptor *const spi, struct io_descriptor **io); - -/** \brief Retrieve the current driver version - * - * \return Current driver version. - */ -uint32_t spi_m_async_get_version(void); - -#ifdef __cplusplus -} -#endif -/**@}*/ -#endif /* ifndef _HAL_SPI_M_ASYNC_H_INCLUDED */ diff --git a/2_Motor_Master/Motor_Master/Motor_Master/hal/src/hal_ext_irq.c b/2_Motor_Master/Motor_Master/Motor_Master/hal/src/hal_ext_irq.c index d0b9292..7a62a80 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/hal/src/hal_ext_irq.c +++ b/2_Motor_Master/Motor_Master/Motor_Master/hal/src/hal_ext_irq.c @@ -33,7 +33,7 @@ #include "hal_ext_irq.h" -#define EXT_IRQ_AMOUNT 3 +#define EXT_IRQ_AMOUNT 4 /** * \brief Driver version diff --git a/2_Motor_Master/Motor_Master/Motor_Master/hal/src/hal_spi_m_async.c b/2_Motor_Master/Motor_Master/Motor_Master/hal/src/hal_spi_m_async.c deleted file mode 100644 index 38c6108..0000000 --- a/2_Motor_Master/Motor_Master/Motor_Master/hal/src/hal_spi_m_async.c +++ /dev/null @@ -1,379 +0,0 @@ -/** - * \file - * - * \brief I/O SPI related functionality implementation. - * - * Copyright (c) 2014-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_async.h" -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Driver version - */ -#define SPI_DRIVER_VERSION 0x00000001u - -#define SPI_DEACTIVATE_NEXT 0x8000 - -static int32_t _spi_m_async_io_write(struct io_descriptor *const io, const uint8_t *const buf, const uint16_t length); -static int32_t _spi_m_async_io_read(struct io_descriptor *const io, uint8_t *const buf, const uint16_t length); - -/** - * \brief Callback for TX - * \param[in, out] dev Pointer to the SPI device instance. - */ -static void _spi_dev_tx(struct _spi_m_async_dev *dev) -{ - struct spi_m_async_descriptor *spi = CONTAINER_OF(dev, struct spi_m_async_descriptor, dev); - - if (!(dev->char_size > 1)) { - _spi_m_async_write_one(dev, spi->xfer.txbuf[spi->xfercnt++]); - } else { - _spi_m_async_write_one(dev, ((uint16_t *)spi->xfer.txbuf)[spi->xfercnt++]); - } - - if (spi->xfercnt == spi->xfer.size) { - _spi_m_async_enable_tx(dev, false); - _spi_m_async_enable_tx_complete(dev, true); - } -} - -/** - * \brief Callback for RX - * \param[in, out] dev Pointer to the SPI device instance. - */ -static void _spi_dev_rx(struct _spi_m_async_dev *dev) -{ - struct spi_m_async_descriptor *spi = CONTAINER_OF(dev, struct spi_m_async_descriptor, dev); - - if (spi->xfer.rxbuf) { - if (!(dev->char_size > 1)) { - /* 8-bit or less */ - spi->xfer.rxbuf[spi->xfercnt++] = (uint8_t)_spi_m_async_read_one(dev); - } else { - /* 9-bit or more */ - ((uint16_t *)spi->xfer.rxbuf)[spi->xfercnt++] = (uint16_t)_spi_m_async_read_one(dev); - } - } else { - /* dummy data read if rxbuf is NULL */ - _spi_m_async_read_one(dev); - spi->xfercnt++; - } - - if (spi->xfercnt < spi->xfer.size) { - if (spi->xfer.txbuf) { - if (!(dev->char_size > 1)) { - _spi_m_async_write_one(dev, spi->xfer.txbuf[spi->xfercnt]); - } else { - _spi_m_async_write_one(dev, ((uint16_t *)spi->xfer.txbuf)[spi->xfercnt]); - } - } else { - _spi_m_async_write_one(dev, dev->dummy_byte); - } - } else { - _spi_m_async_enable_rx(dev, false); - spi->stat = 0; - - if (spi->callbacks.cb_xfer) { - spi->callbacks.cb_xfer(spi); - } - } -} - -/** - * \brief Callback for complete - * \param[in, out] dev Pointer to the SPI device instance. - */ -static void _spi_dev_complete(struct _spi_m_async_dev *dev) -{ - struct spi_m_async_descriptor *spi = CONTAINER_OF(dev, struct spi_m_async_descriptor, dev); - - if (spi->xfercnt >= spi->xfer.size) { - _spi_m_async_enable_tx_complete(dev, false); - spi->stat = 0; - - if (spi->callbacks.cb_xfer) { - spi->callbacks.cb_xfer(spi); - } - } -} - -/** - * \brief Callback for error - * \param[in, out] dev Pointer to the SPI device instance. - * \param[in] status Error status. - */ -static void _spi_dev_error(struct _spi_m_async_dev *dev, int32_t status) -{ - struct spi_m_async_descriptor *spi = CONTAINER_OF(dev, struct spi_m_async_descriptor, dev); - - _spi_m_async_enable_tx(dev, false); - _spi_m_async_enable_rx(dev, false); - _spi_m_async_enable_tx_complete(dev, false); - spi->stat = 0; - - /* Invoke complete callback */ - if (spi->callbacks.cb_error) { - spi->callbacks.cb_error(spi, status); - } -} - -/** - * \brief Initialize the SPI HAL instance function pointer for HPL APIs. - */ -void spi_m_async_set_func_ptr(struct spi_m_async_descriptor *spi, void *const func) -{ - ASSERT(spi); - spi->func = (struct _spi_m_async_hpl_interface *)func; -} - -int32_t spi_m_async_init(struct spi_m_async_descriptor *spi, void *const hw) -{ - int32_t rc = 0; - ASSERT(spi && hw); - spi->dev.prvt = (void *)hw; - rc = _spi_m_async_init(&spi->dev, hw); - - if (rc >= 0) { - _spi_m_async_register_callback(&spi->dev, SPI_DEV_CB_TX, (FUNC_PTR)_spi_dev_tx); - _spi_m_async_register_callback(&spi->dev, SPI_DEV_CB_RX, (FUNC_PTR)_spi_dev_rx); - _spi_m_async_register_callback(&spi->dev, SPI_DEV_CB_COMPLETE, (FUNC_PTR)_spi_dev_complete); - _spi_m_async_register_callback(&spi->dev, SPI_DEV_CB_ERROR, (FUNC_PTR)_spi_dev_error); - } else { - return rc; - } - - spi->io.read = _spi_m_async_io_read; - spi->io.write = _spi_m_async_io_write; - return ERR_NONE; -} - -void spi_m_async_deinit(struct spi_m_async_descriptor *spi) -{ - ASSERT(spi); - _spi_m_async_deinit(&spi->dev); - spi->callbacks.cb_error = NULL; - spi->callbacks.cb_xfer = NULL; -} - -void spi_m_async_enable(struct spi_m_async_descriptor *spi) -{ - ASSERT(spi); - _spi_m_async_enable(&spi->dev); -} - -void spi_m_async_disable(struct spi_m_async_descriptor *spi) -{ - ASSERT(spi); - _spi_m_async_enable_tx(&spi->dev, false); - _spi_m_async_enable_rx(&spi->dev, false); - _spi_m_async_disable(&spi->dev); -} - -int32_t spi_m_async_set_baudrate(struct spi_m_async_descriptor *spi, const uint32_t baud_val) -{ - ASSERT(spi); - - if (spi->stat & SPI_M_ASYNC_STATUS_BUSY) { - return ERR_BUSY; - } - return _spi_m_async_set_baudrate(&spi->dev, baud_val); -} - -int32_t spi_m_async_set_mode(struct spi_m_async_descriptor *spi, const enum spi_transfer_mode mode) -{ - ASSERT(spi); - - if (spi->stat & SPI_M_ASYNC_STATUS_BUSY) { - return ERR_BUSY; - } - return _spi_m_async_set_mode(&spi->dev, mode); -} - -int32_t spi_m_async_set_char_size(struct spi_m_async_descriptor *spi, const enum spi_char_size char_size) -{ - ASSERT(spi); - - if (spi->stat & SPI_M_ASYNC_STATUS_BUSY) { - return ERR_BUSY; - } - return _spi_m_async_set_char_size(&spi->dev, char_size); -} - -int32_t spi_m_async_set_data_order(struct spi_m_async_descriptor *spi, const enum spi_data_order dord) -{ - ASSERT(spi); - - if (spi->stat & SPI_M_ASYNC_STATUS_BUSY) { - return ERR_BUSY; - } - return _spi_m_async_set_data_order(&spi->dev, dord); -} - -/** \brief Do SPI read in background (asynchronously) - * For SPI master, register the buffer, do activate CS and send 0xFFs to get - * data, then deactivate CS 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_async_io_read(struct io_descriptor *io, uint8_t *const buf, const uint16_t length) -{ - ASSERT(io); - struct spi_m_async_descriptor *spi = CONTAINER_OF(io, struct spi_m_async_descriptor, io); - - spi->xfer.rxbuf = buf; - spi->xfer.txbuf = NULL; - spi->xfer.size = length; - spi->xfercnt = 0; - - spi->stat = SPI_M_ASYNC_STATUS_BUSY; - _spi_m_async_enable_rx(&spi->dev, true); - _spi_m_async_write_one(&spi->dev, SPI_DUMMY_CHAR); - - return ERR_NONE; -} - -/** \brief Do SPI data write in background (asynchronously) - * For SPI master, register buffer, do activate CS, buffer send and - * deactivate CS 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_async_io_write(struct io_descriptor *io, const uint8_t *const buf, const uint16_t length) -{ - ASSERT(io); - struct spi_m_async_descriptor *spi = CONTAINER_OF(io, struct spi_m_async_descriptor, io); - - spi->xfer.rxbuf = NULL; - spi->xfer.txbuf = (uint8_t *)buf; - spi->xfer.size = length; - spi->xfercnt = 0; - - spi->stat = SPI_M_ASYNC_STATUS_BUSY; - _spi_m_async_enable_tx(&spi->dev, true); - - return ERR_NONE; -} - -int32_t spi_m_async_transfer(struct spi_m_async_descriptor *spi, uint8_t const *txbuf, uint8_t *const rxbuf, - const uint16_t length) -{ - ASSERT(spi); - - /* Fill transfer descriptor */ - spi->xfer.rxbuf = (uint8_t *)rxbuf; - spi->xfer.txbuf = (uint8_t *)txbuf; - spi->xfer.size = length; - spi->xfercnt = 0; - - spi->stat = SPI_M_ASYNC_STATUS_BUSY; - _spi_m_async_enable_rx(&spi->dev, true); - if (txbuf) { - if (!(spi->dev.char_size > 1)) { - _spi_m_async_write_one(&spi->dev, txbuf[spi->xfercnt]); - } else { - _spi_m_async_write_one(&spi->dev, ((uint16_t *)txbuf)[spi->xfercnt]); - } - } else { - _spi_m_async_write_one(&spi->dev, spi->dev.dummy_byte); - } - - return ERR_NONE; -} - -int32_t spi_m_async_get_status(struct spi_m_async_descriptor *spi, struct spi_m_async_status *p_stat) -{ - /* Get a copy of status to avoid critical issue */ - volatile uint32_t stat = spi->stat; - - if (p_stat) { - p_stat->flags = stat; - p_stat->xfercnt = spi->xfercnt; - } - - if (stat & SPI_M_ASYNC_STATUS_BUSY) { - return ERR_BUSY; - } - - return ERR_NONE; -} - -void spi_m_async_register_callback(struct spi_m_async_descriptor *spi, const enum spi_m_async_cb_type type, - FUNC_PTR func) -{ - ASSERT(spi && (type < SPI_M_ASYNC_CB_N)); - - if (SPI_M_ASYNC_CB_XFER == type) { - spi->callbacks.cb_xfer = (spi_m_async_cb_xfer_t)func; - } else { - spi->callbacks.cb_error = (spi_m_async_cb_error_t)func; - _spi_m_async_set_irq_state(&spi->dev, SPI_DEV_CB_ERROR, NULL != func); - } -} - -int32_t spi_m_async_get_io_descriptor(struct spi_m_async_descriptor *const spi, struct io_descriptor **io) -{ - ASSERT(spi && io); - *io = &spi->io; - return 0; -} - -uint32_t spi_m_async_get_version(void) -{ - return SPI_DRIVER_VERSION; -} - -#ifdef __cplusplus -} -#endif diff --git a/2_Motor_Master/Motor_Master/Motor_Master/hpl/eic/hpl_eic.c b/2_Motor_Master/Motor_Master/Motor_Master/hpl/eic/hpl_eic.c index 522a4ed..459bf16 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/hpl/eic/hpl_eic.c +++ b/2_Motor_Master/Motor_Master/Motor_Master/hpl/eic/hpl_eic.c @@ -70,7 +70,7 @@ static int ffs(int v) } #endif -#define EXT_IRQ_AMOUNT 3 +#define EXT_IRQ_AMOUNT 4 /** * \brief EXTINTx and pin number map @@ -167,6 +167,9 @@ int32_t _ext_irq_init(void (*cb)(const uint32_t pin)) | 0); hri_eic_set_CTRLA_ENABLE_bit(EIC); + NVIC_DisableIRQ(EIC_2_IRQn); + NVIC_ClearPendingIRQ(EIC_2_IRQn); + NVIC_EnableIRQ(EIC_2_IRQn); NVIC_DisableIRQ(EIC_7_IRQn); NVIC_ClearPendingIRQ(EIC_7_IRQn); NVIC_EnableIRQ(EIC_7_IRQn); @@ -187,6 +190,7 @@ int32_t _ext_irq_init(void (*cb)(const uint32_t pin)) */ int32_t _ext_irq_deinit(void) { + NVIC_DisableIRQ(EIC_2_IRQn); NVIC_DisableIRQ(EIC_7_IRQn); NVIC_DisableIRQ(EIC_14_IRQn); NVIC_DisableIRQ(EIC_15_IRQn); @@ -271,6 +275,12 @@ static void _ext_irq_handler(void) /** * \brief EIC interrupt handler */ +void EIC_2_Handler(void) +{ + _ext_irq_handler(); +} /** + * \brief EIC interrupt handler + */ void EIC_7_Handler(void) { _ext_irq_handler(); 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 d81c840..0c0d1ed 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 @@ -164,8 +164,6 @@ static struct usart_configuration _usarts[] = { }; #endif -static struct _spi_async_dev *_sercom2_dev = NULL; - static uint8_t _get_sercom_index(const void *const hw); static uint8_t _sercom_get_irq_num(const void *const hw); static void _sercom_init_irq_param(const void *const hw, void *dev); @@ -592,10 +590,6 @@ static uint8_t _get_sercom_index(const void *const hw) */ static void _sercom_init_irq_param(const void *const hw, void *dev) { - - if (hw == SERCOM2) { - _sercom2_dev = (struct _spi_async_dev *)dev; - } } /** @@ -2367,61 +2361,6 @@ static inline const struct sercomspi_regs_cfg *_spi_get_regs(const uint32_t hw_a return NULL; } -/** - * \brief IRQ handler used - * \param[in, out] p Pointer to SPI device instance. - */ -static void _spi_handler(struct _spi_async_dev *dev) -{ - void * hw = dev->prvt; - hri_sercomspi_intflag_reg_t st; - - st = hri_sercomspi_read_INTFLAG_reg(hw); - st &= hri_sercomspi_read_INTEN_reg(hw); - - if (st & SERCOM_SPI_INTFLAG_DRE) { - dev->callbacks.tx(dev); - } else if (st & SERCOM_SPI_INTFLAG_RXC) { - dev->callbacks.rx(dev); - } else if (st & SERCOM_SPI_INTFLAG_TXC) { - hri_sercomspi_clear_INTFLAG_reg(hw, SERCOM_SPI_INTFLAG_TXC); - dev->callbacks.complete(dev); - } else if (st & SERCOM_SPI_INTFLAG_ERROR) { - hri_sercomspi_clear_STATUS_reg(hw, SERCOM_SPI_STATUS_BUFOVF); - hri_sercomspi_clear_INTFLAG_reg(hw, SERCOM_SPI_INTFLAG_ERROR); - dev->callbacks.err(dev, ERR_OVERFLOW); - } -} - -/** - * \internal Sercom interrupt handler - */ -void SERCOM2_0_Handler(void) -{ - _spi_handler(_sercom2_dev); -} -/** - * \internal Sercom interrupt handler - */ -void SERCOM2_1_Handler(void) -{ - _spi_handler(_sercom2_dev); -} -/** - * \internal Sercom interrupt handler - */ -void SERCOM2_2_Handler(void) -{ - _spi_handler(_sercom2_dev); -} -/** - * \internal Sercom interrupt handler - */ -void SERCOM2_3_Handler(void) -{ - _spi_handler(_sercom2_dev); -} - int32_t _spi_m_sync_init(struct _spi_m_sync_dev *dev, void *const hw) { const struct sercomspi_regs_cfg *regs = _spi_get_regs((uint32_t)hw); diff --git a/2_Motor_Master/Motor_Master/Motor_Master/main.c b/2_Motor_Master/Motor_Master/Motor_Master/main.c index 70bc95d..0c218a2 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/main.c +++ b/2_Motor_Master/Motor_Master/Motor_Master/main.c @@ -13,6 +13,7 @@ #include "statemachine.h" #include "angle_sensors.h" +#include "ADS1299.h" void process_currents() @@ -176,6 +177,7 @@ int main(void) //speed_timer_init(); angle_sensor_init(); + initialize_ads(); enable_NVIC_IRQ(); @@ -195,10 +197,14 @@ int main(void) int16_t* angles; //int16_t* field; //int16_t* temp; - //angles = read_angle(); - //*M1_Joint_abs_position = degrees(angles[0]); - //*M2_Joint_abs_position = degrees(angles[1]); - //field = ang_sense_read(AS_CMD_MAGNITUDE); + angles = read_angle(); + *M1_Joint_abs_position = degrees(angles[0]); + *M2_Joint_abs_position = degrees(angles[1]); + + START(); + *EMG_CH1 = getDeviceID(); + + ////field = ang_sense_read(AS_CMD_MAGNITUDE); //*Spare1_tx = (field[0] & AS_MASK); //*Spare2_tx = (field[1] & AS_MASK); //temp = ang_sense_read(AS_CMD_TEMP); diff --git a/2_Motor_Master/Motor_Master/Motor_Master/motorparameters.h b/2_Motor_Master/Motor_Master/Motor_Master/motorparameters.h index 4e405b4..1aed905 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/motorparameters.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/motorparameters.h @@ -179,6 +179,10 @@ const static BLDCMotor_param_t FH_32mm24BXTR = { .controller_param.Pid_Speed.Ki = 0.0000001f, .controller_param.Pi_Pos.Kp = 40.0f, .controller_param.Pi_Pos.Ki = 0.0f, + //.controller_param.Pid_Speed.Kp = 0.00002f, + //.controller_param.Pid_Speed.Ki = 0.0f, + //.controller_param.Pi_Pos.Kp = 4.0f, + //.controller_param.Pi_Pos.Ki = 0.0f, }; #endif /* MOTORPARAMETERS_H_ */ \ No newline at end of file diff --git a/2_Motor_Slave/Motor_Slave/Motor_Slave/.atmelstart/atmel_start_config.atstart b/2_Motor_Slave/Motor_Slave/Motor_Slave/.atmelstart/atmel_start_config.atstart index 6f0a2d4..92e7d2b 100644 --- a/2_Motor_Slave/Motor_Slave/Motor_Slave/.atmelstart/atmel_start_config.atstart +++ b/2_Motor_Slave/Motor_Slave/Motor_Slave/.atmelstart/atmel_start_config.atstart @@ -597,8 +597,8 @@ drivers: dmac_evosel_7: Event generation disabled dmac_evosel_8: Event generation disabled dmac_evosel_9: Event generation disabled - dmac_lvl_0: Channel priority 1 - dmac_lvl_1: Channel priority 1 + dmac_lvl_0: Channel priority 3 + dmac_lvl_1: Channel priority 2 dmac_lvl_10: Channel priority 0 dmac_lvl_11: Channel priority 0 dmac_lvl_12: Channel priority 0 @@ -632,7 +632,7 @@ drivers: dmac_lvlen0: true dmac_lvlen1: true dmac_lvlen2: true - dmac_lvlen3: false + dmac_lvlen3: true dmac_lvlpri0: 0 dmac_lvlpri1: 0 dmac_lvlpri2: 0 diff --git a/2_Motor_Slave/Motor_Slave/Motor_Slave/Config/hpl_dmac_config.h b/2_Motor_Slave/Motor_Slave/Motor_Slave/Config/hpl_dmac_config.h index 195eb77..b3a477a 100644 --- a/2_Motor_Slave/Motor_Slave/Motor_Slave/Config/hpl_dmac_config.h +++ b/2_Motor_Slave/Motor_Slave/Motor_Slave/Config/hpl_dmac_config.h @@ -78,7 +78,7 @@ // Indicates whether Priority Level 3 is enabled or not // dmac_lvlen3 #ifndef CONF_DMAC_LVLEN3 -#define CONF_DMAC_LVLEN3 0 +#define CONF_DMAC_LVLEN3 1 #endif // Level 3 Round-Robin Arbitration @@ -225,7 +225,7 @@ // Defines the arbitration level for this channel // dmac_lvl_0 #ifndef CONF_DMAC_LVL_0 -#define CONF_DMAC_LVL_0 1 +#define CONF_DMAC_LVL_0 3 #endif // Channel Event Output @@ -449,7 +449,7 @@ // Defines the arbitration level for this channel // dmac_lvl_1 #ifndef CONF_DMAC_LVL_1 -#define CONF_DMAC_LVL_1 1 +#define CONF_DMAC_LVL_1 2 #endif // Channel Event Output diff --git a/2_Motor_Slave/Motor_Slave/Motor_Slave/Motor_Slave.cproj b/2_Motor_Slave/Motor_Slave/Motor_Slave/Motor_Slave.cproj index a7f9ae6..0f4dd27 100644 --- a/2_Motor_Slave/Motor_Slave/Motor_Slave/Motor_Slave.cproj +++ b/2_Motor_Slave/Motor_Slave/Motor_Slave/Motor_Slave.cproj @@ -212,7 +212,7 @@ - + @@ -419,7 +419,7 @@ True Maximum (-g3) True - -std=gnu11 -mfloat-abi=hard -mfpu=fpv4-sp-d16 + -std=gnu99 -mfloat-abi=hard -mfpu=fpv4-sp-d16 True diff --git a/2_Motor_Slave/Motor_Slave/Motor_Slave/main.c b/2_Motor_Slave/Motor_Slave/Motor_Slave/main.c index 99b834d..3633a90 100644 --- a/2_Motor_Slave/Motor_Slave/Motor_Slave/main.c +++ b/2_Motor_Slave/Motor_Slave/Motor_Slave/main.c @@ -87,11 +87,11 @@ void SERCOM1_1_Handler() //SPI_tx_buffer[0] += 1; //tx_buffer[31] += 1; - //DMAC->Channel[0].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE; - //DMAC->Channel[1].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE; + DMAC->Channel[0].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE; + DMAC->Channel[1].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE; - _dma_enable_transaction(CONF_SERCOM_1_RECEIVE_DMA_CHANNEL, false); - _dma_enable_transaction(CONF_SERCOM_1_TRANSMIT_DMA_CHANNEL, false); + //_dma_enable_transaction(CONF_SERCOM_1_RECEIVE_DMA_CHANNEL, false); + //_dma_enable_transaction(CONF_SERCOM_1_TRANSMIT_DMA_CHANNEL, false); //slave_select_high(); //_dma_enable_transaction(CONF_SERCOM_5_RECEIVE_DMA_CHANNEL, false); @@ -108,6 +108,9 @@ void SERCOM1_3_Handler() //tx_buffer[0] += 1; //tx_buffer[31] += 1; + + DMAC->Channel[0].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE; + DMAC->Channel[1].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE; //_dma_enable_transaction(CONF_SERCOM_1_RECEIVE_DMA_CHANNEL, false); //_dma_enable_transaction(CONF_SERCOM_1_TRANSMIT_DMA_CHANNEL, false); @@ -134,15 +137,9 @@ void enable_NVIC_IRQ(void) NVIC_SetPriority(DMAC_0_IRQn, 2); NVIC_SetPriority(ADC1_0_IRQn, 3); NVIC_EnableIRQ(TCC0_0_IRQn); - NVIC_SetPriority(TCC0_0_IRQn, 1); NVIC_EnableIRQ(TCC1_0_IRQn); - NVIC_SetPriority(TCC1_0_IRQn, 1); - //NVIC_EnableIRQ(SERCOM5_0_IRQn); - - NVIC_EnableIRQ(SERCOM1_1_IRQn); - NVIC_SetPriority(SERCOM1_1_IRQn, 0); - NVIC_EnableIRQ(SERCOM1_3_IRQn); - NVIC_SetPriority(SERCOM1_3_IRQn, 0); + //NVIC_EnableIRQ(SERCOM1_3_IRQn); + //NVIC_SetPriority(SERCOM1_3_IRQn, 0); //NVIC_EnableIRQ(SERCOM1_3_IRQn); //NVIC_EnableIRQ(EIC_5_IRQn); } @@ -234,6 +231,9 @@ int main(void) One_ms_timer_init(); custom_logic_enable(); enable_NVIC_IRQ(); + + //DMAC->Channel[0].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE; + //DMAC->Channel[1].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE; _dma_enable_transaction(CONF_SERCOM_1_RECEIVE_DMA_CHANNEL, false); _dma_enable_transaction(CONF_SERCOM_1_TRANSMIT_DMA_CHANNEL, false); @@ -246,12 +246,12 @@ int main(void) /* Replace with your application code */ while (1) { - if (Motor1.timerflags.adc_readings_ready_tic) {process_currents();} - if (Motor1.timerflags.current_loop_tic) { - APPLICATION_StateMachine(); - exec_commutation(&Motor1); - //exec_commutation(&Motor2); - } + //if (Motor1.timerflags.adc_readings_ready_tic) {process_currents();} + //if (Motor1.timerflags.current_loop_tic) { + //APPLICATION_StateMachine(); + //exec_commutation(&Motor1); + ////exec_commutation(&Motor2); + //} if (Motor1.timerflags.motor_telemetry_flag) { Motor1.timerflags.motor_telemetry_flag = false; @@ -259,7 +259,7 @@ int main(void) update_setpoints(); APPLICATION_StateMachine(); exec_commutation(&Motor1); - exec_commutation(&Motor2); + //exec_commutation(&Motor2); //*M3_Joint_abs_position = as5048a_getRawRotation(&AS_1); //*M3_Joint_abs_position = as5048a_getRotationDecInt(&AS_1); diff --git a/Examples/OpenBCI_Cyton_Library b/Examples/OpenBCI_Cyton_Library new file mode 160000 index 0000000..e601937 --- /dev/null +++ b/Examples/OpenBCI_Cyton_Library @@ -0,0 +1 @@ +Subproject commit e601937cead66794231d4a9720672aa9f32e18c2