commiting examples
This commit is contained in:
@@ -52,6 +52,8 @@
|
||||
<files>
|
||||
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/evsys.rst"/>
|
||||
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/spi_master_dma.rst"/>
|
||||
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/spi_master_sync.rst"/>
|
||||
<file category="doc" condition="ARMCC, GCC, IAR" name="hal/documentation/timer.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"/>
|
||||
@@ -62,6 +64,7 @@
|
||||
<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_dma.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_spi_m_sync.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/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"/>
|
||||
@@ -102,7 +105,6 @@
|
||||
<file category="source" condition="ARMCC, GCC, IAR" name="hal/utils/src/utils_event.c"/>
|
||||
<file category="source" condition="ARMCC, GCC, IAR" name="hal/utils/src/utils_list.c"/>
|
||||
<file category="source" condition="GCC" name="hal/utils/src/utils_syscalls.c"/>
|
||||
<file category="doc" condition="ARMCC, GCC, IAR" name="hpl/doc_lite/tc.rst"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hri/hri_ac_e54.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hri/hri_adc_e54.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hri/hri_aes_e54.h"/>
|
||||
@@ -156,17 +158,22 @@
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="atmel_start_pins.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="examples/driver_examples.h"/>
|
||||
<file category="source" condition="ARMCC, GCC, IAR" name="examples/driver_examples.c"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_timer.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hal_usart_sync.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_missing_features.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_pwm.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_reset.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_spi_m_async.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_spi_m_dma.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_spi_m_sync.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hal/include/hpl_spi_s_async.h"/>
|
||||
<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_timer.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_dma.c"/>
|
||||
<file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_spi_m_sync.c"/>
|
||||
<file category="source" condition="ARMCC, GCC, IAR" name="hal/src/hal_timer.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"/>
|
||||
@@ -185,8 +192,8 @@
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hpl/port/hpl_gpio_base.h"/>
|
||||
<file category="source" condition="ARMCC, GCC, IAR" name="hpl/ramecc/hpl_ramecc.c"/>
|
||||
<file category="source" condition="ARMCC, GCC, IAR" name="hpl/sercom/hpl_sercom.c"/>
|
||||
<file category="source" condition="ARMCC, GCC, IAR" name="hpl/tc/tc_lite.c"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hpl/tc/tc_lite.h"/>
|
||||
<file category="source" condition="ARMCC, GCC, IAR" name="hpl/tc/hpl_tc.c"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="hpl/tc/hpl_tc_base.h"/>
|
||||
<file category="source" condition="ARMCC, GCC, IAR" name="stdio_start.c"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="stdio_start.h"/>
|
||||
<file category="header" condition="ARMCC, GCC, IAR" name="atmel_start.h"/>
|
||||
@@ -200,6 +207,7 @@
|
||||
<file attr="config" category="header" condition="ARMCC, GCC, IAR" name="config/hpl_oscctrl_config.h"/>
|
||||
<file attr="config" category="header" condition="ARMCC, GCC, IAR" name="config/hpl_port_config.h"/>
|
||||
<file attr="config" category="header" condition="ARMCC, GCC, IAR" name="config/hpl_sercom_config.h"/>
|
||||
<file attr="config" category="header" condition="ARMCC, GCC, IAR" name="config/hpl_tc_config.h"/>
|
||||
<file attr="config" category="header" condition="ARMCC, GCC, IAR" name="config/peripheral_clk_config.h"/>
|
||||
<file attr="config" category="header" condition="ARMCC, GCC, IAR" name="config/stdio_redirect_config.h"/>
|
||||
<file category="include" condition="ARMCC, GCC, IAR" name=""/>
|
||||
|
||||
@@ -1468,55 +1468,70 @@ drivers:
|
||||
configuration:
|
||||
core_gclk_selection: Generic clock generator 0
|
||||
slow_gclk_selection: Generic clock generator 3
|
||||
SPI_1:
|
||||
user_label: SPI_1
|
||||
definition: Atmel:SAME54_Drivers:0.0.1::SAME54P20A-AU::SERCOM6::driver_config_definition::SPI.Master::HAL:Driver:SPI.Master.Sync
|
||||
functionality: SPI
|
||||
api: HAL:Driver:SPI_Master_Sync
|
||||
configuration:
|
||||
spi_master_advanced: true
|
||||
spi_master_arch_cpha: Sample input on trailing edge
|
||||
spi_master_arch_cpol: SCK is high 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: 1000000
|
||||
spi_master_character_size: 8 bits
|
||||
spi_master_dummybyte: 511
|
||||
spi_master_rx_enable: true
|
||||
optional_signals: []
|
||||
variant:
|
||||
specification: TXPO=0, RXPO=3
|
||||
required_signals:
|
||||
- name: SERCOM6/PAD/0
|
||||
pad: PC04
|
||||
label: MOSI
|
||||
- name: SERCOM6/PAD/1
|
||||
pad: PC05
|
||||
label: SCK
|
||||
- name: SERCOM6/PAD/3
|
||||
pad: PC07
|
||||
label: MISO
|
||||
clocks:
|
||||
domain_group:
|
||||
nodes:
|
||||
- name: Core
|
||||
input: Generic clock generator 0
|
||||
external: false
|
||||
external_frequency: 0
|
||||
- name: Slow
|
||||
input: Generic clock generator 3
|
||||
external: false
|
||||
external_frequency: 0
|
||||
configuration:
|
||||
core_gclk_selection: Generic clock generator 0
|
||||
slow_gclk_selection: Generic clock generator 3
|
||||
TIMER_0:
|
||||
user_label: TIMER_0
|
||||
definition: Atmel:SAME54_Drivers:0.0.1::SAME54P20A-AU::TC0::driver_config_definition::32-bit.Counter.Mode::Lite:TC:Timer
|
||||
definition: Atmel:SAME54_Drivers:0.0.1::SAME54P20A-AU::TC0::driver_config_definition::Timer::HAL:Driver:Timer
|
||||
functionality: Timer
|
||||
api: Lite:TC:Timer
|
||||
api: HAL:Driver:Timer
|
||||
configuration:
|
||||
cc_cc0: 12000
|
||||
cc_cc1: 6000
|
||||
cc_control: true
|
||||
count_control: false
|
||||
count_count: 0
|
||||
ctrla_alock: false
|
||||
ctrla_capten0: false
|
||||
ctrla_capten1: false
|
||||
ctrla_captmode0: DEFAULT
|
||||
ctrla_captmode1: DEFAULT
|
||||
ctrla_control: true
|
||||
ctrla_copen0: false
|
||||
ctrla_copen1: false
|
||||
ctrla_enable: true
|
||||
ctrla_mode: 0
|
||||
ctrla_ondemand: false
|
||||
ctrla_prescaler: DIV1
|
||||
ctrla_prescsync: GCLK
|
||||
ctrla_runstdby: false
|
||||
ctrlbset_cmd: NONE
|
||||
ctrlbset_control: false
|
||||
ctrlbset_dir: false
|
||||
ctrlbset_lupd: false
|
||||
ctrlbset_oneshot: false
|
||||
ctrlc_inven0: false
|
||||
ctrlc_inven1: false
|
||||
dbgctrl_control: false
|
||||
dbgctrl_dbgrun: false
|
||||
drvctrl_control: false
|
||||
evctrl_control: true
|
||||
evctrl_evact: 'OFF'
|
||||
evctrl_mceo0: true
|
||||
evctrl_mceo1: true
|
||||
evctrl_ovfeo: true
|
||||
evctrl_tcei: false
|
||||
evctrl_tcinv: false
|
||||
intenset_control: true
|
||||
intenset_err: false
|
||||
intenset_mc0: false
|
||||
intenset_mc1: true
|
||||
intenset_ovf: true
|
||||
wave_control: true
|
||||
wave_wavegen: MFRQ
|
||||
tc_arch_dbgrun: false
|
||||
tc_arch_evact: Event action disabled
|
||||
tc_arch_mceo0: false
|
||||
tc_arch_mceo1: false
|
||||
tc_arch_ondemand: false
|
||||
tc_arch_ovfeo: false
|
||||
tc_arch_presync: Reload or reset counter on next GCLK
|
||||
tc_arch_runstdby: false
|
||||
tc_arch_tcei: false
|
||||
tc_arch_tcinv: false
|
||||
timer_advanced_configuration: false
|
||||
timer_event_control: true
|
||||
timer_prescaler: Divide by 8
|
||||
timer_tick: 1000
|
||||
optional_signals: []
|
||||
variant: null
|
||||
clocks:
|
||||
@@ -1529,6 +1544,31 @@ drivers:
|
||||
configuration:
|
||||
tc_gclk_selection: Generic clock generator 0
|
||||
pads:
|
||||
PC04:
|
||||
name: PC04
|
||||
definition: Atmel:SAME54_Drivers:0.0.1::SAME54P20A-AU::pad::PC04
|
||||
mode: Digital output
|
||||
user_label: PC04
|
||||
configuration: null
|
||||
PC05:
|
||||
name: PC05
|
||||
definition: Atmel:SAME54_Drivers:0.0.1::SAME54P20A-AU::pad::PC05
|
||||
mode: Digital output
|
||||
user_label: PC05
|
||||
configuration: null
|
||||
Angle_SS:
|
||||
name: PC06
|
||||
definition: Atmel:SAME54_Drivers:0.0.1::SAME54P20A-AU::pad::PC06
|
||||
mode: Digital output
|
||||
user_label: Angle_SS
|
||||
configuration:
|
||||
pad_initial_level: High
|
||||
PC07:
|
||||
name: PC07
|
||||
definition: Atmel:SAME54_Drivers:0.0.1::SAME54P20A-AU::pad::PC07
|
||||
mode: Digital input
|
||||
user_label: PC07
|
||||
configuration: null
|
||||
PB24:
|
||||
name: PB24
|
||||
definition: Atmel:SAME54_Drivers:0.0.1::SAME54P20A-AU::pad::PB24
|
||||
|
||||
@@ -0,0 +1,440 @@
|
||||
/*
|
||||
* A1335.c
|
||||
*
|
||||
* Created: 24/07/2021 17:54:33
|
||||
* Author: Nick-XMG
|
||||
*/
|
||||
#include "A1335.h"
|
||||
|
||||
#define kNOERROR 0
|
||||
#define kPRIMARYREADERROR 1
|
||||
#define kEXTENDEDREADTIMEOUTERROR 2
|
||||
#define kPRIMARYWRITEERROR 3
|
||||
#define kEXTENDEDWRITETIMEOUTERROR 4
|
||||
#define kCRCERROR 5
|
||||
|
||||
#define kUNABLETOCHANGEPROCESSORSTATE 6
|
||||
|
||||
const uint16_t ChipSelectPin = 5;
|
||||
const uint16_t LEDPin = 13;
|
||||
|
||||
const uint32_t WRITE = 0x40;
|
||||
const uint32_t READ = 0x00;
|
||||
const uint32_t COMMAND_MASK = 0xC0;
|
||||
const uint32_t ADDRESS_MASK = 0x3F;
|
||||
|
||||
unsigned long nextTime;
|
||||
bool ledOn = false;
|
||||
bool includeCRC = false;
|
||||
|
||||
struct SPI_S A1 = {
|
||||
.SPI_angleSensor_n = &SPI_1,
|
||||
.state = 0,
|
||||
.SS_pin = Angle_SS,
|
||||
.tx_buffer = NULL,
|
||||
.rx_buffer = NULL,
|
||||
|
||||
};
|
||||
|
||||
void angleSensor_init(struct spi_m_sync_descriptor *spi)
|
||||
{
|
||||
spi_m_sync_get_io_descriptor(spi, &io);
|
||||
spi_m_sync_enable(spi);
|
||||
|
||||
}
|
||||
|
||||
void angleSensor_State_Machine(struct SPI_S *Sn)
|
||||
{
|
||||
uint16_t value;
|
||||
switch(Sn->state){
|
||||
case 0:
|
||||
angleSensor_init(Sn->SPI_angleSensor_n);
|
||||
gpio_set_pin_level(Sn->SS_pin, true);
|
||||
Sn->state++;
|
||||
break;
|
||||
case 1:
|
||||
PrimaryRead(Sn->SS_pin, 0x20, &value);
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* CalculateParity
|
||||
*
|
||||
* From the 16 bit input, calculate the parity
|
||||
*/
|
||||
bool CalculateParity(uint16_t input)
|
||||
{
|
||||
uint16_t count = 0;
|
||||
|
||||
// Count up the number of 1s in the input
|
||||
for (int index = 0; index < 16; ++index)
|
||||
{
|
||||
if ((input & 1) == 1)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
|
||||
input >>= 1;
|
||||
}
|
||||
|
||||
// return true if there is an odd number of 1s
|
||||
return (count & 1) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* CalculateCRC
|
||||
*
|
||||
* Take the 16bit input and generate a 4bit CRC
|
||||
* Polynomial = x^4 + x^1 + 1
|
||||
* LFSR preset to all 1's
|
||||
*/
|
||||
uint8_t CalculateCRC(uint16_t input)
|
||||
{
|
||||
bool CRC0 = true;
|
||||
bool CRC1 = true;
|
||||
bool CRC2 = true;
|
||||
bool CRC3 = true;
|
||||
int i;
|
||||
bool DoInvert;
|
||||
uint16_t mask = 0x8000;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
DoInvert = ((input & mask) != 0) ^ CRC3; // XOR required?
|
||||
|
||||
CRC3 = CRC2;
|
||||
CRC2 = CRC1;
|
||||
CRC1 = CRC0 ^ DoInvert;
|
||||
CRC0 = DoInvert;
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
return (CRC3 ? 8U : 0U) + (CRC2 ? 4U : 0U) + (CRC1 ? 2U : 0U) + (CRC0 ? 1U : 0U);
|
||||
}
|
||||
|
||||
/*
|
||||
* PrimaryRead
|
||||
*
|
||||
* Read from the primary serial registers
|
||||
*/
|
||||
uint16_t PrimaryRead(uint16_t cs, uint16_t address, uint16_t* value)
|
||||
{
|
||||
uint16_t command = ((address & ADDRESS_MASK) | READ) << 8;
|
||||
gpio_set_pin_level(Angle_SS, false);
|
||||
|
||||
struct spi_msg msg;
|
||||
|
||||
|
||||
spi_m_sync_transfer(Sn->SPI_angleSensor_n, )
|
||||
|
||||
|
||||
//SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));
|
||||
//
|
||||
//// Combine the register address and the command into one byte
|
||||
//uint16_t command = ((address & ADDRESS_MASK) | READ) << 8;
|
||||
//
|
||||
//// take the chip select low to select the device
|
||||
//digitalWrite(cs, LOW);
|
||||
//
|
||||
//// send the device the register you want to read
|
||||
//SPI.transfer16(command);
|
||||
//
|
||||
//digitalWrite(cs, HIGH);
|
||||
//digitalWrite(cs, LOW);
|
||||
//
|
||||
//// send the command again to read the contents
|
||||
//value = SPI.transfer16(command);
|
||||
//
|
||||
//// take the chip select high to de-select
|
||||
//digitalWrite(cs, HIGH);
|
||||
//
|
||||
//SPI.endTransaction();
|
||||
//}
|
||||
//
|
||||
return kNOERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* PrimaryWrite
|
||||
*
|
||||
* Write to the primary serial registers
|
||||
*/
|
||||
uint16_t PrimaryWrite(uint16_t cs, uint16_t address, uint16_t value)
|
||||
{
|
||||
//if (includeCRC)
|
||||
//{
|
||||
//SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));
|
||||
//
|
||||
//// On the Teensy, SPI0_CTAR0 is used to describe the SPI transaction for transfer
|
||||
//// while SPI0_CTAR1 is used to describe the SPI transaction for transfer16.
|
||||
//// To do a 20 bit transfer, change the length of the transaction to 4 bits for transfer
|
||||
//// and do a transfer16 followed by a transfer.
|
||||
////uint32_t oldSPI0_CTAR0 = SPI0_CTAR0;
|
||||
//// SPI0_CTAR0 = (SPI0_CTAR0 & 0x87FFFFFF) | SPI_CTAR_FMSZ(3); // using SPI0_CTAR0 to send 4 bits
|
||||
//
|
||||
//// Combine the register address and the command into one byte
|
||||
//uint16_t command = (((address & ADDRESS_MASK) | WRITE) << 8) | ((value >> 8) & 0x0FF);
|
||||
//uint8_t crcCommand = CalculateCRC(command);
|
||||
//
|
||||
//// take the chip select low to select the device:
|
||||
//digitalWrite(cs, LOW);
|
||||
//
|
||||
//SPI.transfer16(command); // Send most significant byte of register data
|
||||
//SPI.transfer(crcCommand); // Send the crc
|
||||
//
|
||||
//// take the chip select high to de-select:
|
||||
//digitalWrite(cs, HIGH);
|
||||
//
|
||||
//command = ((((address + 1) & ADDRESS_MASK) | WRITE) << 8 ) | (value & 0x0FF);
|
||||
//crcCommand = CalculateCRC(command);
|
||||
//
|
||||
//// take the chip select low to select the device:
|
||||
//digitalWrite(cs, LOW);
|
||||
//
|
||||
//SPI.transfer16(command); // Send least significant byte of register data
|
||||
//SPI.transfer(crcCommand); // Send the crc
|
||||
//
|
||||
//// take the chip select high to de-select:
|
||||
//digitalWrite(cs, HIGH);
|
||||
//
|
||||
//// Restore the 8 bit description
|
||||
////SPI0_CTAR0 = oldSPI0_CTAR0;
|
||||
//
|
||||
//SPI.endTransaction();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
//SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));
|
||||
//
|
||||
//// Combine the register address and the command into one byte
|
||||
//uint16_t command = ((address & ADDRESS_MASK) | WRITE) << 8;
|
||||
//
|
||||
//// take the chip select low to select the device:
|
||||
//digitalWrite(cs, LOW);
|
||||
//
|
||||
//SPI.transfer16(command | ((value >> 8) & 0x0FF)); // Send most significant byte of register data
|
||||
//
|
||||
//// take the chip select high to de-select:
|
||||
//digitalWrite(cs, HIGH);
|
||||
//
|
||||
//command = (((address + 1) & ADDRESS_MASK) | WRITE) << 8;
|
||||
//// take the chip select low to select the device:
|
||||
//digitalWrite(cs, LOW);
|
||||
//
|
||||
//SPI.transfer16(command | (value & 0x0FF)); // Send least significant byte of register data
|
||||
//
|
||||
//// take the chip select high to de-select:
|
||||
//digitalWrite(cs, HIGH);
|
||||
//
|
||||
//SPI.endTransaction();
|
||||
//}
|
||||
|
||||
return kNOERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* ExtendedRead
|
||||
*
|
||||
* Read from the SRAM, EEPROM, AUX or Extended Registers
|
||||
*/
|
||||
uint16_t ExtendedRead(uint16_t cs, uint16_t address, uint32_t value)
|
||||
{
|
||||
//uint16_t results;
|
||||
//uint16_t readFlags;
|
||||
//uint32_t timeout;
|
||||
//uint16_t valueMSW;
|
||||
//uint16_t valueLSW;
|
||||
//uint32_t currentTime;
|
||||
//
|
||||
//// Write the address to the Extended Read Address register
|
||||
//results = PrimaryWrite(cs, 0x0A, address & 0xFFFF);
|
||||
//
|
||||
//if (results != kNOERROR)
|
||||
//{
|
||||
//return results;
|
||||
//}
|
||||
//
|
||||
//// Initiate the extended read
|
||||
//results = PrimaryWrite(cs, 0x0C, 0x8000);
|
||||
//
|
||||
//if (results != kNOERROR)
|
||||
//{
|
||||
//return results;
|
||||
//}
|
||||
//
|
||||
//timeout = millis() + 100L;
|
||||
//
|
||||
//do // Wait for the read to be complete
|
||||
//{
|
||||
//results = PrimaryRead(cs, 0x0C, readFlags);
|
||||
//
|
||||
//if (results != kNOERROR)
|
||||
//{
|
||||
//return results;
|
||||
//}
|
||||
//
|
||||
//// Make sure the read is not taking too long
|
||||
//currentTime = millis();
|
||||
//if (timeout < currentTime)
|
||||
//{
|
||||
//return kEXTENDEDREADTIMEOUTERROR;
|
||||
//}
|
||||
//} while ((readFlags & 0x0001) != 0x0001);
|
||||
//
|
||||
//// Read the most significant word from the extended read data
|
||||
//results = PrimaryRead(cs, 0x0E, valueMSW);
|
||||
//
|
||||
//if (results != kNOERROR)
|
||||
//{
|
||||
//return results;
|
||||
//}
|
||||
//
|
||||
//// Read the least significant word from the extended read data
|
||||
//results = PrimaryRead(cs, 0x10, valueLSW);
|
||||
//
|
||||
//// Combine them
|
||||
//value = ((uint32_t)valueMSW << 16) + valueLSW;
|
||||
//
|
||||
//return results;
|
||||
}
|
||||
|
||||
/*
|
||||
* ExtendedWrite
|
||||
*
|
||||
* Write to the SRAM, EEPROM, AUX or Extended Access Commands
|
||||
*/
|
||||
uint16_t ExtendedWrite(uint16_t cs, uint16_t address, uint32_t value)
|
||||
{
|
||||
//uint16_t results;
|
||||
//uint16_t writeFlags;
|
||||
//uint32_t timeout;
|
||||
//
|
||||
//// Write into the extended address register
|
||||
//results = PrimaryWrite(cs, 0x02, address & 0xFFFF);
|
||||
//
|
||||
//if (results != kNOERROR)
|
||||
//{
|
||||
//return results;
|
||||
//}
|
||||
//
|
||||
//// Write the MSW (Most significant word) into the high order write data register
|
||||
//results = PrimaryWrite(cs, 0x04, (value >> 16) & 0xFFFF);
|
||||
//
|
||||
//if (results != kNOERROR)
|
||||
//{
|
||||
//return results;
|
||||
//}
|
||||
//
|
||||
//// Write the LSW (Least significant word) into the low order write data register
|
||||
//results = PrimaryWrite(cs, 0x06, value & 0xFFFF);
|
||||
//
|
||||
//if (results != kNOERROR)
|
||||
//{
|
||||
//return results;
|
||||
//}
|
||||
//
|
||||
//// Start the write process
|
||||
//results = PrimaryWrite(cs, 0x08, 0x8000);
|
||||
//
|
||||
//if (results != kNOERROR)
|
||||
//{
|
||||
//return results;
|
||||
//}
|
||||
//
|
||||
//// If writing to the EEPROM, generate the Program
|
||||
//// Pulses on Vcc
|
||||
//if ((address >= 0x300) && (address < 0x320))
|
||||
//{
|
||||
//// Send the Program Pulses
|
||||
//// Need hardware which this example does not have.
|
||||
//}
|
||||
//
|
||||
//timeout = millis() + 100;
|
||||
//
|
||||
//// Wait for the write to complete
|
||||
//do
|
||||
//{
|
||||
//results = PrimaryRead(cs, 0x08, writeFlags);
|
||||
//
|
||||
//if (results != kNOERROR)
|
||||
//{
|
||||
//return results;
|
||||
//}
|
||||
//
|
||||
//if (timeout < millis())
|
||||
//{
|
||||
//return kEXTENDEDWRITETIMEOUTERROR;
|
||||
//}
|
||||
//} while ((writeFlags & 0x0001) != 0x0001);
|
||||
//
|
||||
//return results;
|
||||
}
|
||||
|
||||
/*
|
||||
* SetProcessorStateToIdle
|
||||
*
|
||||
* Change the processor state to idle
|
||||
* This is needed to write EEPROM, change ORATE or perform certain self tests
|
||||
*/
|
||||
uint16_t SetProcessorStateToIdle(uint8_t cs)
|
||||
{
|
||||
//uint16_t results;
|
||||
//uint16_t value;
|
||||
//
|
||||
//// Write the enter idle state command into the control register
|
||||
//results = PrimaryWrite(cs, 0x1F, 0x8046);
|
||||
//
|
||||
//if (results == kNOERROR)
|
||||
//{
|
||||
//delay(1);
|
||||
//
|
||||
//// Read the status register to see if the processor is in the idle state
|
||||
//results = PrimaryRead(cs, 0x22, value);
|
||||
//
|
||||
//if (results == kNOERROR)
|
||||
//{
|
||||
//if ((value & 0x00FF) != 0x0010)
|
||||
//{
|
||||
//return kUNABLETOCHANGEPROCESSORSTATE;
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
//
|
||||
//return results;
|
||||
}
|
||||
|
||||
/*
|
||||
* SetProcessorStateToRun
|
||||
*
|
||||
* Change the processor state to run
|
||||
* This is needed to process angles
|
||||
*/
|
||||
uint16_t SetProcessorStateToRun(uint8_t cs)
|
||||
{
|
||||
//uint16_t results;
|
||||
//uint16_t value;
|
||||
//
|
||||
//// Write the enter idle state command into the control register
|
||||
//results = PrimaryWrite(cs, 0x1F, 0xC046);
|
||||
//
|
||||
//if (results == kNOERROR)
|
||||
//{
|
||||
//delay(1);
|
||||
//
|
||||
//// Read the status register to see if the processor is in the idle state
|
||||
//results = PrimaryRead(cs, 0x22, value);
|
||||
//
|
||||
//if (results == kNOERROR)
|
||||
//{
|
||||
//if ((value & 0x00FF) != 0x0011)
|
||||
//{
|
||||
//return kUNABLETOCHANGEPROCESSORSTATE;
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
//
|
||||
//return results;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* A1335.h
|
||||
*
|
||||
* Created: 24/07/2021 17:53:53
|
||||
* Author: Nick-XMG
|
||||
*/
|
||||
|
||||
|
||||
#ifndef A1335_H_
|
||||
#define A1335_H_
|
||||
#include <atmel_start.h>
|
||||
|
||||
struct SPI_S {
|
||||
struct spi_m_sync_descriptor *SPI_angleSensor_n;
|
||||
uint8_t state;
|
||||
uint32_t SS_pin;
|
||||
struct spi_xfer xfer;
|
||||
uint8_t *tx_buffer;
|
||||
uint8_t *rx_buffer;
|
||||
};
|
||||
|
||||
struct SPI_S A1;
|
||||
struct io_descriptor *io;
|
||||
|
||||
void angleSensor_init(struct spi_m_sync_descriptor *spi);
|
||||
void angleSensor_State_Machine(struct SPI_S *Sn);
|
||||
|
||||
bool CalculateParity(uint16_t input);
|
||||
uint8_t CalculateCRC(uint16_t input);
|
||||
uint16_t PrimaryRead(uint16_t cs, uint16_t address, uint16_t* value);
|
||||
uint16_t PrimaryWrite(uint16_t cs, uint16_t address, uint16_t value);
|
||||
uint16_t ExtendedRead(uint16_t cs, uint16_t address, uint32_t value);
|
||||
uint16_t ExtendedWrite(uint16_t cs, uint16_t address, uint32_t value);
|
||||
uint16_t SetProcessorStateToRun(uint8_t cs);
|
||||
uint16_t SetProcessorStateToIdle(uint8_t cs);
|
||||
uint16_t SetProcessorStateToRun(uint8_t cs);
|
||||
|
||||
|
||||
#endif /* A1335_H_ */
|
||||
@@ -454,6 +454,165 @@
|
||||
#define CONF_SERCOM_4_SPI_BAUD_RATE ((float)CONF_GCLK_SERCOM4_CORE_FREQUENCY / (float)(2 * CONF_SERCOM_4_SPI_BAUD)) - 1
|
||||
#endif
|
||||
|
||||
#include <peripheral_clk_config.h>
|
||||
|
||||
// Enable configuration of module
|
||||
#ifndef CONF_SERCOM_6_SPI_ENABLE
|
||||
#define CONF_SERCOM_6_SPI_ENABLE 1
|
||||
#endif
|
||||
|
||||
// Set module in SPI Master mode
|
||||
#ifndef CONF_SERCOM_6_SPI_MODE
|
||||
#define CONF_SERCOM_6_SPI_MODE 0x03
|
||||
#endif
|
||||
|
||||
// <h> Basic Configuration
|
||||
|
||||
// <q> Receive buffer enable
|
||||
// <i> Enable receive buffer to receive data from slave (RXEN)
|
||||
// <id> spi_master_rx_enable
|
||||
#ifndef CONF_SERCOM_6_SPI_RXEN
|
||||
#define CONF_SERCOM_6_SPI_RXEN 0x1
|
||||
#endif
|
||||
|
||||
// <o> Character Size
|
||||
// <i> Bit size for all characters sent over the SPI bus (CHSIZE)
|
||||
// <0x0=>8 bits
|
||||
// <0x1=>9 bits
|
||||
// <id> spi_master_character_size
|
||||
#ifndef CONF_SERCOM_6_SPI_CHSIZE
|
||||
#define CONF_SERCOM_6_SPI_CHSIZE 0x0
|
||||
#endif
|
||||
// <o> Baud rate <1-18000000>
|
||||
// <i> The SPI data transfer rate
|
||||
// <id> spi_master_baud_rate
|
||||
#ifndef CONF_SERCOM_6_SPI_BAUD
|
||||
#define CONF_SERCOM_6_SPI_BAUD 1000000
|
||||
#endif
|
||||
|
||||
// </h>
|
||||
|
||||
// <e> Advanced Configuration
|
||||
// <id> spi_master_advanced
|
||||
#ifndef CONF_SERCOM_6_SPI_ADVANCED
|
||||
#define CONF_SERCOM_6_SPI_ADVANCED 1
|
||||
#endif
|
||||
|
||||
// <o> Dummy byte <0x00-0x1ff>
|
||||
// <id> spi_master_dummybyte
|
||||
// <i> Dummy byte used when reading data from the slave without sending any data
|
||||
#ifndef CONF_SERCOM_6_SPI_DUMMYBYTE
|
||||
#define CONF_SERCOM_6_SPI_DUMMYBYTE 0x1ff
|
||||
#endif
|
||||
|
||||
// <o> Data Order
|
||||
// <0=>MSB first
|
||||
// <1=>LSB first
|
||||
// <i> I least significant or most significant bit is shifted out first (DORD)
|
||||
// <id> spi_master_arch_dord
|
||||
#ifndef CONF_SERCOM_6_SPI_DORD
|
||||
#define CONF_SERCOM_6_SPI_DORD 0x0
|
||||
#endif
|
||||
|
||||
// <o> Clock Polarity
|
||||
// <0=>SCK is low when idle
|
||||
// <1=>SCK is high when idle
|
||||
// <i> Determines if the leading edge is rising or falling with a corresponding opposite edge at the trailing edge. (CPOL)
|
||||
// <id> spi_master_arch_cpol
|
||||
#ifndef CONF_SERCOM_6_SPI_CPOL
|
||||
#define CONF_SERCOM_6_SPI_CPOL 0x1
|
||||
#endif
|
||||
|
||||
// <o> Clock Phase
|
||||
// <0x0=>Sample input on leading edge
|
||||
// <0x1=>Sample input on trailing edge
|
||||
// <i> Determines if input data is sampled on leading or trailing SCK edge. (CPHA)
|
||||
// <id> spi_master_arch_cpha
|
||||
#ifndef CONF_SERCOM_6_SPI_CPHA
|
||||
#define CONF_SERCOM_6_SPI_CPHA 0x1
|
||||
#endif
|
||||
|
||||
// <o> Immediate Buffer Overflow Notification
|
||||
// <i> Controls when OVF is asserted (IBON)
|
||||
// <0x0=>In data stream
|
||||
// <0x1=>On buffer overflow
|
||||
// <id> spi_master_arch_ibon
|
||||
#ifndef CONF_SERCOM_6_SPI_IBON
|
||||
#define CONF_SERCOM_6_SPI_IBON 0x0
|
||||
#endif
|
||||
|
||||
// <q> Run in stand-by
|
||||
// <i> Module stays active in stand-by sleep mode. (RUNSTDBY)
|
||||
// <id> spi_master_arch_runstdby
|
||||
#ifndef CONF_SERCOM_6_SPI_RUNSTDBY
|
||||
#define CONF_SERCOM_6_SPI_RUNSTDBY 0x0
|
||||
#endif
|
||||
|
||||
// <o> Debug Stop Mode
|
||||
// <i> Behavior of the baud-rate generator when CPU is halted by external debugger. (DBGSTOP)
|
||||
// <0=>Keep running
|
||||
// <1=>Halt
|
||||
// <id> spi_master_arch_dbgstop
|
||||
#ifndef CONF_SERCOM_6_SPI_DBGSTOP
|
||||
#define CONF_SERCOM_6_SPI_DBGSTOP 0
|
||||
#endif
|
||||
|
||||
// </e>
|
||||
|
||||
// Address mode disabled in master mode
|
||||
#ifndef CONF_SERCOM_6_SPI_AMODE_EN
|
||||
#define CONF_SERCOM_6_SPI_AMODE_EN 0
|
||||
#endif
|
||||
|
||||
#ifndef CONF_SERCOM_6_SPI_AMODE
|
||||
#define CONF_SERCOM_6_SPI_AMODE 0
|
||||
#endif
|
||||
|
||||
#ifndef CONF_SERCOM_6_SPI_ADDR
|
||||
#define CONF_SERCOM_6_SPI_ADDR 0
|
||||
#endif
|
||||
|
||||
#ifndef CONF_SERCOM_6_SPI_ADDRMASK
|
||||
#define CONF_SERCOM_6_SPI_ADDRMASK 0
|
||||
#endif
|
||||
|
||||
#ifndef CONF_SERCOM_6_SPI_SSDE
|
||||
#define CONF_SERCOM_6_SPI_SSDE 0
|
||||
#endif
|
||||
|
||||
#ifndef CONF_SERCOM_6_SPI_MSSEN
|
||||
#define CONF_SERCOM_6_SPI_MSSEN 0x0
|
||||
#endif
|
||||
|
||||
#ifndef CONF_SERCOM_6_SPI_PLOADEN
|
||||
#define CONF_SERCOM_6_SPI_PLOADEN 0
|
||||
#endif
|
||||
|
||||
// <o> Receive Data Pinout
|
||||
// <0x0=>PAD[0]
|
||||
// <0x1=>PAD[1]
|
||||
// <0x2=>PAD[2]
|
||||
// <0x3=>PAD[3]
|
||||
// <id> spi_master_rxpo
|
||||
#ifndef CONF_SERCOM_6_SPI_RXPO
|
||||
#define CONF_SERCOM_6_SPI_RXPO 3
|
||||
#endif
|
||||
|
||||
// <o> Transmit Data Pinout
|
||||
// <0x0=>PAD[0,1]_DO_SCK
|
||||
// <0x1=>PAD[2,3]_DO_SCK
|
||||
// <0x2=>PAD[3,1]_DO_SCK
|
||||
// <0x3=>PAD[0,3]_DO_SCK
|
||||
// <id> spi_master_txpo
|
||||
#ifndef CONF_SERCOM_6_SPI_TXPO
|
||||
#define CONF_SERCOM_6_SPI_TXPO 0
|
||||
#endif
|
||||
|
||||
// Calculate baud register value from requested baudrate value
|
||||
#ifndef CONF_SERCOM_6_SPI_BAUD_RATE
|
||||
#define CONF_SERCOM_6_SPI_BAUD_RATE ((float)CONF_GCLK_SERCOM6_CORE_FREQUENCY / (float)(2 * CONF_SERCOM_6_SPI_BAUD)) - 1
|
||||
#endif
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
#endif // HPL_SERCOM_CONFIG_H
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
/* Auto-generated config file hpl_tc_config.h */
|
||||
#ifndef HPL_TC_CONFIG_H
|
||||
#define HPL_TC_CONFIG_H
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
#ifndef CONF_TC0_ENABLE
|
||||
#define CONF_TC0_ENABLE 1
|
||||
#endif
|
||||
|
||||
#include "peripheral_clk_config.h"
|
||||
|
||||
// <h> Basic configuration
|
||||
|
||||
// <o> Prescaler
|
||||
// <0x0=> No division
|
||||
// <0x1=> Divide by 2
|
||||
// <0x2=> Divide by 4
|
||||
// <0x3=> Divide by 8
|
||||
// <0x4=> Divide by 16
|
||||
// <0x5=> Divide by 64
|
||||
// <0x6=> Divide by 256
|
||||
// <0x7=> Divide by 1024
|
||||
// <i> This defines the prescaler value
|
||||
// <id> timer_prescaler
|
||||
#ifndef CONF_TC0_PRESCALER
|
||||
#define CONF_TC0_PRESCALER 0x3
|
||||
#endif
|
||||
|
||||
// <o> Length of one timer tick in uS <0-4294967295>
|
||||
// <id> timer_tick
|
||||
#ifndef CONF_TC0_TIMER_TICK
|
||||
#define CONF_TC0_TIMER_TICK 1000
|
||||
#endif
|
||||
// </h>
|
||||
|
||||
// <e> Advanced configuration
|
||||
// <id> timer_advanced_configuration
|
||||
#ifndef CONF_TC0__ADVANCED_CONFIGURATION_ENABLE
|
||||
#define CONF_TC0__ADVANCED_CONFIGURATION_ENABLE 0
|
||||
#endif
|
||||
|
||||
// <y> Prescaler and Counter Synchronization Selection
|
||||
// <TC_CTRLA_PRESCSYNC_GCLK_Val"> Reload or reset counter on next GCLK
|
||||
// <TC_CTRLA_PRESCSYNC_PRESC_Val"> Reload or reset counter on next prescaler clock
|
||||
// <TC_CTRLA_PRESCSYNC_RESYNC_Val"> Reload or reset counter on next GCLK and reset prescaler counter
|
||||
// <i> These bits select if on retrigger event, the Counter should be cleared or reloaded on the next GCLK_TCx clock or on the next prescaled GCLK_TCx clock.
|
||||
// <id> tc_arch_presync
|
||||
#ifndef CONF_TC0_PRESCSYNC
|
||||
#define CONF_TC0_PRESCSYNC TC_CTRLA_PRESCSYNC_GCLK_Val
|
||||
#endif
|
||||
|
||||
// <q> Run in standby
|
||||
// <i> Indicates whether the module will continue to run in standby sleep mode
|
||||
// <id> tc_arch_runstdby
|
||||
#ifndef CONF_TC0_RUNSTDBY
|
||||
#define CONF_TC0_RUNSTDBY 0
|
||||
#endif
|
||||
|
||||
// <q> Run in debug mode
|
||||
// <i> Indicates whether the module will run in debug mode
|
||||
// <id> tc_arch_dbgrun
|
||||
#ifndef CONF_TC0_DBGRUN
|
||||
#define CONF_TC0_DBGRUN 0
|
||||
#endif
|
||||
|
||||
// <q> Run on demand
|
||||
// <i> Run if requested by some other peripheral in the device
|
||||
// <id> tc_arch_ondemand
|
||||
#ifndef CONF_TC0_ONDEMAND
|
||||
#define CONF_TC0_ONDEMAND 0
|
||||
#endif
|
||||
|
||||
// </e>
|
||||
|
||||
// <e> Event control
|
||||
// <id> timer_event_control
|
||||
#ifndef CONF_TC0_EVENT_CONTROL_ENABLE
|
||||
#define CONF_TC0_EVENT_CONTROL_ENABLE 1
|
||||
#endif
|
||||
|
||||
// <q> Output Event On Match or Capture on Channel 0
|
||||
// <i> Enable output of event on timer tick
|
||||
// <id> tc_arch_mceo0
|
||||
#ifndef CONF_TC0_MCEO0
|
||||
#define CONF_TC0_MCEO0 0
|
||||
#endif
|
||||
|
||||
// <q> Output Event On Match or Capture on Channel 1
|
||||
// <i> Enable output of event on timer tick
|
||||
// <id> tc_arch_mceo1
|
||||
#ifndef CONF_TC0_MCEO1
|
||||
#define CONF_TC0_MCEO1 0
|
||||
#endif
|
||||
|
||||
// <q> Output Event On Timer Tick
|
||||
// <i> Enable output of event on timer tick
|
||||
// <id> tc_arch_ovfeo
|
||||
#ifndef CONF_TC0_OVFEO
|
||||
#define CONF_TC0_OVFEO 0
|
||||
#endif
|
||||
|
||||
// <q> Event Input
|
||||
// <i> Enable asynchronous input events
|
||||
// <id> tc_arch_tcei
|
||||
#ifndef CONF_TC0_TCEI
|
||||
#define CONF_TC0_TCEI 0
|
||||
#endif
|
||||
|
||||
// <q> Inverted Event Input
|
||||
// <i> Invert the asynchronous input events
|
||||
// <id> tc_arch_tcinv
|
||||
#ifndef CONF_TC0_TCINV
|
||||
#define CONF_TC0_TCINV 0
|
||||
#endif
|
||||
|
||||
// <o> Event action
|
||||
// <0=> Event action disabled
|
||||
// <1=> Start, restart or re-trigger TC on event
|
||||
// <2=> Count on event
|
||||
// <3=> Start on event
|
||||
// <4=> Time stamp capture
|
||||
// <5=> Period captured in CC0, pulse width in CC1
|
||||
// <6=> Period captured in CC1, pulse width in CC0
|
||||
// <7=> Pulse width capture
|
||||
// <i> Event which will be performed on an event
|
||||
//<id> tc_arch_evact
|
||||
#ifndef CONF_TC0_EVACT
|
||||
#define CONF_TC0_EVACT 0
|
||||
#endif
|
||||
// </e>
|
||||
|
||||
// Default values which the driver needs in order to work correctly
|
||||
|
||||
// Mode set to 32-bit
|
||||
#ifndef CONF_TC0_MODE
|
||||
#define CONF_TC0_MODE TC_CTRLA_MODE_COUNT32_Val
|
||||
#endif
|
||||
|
||||
// CC 1 register set to 0
|
||||
#ifndef CONF_TC0_CC1
|
||||
#define CONF_TC0_CC1 0
|
||||
#endif
|
||||
|
||||
#ifndef CONF_TC0_ALOCK
|
||||
#define CONF_TC0_ALOCK 0
|
||||
#endif
|
||||
|
||||
// Not used in 32-bit mode
|
||||
#define CONF_TC0_PER 0
|
||||
|
||||
// Calculating correct top value based on requested tick interval.
|
||||
#define CONF_TC0_PRESCALE (1 << CONF_TC0_PRESCALER)
|
||||
|
||||
// Prescaler set to 64
|
||||
#if CONF_TC0_PRESCALER > 0x4
|
||||
#undef CONF_TC0_PRESCALE
|
||||
#define CONF_TC0_PRESCALE 64
|
||||
#endif
|
||||
|
||||
// Prescaler set to 256
|
||||
#if CONF_TC0_PRESCALER > 0x5
|
||||
#undef CONF_TC0_PRESCALE
|
||||
#define CONF_TC0_PRESCALE 256
|
||||
#endif
|
||||
|
||||
// Prescaler set to 1024
|
||||
#if CONF_TC0_PRESCALER > 0x6
|
||||
#undef CONF_TC0_PRESCALE
|
||||
#define CONF_TC0_PRESCALE 1024
|
||||
#endif
|
||||
|
||||
#ifndef CONF_TC0_CC0
|
||||
#define CONF_TC0_CC0 \
|
||||
(uint32_t)(((float)CONF_TC0_TIMER_TICK / 1000000.f) / (1.f / (CONF_GCLK_TC0_FREQUENCY / CONF_TC0_PRESCALE)))
|
||||
#endif
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
#endif // HPL_TC_CONFIG_H
|
||||
@@ -664,6 +664,86 @@
|
||||
#define CONF_GCLK_SERCOM4_SLOW_FREQUENCY 32768
|
||||
#endif
|
||||
|
||||
// <y> Core Clock Source
|
||||
// <id> core_gclk_selection
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK0_Val"> Generic clock generator 0
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK1_Val"> Generic clock generator 1
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK2_Val"> Generic clock generator 2
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK3_Val"> Generic clock generator 3
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK4_Val"> Generic clock generator 4
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK5_Val"> Generic clock generator 5
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK6_Val"> Generic clock generator 6
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK7_Val"> Generic clock generator 7
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK8_Val"> Generic clock generator 8
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK9_Val"> Generic clock generator 9
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK10_Val"> Generic clock generator 10
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK11_Val"> Generic clock generator 11
|
||||
|
||||
// <i> Select the clock source for CORE.
|
||||
#ifndef CONF_GCLK_SERCOM6_CORE_SRC
|
||||
#define CONF_GCLK_SERCOM6_CORE_SRC GCLK_PCHCTRL_GEN_GCLK0_Val
|
||||
#endif
|
||||
|
||||
// <y> Slow Clock Source
|
||||
// <id> slow_gclk_selection
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK0_Val"> Generic clock generator 0
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK1_Val"> Generic clock generator 1
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK2_Val"> Generic clock generator 2
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK3_Val"> Generic clock generator 3
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK4_Val"> Generic clock generator 4
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK5_Val"> Generic clock generator 5
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK6_Val"> Generic clock generator 6
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK7_Val"> Generic clock generator 7
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK8_Val"> Generic clock generator 8
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK9_Val"> Generic clock generator 9
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK10_Val"> Generic clock generator 10
|
||||
|
||||
// <GCLK_PCHCTRL_GEN_GCLK11_Val"> Generic clock generator 11
|
||||
|
||||
// <i> Select the slow clock source.
|
||||
#ifndef CONF_GCLK_SERCOM6_SLOW_SRC
|
||||
#define CONF_GCLK_SERCOM6_SLOW_SRC GCLK_PCHCTRL_GEN_GCLK3_Val
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def CONF_GCLK_SERCOM6_CORE_FREQUENCY
|
||||
* \brief SERCOM6's Core Clock frequency
|
||||
*/
|
||||
#ifndef CONF_GCLK_SERCOM6_CORE_FREQUENCY
|
||||
#define CONF_GCLK_SERCOM6_CORE_FREQUENCY 12000000
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def CONF_GCLK_SERCOM6_SLOW_FREQUENCY
|
||||
* \brief SERCOM6's Slow Clock frequency
|
||||
*/
|
||||
#ifndef CONF_GCLK_SERCOM6_SLOW_FREQUENCY
|
||||
#define CONF_GCLK_SERCOM6_SLOW_FREQUENCY 32768
|
||||
#endif
|
||||
|
||||
// <y> TC Clock Source
|
||||
// <id> tc_gclk_selection
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
<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_dma.h" IsConfig="false" Hash="MRP9iaBaY97VrZIf+yI+nQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_spi_m_sync.h" IsConfig="false" Hash="2oma6hRMCcowUy2wVveqMg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/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" />
|
||||
@@ -147,22 +148,27 @@
|
||||
<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="fEng6McsWFklpCbIjKrIjw" />
|
||||
<AcmeProjectActionInfo Action="File" Source="driver_init.h" IsConfig="false" Hash="4dqeaMMK6gNiOW3IQ7EmsA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="atmel_start_pins.h" IsConfig="false" Hash="A1Tog62YLWQY9uxAyXioGw" />
|
||||
<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="driver_init.c" IsConfig="false" Hash="QBUqwpCJeyoGSxNrCUcclw" />
|
||||
<AcmeProjectActionInfo Action="File" Source="driver_init.h" IsConfig="false" Hash="p9Zx2ca3FBTVOqvkIPG77g" />
|
||||
<AcmeProjectActionInfo Action="File" Source="atmel_start_pins.h" IsConfig="false" Hash="DJf/0MMtvERgtsQEJaEkOw" />
|
||||
<AcmeProjectActionInfo Action="File" Source="examples/driver_examples.h" IsConfig="false" Hash="zm/3WWETmRyjIGoVj5URVA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="examples/driver_examples.c" IsConfig="false" Hash="QuMSe9l6cVgZttwFD+4Qnw" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hal_timer.h" IsConfig="false" Hash="5pZVthtMl40VMvofOld2ng" />
|
||||
<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_pwm.h" IsConfig="false" Hash="1wL9C0Z542rKOnnyJpZ7Yg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_reset.h" IsConfig="false" Hash="WwLFRlBtuZ/qnD1JuDKnRQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_spi_m_async.h" IsConfig="false" Hash="JyMw9jeJO0jGqfT03txHXQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_spi_m_dma.h" IsConfig="false" Hash="OoU5yflSLAc5VbWSzixnvg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_spi_m_sync.h" IsConfig="false" Hash="s1GhyLjhjIsfqixooG3LFA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_spi_s_async.h" IsConfig="false" Hash="ptPiaJ1lVqH5794NmOHDFQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_spi_s_sync.h" IsConfig="false" Hash="gEGr6GqKbsOQvxQYz2fotA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/include/hpl_timer.h" IsConfig="false" Hash="s/0PW0pyF4MQIYZJ6S0wyA" />
|
||||
<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_dma.c" IsConfig="false" Hash="KMrinO/3xx7qWxy2PsJB7g" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/src/hal_spi_m_sync.c" IsConfig="false" Hash="Q0IudnTEWeoIkfQIoYIqxA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hal/src/hal_timer.c" IsConfig="false" Hash="F2MrEXhHq4umI9xpONnlGg" />
|
||||
<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" />
|
||||
@@ -181,8 +187,8 @@
|
||||
<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="hcMq5dgdlyb9xXr1YOQnMQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/tc/tc_lite.c" IsConfig="false" Hash="h3lF0y7cJM1yyFbWGx7QkQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/tc/tc_lite.h" IsConfig="false" Hash="Gzd12xGkTZwkQmCYoTHN6Q" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/tc/hpl_tc.c" IsConfig="false" Hash="K821n7/OyoUvRDBdLUvZmg" />
|
||||
<AcmeProjectActionInfo Action="File" Source="hpl/tc/hpl_tc_base.h" IsConfig="false" Hash="gjj5IyaZPy6sUReifzS1GQ" />
|
||||
<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" />
|
||||
@@ -195,8 +201,9 @@
|
||||
<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="gJ8Gplj+AF/VaB/y7//74w" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/peripheral_clk_config.h" IsConfig="true" Hash="9F6jT6g2yhmqyb5sOdX/8w" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/hpl_sercom_config.h" IsConfig="true" Hash="ss6xeOYJNFcqMSETGiWYJA" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/hpl_tc_config.h" IsConfig="true" Hash="ih4+DqJB6yYatFzAZs7wXQ" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/peripheral_clk_config.h" IsConfig="true" Hash="4/cCayiNQ3Qa9WFHxg1Vog" />
|
||||
<AcmeProjectActionInfo Action="File" Source="config/stdio_redirect_config.h" IsConfig="true" Hash="CKmkBk12sfr7mb+HRQBuzg" />
|
||||
</AcmeActionInfos>
|
||||
<NonsecureFilesInfo />
|
||||
@@ -429,6 +436,12 @@
|
||||
</ToolchainSettings>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="A1335.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="A1335.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="atmel_start.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
@@ -465,6 +478,9 @@
|
||||
<Compile Include="Config\hpl_sercom_config.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Config\hpl_tc_config.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Config\peripheral_clk_config.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
@@ -519,6 +535,12 @@
|
||||
<Compile Include="hal\include\hal_spi_m_dma.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hal\include\hal_spi_m_sync.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hal\include\hal_timer.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hal\include\hal_usart_sync.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
@@ -561,6 +583,9 @@
|
||||
<Compile Include="hal\include\hpl_missing_features.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hal\include\hpl_pwm.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hal\include\hpl_ramecc.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
@@ -597,6 +622,9 @@
|
||||
<Compile Include="hal\include\hpl_spi_s_sync.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hal\include\hpl_timer.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hal\include\hpl_usart.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
@@ -633,6 +661,12 @@
|
||||
<Compile Include="hal\src\hal_spi_m_dma.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hal\src\hal_spi_m_sync.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hal\src\hal_timer.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hal\src\hal_usart_sync.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
@@ -726,10 +760,10 @@
|
||||
<Compile Include="hpl\sercom\hpl_sercom.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hpl\tc\tc_lite.c">
|
||||
<Compile Include="hpl\tc\hpl_tc.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hpl\tc\tc_lite.h">
|
||||
<Compile Include="hpl\tc\hpl_tc_base.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hri\hri_ac_e54.h">
|
||||
@@ -887,7 +921,6 @@
|
||||
<Folder Include="hpl\cmcc\" />
|
||||
<Folder Include="hpl\core\" />
|
||||
<Folder Include="hpl\dmac\" />
|
||||
<Folder Include="hpl\doc_lite\" />
|
||||
<Folder Include="hpl\evsys\" />
|
||||
<Folder Include="hpl\gclk\" />
|
||||
<Folder Include="hpl\mclk\" />
|
||||
@@ -918,10 +951,13 @@
|
||||
<None Include="hal\documentation\spi_master_dma.rst">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="hal\documentation\usart_sync.rst">
|
||||
<None Include="hal\documentation\spi_master_sync.rst">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="hpl\doc_lite\tc.rst">
|
||||
<None Include="hal\documentation\timer.rst">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="hal\documentation\usart_sync.rst">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -33,5 +33,9 @@
|
||||
#define PB27 GPIO(GPIO_PORTB, 27)
|
||||
#define SPI_CS GPIO(GPIO_PORTB, 28)
|
||||
#define PB29 GPIO(GPIO_PORTB, 29)
|
||||
#define PC04 GPIO(GPIO_PORTC, 4)
|
||||
#define PC05 GPIO(GPIO_PORTC, 5)
|
||||
#define Angle_SS GPIO(GPIO_PORTC, 6)
|
||||
#define PC07 GPIO(GPIO_PORTC, 7)
|
||||
|
||||
#endif // ATMEL_START_PINS_H_INCLUDED
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
#include <utils.h>
|
||||
#include <hal_init.h>
|
||||
|
||||
struct spi_m_sync_descriptor SPI_1;
|
||||
struct timer_descriptor TIMER_0;
|
||||
|
||||
struct usart_sync_descriptor TARGET_IO;
|
||||
|
||||
struct spi_m_dma_descriptor SPI_0;
|
||||
@@ -103,12 +106,73 @@ void SPI_0_init(void)
|
||||
SPI_0_PORT_init();
|
||||
}
|
||||
|
||||
void TIMER_0_CLOCK_init(void)
|
||||
void SPI_1_PORT_init(void)
|
||||
{
|
||||
|
||||
gpio_set_pin_level(PC04,
|
||||
// <y> Initial level
|
||||
// <id> pad_initial_level
|
||||
// <false"> Low
|
||||
// <true"> High
|
||||
false);
|
||||
|
||||
// Set pin direction to output
|
||||
gpio_set_pin_direction(PC04, GPIO_DIRECTION_OUT);
|
||||
|
||||
gpio_set_pin_function(PC04, PINMUX_PC04C_SERCOM6_PAD0);
|
||||
|
||||
gpio_set_pin_level(PC05,
|
||||
// <y> Initial level
|
||||
// <id> pad_initial_level
|
||||
// <false"> Low
|
||||
// <true"> High
|
||||
false);
|
||||
|
||||
// Set pin direction to output
|
||||
gpio_set_pin_direction(PC05, GPIO_DIRECTION_OUT);
|
||||
|
||||
gpio_set_pin_function(PC05, PINMUX_PC05C_SERCOM6_PAD1);
|
||||
|
||||
// Set pin direction to input
|
||||
gpio_set_pin_direction(PC07, GPIO_DIRECTION_IN);
|
||||
|
||||
gpio_set_pin_pull_mode(PC07,
|
||||
// <y> Pull configuration
|
||||
// <id> pad_pull_config
|
||||
// <GPIO_PULL_OFF"> Off
|
||||
// <GPIO_PULL_UP"> Pull-up
|
||||
// <GPIO_PULL_DOWN"> Pull-down
|
||||
GPIO_PULL_OFF);
|
||||
|
||||
gpio_set_pin_function(PC07, PINMUX_PC07C_SERCOM6_PAD3);
|
||||
}
|
||||
|
||||
void SPI_1_CLOCK_init(void)
|
||||
{
|
||||
hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM6_GCLK_ID_CORE, CONF_GCLK_SERCOM6_CORE_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
||||
hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM6_GCLK_ID_SLOW, CONF_GCLK_SERCOM6_SLOW_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
||||
|
||||
hri_mclk_set_APBDMASK_SERCOM6_bit(MCLK);
|
||||
}
|
||||
|
||||
void SPI_1_init(void)
|
||||
{
|
||||
SPI_1_CLOCK_init();
|
||||
spi_m_sync_init(&SPI_1, SERCOM6);
|
||||
SPI_1_PORT_init();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Timer initialization function
|
||||
*
|
||||
* Enables Timer peripheral, clocks and initializes Timer driver
|
||||
*/
|
||||
static void TIMER_0_init(void)
|
||||
{
|
||||
hri_mclk_set_APBAMASK_TC0_bit(MCLK);
|
||||
|
||||
hri_mclk_set_APBAMASK_TC1_bit(MCLK);
|
||||
hri_gclk_write_PCHCTRL_reg(GCLK, TC0_GCLK_ID, CONF_GCLK_TC0_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
||||
|
||||
timer_init(&TIMER_0, TC0, _tc_get_timer());
|
||||
}
|
||||
|
||||
void system_init(void)
|
||||
@@ -129,13 +193,27 @@ void system_init(void)
|
||||
|
||||
gpio_set_pin_function(SPI_CS, GPIO_PIN_FUNCTION_OFF);
|
||||
|
||||
// GPIO on PC06
|
||||
|
||||
gpio_set_pin_level(Angle_SS,
|
||||
// <y> Initial level
|
||||
// <id> pad_initial_level
|
||||
// <false"> Low
|
||||
// <true"> High
|
||||
true);
|
||||
|
||||
// Set pin direction to output
|
||||
gpio_set_pin_direction(Angle_SS, GPIO_DIRECTION_OUT);
|
||||
|
||||
gpio_set_pin_function(Angle_SS, GPIO_PIN_FUNCTION_OFF);
|
||||
|
||||
EVENT_SYSTEM_0_init();
|
||||
|
||||
TARGET_IO_init();
|
||||
|
||||
SPI_0_init();
|
||||
|
||||
TIMER_0_CLOCK_init();
|
||||
SPI_1_init();
|
||||
|
||||
TIMER_0_init();
|
||||
}
|
||||
|
||||
@@ -26,11 +26,15 @@ extern "C" {
|
||||
#include <hal_usart_sync.h>
|
||||
|
||||
#include <hal_spi_m_dma.h>
|
||||
#include <tc_lite.h>
|
||||
#include <hal_spi_m_sync.h>
|
||||
#include <hal_timer.h>
|
||||
#include <hpl_tc_base.h>
|
||||
|
||||
extern struct usart_sync_descriptor TARGET_IO;
|
||||
|
||||
extern struct spi_m_dma_descriptor SPI_0;
|
||||
extern struct spi_m_dma_descriptor SPI_0;
|
||||
extern struct spi_m_sync_descriptor SPI_1;
|
||||
extern struct timer_descriptor TIMER_0;
|
||||
|
||||
void TARGET_IO_PORT_init(void);
|
||||
void TARGET_IO_CLOCK_init(void);
|
||||
@@ -40,9 +44,9 @@ void SPI_0_PORT_init(void);
|
||||
void SPI_0_CLOCK_init(void);
|
||||
void SPI_0_init(void);
|
||||
|
||||
void TIMER_0_CLOCK_init(void);
|
||||
|
||||
int8_t TIMER_0_init(void);
|
||||
void SPI_1_PORT_init(void);
|
||||
void SPI_1_CLOCK_init(void);
|
||||
void SPI_1_init(void);
|
||||
|
||||
/**
|
||||
* \brief Perform system initialization, initialize pins and clocks for
|
||||
|
||||
@@ -47,3 +47,44 @@ void SPI_0_example(void)
|
||||
spi_m_dma_enable(&SPI_0);
|
||||
io_write(io, example_SPI_0, 12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of using SPI_1 to write "Hello World" using the IO abstraction.
|
||||
*/
|
||||
static uint8_t example_SPI_1[12] = "Hello World!";
|
||||
|
||||
void SPI_1_example(void)
|
||||
{
|
||||
struct io_descriptor *io;
|
||||
spi_m_sync_get_io_descriptor(&SPI_1, &io);
|
||||
|
||||
spi_m_sync_enable(&SPI_1);
|
||||
io_write(io, example_SPI_1, 12);
|
||||
}
|
||||
|
||||
static struct timer_task TIMER_0_task1, TIMER_0_task2;
|
||||
|
||||
/**
|
||||
* Example of using TIMER_0.
|
||||
*/
|
||||
static void TIMER_0_task1_cb(const struct timer_task *const timer_task)
|
||||
{
|
||||
}
|
||||
|
||||
static void TIMER_0_task2_cb(const struct timer_task *const timer_task)
|
||||
{
|
||||
}
|
||||
|
||||
void TIMER_0_example(void)
|
||||
{
|
||||
TIMER_0_task1.interval = 100;
|
||||
TIMER_0_task1.cb = TIMER_0_task1_cb;
|
||||
TIMER_0_task1.mode = TIMER_TASK_REPEAT;
|
||||
TIMER_0_task2.interval = 200;
|
||||
TIMER_0_task2.cb = TIMER_0_task2_cb;
|
||||
TIMER_0_task2.mode = TIMER_TASK_REPEAT;
|
||||
|
||||
timer_add_task(&TIMER_0, &TIMER_0_task1);
|
||||
timer_add_task(&TIMER_0, &TIMER_0_task2);
|
||||
timer_start(&TIMER_0);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ void TARGET_IO_example(void);
|
||||
|
||||
void SPI_0_example(void);
|
||||
|
||||
void TIMER_0_example(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
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
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
============================
|
||||
The Timer driver (bare-bone)
|
||||
============================
|
||||
|
||||
The Timer driver provides means for delayed and periodical function invocation.
|
||||
|
||||
A timer task is a piece of code (function) executed at a specific time or periodically by the timer after the task has
|
||||
been added to the timers task queue. The execution delay or period is set in ticks, where one tick is defined as a
|
||||
configurable number of clock cycles in the hardware timer. Changing the number of clock cycles in a tick automatically
|
||||
changes execution delays and periods for all tasks in the timers task queue.
|
||||
|
||||
A task has two operation modes, single-shot or repeating mode. In single-shot mode the task is removed from the task queue
|
||||
and then is executed once, in repeating mode the task reschedules itself automatically after it has executed based on
|
||||
the period set in the task configuration.
|
||||
In single-shot mode a task is removed from the task queue before its callback is invoked. It allows an application to
|
||||
reuse the memory of expired task in the callback.
|
||||
|
||||
Each instance of the Timer driver supports infinite amount of timer tasks, only limited by the amount of RAM available.
|
||||
|
||||
Features
|
||||
--------
|
||||
* Initialization and de-initialization
|
||||
* Starting and stopping
|
||||
* Timer tasks - periodical invocation of functions
|
||||
* Changing and obtaining of the period of a timer
|
||||
|
||||
Applications
|
||||
------------
|
||||
* Delayed and periodical function execution for middle-ware stacks and applications.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
* Each instance of the driver requires separate hardware timer capable of generating periodic interrupt.
|
||||
|
||||
Concurrency
|
||||
-----------
|
||||
The Timer driver is an interrupt driven driver.This means that the interrupt that triggers a task may occur during
|
||||
the process of adding or removing a task via the driver's API. In such case the interrupt processing is postponed
|
||||
until the task adding or removing is complete.
|
||||
|
||||
The task queue is not protected from the access by interrupts not used by the driver. Due to this
|
||||
it is not recommended to add or remove a task from such interrupts: in case if a higher priority interrupt supersedes
|
||||
the driver's interrupt, adding or removing a task may cause unpredictable behavior of the driver.
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
* The driver is designed to work outside of an operating system environment, the task queue is therefore processed in interrupt context which may delay execution of other interrupts.
|
||||
* If there are a lot of frequently called interrupts with the priority higher than the driver's one, it may cause delay for triggering of a task.
|
||||
|
||||
Knows issues and workarounds
|
||||
----------------------------
|
||||
Not applicable
|
||||
@@ -0,0 +1,221 @@
|
||||
/**
|
||||
* \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 */
|
||||
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief Timer task 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_TIMER_H_INCLUDED
|
||||
#define _HAL_TIMER_H_INCLUDED
|
||||
|
||||
#include <utils_list.h>
|
||||
#include <hpl_timer.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \addtogroup doc_driver_hal_timer
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Timer mode type
|
||||
*/
|
||||
enum timer_task_mode { TIMER_TASK_ONE_SHOT, TIMER_TASK_REPEAT };
|
||||
|
||||
/**
|
||||
* \brief Timer task descriptor
|
||||
*
|
||||
* The timer task descriptor forward declaration.
|
||||
*/
|
||||
struct timer_task;
|
||||
|
||||
/**
|
||||
* \brief Timer task callback function type
|
||||
*/
|
||||
typedef void (*timer_cb_t)(const struct timer_task *const timer_task);
|
||||
|
||||
/**
|
||||
* \brief Timer task structure
|
||||
*/
|
||||
struct timer_task {
|
||||
struct list_element elem; /*! List element. */
|
||||
uint32_t time_label; /*! Absolute timer start time. */
|
||||
|
||||
uint32_t interval; /*! Number of timer ticks before calling the task. */
|
||||
timer_cb_t cb; /*! Function pointer to the task. */
|
||||
enum timer_task_mode mode; /*! Task mode: one shot or repeat. */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Timer structure
|
||||
*/
|
||||
struct timer_descriptor {
|
||||
struct _timer_device device;
|
||||
uint32_t time;
|
||||
struct list_descriptor tasks; /*! Timer tasks list. */
|
||||
volatile uint8_t flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Initialize timer
|
||||
*
|
||||
* This function initializes the given timer.
|
||||
* It checks if the given hardware is not initialized and if the given hardware
|
||||
* is permitted to be initialized.
|
||||
*
|
||||
* \param[out] descr A timer descriptor to initialize
|
||||
* \param[in] hw The pointer to the hardware instance
|
||||
* \param[in] func The pointer to a set of function pointers
|
||||
*
|
||||
* \return Initialization status.
|
||||
*/
|
||||
int32_t timer_init(struct timer_descriptor *const descr, void *const hw, struct _timer_hpl_interface *const func);
|
||||
|
||||
/**
|
||||
* \brief Deinitialize timer
|
||||
*
|
||||
* This function deinitializes the given timer.
|
||||
* It checks if the given hardware is initialized and if the given hardware is
|
||||
* permitted to be deinitialized.
|
||||
*
|
||||
* \param[in] descr A timer descriptor to deinitialize
|
||||
*
|
||||
* \return De-initialization status.
|
||||
*/
|
||||
int32_t timer_deinit(struct timer_descriptor *const descr);
|
||||
|
||||
/**
|
||||
* \brief Start timer
|
||||
*
|
||||
* This function starts the given timer.
|
||||
* It checks if the given hardware is initialized.
|
||||
*
|
||||
* \param[in] descr The timer descriptor of a timer to start
|
||||
*
|
||||
* \return Timer starting status.
|
||||
*/
|
||||
int32_t timer_start(struct timer_descriptor *const descr);
|
||||
|
||||
/**
|
||||
* \brief Stop timer
|
||||
*
|
||||
* This function stops the given timer.
|
||||
* It checks if the given hardware is initialized.
|
||||
*
|
||||
* \param[in] descr The timer descriptor of a timer to stop
|
||||
*
|
||||
* \return Timer stopping status.
|
||||
*/
|
||||
int32_t timer_stop(struct timer_descriptor *const descr);
|
||||
|
||||
/**
|
||||
* \brief Set amount of clock cycles per timer tick
|
||||
*
|
||||
* This function sets the amount of clock cycles per timer tick for the given timer.
|
||||
* It checks if the given hardware is initialized.
|
||||
*
|
||||
* \param[in] descr The timer descriptor of a timer to stop
|
||||
* \param[in] clock_cycles The amount of clock cycles per tick to set
|
||||
*
|
||||
* \return Setting clock cycles amount status.
|
||||
*/
|
||||
int32_t timer_set_clock_cycles_per_tick(struct timer_descriptor *const descr, const uint32_t clock_cycles);
|
||||
|
||||
/**
|
||||
* \brief Retrieve the amount of clock cycles in a tick
|
||||
*
|
||||
* This function retrieves how many clock cycles there are in a single timer tick.
|
||||
* It checks if the given hardware is initialized.
|
||||
*
|
||||
* \param[in] descr The timer descriptor of a timer to convert ticks to
|
||||
* clock cycles
|
||||
* \param[out] cycles The amount of clock cycles
|
||||
*
|
||||
* \return The status of clock cycles retrieving.
|
||||
*/
|
||||
int32_t timer_get_clock_cycles_in_tick(const struct timer_descriptor *const descr, uint32_t *const cycles);
|
||||
|
||||
/**
|
||||
* \brief Add timer task
|
||||
*
|
||||
* This function adds the given timer task to the given timer.
|
||||
* It checks if the given hardware is initialized.
|
||||
*
|
||||
* \param[in] descr The timer descriptor of a timer to add task to
|
||||
* \param[in] task A task to add
|
||||
*
|
||||
* \return Timer's task adding status.
|
||||
*/
|
||||
int32_t timer_add_task(struct timer_descriptor *const descr, struct timer_task *const task);
|
||||
|
||||
/**
|
||||
* \brief Remove timer task
|
||||
*
|
||||
* This function removes the given timer task from the given timer.
|
||||
* It checks if the given hardware is initialized.
|
||||
*
|
||||
* \param[in] descr The timer descriptor of a timer to remove task from
|
||||
* \param[in] task A task to remove
|
||||
*
|
||||
* \return Timer's task removing status.
|
||||
*/
|
||||
int32_t timer_remove_task(struct timer_descriptor *const descr, const struct timer_task *const task);
|
||||
|
||||
/**
|
||||
* \brief Retrieve the current driver version
|
||||
*
|
||||
* \return Current driver version.
|
||||
*/
|
||||
uint32_t timer_get_version(void);
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HAL_TIMER_H_INCLUDED */
|
||||
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief PWM 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 _HPL_PWM_H_INCLUDED
|
||||
#define _HPL_PWM_H_INCLUDED
|
||||
|
||||
/**
|
||||
* \addtogroup HPL PWM
|
||||
*
|
||||
* \section hpl_pwm_rev Revision History
|
||||
* - v1.0.0 Initial Release
|
||||
*
|
||||
*@{
|
||||
*/
|
||||
|
||||
#include <compiler.h>
|
||||
#include "hpl_irq.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief PWM callback types
|
||||
*/
|
||||
enum _pwm_callback_type { PWM_DEVICE_PERIOD_CB, PWM_DEVICE_ERROR_CB };
|
||||
|
||||
/**
|
||||
* \brief PWM pulse-width period
|
||||
*/
|
||||
typedef uint32_t pwm_period_t;
|
||||
|
||||
/**
|
||||
* \brief PWM device structure
|
||||
*
|
||||
* The PWM device structure forward declaration.
|
||||
*/
|
||||
struct _pwm_device;
|
||||
|
||||
/**
|
||||
* \brief PWM interrupt callbacks
|
||||
*/
|
||||
struct _pwm_callback {
|
||||
void (*pwm_period_cb)(struct _pwm_device *device);
|
||||
void (*pwm_error_cb)(struct _pwm_device *device);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief PWM descriptor device structure
|
||||
*/
|
||||
struct _pwm_device {
|
||||
struct _pwm_callback callback;
|
||||
struct _irq_descriptor irq;
|
||||
void * hw;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief PWM functions, pointers to low-level functions
|
||||
*/
|
||||
struct _pwm_hpl_interface {
|
||||
int32_t (*init)(struct _pwm_device *const device, void *const hw);
|
||||
void (*deinit)(struct _pwm_device *const device);
|
||||
void (*start_pwm)(struct _pwm_device *const device);
|
||||
void (*stop_pwm)(struct _pwm_device *const device);
|
||||
void (*set_pwm_param)(struct _pwm_device *const device, const pwm_period_t period, const pwm_period_t duty_cycle);
|
||||
bool (*is_pwm_enabled)(const struct _pwm_device *const device);
|
||||
pwm_period_t (*pwm_get_period)(const struct _pwm_device *const device);
|
||||
uint32_t (*pwm_get_duty)(const struct _pwm_device *const device);
|
||||
void (*set_irq_state)(struct _pwm_device *const device, const enum _pwm_callback_type type, const bool disable);
|
||||
};
|
||||
/**
|
||||
* \brief Initialize TC
|
||||
*
|
||||
* This function does low level TC configuration.
|
||||
*
|
||||
* \param[in] device The pointer to PWM device instance
|
||||
* \param[in] hw The pointer to hardware instance
|
||||
*
|
||||
* \return Initialization status.
|
||||
*/
|
||||
int32_t _pwm_init(struct _pwm_device *const device, void *const hw);
|
||||
|
||||
/**
|
||||
* \brief Deinitialize TC
|
||||
*
|
||||
* \param[in] device The pointer to PWM device instance
|
||||
*/
|
||||
void _pwm_deinit(struct _pwm_device *const device);
|
||||
|
||||
/**
|
||||
* \brief Retrieve offset of the given tc hardware instance
|
||||
*
|
||||
* \param[in] device The pointer to PWM device instance
|
||||
*
|
||||
* \return The offset of the given tc hardware instance
|
||||
*/
|
||||
uint8_t _pwm_get_hardware_offset(const struct _pwm_device *const device);
|
||||
|
||||
/**
|
||||
* \brief Start hardware pwm
|
||||
*
|
||||
* \param[in] device The pointer to PWM device instance
|
||||
*/
|
||||
void _pwm_enable(struct _pwm_device *const device);
|
||||
|
||||
/**
|
||||
* \brief Stop hardware pwm
|
||||
*
|
||||
* \param[in] device The pointer to PWM device instance
|
||||
*/
|
||||
void _pwm_disable(struct _pwm_device *const device);
|
||||
|
||||
/**
|
||||
* \brief Set pwm parameter
|
||||
*
|
||||
* \param[in] device The pointer to PWM device instance
|
||||
* \param[in] period Total period of one PWM cycle.
|
||||
* \param[in] duty_cycle Period of PWM first half during one cycle.
|
||||
*/
|
||||
void _pwm_set_param(struct _pwm_device *const device, const pwm_period_t period, const pwm_period_t duty_cycle);
|
||||
|
||||
/**
|
||||
* \brief Check if pwm is working
|
||||
*
|
||||
* \param[in] device The pointer to PWM device instance
|
||||
*
|
||||
* \return Check status.
|
||||
* \retval true The given pwm is working
|
||||
* \retval false The given pwm is not working
|
||||
*/
|
||||
bool _pwm_is_enabled(const struct _pwm_device *const device);
|
||||
|
||||
/**
|
||||
* \brief Get pwm waveform period value
|
||||
*
|
||||
* \param[in] device The pointer to PWM device instance
|
||||
*
|
||||
* \return Period value.
|
||||
*/
|
||||
pwm_period_t _pwm_get_period(const struct _pwm_device *const device);
|
||||
|
||||
/**
|
||||
* \brief Get pwm waveform duty cycle value
|
||||
*
|
||||
* \param[in] device The pointer to PWM device instance
|
||||
*
|
||||
* \return Duty cycle value
|
||||
*/
|
||||
uint32_t _pwm_get_duty(const struct _pwm_device *const device);
|
||||
|
||||
/**
|
||||
* \brief Enable/disable PWM interrupt
|
||||
*
|
||||
* param[in] device The pointer to PWM device instance
|
||||
* param[in] type The type of interrupt to disable/enable if applicable
|
||||
* param[in] disable Enable or disable
|
||||
*/
|
||||
void _pwm_set_irq_state(struct _pwm_device *const device, const enum _pwm_callback_type type, const bool disable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/**@}*/
|
||||
#endif /* _HPL_PWM_H_INCLUDED */
|
||||
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief Timer 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 _HPL_TIMER_H_INCLUDED
|
||||
#define _HPL_TIMER_H_INCLUDED
|
||||
|
||||
/**
|
||||
* \addtogroup HPL Timer
|
||||
*
|
||||
* \section hpl_timer_rev Revision History
|
||||
* - v1.0.0 Initial Release
|
||||
*
|
||||
*@{
|
||||
*/
|
||||
|
||||
#include <compiler.h>
|
||||
#include <hpl_irq.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Timer device structure
|
||||
*
|
||||
* The Timer device structure forward declaration.
|
||||
*/
|
||||
struct _timer_device;
|
||||
|
||||
/**
|
||||
* \brief Timer interrupt callbacks
|
||||
*/
|
||||
struct _timer_callbacks {
|
||||
void (*period_expired)(struct _timer_device *device);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Timer device structure
|
||||
*/
|
||||
struct _timer_device {
|
||||
struct _timer_callbacks timer_cb;
|
||||
struct _irq_descriptor irq;
|
||||
void * hw;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Timer functions, pointers to low-level functions
|
||||
*/
|
||||
struct _timer_hpl_interface {
|
||||
int32_t (*init)(struct _timer_device *const device, void *const hw);
|
||||
void (*deinit)(struct _timer_device *const device);
|
||||
void (*start_timer)(struct _timer_device *const device);
|
||||
void (*stop_timer)(struct _timer_device *const device);
|
||||
void (*set_timer_period)(struct _timer_device *const device, const uint32_t clock_cycles);
|
||||
uint32_t (*get_period)(const struct _timer_device *const device);
|
||||
bool (*is_timer_started)(const struct _timer_device *const device);
|
||||
void (*set_timer_irq)(struct _timer_device *const device);
|
||||
};
|
||||
/**
|
||||
* \brief Initialize TCC
|
||||
*
|
||||
* This function does low level TCC configuration.
|
||||
*
|
||||
* \param[in] device The pointer to timer device instance
|
||||
* \param[in] hw The pointer to hardware instance
|
||||
*
|
||||
* \return Initialization status.
|
||||
*/
|
||||
int32_t _timer_init(struct _timer_device *const device, void *const hw);
|
||||
|
||||
/**
|
||||
* \brief Deinitialize TCC
|
||||
*
|
||||
* \param[in] device The pointer to timer device instance
|
||||
*/
|
||||
void _timer_deinit(struct _timer_device *const device);
|
||||
|
||||
/**
|
||||
* \brief Start hardware timer
|
||||
*
|
||||
* \param[in] device The pointer to timer device instance
|
||||
*/
|
||||
void _timer_start(struct _timer_device *const device);
|
||||
|
||||
/**
|
||||
* \brief Stop hardware timer
|
||||
*
|
||||
* \param[in] device The pointer to timer device instance
|
||||
*/
|
||||
void _timer_stop(struct _timer_device *const device);
|
||||
|
||||
/**
|
||||
* \brief Set timer period
|
||||
*
|
||||
* \param[in] device The pointer to timer device instance
|
||||
*/
|
||||
void _timer_set_period(struct _timer_device *const device, const uint32_t clock_cycles);
|
||||
|
||||
/**
|
||||
* \brief Retrieve timer period
|
||||
*
|
||||
* \param[in] device The pointer to timer device instance
|
||||
*
|
||||
* \return Timer period
|
||||
*/
|
||||
uint32_t _timer_get_period(const struct _timer_device *const device);
|
||||
|
||||
/**
|
||||
* \brief Check if timer is running
|
||||
*
|
||||
* \param[in] device The pointer to timer device instance
|
||||
*
|
||||
* \return Check status.
|
||||
* \retval true The given timer is running
|
||||
* \retval false The given timer is not running
|
||||
*/
|
||||
bool _timer_is_started(const struct _timer_device *const device);
|
||||
|
||||
/**
|
||||
* \brief Set timer IRQ
|
||||
*
|
||||
* \param[in] device The pointer to timer device instance
|
||||
*/
|
||||
void _timer_set_irq(struct _timer_device *const device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/**@}*/
|
||||
#endif /* _HPL_TIMER_H_INCLUDED */
|
||||
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* \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
|
||||
@@ -0,0 +1,250 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief Timer 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_timer.h"
|
||||
#include <utils_assert.h>
|
||||
#include <utils.h>
|
||||
#include <hal_atomic.h>
|
||||
#include <hpl_irq.h>
|
||||
|
||||
/**
|
||||
* \brief Driver version
|
||||
*/
|
||||
#define DRIVER_VERSION 0x00000001u
|
||||
|
||||
/**
|
||||
* \brief Timer flags
|
||||
*/
|
||||
#define TIMER_FLAG_QUEUE_IS_TAKEN 1
|
||||
#define TIMER_FLAG_INTERRUPT_TRIGERRED 2
|
||||
|
||||
static void timer_add_timer_task(struct list_descriptor *list, struct timer_task *const new_task, const uint32_t time);
|
||||
static void timer_process_counted(struct _timer_device *device);
|
||||
|
||||
/**
|
||||
* \brief Initialize timer
|
||||
*/
|
||||
int32_t timer_init(struct timer_descriptor *const descr, void *const hw, struct _timer_hpl_interface *const func)
|
||||
{
|
||||
ASSERT(descr && hw);
|
||||
_timer_init(&descr->device, hw);
|
||||
descr->time = 0;
|
||||
descr->device.timer_cb.period_expired = timer_process_counted;
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Deinitialize timer
|
||||
*/
|
||||
int32_t timer_deinit(struct timer_descriptor *const descr)
|
||||
{
|
||||
ASSERT(descr);
|
||||
_timer_deinit(&descr->device);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Start timer
|
||||
*/
|
||||
int32_t timer_start(struct timer_descriptor *const descr)
|
||||
{
|
||||
ASSERT(descr);
|
||||
if (_timer_is_started(&descr->device)) {
|
||||
return ERR_DENIED;
|
||||
}
|
||||
_timer_start(&descr->device);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Stop timer
|
||||
*/
|
||||
int32_t timer_stop(struct timer_descriptor *const descr)
|
||||
{
|
||||
ASSERT(descr);
|
||||
if (!_timer_is_started(&descr->device)) {
|
||||
return ERR_DENIED;
|
||||
}
|
||||
_timer_stop(&descr->device);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set amount of clock cycler per timer tick
|
||||
*/
|
||||
int32_t timer_set_clock_cycles_per_tick(struct timer_descriptor *const descr, const uint32_t clock_cycles)
|
||||
{
|
||||
ASSERT(descr);
|
||||
_timer_set_period(&descr->device, clock_cycles);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add timer task
|
||||
*/
|
||||
int32_t timer_add_task(struct timer_descriptor *const descr, struct timer_task *const task)
|
||||
{
|
||||
ASSERT(descr && task);
|
||||
|
||||
descr->flags |= TIMER_FLAG_QUEUE_IS_TAKEN;
|
||||
if (is_list_element(&descr->tasks, task)) {
|
||||
descr->flags &= ~TIMER_FLAG_QUEUE_IS_TAKEN;
|
||||
ASSERT(false);
|
||||
return ERR_ALREADY_INITIALIZED;
|
||||
}
|
||||
task->time_label = descr->time;
|
||||
timer_add_timer_task(&descr->tasks, task, descr->time);
|
||||
|
||||
descr->flags &= ~TIMER_FLAG_QUEUE_IS_TAKEN;
|
||||
if (descr->flags & TIMER_FLAG_INTERRUPT_TRIGERRED) {
|
||||
CRITICAL_SECTION_ENTER()
|
||||
descr->flags &= ~TIMER_FLAG_INTERRUPT_TRIGERRED;
|
||||
_timer_set_irq(&descr->device);
|
||||
CRITICAL_SECTION_LEAVE()
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Remove timer task
|
||||
*/
|
||||
int32_t timer_remove_task(struct timer_descriptor *const descr, const struct timer_task *const task)
|
||||
{
|
||||
ASSERT(descr && task);
|
||||
|
||||
descr->flags |= TIMER_FLAG_QUEUE_IS_TAKEN;
|
||||
if (!is_list_element(&descr->tasks, task)) {
|
||||
descr->flags &= ~TIMER_FLAG_QUEUE_IS_TAKEN;
|
||||
ASSERT(false);
|
||||
return ERR_NOT_FOUND;
|
||||
}
|
||||
list_delete_element(&descr->tasks, task);
|
||||
|
||||
descr->flags &= ~TIMER_FLAG_QUEUE_IS_TAKEN;
|
||||
if (descr->flags & TIMER_FLAG_INTERRUPT_TRIGERRED) {
|
||||
CRITICAL_SECTION_ENTER()
|
||||
descr->flags &= ~TIMER_FLAG_INTERRUPT_TRIGERRED;
|
||||
_timer_set_irq(&descr->device);
|
||||
CRITICAL_SECTION_LEAVE()
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieve the amount of clock cycles in a tick
|
||||
*/
|
||||
int32_t timer_get_clock_cycles_in_tick(const struct timer_descriptor *const descr, uint32_t *const cycles)
|
||||
{
|
||||
ASSERT(descr && cycles);
|
||||
*cycles = _timer_get_period(&descr->device);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieve the current driver version
|
||||
*/
|
||||
uint32_t timer_get_version(void)
|
||||
{
|
||||
return DRIVER_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal Insert a timer task into sorted timer's list
|
||||
*
|
||||
* \param[in] head The pointer to the head of timer task list
|
||||
* \param[in] task The pointer to task to add
|
||||
* \param[in] time Current timer time
|
||||
*/
|
||||
static void timer_add_timer_task(struct list_descriptor *list, struct timer_task *const new_task, const uint32_t time)
|
||||
{
|
||||
struct timer_task *it, *prev = NULL, *head = (struct timer_task *)list_get_head(list);
|
||||
|
||||
if (!head) {
|
||||
list_insert_as_head(list, new_task);
|
||||
return;
|
||||
}
|
||||
|
||||
for (it = head; it; it = (struct timer_task *)list_get_next_element(it)) {
|
||||
uint32_t time_left;
|
||||
|
||||
if (it->time_label <= time) {
|
||||
time_left = it->interval - (time - it->time_label);
|
||||
} else {
|
||||
time_left = it->interval - (0xFFFFFFFF - it->time_label) - time;
|
||||
}
|
||||
if (time_left >= new_task->interval)
|
||||
break;
|
||||
prev = it;
|
||||
}
|
||||
|
||||
if (it == head) {
|
||||
list_insert_as_head(list, new_task);
|
||||
} else {
|
||||
list_insert_after(prev, new_task);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal Process interrupts
|
||||
*/
|
||||
static void timer_process_counted(struct _timer_device *device)
|
||||
{
|
||||
struct timer_descriptor *timer = CONTAINER_OF(device, struct timer_descriptor, device);
|
||||
struct timer_task * it = (struct timer_task *)list_get_head(&timer->tasks);
|
||||
uint32_t time = ++timer->time;
|
||||
|
||||
if ((timer->flags & TIMER_FLAG_QUEUE_IS_TAKEN) || (timer->flags & TIMER_FLAG_INTERRUPT_TRIGERRED)) {
|
||||
timer->flags |= TIMER_FLAG_INTERRUPT_TRIGERRED;
|
||||
return;
|
||||
}
|
||||
|
||||
while (it && ((time - it->time_label) >= it->interval)) {
|
||||
struct timer_task *tmp = it;
|
||||
|
||||
list_remove_head(&timer->tasks);
|
||||
if (TIMER_TASK_REPEAT == tmp->mode) {
|
||||
tmp->time_label = time;
|
||||
timer_add_timer_task(&timer->tasks, tmp, time);
|
||||
}
|
||||
it = (struct timer_task *)list_get_head(&timer->tasks);
|
||||
|
||||
tmp->cb(tmp);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
=========
|
||||
TC driver
|
||||
=========
|
||||
The TC consists of a counter, a prescaler, compare/capture channels and control logic. The counter can be set to count events, or it can be configured to count clock pulses. The counter, together with the compare/capture channels, can be configured to timestamp input events, allowing capture of frequency and pulse width. It can also perform waveform generation, such as frequency generation and pulse-width modulation (PWM)
|
||||
|
||||
The timer/counter is clocked by the peripheral clock with optional prescaling or from the event system.
|
||||
|
||||
Features
|
||||
--------
|
||||
* Initialization
|
||||
|
||||
Applications
|
||||
------------
|
||||
* Frequency Generation
|
||||
* Single-slope PWM (pulse width modulation)
|
||||
* Dual-slope PWM
|
||||
* Count on event
|
||||
* Quadrature decoding
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
* CLK for clock
|
||||
* CPUINT/PMIC for Interrupt
|
||||
* EVSYS for events
|
||||
* UPDI/PDI/JTAG for debug
|
||||
* PORT for Waveform Generation
|
||||
|
||||
Concurrency
|
||||
-----------
|
||||
N/A
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
N/A
|
||||
|
||||
Knows issues and workarounds
|
||||
----------------------------
|
||||
N/A
|
||||
|
||||
@@ -0,0 +1,347 @@
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM TC
|
||||
*
|
||||
* 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 <hpl_pwm.h>
|
||||
#include <hpl_tc_config.h>
|
||||
#include <hpl_timer.h>
|
||||
#include <utils.h>
|
||||
#include <utils_assert.h>
|
||||
#include <hpl_tc_base.h>
|
||||
|
||||
#ifndef CONF_TC0_ENABLE
|
||||
#define CONF_TC0_ENABLE 0
|
||||
#endif
|
||||
#ifndef CONF_TC1_ENABLE
|
||||
#define CONF_TC1_ENABLE 0
|
||||
#endif
|
||||
#ifndef CONF_TC2_ENABLE
|
||||
#define CONF_TC2_ENABLE 0
|
||||
#endif
|
||||
#ifndef CONF_TC3_ENABLE
|
||||
#define CONF_TC3_ENABLE 0
|
||||
#endif
|
||||
#ifndef CONF_TC4_ENABLE
|
||||
#define CONF_TC4_ENABLE 0
|
||||
#endif
|
||||
#ifndef CONF_TC5_ENABLE
|
||||
#define CONF_TC5_ENABLE 0
|
||||
#endif
|
||||
#ifndef CONF_TC6_ENABLE
|
||||
#define CONF_TC6_ENABLE 0
|
||||
#endif
|
||||
#ifndef CONF_TC7_ENABLE
|
||||
#define CONF_TC7_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Macro is used to fill usart configuration structure based on its
|
||||
* number
|
||||
*
|
||||
* \param[in] n The number of structures
|
||||
*/
|
||||
#define TC_CONFIGURATION(n) \
|
||||
{ \
|
||||
n, TC##n##_IRQn, \
|
||||
TC_CTRLA_MODE(CONF_TC##n##_MODE) | TC_CTRLA_PRESCSYNC(CONF_TC##n##_PRESCSYNC) \
|
||||
| (CONF_TC##n##_RUNSTDBY << TC_CTRLA_RUNSTDBY_Pos) | (CONF_TC##n##_ONDEMAND << TC_CTRLA_ONDEMAND_Pos) \
|
||||
| TC_CTRLA_PRESCALER(CONF_TC##n##_PRESCALER) | (CONF_TC##n##_ALOCK << TC_CTRLA_ALOCK_Pos), \
|
||||
(CONF_TC##n##_OVFEO << TC_EVCTRL_OVFEO_Pos) | (CONF_TC##n##_TCEI << TC_EVCTRL_TCEI_Pos) \
|
||||
| (CONF_TC##n##_TCINV << TC_EVCTRL_TCINV_Pos) | (CONF_TC##n##_EVACT << TC_EVCTRL_EVACT_Pos) \
|
||||
| (CONF_TC##n##_MCEO0 << TC_EVCTRL_MCEO0_Pos) | (CONF_TC##n##_MCEO1 << TC_EVCTRL_MCEO1_Pos), \
|
||||
(CONF_TC##n##_DBGRUN << TC_DBGCTRL_DBGRUN_Pos), CONF_TC##n##_PER, CONF_TC##n##_CC0, CONF_TC##n##_CC1, \
|
||||
}
|
||||
/**
|
||||
* \brief TC configuration type
|
||||
*/
|
||||
struct tc_configuration {
|
||||
uint8_t number;
|
||||
IRQn_Type irq;
|
||||
hri_tc_ctrla_reg_t ctrl_a;
|
||||
hri_tc_evctrl_reg_t event_ctrl;
|
||||
hri_tc_dbgctrl_reg_t dbg_ctrl;
|
||||
hri_tccount8_per_reg_t per;
|
||||
hri_tccount32_cc_reg_t cc0;
|
||||
hri_tccount32_cc_reg_t cc1;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Array of TC configurations
|
||||
*/
|
||||
static struct tc_configuration _tcs[] = {
|
||||
#if CONF_TC0_ENABLE == 1
|
||||
TC_CONFIGURATION(0),
|
||||
#endif
|
||||
#if CONF_TC1_ENABLE == 1
|
||||
TC_CONFIGURATION(1),
|
||||
#endif
|
||||
#if CONF_TC2_ENABLE == 1
|
||||
TC_CONFIGURATION(2),
|
||||
#endif
|
||||
#if CONF_TC3_ENABLE == 1
|
||||
TC_CONFIGURATION(3),
|
||||
#endif
|
||||
#if CONF_TC4_ENABLE == 1
|
||||
TC_CONFIGURATION(4),
|
||||
#endif
|
||||
#if CONF_TC5_ENABLE == 1
|
||||
TC_CONFIGURATION(5),
|
||||
#endif
|
||||
#if CONF_TC6_ENABLE == 1
|
||||
TC_CONFIGURATION(6),
|
||||
#endif
|
||||
#if CONF_TC7_ENABLE == 1
|
||||
TC_CONFIGURATION(7),
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct _timer_device *_tc0_dev = NULL;
|
||||
|
||||
static int8_t get_tc_index(const void *const hw);
|
||||
static void _tc_init_irq_param(const void *const hw, void *dev);
|
||||
static inline uint8_t _get_hardware_offset(const void *const hw);
|
||||
/**
|
||||
* \brief Initialize TC
|
||||
*/
|
||||
int32_t _timer_init(struct _timer_device *const device, void *const hw)
|
||||
{
|
||||
int8_t i = get_tc_index(hw);
|
||||
|
||||
device->hw = hw;
|
||||
ASSERT(ARRAY_SIZE(_tcs));
|
||||
|
||||
if (!hri_tc_is_syncing(hw, TC_SYNCBUSY_SWRST)) {
|
||||
if (hri_tc_get_CTRLA_reg(hw, TC_CTRLA_ENABLE)) {
|
||||
hri_tc_clear_CTRLA_ENABLE_bit(hw);
|
||||
hri_tc_wait_for_sync(hw, TC_SYNCBUSY_ENABLE);
|
||||
}
|
||||
hri_tc_write_CTRLA_reg(hw, TC_CTRLA_SWRST);
|
||||
}
|
||||
hri_tc_wait_for_sync(hw, TC_SYNCBUSY_SWRST);
|
||||
|
||||
hri_tc_write_CTRLA_reg(hw, _tcs[i].ctrl_a);
|
||||
hri_tc_write_DBGCTRL_reg(hw, _tcs[i].dbg_ctrl);
|
||||
hri_tc_write_EVCTRL_reg(hw, _tcs[i].event_ctrl);
|
||||
hri_tc_write_WAVE_reg(hw, TC_WAVE_WAVEGEN_MFRQ);
|
||||
|
||||
if ((_tcs[i].ctrl_a & TC_CTRLA_MODE_Msk) == TC_CTRLA_MODE_COUNT32) {
|
||||
hri_tccount32_write_CC_reg(hw, 0, _tcs[i].cc0);
|
||||
hri_tccount32_write_CC_reg(hw, 1, _tcs[i].cc1);
|
||||
|
||||
} else if ((_tcs[i].ctrl_a & TC_CTRLA_MODE_Msk) == TC_CTRLA_MODE_COUNT16) {
|
||||
hri_tccount16_write_CC_reg(hw, 0, (uint16_t)_tcs[i].cc0);
|
||||
hri_tccount16_write_CC_reg(hw, 1, (uint16_t)_tcs[i].cc1);
|
||||
|
||||
} else if ((_tcs[i].ctrl_a & TC_CTRLA_MODE_Msk) == TC_CTRLA_MODE_COUNT8) {
|
||||
hri_tccount8_write_CC_reg(hw, 0, (uint8_t)_tcs[i].cc0);
|
||||
hri_tccount8_write_CC_reg(hw, 1, (uint8_t)_tcs[i].cc1);
|
||||
hri_tccount8_write_PER_reg(hw, _tcs[i].per);
|
||||
}
|
||||
hri_tc_set_INTEN_OVF_bit(hw);
|
||||
|
||||
_tc_init_irq_param(hw, (void *)device);
|
||||
NVIC_DisableIRQ(_tcs[i].irq);
|
||||
NVIC_ClearPendingIRQ(_tcs[i].irq);
|
||||
NVIC_EnableIRQ(_tcs[i].irq);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
/**
|
||||
* \brief De-initialize TC
|
||||
*/
|
||||
void _timer_deinit(struct _timer_device *const device)
|
||||
{
|
||||
void *const hw = device->hw;
|
||||
int8_t i = get_tc_index(hw);
|
||||
ASSERT(ARRAY_SIZE(_tcs));
|
||||
|
||||
NVIC_DisableIRQ(_tcs[i].irq);
|
||||
|
||||
hri_tc_clear_CTRLA_ENABLE_bit(hw);
|
||||
hri_tc_set_CTRLA_SWRST_bit(hw);
|
||||
}
|
||||
/**
|
||||
* \brief Start hardware timer
|
||||
*/
|
||||
void _timer_start(struct _timer_device *const device)
|
||||
{
|
||||
hri_tc_set_CTRLA_ENABLE_bit(device->hw);
|
||||
}
|
||||
/**
|
||||
* \brief Stop hardware timer
|
||||
*/
|
||||
void _timer_stop(struct _timer_device *const device)
|
||||
{
|
||||
hri_tc_clear_CTRLA_ENABLE_bit(device->hw);
|
||||
}
|
||||
/**
|
||||
* \brief Set timer period
|
||||
*/
|
||||
void _timer_set_period(struct _timer_device *const device, const uint32_t clock_cycles)
|
||||
{
|
||||
void *const hw = device->hw;
|
||||
|
||||
if (TC_CTRLA_MODE_COUNT32_Val == hri_tc_read_CTRLA_MODE_bf(hw)) {
|
||||
hri_tccount32_write_CC_reg(hw, 0, clock_cycles);
|
||||
} else if (TC_CTRLA_MODE_COUNT16_Val == hri_tc_read_CTRLA_MODE_bf(hw)) {
|
||||
hri_tccount16_write_CC_reg(hw, 0, (uint16_t)clock_cycles);
|
||||
} else if (TC_CTRLA_MODE_COUNT8_Val == hri_tc_read_CTRLA_MODE_bf(hw)) {
|
||||
hri_tccount8_write_PER_reg(hw, clock_cycles);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief Retrieve timer period
|
||||
*/
|
||||
uint32_t _timer_get_period(const struct _timer_device *const device)
|
||||
{
|
||||
void *const hw = device->hw;
|
||||
|
||||
if (TC_CTRLA_MODE_COUNT32_Val == hri_tc_read_CTRLA_MODE_bf(hw)) {
|
||||
return hri_tccount32_read_CC_reg(hw, 0);
|
||||
} else if (TC_CTRLA_MODE_COUNT16_Val == hri_tc_read_CTRLA_MODE_bf(hw)) {
|
||||
return hri_tccount16_read_CC_reg(hw, 0);
|
||||
} else if (TC_CTRLA_MODE_COUNT8_Val == hri_tc_read_CTRLA_MODE_bf(hw)) {
|
||||
return hri_tccount8_read_PER_reg(hw);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* \brief Check if timer is running
|
||||
*/
|
||||
bool _timer_is_started(const struct _timer_device *const device)
|
||||
{
|
||||
return hri_tc_get_CTRLA_ENABLE_bit(device->hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieve timer helper functions
|
||||
*/
|
||||
struct _timer_hpl_interface *_tc_get_timer(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieve pwm helper functions
|
||||
*/
|
||||
struct _pwm_hpl_interface *_tc_get_pwm(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
/**
|
||||
* \brief Set timer IRQ
|
||||
*
|
||||
* \param[in] hw The pointer to hardware instance
|
||||
*/
|
||||
void _timer_set_irq(struct _timer_device *const device)
|
||||
{
|
||||
void *const hw = device->hw;
|
||||
int8_t i = get_tc_index(hw);
|
||||
ASSERT(ARRAY_SIZE(_tcs));
|
||||
|
||||
_irq_set(_tcs[i].irq);
|
||||
}
|
||||
/**
|
||||
* \internal TC interrupt handler for Timer
|
||||
*
|
||||
* \param[in] instance TC instance number
|
||||
*/
|
||||
static void tc_interrupt_handler(struct _timer_device *device)
|
||||
{
|
||||
void *const hw = device->hw;
|
||||
|
||||
if (hri_tc_get_interrupt_OVF_bit(hw)) {
|
||||
hri_tc_clear_interrupt_OVF_bit(hw);
|
||||
device->timer_cb.period_expired(device);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief TC interrupt handler
|
||||
*/
|
||||
void TC0_Handler(void)
|
||||
{
|
||||
tc_interrupt_handler(_tc0_dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal Retrieve TC index
|
||||
*
|
||||
* \param[in] hw The pointer to hardware instance
|
||||
*
|
||||
* \return The index of TC configuration
|
||||
*/
|
||||
static int8_t get_tc_index(const void *const hw)
|
||||
{
|
||||
uint8_t index = _get_hardware_offset(hw);
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(_tcs); i++) {
|
||||
if (_tcs[i].number == index) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Init irq param with the given tc hardware instance
|
||||
*/
|
||||
static void _tc_init_irq_param(const void *const hw, void *dev)
|
||||
{
|
||||
if (hw == TC0) {
|
||||
_tc0_dev = (struct _timer_device *)dev;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal Retrieve TC hardware index
|
||||
*
|
||||
* \param[in] hw The pointer to hardware instance
|
||||
*/
|
||||
static inline uint8_t _get_hardware_offset(const void *const hw)
|
||||
{
|
||||
/* List of available TC modules. */
|
||||
Tc *const tc_modules[TC_INST_NUM] = TC_INSTS;
|
||||
|
||||
/* Find index for TC instance. */
|
||||
for (uint32_t i = 0; i < TC_INST_NUM; i++) {
|
||||
if ((uint32_t)hw == (uint32_t)tc_modules[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief TC related functionality declaration.
|
||||
* \brief SAM Timer/Counter
|
||||
*
|
||||
* Copyright (c) 2017 Microchip Technology Inc. and its subsidiaries.
|
||||
* Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
@@ -29,36 +28,50 @@
|
||||
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TC_H_INCLUDED
|
||||
#define _TC_H_INCLUDED
|
||||
#ifndef _HPL_TC_BASE_H_INCLUDED
|
||||
#define _HPL_TC_BASE_H_INCLUDED
|
||||
|
||||
#include <compiler.h>
|
||||
#include <utils_assert.h>
|
||||
|
||||
/**
|
||||
* \addtogroup tc driver
|
||||
*
|
||||
* \section tc Revision History
|
||||
* - v0.0.0.1 Initial Commit
|
||||
*
|
||||
*@{
|
||||
*/
|
||||
#include <hpl_timer.h>
|
||||
#include <hpl_pwm.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Initialize tc interface
|
||||
* \return Initialization status.
|
||||
* \addtogroup tc_group TC Hardware Proxy Layer
|
||||
*
|
||||
* \section tc_hpl_rev Revision History
|
||||
* - v0.0.0.1 Initial Commit
|
||||
*
|
||||
*@{
|
||||
*/
|
||||
int8_t TIMER_0_init();
|
||||
|
||||
/**
|
||||
* \name HPL functions
|
||||
*/
|
||||
//@{
|
||||
|
||||
/**
|
||||
* \brief Retrieve timer helper functions
|
||||
*
|
||||
* \return A pointer to set of timer helper functions
|
||||
*/
|
||||
struct _timer_hpl_interface *_tc_get_timer(void);
|
||||
|
||||
/**
|
||||
* \brief Retrieve pwm helper functions
|
||||
*
|
||||
* \return A pointer to set of pwm helper functions
|
||||
*/
|
||||
struct _pwm_hpl_interface *_tc_get_pwm(void);
|
||||
|
||||
//@}
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TC_H_INCLUDED */
|
||||
#endif /* _HPL_TC_BASE_H_INCLUDED */
|
||||
@@ -1,101 +0,0 @@
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief TC related functionality implementation.
|
||||
*
|
||||
* Copyright (c) 2017 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 "tc_lite.h"
|
||||
|
||||
/**
|
||||
* \brief Initialize TC interface
|
||||
*/
|
||||
int8_t TIMER_0_init()
|
||||
{
|
||||
|
||||
if (!hri_tc_is_syncing(TC0, TC_SYNCBUSY_SWRST)) {
|
||||
if (hri_tc_get_CTRLA_reg(TC0, TC_CTRLA_ENABLE)) {
|
||||
hri_tc_clear_CTRLA_ENABLE_bit(TC0);
|
||||
hri_tc_wait_for_sync(TC0, TC_SYNCBUSY_ENABLE);
|
||||
}
|
||||
hri_tc_write_CTRLA_reg(TC0, TC_CTRLA_SWRST);
|
||||
}
|
||||
hri_tc_wait_for_sync(TC0, TC_SYNCBUSY_SWRST);
|
||||
|
||||
// hri_tc_write_CTRLA_reg(TC0,0 << TC_CTRLA_CAPTMODE0_Pos /* Capture mode Channel 0: 0 */
|
||||
// | 0 << TC_CTRLA_CAPTMODE1_Pos /* Capture mode Channel 1: 0 */
|
||||
// | 0 << TC_CTRLA_COPEN0_Pos /* Capture Pin 0 Enable: disabled */
|
||||
// | 0 << TC_CTRLA_COPEN1_Pos /* Capture Pin 1 Enable: disabled */
|
||||
// | 0 << TC_CTRLA_CAPTEN0_Pos /* Capture Channel 0 Enable: disabled */
|
||||
// | 0 << TC_CTRLA_CAPTEN1_Pos /* Capture Channel 1 Enable: disabled */
|
||||
// | 0 << TC_CTRLA_ALOCK_Pos /* Auto Lock: disabled */
|
||||
// | 0 << TC_CTRLA_PRESCSYNC_Pos /* Prescaler and Counter Synchronization: 0 */
|
||||
// | 0 << TC_CTRLA_ONDEMAND_Pos /* Clock On Demand: disabled */
|
||||
// | 0 << TC_CTRLA_RUNSTDBY_Pos /* Run in Standby: disabled */
|
||||
// | 0 << TC_CTRLA_PRESCALER_Pos /* Setting: 0 */
|
||||
// | 0x0 << TC_CTRLA_MODE_Pos); /* Operating Mode: 0x0 */
|
||||
|
||||
hri_tc_write_CTRLB_reg(TC0,
|
||||
0 << TC_CTRLBSET_CMD_Pos /* Command: 0 */
|
||||
| 0 << TC_CTRLBSET_ONESHOT_Pos /* One-Shot: disabled */
|
||||
| 0 << TC_CTRLBCLR_LUPD_Pos /* Setting: disabled */
|
||||
| 0 << TC_CTRLBSET_DIR_Pos); /* Counter Direction: disabled */
|
||||
|
||||
hri_tc_write_WAVE_reg(TC0, 1); /* Waveform Generation Mode: 1 */
|
||||
|
||||
// hri_tc_write_DRVCTRL_reg(TC0,0 << TC_DRVCTRL_INVEN1_Pos /* Output Waveform 1 Invert Enable: disabled */
|
||||
// | 0 << TC_DRVCTRL_INVEN0_Pos); /* Output Waveform 0 Invert Enable: disabled */
|
||||
|
||||
// hri_tc_write_DBGCTRL_reg(TC0,0); /* Run in debug: 0 */
|
||||
|
||||
hri_tccount32_write_CC_reg(TC0, 0, 0x2ee0); /* Compare/Capture Value: 0x2ee0 */
|
||||
|
||||
hri_tccount32_write_CC_reg(TC0, 1, 0x1770); /* Compare/Capture Value: 0x1770 */
|
||||
|
||||
// hri_tccount32_write_COUNT_reg(TC0,0x0); /* Counter Value: 0x0 */
|
||||
|
||||
hri_tc_write_EVCTRL_reg(TC0,
|
||||
1 << TC_EVCTRL_MCEO0_Pos /* Match or Capture Channel 0 Event Output Enable: enabled */
|
||||
| 1 << TC_EVCTRL_MCEO1_Pos /* Match or Capture Channel 1 Event Output Enable: enabled */
|
||||
| 1 << TC_EVCTRL_OVFEO_Pos /* Overflow/Underflow Event Output Enable: enabled */
|
||||
| 0 << TC_EVCTRL_TCEI_Pos /* TC Event Input: disabled */
|
||||
| 0 << TC_EVCTRL_TCINV_Pos /* TC Inverted Event Input: disabled */
|
||||
| 0); /* Event Action: 0 */
|
||||
|
||||
hri_tc_write_INTEN_reg(TC0,
|
||||
0 << TC_INTENSET_MC0_Pos /* Match or Capture Channel 0 Interrupt Enable: disabled */
|
||||
| 1 << TC_INTENSET_MC1_Pos /* Match or Capture Channel 1 Interrupt Enable: enabled */
|
||||
| 0 << TC_INTENSET_ERR_Pos /* Error Interrupt Enable: disabled */
|
||||
| 1 << TC_INTENSET_OVF_Pos); /* Overflow Interrupt enable: enabled */
|
||||
|
||||
hri_tc_write_CTRLA_ENABLE_bit(TC0, 1 << TC_CTRLA_ENABLE_Pos); /* Enable: enabled */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <atmel_start.h>
|
||||
#include "spi_slave_dma_config.h"
|
||||
#include "A1335.h"
|
||||
|
||||
/* Buffer length to transfer/receive */
|
||||
#define BUFFER_LEN (6)
|
||||
@@ -19,6 +20,25 @@ volatile uint8_t received_data_len = 0;
|
||||
static uint8_t rx_buffer[BUFFER_LEN] = {0};
|
||||
static uint8_t tx_buffer[BUFFER_LEN] = "Hell0";
|
||||
|
||||
static struct timer_task TIMER_0_task1;
|
||||
|
||||
static void task1_cb(const struct timer_task *const timer_task)
|
||||
{
|
||||
volatile int i = 0;
|
||||
angleSensor_State_Machine(&A1);
|
||||
|
||||
}
|
||||
|
||||
void TIMER_0_init(void)
|
||||
{
|
||||
TIMER_0_task1.interval = 10;
|
||||
TIMER_0_task1.cb = task1_cb;
|
||||
TIMER_0_task1.mode = TIMER_TASK_REPEAT;
|
||||
timer_add_task(&TIMER_0, &TIMER_0_task1);
|
||||
timer_start(&TIMER_0);
|
||||
}
|
||||
|
||||
|
||||
/* DMA Transfer complete callback for SPI master TX */
|
||||
static void spi_master_tx_complete_cb(struct _dma_resource *resource)
|
||||
{
|
||||
@@ -69,6 +89,8 @@ int main(void)
|
||||
atmel_start_init();
|
||||
/* Initialize SPI master IO and Callback */
|
||||
spi_master_init();
|
||||
TIMER_0_init();
|
||||
|
||||
spi_m_dma_enable(&SPI_0);
|
||||
|
||||
/* Start SPI Master data transfer using DMA */
|
||||
@@ -79,30 +101,30 @@ int main(void)
|
||||
printf("Init Complete\n\r");
|
||||
/* Replace with your application code */
|
||||
while (1) {
|
||||
delay_ms(1000);
|
||||
tx_buffer[4] = tx_buffer[4]+1;
|
||||
//spi_master_rx(rx_buffer, BUFFER_LEN);
|
||||
spi_master_tx(tx_buffer, BUFFER_LEN);
|
||||
|
||||
if (spi_master_tx_complete) {
|
||||
spi_master_rx_complete = false;
|
||||
printf("Master Sent DATA = ");
|
||||
/* Print Received data by SPI Master from SPI Slave on Console */
|
||||
for (int i = 0; i < BUFFER_LEN; i++) {
|
||||
printf("%c", tx_buffer[i]);
|
||||
}
|
||||
printf("\n\r");
|
||||
|
||||
}
|
||||
/* Check for SPI Master is received data from SPI Slave */
|
||||
if (spi_master_rx_complete) {
|
||||
spi_master_rx_complete = false;
|
||||
printf("Master Recieved DATA = ");
|
||||
/* Print Received data by SPI Master from SPI Slave on Console */
|
||||
for (int i = 0; i < BUFFER_LEN; i++) {
|
||||
printf("%c", rx_buffer[i]);
|
||||
}
|
||||
printf("\n\r");
|
||||
}
|
||||
//delay_ms(1000);
|
||||
//tx_buffer[4] = tx_buffer[4]+1;
|
||||
////spi_master_rx(rx_buffer, BUFFER_LEN);
|
||||
//spi_master_tx(tx_buffer, BUFFER_LEN);
|
||||
//
|
||||
//if (spi_master_tx_complete) {
|
||||
//spi_master_rx_complete = false;
|
||||
//printf("Master Sent DATA = ");
|
||||
///* Print Received data by SPI Master from SPI Slave on Console */
|
||||
//for (int i = 0; i < BUFFER_LEN; i++) {
|
||||
//printf("%c", tx_buffer[i]);
|
||||
//}
|
||||
//printf("\n\r");
|
||||
//
|
||||
//}
|
||||
///* Check for SPI Master is received data from SPI Slave */
|
||||
//if (spi_master_rx_complete) {
|
||||
//spi_master_rx_complete = false;
|
||||
//printf("Master Recieved DATA = ");
|
||||
///* Print Received data by SPI Master from SPI Slave on Console */
|
||||
//for (int i = 0; i < BUFFER_LEN; i++) {
|
||||
//printf("%c", rx_buffer[i]);
|
||||
//}
|
||||
//printf("\n\r");
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user