commiting examples
This commit is contained in:
@@ -50,7 +50,7 @@
|
||||
<description>Atmel Start Framework</description>
|
||||
<RTE_Components_h>#define ATMEL_START</RTE_Components_h>
|
||||
<files>
|
||||
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/spi_master_sync.rst"/>
|
||||
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/spi_master_dma.rst"/>
|
||||
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/usart_sync.rst"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_atomic.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_cache.h"/>
|
||||
@@ -59,7 +59,7 @@
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_init.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_io.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_sleep.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_spi_m_sync.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_spi_m_dma.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_cmcc.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_core.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_delay.h"/>
|
||||
@@ -161,7 +161,7 @@
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_spi_s_sync.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_usart_async.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_usart_sync.h"/>
|
||||
<file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_spi_m_sync.c"/>
|
||||
<file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_spi_m_dma.c"/>
|
||||
<file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_usart_sync.c"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/utils/include/parts.h"/>
|
||||
<file category="source" condition="ARMCC, GCC, IAR" name="hpl/cmcc/hpl_cmcc.c"/>
|
||||
|
||||
@@ -146,7 +146,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
|
||||
@@ -157,7 +157,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
|
||||
@@ -179,7 +179,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
|
||||
@@ -211,7 +211,7 @@ drivers:
|
||||
dmac_dstinc_7: false
|
||||
dmac_dstinc_8: false
|
||||
dmac_dstinc_9: false
|
||||
dmac_enable: false
|
||||
dmac_enable: true
|
||||
dmac_evact_0: No action
|
||||
dmac_evact_1: No action
|
||||
dmac_evact_10: No action
|
||||
@@ -417,7 +417,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
|
||||
@@ -449,7 +449,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
|
||||
@@ -512,8 +512,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: SERCOM4 RX Trigger
|
||||
dmac_trifsrc_1: SERCOM4 TX Trigger
|
||||
dmac_trifsrc_10: Only software/event triggers
|
||||
dmac_trifsrc_11: Only software/event triggers
|
||||
dmac_trifsrc_12: Only software/event triggers
|
||||
@@ -544,8 +544,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
|
||||
@@ -1000,12 +1000,12 @@ drivers:
|
||||
slow_gclk_selection: Generic clock generator 3
|
||||
SPI_0:
|
||||
user_label: SPI_0
|
||||
definition: Atmel:SAME54_Drivers:0.0.1::SAME54P20A-AU::SERCOM4::driver_config_definition::SPI.Master::HAL:Driver:SPI.Master.Sync
|
||||
definition: Atmel:SAME54_Drivers:0.0.1::SAME54P20A-AU::SERCOM4::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_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
|
||||
@@ -1013,7 +1013,10 @@ drivers:
|
||||
spi_master_arch_runstdby: false
|
||||
spi_master_baud_rate: 1000000
|
||||
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:
|
||||
|
||||
@@ -50,8 +50,7 @@ uint8_t spiCalcEvenParity(uint16_t value){
|
||||
|
||||
uint16_t read(uint16_t registerAddress)
|
||||
{
|
||||
uint8_t dummy_packet[2] = {0xC0,0x00};
|
||||
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } t;
|
||||
|
||||
uint8_t in_buf[2], out_buf[2];
|
||||
|
||||
volatile uint16_t command = 0b0100000000000000; // PAR=0 R/W=R
|
||||
@@ -72,7 +71,7 @@ uint16_t read(uint16_t registerAddress)
|
||||
|
||||
/* Send Command */
|
||||
gpio_set_pin_level(AS5048A_CS, false);
|
||||
//io_write(io, &out_buf, 2);
|
||||
|
||||
spi_m_sync_transfer(&SPI_0, &xfer);
|
||||
gpio_set_pin_level(AS5048A_CS, true);
|
||||
// spi_m_sync_transfer(&SPI_0, &xfer);
|
||||
|
||||
167
Examples/AS5048A_test/AS5048A_test/AS5048A_dma.c
Normal file
167
Examples/AS5048A_test/AS5048A_test/AS5048A_dma.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* AS5048A_dma.c
|
||||
*
|
||||
* Created: 18/07/2021 14:38:25
|
||||
* Author: Nick-XMG
|
||||
*/
|
||||
|
||||
#include "AS5048A_dma.h"
|
||||
#include "atmel_start_pins.h"
|
||||
|
||||
|
||||
static uint8_t AS5048A_rx_buffer[2] = {0};
|
||||
static uint8_t AS5048A_tx_buffer[2] = {0};
|
||||
|
||||
|
||||
void spi_master_tx_complete_cb(struct _dma_resource *const resource)
|
||||
{
|
||||
//DMAC->Channel[CONF_SERCOM_6_TRANSMIT_DMA_CHANNEL].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE;
|
||||
delay_us(10);
|
||||
gpio_set_pin_level(SPI_SS, true);
|
||||
}
|
||||
|
||||
void spi_master_rx_complete_cb(struct _dma_resource *const resource)
|
||||
{
|
||||
//DMAC->Channel[CONF_SERCOM_6_RECEIVE_DMA_CHANNEL].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE;
|
||||
gpio_set_pin_level(SPI_SS, true);
|
||||
|
||||
}
|
||||
|
||||
void as5048a_init(void)
|
||||
{
|
||||
spi_m_dma_enable(&SPI_0);
|
||||
/* tx_descriptor */
|
||||
DmacDescriptor tx_descriptor;
|
||||
tx_descriptor.DSTADDR.reg = (uint32_t)&AS5048A_SPI->SPI.DATA.reg; // destination address is SPI DATA register
|
||||
tx_descriptor.SRCADDR.reg = (uint32_t)(AS5048A_tx_buffer + sizeof AS5048A_tx_buffer); // source address is the DMA buffer
|
||||
tx_descriptor.DESCADDR.reg = 0; // only one transfer descriptor
|
||||
tx_descriptor.BTCTRL.bit.BEATSIZE = DMAC_BTCTRL_BEATSIZE_BYTE_Val; // beat size is one byte
|
||||
tx_descriptor.BTCTRL.bit.DSTINC = 0; // destination address increment disabled
|
||||
tx_descriptor.BTCTRL.bit.SRCINC = 1; // source address increment enabled
|
||||
tx_descriptor.BTCTRL.bit.STEPSEL = DMAC_BTCTRL_STEPSEL_SRC_Val; // flexible source address increment size
|
||||
tx_descriptor.BTCTRL.bit.STEPSIZE = DMAC_BTCTRL_STEPSIZE_X1_Val; // source address increment is one byte
|
||||
tx_descriptor.BTCTRL.bit.BLOCKACT = DMAC_BTCTRL_BLOCKACT_NOACT_Val; // request interrupt at end of block transfer
|
||||
tx_descriptor.BTCNT.reg = sizeof AS5048A_tx_buffer; // beat count
|
||||
tx_descriptor.BTCTRL.bit.VALID = 1;
|
||||
|
||||
//DMA_add_channel(0x0D, tx_descriptor, 1);
|
||||
|
||||
/* Register Callback */
|
||||
spi_m_dma_register_callback(&SPI_0, SPI_M_DMA_CB_TX_DONE, spi_master_tx_complete_cb);
|
||||
//struct _dma_resource *resource_tx;
|
||||
//_dma_get_channel_resource(&resource_tx, CONF_SERCOM_6_TRANSMIT_DMA_CHANNEL);
|
||||
//resource_tx->dma_cb.transfer_done = DMAC_Handler_tx_cb;
|
||||
|
||||
/* rx_descriptor */
|
||||
DmacDescriptor rx_descriptor;
|
||||
rx_descriptor.DSTADDR.reg = (uint32_t)(AS5048A_rx_buffer + sizeof AS5048A_rx_buffer); // destination address is SPI DATA register
|
||||
rx_descriptor.SRCADDR.reg = (uint32_t)&AS5048A_SPI->SPI.DATA.reg; // source address is the DMA buffer
|
||||
rx_descriptor.DESCADDR.reg = 0; // only one transfer descriptor
|
||||
rx_descriptor.BTCTRL.bit.BEATSIZE = DMAC_BTCTRL_BEATSIZE_BYTE_Val; // beat size is one byte
|
||||
rx_descriptor.BTCTRL.bit.DSTINC = 0; // destination address increment disabled
|
||||
rx_descriptor.BTCTRL.bit.SRCINC = 1; // source address increment enabled
|
||||
rx_descriptor.BTCTRL.bit.STEPSEL = DMAC_BTCTRL_STEPSEL_SRC_Val; // flexible source address increment size
|
||||
rx_descriptor.BTCTRL.bit.STEPSIZE = DMAC_BTCTRL_STEPSIZE_X1_Val; // source address increment is one byte
|
||||
rx_descriptor.BTCTRL.bit.BLOCKACT = DMAC_BTCTRL_BLOCKACT_NOACT_Val; // request interrupt at end of block transfer
|
||||
rx_descriptor.BTCNT.reg = sizeof AS5048A_rx_buffer; // beat count
|
||||
rx_descriptor.BTCTRL.bit.VALID = 1;
|
||||
|
||||
//DMA_add_channel(0x0C, rx_descriptor, 0);
|
||||
|
||||
/* Register Callback */
|
||||
|
||||
|
||||
spi_m_dma_register_callback(&SPI_0, SPI_M_DMA_CB_RX_DONE, spi_master_rx_complete_cb);
|
||||
//struct _dma_resource *resource_rx;
|
||||
//_dma_get_channel_resource(&resource_tx, CONF_SERCOM_6_RECEIVE_DMA_CHANNEL);
|
||||
//resource_tx->dma_cb.transfer_done = DMAC_Handler_rx_cb;
|
||||
|
||||
//DMA_enable();
|
||||
|
||||
}
|
||||
|
||||
uint16_t as5048a_read(uint16_t registerAddress)
|
||||
{
|
||||
uint8_t in_buf[2], out_buf[2];
|
||||
|
||||
volatile uint16_t command = 0b0100000000000000; // PAR=0 R/W=R
|
||||
command = command | registerAddress;
|
||||
|
||||
//Add a parity bit on the the MSB
|
||||
command |= ((uint16_t)spiCalcEvenParity(command)<<15);
|
||||
|
||||
//Split the command into two bytes
|
||||
AS5048A_tx_buffer[1] = command & 0xFF;
|
||||
AS5048A_tx_buffer[0] = ( command >> 8 ) & 0xFF;
|
||||
|
||||
gpio_set_pin_level(SPI_SS, false);
|
||||
spi_m_dma_transfer(&SPI_0, AS5048A_tx_buffer, AS5048A_rx_buffer, sizeof AS5048A_tx_buffer );
|
||||
//gpio_set_pin_level(SPI_SS, false);
|
||||
//_dma_enable_transaction(0,false);
|
||||
//_dma_enable_transaction(1,false);
|
||||
|
||||
if (AS5048A_rx_buffer[1] & 0x40) {
|
||||
int i = 0;
|
||||
//as5048a.errorFlag = 1;
|
||||
} else {
|
||||
//as5048a.errorFlag = 0;
|
||||
}
|
||||
return (( ( AS5048A_rx_buffer[1] & 0xFF ) << 8 ) | ( AS5048A_rx_buffer[0] & 0xFF )) & ~0xC000;
|
||||
|
||||
}
|
||||
|
||||
void as5048a_write(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint8_t calcEvenParity(uint16_t value)
|
||||
{
|
||||
uint8_t cnt = 0;
|
||||
uint8_t i;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (value & 0x1)
|
||||
{
|
||||
cnt++;
|
||||
}
|
||||
value >>= 1;
|
||||
}
|
||||
return cnt & 0x1;
|
||||
}
|
||||
|
||||
void DMA_add_channel(const int trigger_source, DmacDescriptor descriptor, const uint8_t channel)
|
||||
{
|
||||
/* disable DMA if enabled */
|
||||
if (DMAC->CTRL.bit.DMAENABLE)
|
||||
DMAC->CTRL.bit.DMAENABLE = 0;
|
||||
while (DMAC->CTRL.bit.DMAENABLE);
|
||||
|
||||
|
||||
_dma_set_descriptor(channel, descriptor);
|
||||
|
||||
/* add transfer descriptor to transfer descriptor section (before enabling channel!) */
|
||||
//memcpy(descriptor_section + channel * sizeof(DmacDescriptor) , descriptor, sizeof(DmacDescriptor));
|
||||
|
||||
/* configure and enable first least significant free channel */
|
||||
// use first free channel
|
||||
DMAC->Channel[channel].CHPRILVL.bit.PRILVL = 0x00; // channel priority level 0
|
||||
DMAC->Channel[channel].CHCTRLA.bit.TRIGACT = 0x02; // one trigger each beat transfer
|
||||
DMAC->Channel[channel].CHCTRLA.bit.TRIGSRC = trigger_source; // select trigger source
|
||||
DMAC->Channel[channel].CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE; // enable channel
|
||||
|
||||
/* enable DMA block transfer complete interrupt */
|
||||
DMAC->Channel[channel].CHINTENSET.bit.TCMPL = 1; // enable DMA block transfer complete interrupt
|
||||
NVIC_EnableIRQ(DMAC_1_IRQn);
|
||||
|
||||
}
|
||||
|
||||
void DMA_enable(void)
|
||||
{
|
||||
/* enable DMA controller */
|
||||
DMAC->CTRL.bit.DMAENABLE = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
43
Examples/AS5048A_test/AS5048A_test/AS5048A_dma.h
Normal file
43
Examples/AS5048A_test/AS5048A_test/AS5048A_dma.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* AS5048A_dma.h
|
||||
*
|
||||
* Created: 18/07/2021 14:38:15
|
||||
* Author: Nick-XMG
|
||||
*/
|
||||
|
||||
#ifndef AS5048A_DMA_H_
|
||||
#define AS5048A_DMA_H_
|
||||
|
||||
#include <atmel_start.h>
|
||||
#include <hpl_dma.h>
|
||||
|
||||
/* AS5048 Registers */
|
||||
#define AS5048A_CMD_NOP 0x0000
|
||||
#define AS5048A_READ 0x4000
|
||||
#define AS5048A_CLEAR_ERROR_FLAG 0x0001
|
||||
#define AS5048A_PROGRAMMING_CONTROL 0x0003
|
||||
#define AS5048A_OTP_REGISTER_ZERO_POS_HIGH 0x0016
|
||||
#define AS5048A_OTP_REGISTER_ZERO_POS_LOW 0x0017
|
||||
#define AS5048A_DIAG_AGC 0x3FFD
|
||||
#define AS5048A_MAGNITUDE 0x3FFE
|
||||
#define AS5048A_ANGLE 0x3FFF
|
||||
|
||||
/* AS5048 parameters */
|
||||
#define AS5048A_MAX_VALUE 8191.0f
|
||||
|
||||
/* DMA channel for SPI Master TX and RX */
|
||||
#define CONF_SERCOM_6_TRANSMIT_DMA_CHANNEL 0
|
||||
#define CONF_SERCOM_6_RECEIVE_DMA_CHANNEL 1
|
||||
#define AS5048A_SPI SERCOM4
|
||||
|
||||
void as5048a_init(void);
|
||||
uint16_t as5048a_read(uint16_t registerAddress);
|
||||
void as5048a_write(void);
|
||||
uint8_t calcEvenParity(uint16_t value);
|
||||
void DMA_add_channel(const int trigger_source, DmacDescriptor descriptor, const uint8_t channel);
|
||||
void DMA_enable(void);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* AS5048A_DMA_H_ */
|
||||
@@ -58,7 +58,7 @@
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_init.h" IsConfig="false" Hash="OrYSVpF3YA5XrOBImWpdSg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_io.h" IsConfig="false" Hash="XZRSabc39WU/0MFBLYGLvQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_sleep.h" IsConfig="false" Hash="KuZDwgrLdU+fuMG82ZFTqg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_spi_m_sync.h" IsConfig="false" Hash="2oma6hRMCcowUy2wVveqMg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_spi_m_dma.h" IsConfig="false" Hash="MRP9iaBaY97VrZIf+yI+nQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_cmcc.h" IsConfig="false" Hash="mDAHEzTxsniAe2HtqO43oA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_core.h" IsConfig="false" Hash="XeEtUlBSwXUmLA41hFYYWg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_delay.h" IsConfig="false" Hash="3tgjyGPrs0ePCewpMUQPbQ" />
|
||||
@@ -144,11 +144,11 @@
|
||||
<AcmeProjectActionInfo Action="File" Source="stdio_redirect/stdio_io.c" IsConfig="false" Hash="Nx8PfIAymK/f5AjLql/CyQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="stdio_redirect/stdio_io.h" IsConfig="false" Hash="4X02f8UL8cjBHeGJM3BnHw" />
|
||||
<AcmeProjectActionInfo Action="File" Source="main.c" IsConfig="false" Hash="k0AH7j+BrmdFhBPzCCMptA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="driver_init.c" IsConfig="false" Hash="YY6vPpiyDxSIT1+YpzM7Kw" />
|
||||
<AcmeProjectActionInfo Action="File" Source="driver_init.h" IsConfig="false" Hash="HHGaPRA14zpRrZmWNf1CpA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="driver_init.c" IsConfig="false" Hash="PLbWLP8oINvN7KOAwvpoMw" />
|
||||
<AcmeProjectActionInfo Action="File" Source="driver_init.h" IsConfig="false" Hash="KySSAkcWv9PPl3bgQY8WRg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="atmel_start_pins.h" IsConfig="false" Hash="M5pyeMRZyoPpiWeIh6Kfwg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="examples/driver_examples.h" IsConfig="false" Hash="Rmw7b009Kyb5JTTerAW1RA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="examples/driver_examples.c" IsConfig="false" Hash="UJMLSdu355whTkvhArrZiQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="examples/driver_examples.h" IsConfig="false" Hash="dkK05IW/Rlgtb0Wi2Od/sA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="examples/driver_examples.c" IsConfig="false" Hash="lGVC3kcjrnpxt217aSMKlw" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_usart_sync.h" IsConfig="false" Hash="ZzIGSRyjZuxRzFAtNNt7sw" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_missing_features.h" IsConfig="false" Hash="XsAvpgfutzkw0Y5SydYFaw" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_reset.h" IsConfig="false" Hash="WwLFRlBtuZ/qnD1JuDKnRQ" />
|
||||
@@ -159,14 +159,14 @@
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_spi_s_sync.h" IsConfig="false" Hash="gEGr6GqKbsOQvxQYz2fotA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_usart_async.h" IsConfig="false" Hash="tBfmk3BN3Q1WbYVoWDbsJw" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_usart_sync.h" IsConfig="false" Hash="Yj+PoPxG2CqDOy5XoIWkwg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/src/hal_spi_m_sync.c" IsConfig="false" Hash="Q0IudnTEWeoIkfQIoYIqxA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/src/hal_spi_m_dma.c" IsConfig="false" Hash="KMrinO/3xx7qWxy2PsJB7g" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/src/hal_usart_sync.c" IsConfig="false" Hash="VBVlAmBFEYTTUMHeIRFSxg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/utils/include/parts.h" IsConfig="false" Hash="THMC0T2wU10PzPgIVGK93g" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/cmcc/hpl_cmcc.c" IsConfig="false" Hash="xrdKSj3ppVwQWgZ3zrlaRg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/core/hpl_core_m4.c" IsConfig="false" Hash="VG4QALndju794J3HSKhsEQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/core/hpl_core_port.h" IsConfig="false" Hash="RXrDMMracCeflR1F9jWiGg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/core/hpl_init.c" IsConfig="false" Hash="/W7xK3rVKLxPEwN+aiJq8Q" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/dmac/hpl_dmac.c" IsConfig="false" Hash="RW/GgakK2RoVdDBtrCxYaA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/dmac/hpl_dmac.c" IsConfig="false" Hash="hfo1VP6av1KthYmILu3PCg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/gclk/hpl_gclk.c" IsConfig="false" Hash="5XO/19EedZQ0lq6yB8UTWQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/gclk/hpl_gclk_base.h" IsConfig="false" Hash="VnaHvu/VnbGvOxrehrp2mQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/mclk/hpl_mclk.c" IsConfig="false" Hash="XNSKHdNpSWfkSJUMnJUASA" />
|
||||
@@ -176,19 +176,19 @@
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/pm/hpl_pm_base.h" IsConfig="false" Hash="KOec1StxUZxY/RKBDbMkpg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/port/hpl_gpio_base.h" IsConfig="false" Hash="tEjgvZ4kvfccSWnEgilG5Q" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/ramecc/hpl_ramecc.c" IsConfig="false" Hash="pMdmwVWBg16VG8HOwA3DPw" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/sercom/hpl_sercom.c" IsConfig="false" Hash="CjIu1Ksl4k1CotxZpVcqMA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/sercom/hpl_sercom.c" IsConfig="false" Hash="hcMq5dgdlyb9xXr1YOQnMQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="stdio_start.c" IsConfig="false" Hash="WtwT7ld+0j4cPDj52v3y1A" />
|
||||
<AcmeProjectActionInfo Action="File" Source="stdio_start.h" IsConfig="false" Hash="5j2k69zdoQpbzluEyr/rHQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="atmel_start.h" IsConfig="false" Hash="TNU9VszFRFbDuMJ3vToUzg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="atmel_start.c" IsConfig="false" Hash="lom1/YOY9m/TDACgnyb3yA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/hpl_cmcc_config.h" IsConfig="true" Hash="bmtxQ8rLloaRtAo2HeXZRQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/hpl_dmac_config.h" IsConfig="true" Hash="mNec32O7w53e4vDmQlvjCA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/hpl_dmac_config.h" IsConfig="true" Hash="ns3tY+WWZKF5xxMvthvqEQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/hpl_gclk_config.h" IsConfig="true" Hash="qFfXbIiu7Skw/l5fYsEt7Q" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/hpl_mclk_config.h" IsConfig="true" Hash="pxBzoQXTG66x4dbzVzxteg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/hpl_osc32kctrl_config.h" IsConfig="true" Hash="HgvzEqDUH4jq/syjj/+G+Q" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/hpl_oscctrl_config.h" IsConfig="true" Hash="uzEpFoaBTLlpyWknL/fmxg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/hpl_port_config.h" IsConfig="true" Hash="5iQ/eeupKkHFkYA/g43bXQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/hpl_sercom_config.h" IsConfig="true" Hash="4cR+7kwM1FGXaHKzMryPIw" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/hpl_sercom_config.h" IsConfig="true" Hash="YlSwcGH0BPsqcwA8k4enSA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/peripheral_clk_config.h" IsConfig="true" Hash="zg2vMh4Usy8Jbwc/RH3Ljg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/stdio_redirect_config.h" IsConfig="true" Hash="CKmkBk12sfr7mb+HRQBuzg" />
|
||||
</AcmeActionInfos>
|
||||
@@ -343,6 +343,7 @@
|
||||
<armgcc.compiler.optimization.DebugLevel>Maximum (-g3)</armgcc.compiler.optimization.DebugLevel>
|
||||
<armgcc.compiler.warnings.AllWarnings>True</armgcc.compiler.warnings.AllWarnings>
|
||||
<armgcc.compiler.miscellaneous.OtherFlags>-std=gnu99 -mfloat-abi=softfp -mfpu=fpv4-sp-d16</armgcc.compiler.miscellaneous.OtherFlags>
|
||||
<armgcc.linker.general.UseNewlibNano>True</armgcc.linker.general.UseNewlibNano>
|
||||
<armgcc.linker.libraries.Libraries>
|
||||
<ListValues>
|
||||
<Value>libm</Value>
|
||||
@@ -416,6 +417,12 @@
|
||||
<Compile Include="AS5048A.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="AS5048A_dma.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="AS5048A_dma.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="atmel_start.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
@@ -497,7 +504,7 @@
|
||||
<Compile Include="hal\include\hal_sleep.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hal\include\hal_spi_m_sync.h">
|
||||
<Compile Include="hal\include\hal_spi_m_dma.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hal\include\hal_usart_sync.h">
|
||||
@@ -605,7 +612,7 @@
|
||||
<Compile Include="hal\src\hal_sleep.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hal\src\hal_spi_m_sync.c">
|
||||
<Compile Include="hal\src\hal_spi_m_dma.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hal\src\hal_usart_sync.c">
|
||||
@@ -875,7 +882,7 @@
|
||||
<None Include="documentation\stdio.rst">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="hal\documentation\spi_master_sync.rst">
|
||||
<None Include="hal\documentation\spi_master_dma.rst">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="hal\documentation\usart_sync.rst">
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
// <i> Indicates whether dmac is enabled or not
|
||||
// <id> dmac_enable
|
||||
#ifndef CONF_DMAC_ENABLE
|
||||
#define CONF_DMAC_ENABLE 0
|
||||
#define CONF_DMAC_ENABLE 1
|
||||
#endif
|
||||
|
||||
// <q> Priority Level 0
|
||||
@@ -105,7 +105,7 @@
|
||||
// <e> Channel 0 settings
|
||||
// <id> 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
|
||||
|
||||
// <q> Channel Run in Standby
|
||||
@@ -122,7 +122,7 @@
|
||||
// <i> Defines the trigger action used for a transfer
|
||||
// <id> dmac_trigact_0
|
||||
#ifndef CONF_DMAC_TRIGACT_0
|
||||
#define CONF_DMAC_TRIGACT_0 0
|
||||
#define CONF_DMAC_TRIGACT_0 2
|
||||
#endif
|
||||
|
||||
// <o> Trigger source
|
||||
@@ -214,7 +214,7 @@
|
||||
// <i> Defines the peripheral trigger which is source of the transfer
|
||||
// <id> dmac_trifsrc_0
|
||||
#ifndef CONF_DMAC_TRIGSRC_0
|
||||
#define CONF_DMAC_TRIGSRC_0 0
|
||||
#define CONF_DMAC_TRIGSRC_0 12
|
||||
#endif
|
||||
|
||||
// <o> Channel Arbitration Level
|
||||
@@ -291,7 +291,7 @@
|
||||
// <i> Indicates whether the destination address incrementation is enabled or not
|
||||
// <id> dmac_dstinc_0
|
||||
#ifndef CONF_DMAC_DSTINC_0
|
||||
#define CONF_DMAC_DSTINC_0 0
|
||||
#define CONF_DMAC_DSTINC_0 1
|
||||
#endif
|
||||
|
||||
// <o> Beat Size
|
||||
@@ -329,7 +329,7 @@
|
||||
// <e> Channel 1 settings
|
||||
// <id> 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
|
||||
|
||||
// <q> Channel Run in Standby
|
||||
@@ -346,7 +346,7 @@
|
||||
// <i> Defines the trigger action used for a transfer
|
||||
// <id> dmac_trigact_1
|
||||
#ifndef CONF_DMAC_TRIGACT_1
|
||||
#define CONF_DMAC_TRIGACT_1 0
|
||||
#define CONF_DMAC_TRIGACT_1 2
|
||||
#endif
|
||||
|
||||
// <o> Trigger source
|
||||
@@ -438,7 +438,7 @@
|
||||
// <i> Defines the peripheral trigger which is source of the transfer
|
||||
// <id> dmac_trifsrc_1
|
||||
#ifndef CONF_DMAC_TRIGSRC_1
|
||||
#define CONF_DMAC_TRIGSRC_1 0
|
||||
#define CONF_DMAC_TRIGSRC_1 13
|
||||
#endif
|
||||
|
||||
// <o> Channel Arbitration Level
|
||||
@@ -501,14 +501,14 @@
|
||||
// <i> Defines whether source or destination addresses are using the step size settings
|
||||
// <id> dmac_stepsel_1
|
||||
#ifndef CONF_DMAC_STEPSEL_1
|
||||
#define CONF_DMAC_STEPSEL_1 0
|
||||
#define CONF_DMAC_STEPSEL_1 1
|
||||
#endif
|
||||
|
||||
// <q> Source Address Increment
|
||||
// <i> Indicates whether the source address incrementation is enabled or not
|
||||
// <id> dmac_srcinc_1
|
||||
#ifndef CONF_DMAC_SRCINC_1
|
||||
#define CONF_DMAC_SRCINC_1 0
|
||||
#define CONF_DMAC_SRCINC_1 1
|
||||
#endif
|
||||
|
||||
// <q> Destination Address Increment
|
||||
|
||||
@@ -280,6 +280,28 @@
|
||||
#define CONF_SERCOM_4_SPI_ENABLE 1
|
||||
#endif
|
||||
|
||||
//<o> SPI DMA TX Channel <0-32>
|
||||
//<i> This defines DMA channel to be used
|
||||
//<id> spi_master_dma_tx_channel
|
||||
#ifndef CONF_SERCOM_4_SPI_M_DMA_TX_CHANNEL
|
||||
#define CONF_SERCOM_4_SPI_M_DMA_TX_CHANNEL 1
|
||||
#endif
|
||||
|
||||
// <e> SPI RX Channel Enable
|
||||
// <id> spi_master_rx_channel
|
||||
#ifndef CONF_SERCOM_4_SPI_RX_CHANNEL
|
||||
#define CONF_SERCOM_4_SPI_RX_CHANNEL 1
|
||||
#endif
|
||||
|
||||
//<o> DMA Channel <0-32>
|
||||
//<i> This defines DMA channel to be used
|
||||
//<id> spi_master_dma_rx_channel
|
||||
#ifndef CONF_SERCOM_4_SPI_M_DMA_RX_CHANNEL
|
||||
#define CONF_SERCOM_4_SPI_M_DMA_RX_CHANNEL 0
|
||||
#endif
|
||||
|
||||
// </e>
|
||||
|
||||
// Set module in SPI Master mode
|
||||
#ifndef CONF_SERCOM_4_SPI_MODE
|
||||
#define CONF_SERCOM_4_SPI_MODE 0x03
|
||||
@@ -314,7 +336,7 @@
|
||||
// <e> Advanced Configuration
|
||||
// <id> spi_master_advanced
|
||||
#ifndef CONF_SERCOM_4_SPI_ADVANCED
|
||||
#define CONF_SERCOM_4_SPI_ADVANCED 0
|
||||
#define CONF_SERCOM_4_SPI_ADVANCED 1
|
||||
#endif
|
||||
|
||||
// <o> Dummy byte <0x00-0x1ff>
|
||||
@@ -348,7 +370,7 @@
|
||||
// <i> Determines if input data is sampled on leading or trailing SCK edge. (CPHA)
|
||||
// <id> spi_master_arch_cpha
|
||||
#ifndef CONF_SERCOM_4_SPI_CPHA
|
||||
#define CONF_SERCOM_4_SPI_CPHA 0x0
|
||||
#define CONF_SERCOM_4_SPI_CPHA 0x1
|
||||
#endif
|
||||
|
||||
// <o> Immediate Buffer Overflow Notification
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
#include <utils.h>
|
||||
#include <hal_init.h>
|
||||
|
||||
struct spi_m_sync_descriptor SPI_0;
|
||||
|
||||
struct usart_sync_descriptor TARGET_IO;
|
||||
|
||||
struct spi_m_dma_descriptor SPI_0;
|
||||
|
||||
void TARGET_IO_PORT_init(void)
|
||||
{
|
||||
|
||||
@@ -90,7 +90,7 @@ void SPI_0_CLOCK_init(void)
|
||||
void SPI_0_init(void)
|
||||
{
|
||||
SPI_0_CLOCK_init();
|
||||
spi_m_sync_init(&SPI_0, SERCOM4);
|
||||
spi_m_dma_init(&SPI_0, SERCOM4);
|
||||
SPI_0_PORT_init();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,12 @@ extern "C" {
|
||||
#include <hal_sleep.h>
|
||||
|
||||
#include <hal_usart_sync.h>
|
||||
#include <hal_spi_m_sync.h>
|
||||
|
||||
#include <hal_spi_m_dma.h>
|
||||
|
||||
extern struct usart_sync_descriptor TARGET_IO;
|
||||
extern struct spi_m_sync_descriptor SPI_0;
|
||||
|
||||
extern struct spi_m_dma_descriptor SPI_0;
|
||||
|
||||
void TARGET_IO_PORT_init(void);
|
||||
void TARGET_IO_CLOCK_init(void);
|
||||
|
||||
@@ -24,14 +24,26 @@ void TARGET_IO_example(void)
|
||||
|
||||
/**
|
||||
* Example of using SPI_0 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_0[12] = "Hello World!";
|
||||
|
||||
static void tx_complete_cb_SPI_0(struct _dma_resource *resource)
|
||||
{
|
||||
/* Transfer completed */
|
||||
}
|
||||
|
||||
void SPI_0_example(void)
|
||||
{
|
||||
struct io_descriptor *io;
|
||||
spi_m_sync_get_io_descriptor(&SPI_0, &io);
|
||||
spi_m_dma_get_io_descriptor(&SPI_0, &io);
|
||||
|
||||
spi_m_sync_enable(&SPI_0);
|
||||
spi_m_dma_register_callback(&SPI_0, SPI_M_DMA_CB_TX_DONE, tx_complete_cb_SPI_0);
|
||||
spi_m_dma_enable(&SPI_0);
|
||||
io_write(io, example_SPI_0, 12);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ extern "C" {
|
||||
|
||||
void TARGET_IO_example(void);
|
||||
|
||||
void SPI_0_example(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
@@ -1,51 +0,0 @@
|
||||
The SPI Master Synchronous Driver
|
||||
=================================
|
||||
|
||||
The serial peripheral interface (SPI) is a synchronous serial communication
|
||||
interface.
|
||||
|
||||
SPI devices communicate in full duplex mode using a master-slave
|
||||
architecture with a single master. The 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
|
||||
|
||||
Applications
|
||||
------------
|
||||
|
||||
Send/receive/exchange data with a SPI slave device. E.g., serial flash, SD card,
|
||||
LCD controller, etc.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
SPI master capable hardware
|
||||
|
||||
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.
|
||||
|
||||
Known issues and workarounds
|
||||
----------------------------
|
||||
|
||||
N/A
|
||||
|
||||
257
Examples/AS5048A_test/AS5048A_test/hal/include/hal_spi_m_dma.h
Normal file
257
Examples/AS5048A_test/AS5048A_test/hal/include/hal_spi_m_dma.h
Normal file
@@ -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 <hal_io.h>
|
||||
#include <hpl_spi_m_dma.h>
|
||||
|
||||
/**
|
||||
* \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 */
|
||||
@@ -1,221 +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_SYNC_H_INCLUDED
|
||||
#define _HAL_SPI_M_SYNC_H_INCLUDED
|
||||
|
||||
#include <hal_io.h>
|
||||
#include <hpl_spi_m_sync.h>
|
||||
|
||||
/**
|
||||
* \addtogroup doc_driver_hal_spi_master_sync
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief SPI HAL driver struct for polling mode
|
||||
*
|
||||
*/
|
||||
struct spi_m_sync_descriptor {
|
||||
struct _spi_m_sync_hpl_interface *func;
|
||||
/** SPI device instance */
|
||||
struct _spi_sync_dev dev;
|
||||
/** I/O read/write */
|
||||
struct io_descriptor io;
|
||||
/** Flags for HAL driver */
|
||||
uint16_t flags;
|
||||
};
|
||||
|
||||
/** \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_sync_set_func_ptr(struct spi_m_sync_descriptor *spi, void *const func);
|
||||
|
||||
/** \brief Initialize SPI HAL instance and hardware for polling mode
|
||||
*
|
||||
* Initialize SPI HAL with polling 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_sync_init(struct spi_m_sync_descriptor *spi, void *const hw);
|
||||
|
||||
/** \brief Deinitialize the SPI HAL instance and hardware
|
||||
*
|
||||
* Abort transfer, disable and reset SPI, deinit software.
|
||||
*
|
||||
* \param[in] spi Pointer to the HAL SPI instance.
|
||||
*
|
||||
* \return Operation status.
|
||||
* \retval ERR_NONE Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
void spi_m_sync_deinit(struct spi_m_sync_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_sync_enable(struct spi_m_sync_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_sync_disable(struct spi_m_sync_descriptor *spi);
|
||||
|
||||
/** \brief Set SPI baudrate
|
||||
*
|
||||
* Works if SPI is initialized as master, it sets the baudrate.
|
||||
*
|
||||
* \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
|
||||
* \retval ERR_INVALID_ARG The baudrate is not supported.
|
||||
*/
|
||||
int32_t spi_m_sync_set_baudrate(struct spi_m_sync_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 (0~3).
|
||||
*
|
||||
* \return Operation status.
|
||||
* \retval ERR_NONE Success.
|
||||
* \retval ERR_BUSY Busy
|
||||
* \retval ERR_INVALID_ARG The mode is not supported.
|
||||
*/
|
||||
int32_t spi_m_sync_set_mode(struct spi_m_sync_descriptor *spi, const enum spi_transfer_mode mode);
|
||||
|
||||
/** \brief Set SPI transfer character size in number of bits
|
||||
*
|
||||
* The character size (\ref spi_char_size) 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 (~16, recommended 8).
|
||||
*
|
||||
* \return Operation status.
|
||||
* \retval ERR_NONE Success.
|
||||
* \retval ERR_BUSY Busy
|
||||
* \retval ERR_INVALID_ARG The char size is not supported.
|
||||
*/
|
||||
int32_t spi_m_sync_set_char_size(struct spi_m_sync_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
|
||||
* \retval ERR_INVALID_ARG The data order is not supported.
|
||||
*/
|
||||
int32_t spi_m_sync_set_data_order(struct spi_m_sync_descriptor *spi, const enum spi_data_order dord);
|
||||
|
||||
/** \brief Perform the SPI data transfer (TX and RX) in polling way
|
||||
*
|
||||
* Activate CS, do TX and RX and deactivate CS. It blocks.
|
||||
*
|
||||
* \param[in, out] spi Pointer to the HAL SPI instance.
|
||||
* \param[in] xfer Pointer to the transfer information (\ref spi_xfer).
|
||||
*
|
||||
* \retval size Success.
|
||||
* \retval >=0 Timeout, with number of characters transferred.
|
||||
* \retval ERR_BUSY SPI is busy
|
||||
*/
|
||||
int32_t spi_m_sync_transfer(struct spi_m_sync_descriptor *spi, const struct spi_xfer *xfer);
|
||||
|
||||
/**
|
||||
* \brief Return the 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_sync_get_io_descriptor(struct spi_m_sync_descriptor *const spi, struct io_descriptor **io);
|
||||
|
||||
/** \brief Retrieve the current driver version
|
||||
*
|
||||
* \return Current driver version.
|
||||
*/
|
||||
uint32_t spi_m_sync_get_version(void);
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ifndef _HAL_SPI_M_SYNC_H_INCLUDED */
|
||||
183
Examples/AS5048A_test/AS5048A_test/hal/src/hal_spi_m_dma.c
Normal file
183
Examples/AS5048A_test/AS5048A_test/hal/src/hal_spi_m_dma.c
Normal file
@@ -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 <utils_assert.h>
|
||||
#include <utils.h>
|
||||
|
||||
/**
|
||||
* \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;
|
||||
}
|
||||
@@ -1,201 +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_spi_m_sync.h"
|
||||
#include <utils_assert.h>
|
||||
#include <utils.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Driver version
|
||||
*/
|
||||
#define SPI_M_SYNC_DRIVER_VERSION 0x00000001u
|
||||
|
||||
#define SPI_DEACTIVATE_NEXT 0x8000
|
||||
|
||||
static int32_t _spi_m_sync_io_write(struct io_descriptor *const io, const uint8_t *const buf, const uint16_t length);
|
||||
static int32_t _spi_m_sync_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_sync_set_func_ptr(struct spi_m_sync_descriptor *spi, void *const func)
|
||||
{
|
||||
ASSERT(spi);
|
||||
spi->func = (struct _spi_m_sync_hpl_interface *)func;
|
||||
}
|
||||
|
||||
int32_t spi_m_sync_init(struct spi_m_sync_descriptor *spi, void *const hw)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
ASSERT(spi && hw);
|
||||
spi->dev.prvt = (void *)hw;
|
||||
rc = _spi_m_sync_init(&spi->dev, hw);
|
||||
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
spi->flags = SPI_DEACTIVATE_NEXT;
|
||||
spi->io.read = _spi_m_sync_io_read;
|
||||
spi->io.write = _spi_m_sync_io_write;
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
void spi_m_sync_deinit(struct spi_m_sync_descriptor *spi)
|
||||
{
|
||||
ASSERT(spi);
|
||||
_spi_m_sync_deinit(&spi->dev);
|
||||
}
|
||||
|
||||
void spi_m_sync_enable(struct spi_m_sync_descriptor *spi)
|
||||
{
|
||||
ASSERT(spi);
|
||||
_spi_m_sync_enable(&spi->dev);
|
||||
}
|
||||
|
||||
void spi_m_sync_disable(struct spi_m_sync_descriptor *spi)
|
||||
{
|
||||
ASSERT(spi);
|
||||
_spi_m_sync_disable(&spi->dev);
|
||||
}
|
||||
|
||||
int32_t spi_m_sync_set_baudrate(struct spi_m_sync_descriptor *spi, const uint32_t baud_val)
|
||||
{
|
||||
ASSERT(spi);
|
||||
return _spi_m_sync_set_baudrate(&spi->dev, baud_val);
|
||||
}
|
||||
|
||||
int32_t spi_m_sync_set_mode(struct spi_m_sync_descriptor *spi, const enum spi_transfer_mode mode)
|
||||
{
|
||||
ASSERT(spi);
|
||||
return _spi_m_sync_set_mode(&spi->dev, mode);
|
||||
}
|
||||
|
||||
int32_t spi_m_sync_set_char_size(struct spi_m_sync_descriptor *spi, const enum spi_char_size char_size)
|
||||
{
|
||||
ASSERT(spi);
|
||||
return _spi_m_sync_set_char_size(&spi->dev, char_size);
|
||||
}
|
||||
|
||||
int32_t spi_m_sync_set_data_order(struct spi_m_sync_descriptor *spi, const enum spi_data_order dord)
|
||||
{
|
||||
ASSERT(spi);
|
||||
return _spi_m_sync_set_data_order(&spi->dev, dord);
|
||||
}
|
||||
|
||||
/** \brief Do SPI read in polling way
|
||||
* For SPI master, activate CS, do send 0xFFs and read data, deactivate CS.
|
||||
*
|
||||
* It blocks until all data read or error.
|
||||
*
|
||||
* \param[in, out] spi Pointer to the HAL SPI instance.
|
||||
* \param[out] buf Pointer to the buffer to store read data.
|
||||
* \param[in] size Size of the data in number of characters.
|
||||
* \return Operation status.
|
||||
* \retval size Success.
|
||||
* \retval >=0 Time out, with number of characters read.
|
||||
*/
|
||||
static int32_t _spi_m_sync_io_read(struct io_descriptor *io, uint8_t *buf, const uint16_t length)
|
||||
{
|
||||
ASSERT(io);
|
||||
|
||||
struct spi_m_sync_descriptor *spi = CONTAINER_OF(io, struct spi_m_sync_descriptor, io);
|
||||
struct spi_xfer xfer;
|
||||
|
||||
xfer.rxbuf = buf;
|
||||
xfer.txbuf = 0;
|
||||
xfer.size = length;
|
||||
|
||||
return spi_m_sync_transfer(spi, &xfer);
|
||||
}
|
||||
|
||||
/** \brief Do SPI data write in polling way
|
||||
* For SPI master, activate CS, do buffer send and deactivate CS. The data back
|
||||
* is discarded.
|
||||
*
|
||||
* The data read back is discarded.
|
||||
*
|
||||
* It blocks until all data sent or error.
|
||||
*
|
||||
* \param[in, out] spi Pointer to the HAL SPI instance.
|
||||
* \param[in] p_xfer Pointer to the transfer information (\ref spi_transfer).
|
||||
* \return Operation status.
|
||||
* \retval size Success.
|
||||
* \retval >=0 Timeout, with number of characters transferred.
|
||||
*/
|
||||
static int32_t _spi_m_sync_io_write(struct io_descriptor *const io, const uint8_t *const buf, const uint16_t length)
|
||||
{
|
||||
ASSERT(io);
|
||||
|
||||
struct spi_m_sync_descriptor *spi = CONTAINER_OF(io, struct spi_m_sync_descriptor, io);
|
||||
struct spi_xfer xfer;
|
||||
|
||||
xfer.rxbuf = 0;
|
||||
xfer.txbuf = (uint8_t *)buf;
|
||||
xfer.size = length;
|
||||
|
||||
return spi_m_sync_transfer(spi, &xfer);
|
||||
}
|
||||
|
||||
int32_t spi_m_sync_transfer(struct spi_m_sync_descriptor *spi, const struct spi_xfer *p_xfer)
|
||||
{
|
||||
struct spi_msg msg;
|
||||
|
||||
ASSERT(spi && p_xfer);
|
||||
|
||||
msg.txbuf = p_xfer->txbuf;
|
||||
msg.rxbuf = p_xfer->rxbuf;
|
||||
msg.size = p_xfer->size;
|
||||
return _spi_m_sync_trans(&spi->dev, &msg);
|
||||
}
|
||||
|
||||
int32_t spi_m_sync_get_io_descriptor(struct spi_m_sync_descriptor *const spi, struct io_descriptor **io)
|
||||
{
|
||||
ASSERT(spi && io);
|
||||
*io = &spi->io;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t spi_m_sync_get_version(void)
|
||||
{
|
||||
return SPI_M_SYNC_DRIVER_VERSION;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -37,7 +37,6 @@
|
||||
#include <hpl_dmac_config.h>
|
||||
#include <utils_repeat_macro.h>
|
||||
|
||||
#if CONF_DMAC_ENABLE
|
||||
/* Section containing first descriptors for all DMAC channels */
|
||||
COMPILER_ALIGNED(16)
|
||||
DmacDescriptor _descriptor_section[DMAC_CH_NUM];
|
||||
@@ -75,6 +74,15 @@ struct dmac_channel_cfg {
|
||||
/* DMAC channel configurations */
|
||||
const static struct dmac_channel_cfg _cfgs[] = {REPEAT_MACRO(DMAC_CHANNEL_CFG, i, DMAC_CH_NUM)};
|
||||
|
||||
|
||||
// ADDED
|
||||
int32_t _dma_set_descriptor(const uint8_t channel, const DmacDescriptor descriptor)
|
||||
{
|
||||
_descriptor_section[channel] = descriptor;
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialize DMAC
|
||||
*/
|
||||
@@ -259,5 +267,3 @@ void DMAC_4_Handler(void)
|
||||
{
|
||||
_dmac_handler();
|
||||
}
|
||||
|
||||
#endif /* CONF_DMAC_ENABLE */
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
#include <hpl_spi_m_dma.h>
|
||||
#include <hpl_dma.h>
|
||||
#include <hpl_i2c_m_async.h>
|
||||
#include <hpl_i2c_m_sync.h>
|
||||
@@ -2957,3 +2958,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;
|
||||
}
|
||||
|
||||
@@ -1,29 +1,76 @@
|
||||
#include <atmel_start.h>
|
||||
#include "AS5048A.h"
|
||||
#include "AS5048A_dma.h"
|
||||
|
||||
#define CONF_DELAY_US 10
|
||||
|
||||
#define BUFFER_LEN (6)
|
||||
static uint8_t rx_buffer[BUFFER_LEN] = {0};
|
||||
static uint8_t tx_buffer[BUFFER_LEN] = "Hello";
|
||||
|
||||
|
||||
|
||||
/* DMA Transfer complete callback for SPI master TX */
|
||||
static void spi_master_tx_complete_cb(struct _dma_resource *resource)
|
||||
{
|
||||
/* Transfer completed */
|
||||
delay_us(CONF_DELAY_US);
|
||||
gpio_set_pin_level(SPI_SS, true);
|
||||
}
|
||||
|
||||
/* DMA Transfer complete callback for SPI master RX */
|
||||
static void spi_master_rx_complete_cb(struct _dma_resource *resource)
|
||||
{
|
||||
/* Transfer completed */
|
||||
gpio_set_pin_level(SPI_SS, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* IO descriptor for SPI master */
|
||||
struct io_descriptor *io_spi_master;
|
||||
|
||||
/* SPI master IO and Callback Initialization */
|
||||
void spi_master_init(void)
|
||||
{
|
||||
spi_m_dma_enable(&SPI_0);
|
||||
spi_m_dma_get_io_descriptor(&SPI_0, &io_spi_master);
|
||||
spi_m_dma_register_callback(&SPI_0, SPI_M_DMA_CB_TX_DONE, spi_master_tx_complete_cb);
|
||||
spi_m_dma_register_callback(&SPI_0, SPI_M_DMA_CB_RX_DONE, spi_master_rx_complete_cb);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Initializes MCU, drivers and middleware */
|
||||
atmel_start_init();
|
||||
if(AS5048A_init())
|
||||
printf("Init Complete\n");
|
||||
else
|
||||
printf("Init failed\n");
|
||||
|
||||
//spi_master_init();
|
||||
as5048a_init();
|
||||
//spi_m_dma_enable(&SPI_0);
|
||||
//io_write(io_spi_master, tx_buffer, BUFFER_LEN );
|
||||
|
||||
/* Replace with your application code */
|
||||
as5048a_read(AS5048A_CLEAR_ERROR_FLAG);
|
||||
while (1) {
|
||||
delay_ms(1000);
|
||||
// gpio_set_pin_level(SPI_SS, false);
|
||||
// spi_m_dma_transfer(&SPI_0, tx_buffer, rx_buffer, BUFFER_LEN );
|
||||
|
||||
//printf("%u\r\n", getRawRotation());
|
||||
//volatile float angle = getRotationInDegrees();
|
||||
//read(AS5048A_ANGLE);
|
||||
read(AS5048A_CLEAR_ERROR_FLAG);
|
||||
delay_ms(500);
|
||||
read(AS5048A_CMD_NOP);
|
||||
delay_ms(500);
|
||||
read(AS5048A_CMD_NOP);
|
||||
delay_ms(500);
|
||||
//volatile float angle = getRotationInDegrees();
|
||||
//printf("%f\r\n", angle);
|
||||
}
|
||||
}
|
||||
//as5048a_read(AS5048A_CLEAR_ERROR_FLAG);
|
||||
//delay_ms(100);
|
||||
//as5048a_read(AS5048A_CMD_NOP);
|
||||
|
||||
//uint16_t raw_angle = (( ( in_buf[1] & 0xFF ) << 8 ) | ( in_buf[0] & 0xFF )) & ~0xC000);
|
||||
|
||||
printf("%u\n\r", as5048a_read(AS5048A_ANGLE));
|
||||
//printf("%i\n\r", as5048a_read(AS5048A_ANGLE));
|
||||
|
||||
|
||||
//delay_ms(100);
|
||||
//as5048a_read(AS5048A_CMD_NOP);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user