commiting examples

This commit is contained in:
Nicolas Trimborn
2021-07-26 10:32:22 +02:00
parent 76cd702edc
commit 312768d2cf
589 changed files with 464854 additions and 446 deletions

View File

@@ -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=""/>

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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_ */

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -16,6 +16,8 @@ void TARGET_IO_example(void);
void SPI_0_example(void);
void TIMER_0_example(void);
#ifdef __cplusplus
}
#endif

View File

@@ -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

View File

@@ -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

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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");
//}
}
}