Commit 257540f8 authored by Martin Vítek's avatar Martin Vítek

Add Debug, polishing, doing weird stuff

parent 266d4f9e
......@@ -4,7 +4,10 @@
#include <cstdint>
#include "Debug.h"
/*
ADC pins
PA02 - AIN0 - current 180V
......@@ -14,12 +17,48 @@
PB03 - AIN11 - ambient light
PB08 - AIN2 - temperature boost
PB09 - AIN3 - current 12V
8MHz -> DIV4 -> ADC clock 2MHz
*/
class adc_class
{
public:
adc_class()
enum inputs
{
CURRENT_180V = 0,
VOLTAGE_180V = 1,
CURRENT_12V = 2,
VOLTAGE_12V = 3,
TEMPERATURE_BOOST = 4,
TEMPERATURE_AMBIENT = 5,
AMBIENT_LIGHT = 6,
};
const static uint8_t number_of_inputs = 7;
const uint8_t input[number_of_inputs];
volatile uint8_t current_pass;
const static uint8_t number_of_passes = 3;
volatile uint8_t current_input;
volatile uint16_t result[number_of_inputs*number_of_passes];
uint32_t value[number_of_inputs];
volatile bool done;
public:
adc_class(): input{ ADC_INPUTCTRL_MUXPOS_PIN0,
ADC_INPUTCTRL_MUXPOS_PIN1,
ADC_INPUTCTRL_MUXPOS_PIN3,
ADC_INPUTCTRL_MUXPOS_PIN4,
ADC_INPUTCTRL_MUXPOS_PIN2,
ADC_INPUTCTRL_MUXPOS_PIN10,
ADC_INPUTCTRL_MUXPOS_PIN11 },
current_pass(0),
current_input(0),
done(false)
{
}
......@@ -39,26 +78,19 @@ class adc_class
PORT_WRCONFIG_PMUX(PORT_PMUX_PMUXO_B_Val) |
PORT_WRCONFIG_PINMASK(PORT_PB02 | PORT_PB03 | PORT_PB08 | PORT_PB09);
//Enable CLK_ADC_APB (enabled by default, but why not)
PM->APBCMASK.bit.ADC_ = 1;
//Enable GCLK_ADC
//Clock from GCLK5 - source internal 1MHz, no division
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(5) | GCLK_CLKCTRL_ID_ADC;
//Enable internal temperature sensor
SYSCTRL->VREF.bit.TSEN = 1;
//SYSCTRL->VREF.bit.TSEN = 1;
//Select reference - 1.0V
ADC->REFCTRL.reg = ADC_REFCTRL_REFSEL_INT1V;
//Prescaler 4 -> 250kHz, 12bit, single-ended mode
//Prescaler 4 -> 2MHz, 12bit, single-ended mode
ADC->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV4 | ADC_CTRLB_RESSEL_12BIT;
while (ADC->STATUS.bit.SYNCBUSY) ;;
//Select negative input as GND, positive as AIN0
ADC->INPUTCTRL.reg = ADC_INPUTCTRL_MUXNEG_GND | ADC_INPUTCTRL_MUXPOS_PIN11;
set_input(input[0]);
//Load calibration from NVM (BIAS_CAL, LINEARITY_CAL) to CALIB
//From: http://www.avrfreaks.net/forum/adc-conversion-asf-sam-d10-xplained-board-doesnt-work
......@@ -69,6 +101,20 @@ class adc_class
ADC->CTRLA.bit.ENABLE = 1;
while (ADC->STATUS.bit.SYNCBUSY) ;;
//Trash first conversion after change of reference
start_conversion();
uint16_t dummy = get();
//Enable Result Ready Interrupt
ADC->INTENSET.reg = ADC_INTENSET_RESRDY;
}
void set_input(uint8_t input)
{
ADC->INPUTCTRL.reg = ADC_INPUTCTRL_GAIN(0) | ADC_INPUTCTRL_MUXNEG_GND | input;
while (ADC->STATUS.bit.SYNCBUSY) ;;
}
void start_conversion()
......@@ -85,4 +131,87 @@ class adc_class
return (uint16_t)ADC->RESULT.reg;
}
void irq_handler()
{
if (ADC->INTFLAG.bit.RESRDY)
{
result[(current_pass*number_of_inputs) + current_input] = ADC->RESULT.reg;
current_input++;
if (current_input >= number_of_inputs)
{
current_input = 0;
current_pass++;
if (current_pass >= number_of_passes)
{
current_pass = 0;
done = true;
return;
}
}
set_input(input[current_input]);
start_conversion();
}
}
void convert_values()
{
uint32_t sum;
//Average of number_of_passes samples
for (uint8_t i=0; i<number_of_inputs; i++)
{
debug.uart.send("Input: ");
debug.uart.send_dec(i);
debug.uart.send('\t');
debug.uart.send_dec(result[i]);
debug.uart.send('\t');
debug.uart.send_dec(result[i+number_of_inputs]);
debug.uart.send('\t');
debug.uart.send_dec(result[i+number_of_inputs*2]);
sum = result[i] + result[i+number_of_inputs] + result[i+2*number_of_inputs];
value[i] = sum / number_of_passes;
debug.uart.send("\t\t");
debug.uart.send_dec(value[i]);
debug.uart.send_new_line();
}
debug.uart.send_new_line();
//Conversion to normal numbers
auto get_voltage = [] (const uint32_t adc_result) { return ((adc_result*1000000UL)/(4096UL)); };//Returns voltage in 10^-6 V
auto divider = [] (const uint32_t R1, const uint32_t R2) { return (((R1+R2)/R2)*100UL); }; //Returns coefficient of divider * 100
auto current = [] (const uint32_t Rs, const uint32_t Rl) { return (Rs*Rl*200); }; //Returns current transfer (resistance in mR)
value[VOLTAGE_12V] = get_voltage(value[VOLTAGE_12V]) * divider(39'000UL, 2'200UL) / 1000UL; //18V -> 18 000 000uV
value[VOLTAGE_180V] = get_voltage(value[VOLTAGE_180V]) * divider(820'000UL, 3'900UL) / 1000UL; //210V -> 210 000 000uV
value[CURRENT_12V] = get_voltage(value[CURRENT_12V]) / current(200, 22'000'000) / 1000;
value[CURRENT_180V] = get_voltage(value[CURRENT_180V]) / current(4'700, 33'000'000) / 1000;
value[TEMPERATURE_BOOST] = get_voltage(value[TEMPERATURE_BOOST]) / 100 - 500'000; //20,25C -> 2025
value[TEMPERATURE_AMBIENT] = get_voltage(value[TEMPERATURE_AMBIENT]) / 100 - 500'000; //20,25C -> 2025
value[AMBIENT_LIGHT] = get_voltage(value[AMBIENT_LIGHT]) / 1000; //1000lx -> 1000
debug.uart.send("Voltage 12V:\t");
debug.uart.send_dec(value[VOLTAGE_12V]);debug.uart.send("\t\t");
debug.uart.send_dec(value[VOLTAGE_12V]/100000);debug.uart.send('.');debug.uart.send_dec(value[VOLTAGE_12V%100000]);
debug.uart.send_new_line();
debug.uart.send("Voltage 180V:\t");
debug.uart.send_dec(value[VOLTAGE_180V]);debug.uart.send("\t\t");
debug.uart.send_dec(value[VOLTAGE_180V]/100000);debug.uart.send('.');debug.uart.send_dec(value[VOLTAGE_180V%100000]);
debug.uart.send_new_line();
debug.uart.send_new_line();
}
};
#include "Debug.h"
#include "USART.h"
//#include "ethernet_frame.h"
USART uart(SERCOM1->USART, 115200);
Debug debug(uart);
Debug::Debug(USART &uart) : uart(uart)
{
}
void Debug::message(const char *s)
{
uart.send("[MESSAGE] ");
uart.send(s);
uart.send("\n\r");
}
void Debug::info(const char *s)
{
uart.send("[INFO] ");
uart.send(s);
uart.send("\n\r");
}
void Debug::error(const char *s)
{
uart.send("[ERROR] ");
uart.send(s);
uart.send("\n\r");
}
void Debug::reg(const char* name, const uint8_t value)
{
uart.send("[REGISTER] ");
uart.send(name);
uart.send(":\t");
uart.send_binary8(value);
uart.send_new_line();
}
void Debug::reg(const char* name, const uint16_t value)
{
uart.send("[REGISTER] ");
uart.send(name);
uart.send(":\t");
uart.send_binary8(value>>8);
uart.send(' ');
uart.send_binary8(value&0xFF);
uart.send_new_line();
}
/*
void Debug::frame(const ethernet_frame &frame)
{
uart.send("[FRAME] \n\r");
uart.send("\tDEST: ");
for (uint8_t i = 0; i < 6; i++)
{
uart.send_hex8(frame.dest_address[i]);
uart.send_char(' ');
}
uart.send_new_line();
uart.send("\tSRC: ");
for (uint8_t i = 0; i < 6; i++)
{
uart.send_hex8(frame.src_address[i]);
uart.send_char(' ');
}
uart.send_new_line();
uart.send("\tPayload: ");
for (uint16_t i = 0; i < frame.payload.length; i++)
{
uart.send_hex8(frame.payload.data[i]);
uart.send_char(' ');
}
uart.send_new_line();
uart.send("\tCRC: ");
uart.send_hex32(frame.crc);
uart.send_new_line();
uart.send_new_line();
}
*/
#pragma once
#include "USART.h"
//#include "ethernet_frame.h"
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
#define BYTE_TO_BINARY(byte) \
(byte & 0x80 ? '1' : '0'), \
(byte & 0x40 ? '1' : '0'), \
(byte & 0x20 ? '1' : '0'), \
(byte & 0x10 ? '1' : '0'), \
(byte & 0x08 ? '1' : '0'), \
(byte & 0x04 ? '1' : '0'), \
(byte & 0x02 ? '1' : '0'), \
(byte & 0x01 ? '1' : '0')
class Debug
{
public:
USART& uart;
/*
static int uart_putchar(const char c, FILE *stream)
{
if (c == '\n') uart_putchar('\r', stream);
while(!(UCSRA & (1<<UDRE))) ;;
UDR = c;
return 0;
};
*/
public:
Debug(USART& uart);
void message(const char* s);
void info(const char* s);
void error(const char* s);
void reg(const char* name, const uint8_t value);
void reg(const char* name, const uint16_t value);
//void frame(const ethernet_frame &frame);
};
extern USART uart;
extern Debug debug;
......@@ -35,7 +35,7 @@ class PWM
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0) | GCLK_CLKCTRL_ID_TC2_TC3;
//1MHz clock, normal PWM
timer.CTRLA.reg = TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_PRESCSYNC_GCLK | TC_CTRLA_WAVEGEN_NPWM | TC_CTRLA_MODE_COUNT8;
timer.CTRLA.reg = TC_CTRLA_PRESCALER_DIV2 | TC_CTRLA_PRESCSYNC_GCLK | TC_CTRLA_WAVEGEN_NPWM | TC_CTRLA_MODE_COUNT8;
while (timer.STATUS.bit.SYNCBUSY) ;;
......
......@@ -4,21 +4,30 @@
#include "sam.h"
/*
SPI pins
PA08 - PAD[0] - MISO
PA10 - PAD[2] - MOSI
PA11 - PAD[3] - SCK
48MHz clock
Baudrate - max 11.9MHz
*/
class SPI
{
private:
volatile SercomSpi& spi;
uint32_t baudrate;
public:
SPI(volatile SercomSpi& spi): spi(spi)
SPI(volatile SercomSpi& spi, const uint32_t baudrate): spi(spi),
baudrate(baudrate)
{
}
......@@ -32,21 +41,14 @@ class SPI
PORT_WRCONFIG_PMUX(PORT_PMUX_PMUXO_C_Val) |
PORT_WRCONFIG_PINMASK(PORT_PA11 | PORT_PA10 | PORT_PA08);
//Enable CLK_SERCOM0_APB
PM->APBCMASK.bit.SERCOM0_ = 1;
//Enable GCLK_SERCOM0_CORE
//Clock from GCLK5 - source internal 1MHz, no division
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(5) | GCLK_CLKCTRL_ID_SERCOM0_CORE;
//SPI master, MSB first, mode 0, PAD[0] MISO, PAD[2] MOSI, PAD[3] ACK
spi.CTRLA.reg = SERCOM_SPI_CTRLA_DIPO(0) | SERCOM_SPI_CTRLA_DOPO(1) | SERCOM_SPI_CTRLA_MODE_SPI_MASTER;
//Enable RX, 8bit data
spi.CTRLB.reg = SERCOM_SPI_CTRLB_RXEN;
//Set baudrate to something
spi.BAUD.reg = 0;
//Set baudrate
spi.BAUD.reg = SystemCoreClock/baudrate;
//Enable SPI
spi.CTRLA.bit.ENABLE = 1;
......@@ -54,7 +56,20 @@ class SPI
while (spi.STATUS.bit.SYNCBUSY) ;;
}
void write(uint8_t data)
void set_baudrate(const uint32_t baudrate)
{
if (baudrate > 11'904'761) this->baudrate = 11'904'761;
else this->baudrate = baudrate;
spi.BAUD.reg = SystemCoreClock/this->baudrate;
}
uint32_t get_baudrate()
{
return SystemCoreClock/spi.BAUD.reg;
}
void write(const uint8_t data)
{
while (!spi.INTFLAG.bit.DRE) ;;
......@@ -77,7 +92,7 @@ class SPI
return spi.DATA.reg;
}
uint8_t write_and_read(uint8_t data)
uint8_t write_and_read(const uint8_t data)
{
while (!spi.INTFLAG.bit.DRE) ;;
......
......@@ -15,8 +15,8 @@ System::System()
void System::init_clock()
{
//Enable external 32kHz crystal, 1068us start-up
SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_STARTUP(0x03) | SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_EN32K;
//Enable external 32kHz crystal, 125 092us start-up
SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_STARTUP(0x06) | SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_EN32K;
SYSCTRL->XOSC32K.bit.ENABLE = 1;
while (!SYSCTRL->PCLKSR.bit.XOSC32KRDY) ;;
......@@ -32,14 +32,12 @@ void System::init_clock()
//Disable on-demand mode (errata)
while (!SYSCTRL->PCLKSR.bit.DFLLRDY) ;;
SYSCTRL->DFLLCTRL.reg = 0;
SYSCTRL->DFLLCTRL.reg = 0;
//Get and load coarse and fine values from NVM
//Get and set coarse and fine values from NVM
while (!SYSCTRL->PCLKSR.bit.DFLLRDY) ;;
SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE((*(uint32_t *) FUSES_DFLL48M_COARSE_CAL_ADDR >> FUSES_DFLL48M_COARSE_CAL_Pos)) |
SYSCTRL_DFLLVAL_FINE( (*(uint32_t *) FUSES_DFLL48M_FINE_CAL_ADDR >> FUSES_DFLL48M_FINE_CAL_Pos));
while (!SYSCTRL->PCLKSR.bit.DFLLRDY) ;;
//Set coarse step, fine step, multiplier
while (!SYSCTRL->PCLKSR.bit.DFLLRDY) ;;
......@@ -54,26 +52,62 @@ void System::init_clock()
//Enable DFLL 48MHz as clock source
while (!SYSCTRL->PCLKSR.bit.DFLLRDY) ;;
SYSCTRL->DFLLCTRL.bit.ENABLE = 1;
while (!SYSCTRL->PCLKSR.bit.DFLLRDY || !SYSCTRL->PCLKSR.bit.DFLLLCKC || !SYSCTRL->PCLKSR.bit.DFLLLCKF) ;;
while (!SYSCTRL->PCLKSR.bit.DFLLRDY) ;;
//Set flash wait state to 1, which we need to do at 48MHz
//Set flash wait state to 1, which we need to do at 48MHz (NVM characteristics p. 628, table 33-32)
NVMCTRL->CTRLB.bit.RWS = 1;
//Set DFLL as GCLK0 source
GCLK->GENDIV.reg = GCLK_GENDIV_DIV(1) | GCLK_GENDIV_ID(0);
GCLK->GENDIV.reg = GCLK_GENDIV_DIV(1) | GCLK_GENDIV_ID(0);
GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_IDC | GCLK_GENCTRL_ID(0);
while(GCLK->STATUS.bit.SYNCBUSY) ;;
SystemCoreClock = 48'000'000;
//Set DFLL as GCLK2 source, DIV6
GCLK->GENDIV.reg = GCLK_GENDIV_DIV(6) | GCLK_GENDIV_ID(2);
GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_IDC | GCLK_GENCTRL_ID(2);
while(GCLK->STATUS.bit.SYNCBUSY) ;;
GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_IDC | GCLK_GENCTRL_ID(0) | GCLK_GENCTRL_OE;
//Enable CLK for peripherals
PM->APBCMASK.reg |= PM_APBCMASK_SERCOM0 |
PM_APBCMASK_SERCOM1 |
PM_APBCMASK_ADC |
PM_APBCMASK_TC0 |
PM_APBCMASK_TC2 |
PM_APBCMASK_TC5;
//Set GCLK0 as source for peripherals - 48MHz
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0) | GCLK_CLKCTRL_ID_SERCOM0_CORE;
while(GCLK->STATUS.bit.SYNCBUSY) ;;
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0) | GCLK_CLKCTRL_ID_SERCOM1_CORE;
while(GCLK->STATUS.bit.SYNCBUSY) ;;
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0) | GCLK_CLKCTRL_ID_TC0_TC1;
while(GCLK->STATUS.bit.SYNCBUSY) ;;
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0) | GCLK_CLKCTRL_ID_TC2_TC3;
while(GCLK->STATUS.bit.SYNCBUSY) ;;
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0) | GCLK_CLKCTRL_ID_TC4_TC5;
while(GCLK->STATUS.bit.SYNCBUSY) ;;
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0) | GCLK_CLKCTRL_ID_EIC;
while(GCLK->STATUS.bit.SYNCBUSY) ;;
PM->CPUSEL.reg = PM_CPUSEL_CPUDIV_DIV1 ;
PM->APBASEL.reg = PM_APBASEL_APBADIV_DIV1_Val ;
PM->APBBSEL.reg = PM_APBBSEL_APBBDIV_DIV1_Val ;
PM->APBCSEL.reg = PM_APBCSEL_APBCDIV_DIV1_Val ;
//Set GCLK1 as source for RTC - 32.768kHz
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(1) | GCLK_CLKCTRL_ID_RTC;
while(GCLK->STATUS.bit.SYNCBUSY) ;;
SystemCoreClock = 48'000'000;
//Set GCLK2 as source for ADC - 8MHz
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(2) | GCLK_CLKCTRL_ID_ADC;
while(GCLK->STATUS.bit.SYNCBUSY) ;;
}
void System::init_interrupts()
{
NVIC_EnableIRQ(ADC_IRQn);
}
void System::delay_us(const uint16_t delay)
......
......@@ -4,12 +4,30 @@
#include <cstdint>
/*
48MHz - DIV0 - GCLK0 - SERCOM0 (SPI)
- SERCOM1 (UART)
- TC0 (System control)
- TC2 (Boost PWM)
- TC5 (Separator PWM)
- EIC
32.768kHz - DIV0 - GCLK1 - DFLL
- RTC
48Mhz (8MHz)- DIV6 - GCLK2 - ADC
*/
class System
{
public:
System();
void init_clock();
void init_interrupts();
void delay_us(const uint16_t delay);
void delay_ms(uint16_t delay);
......
......@@ -2,10 +2,31 @@
#include "sam.h"
#include <cstdint>
/*
UART pins
PA17 - PAD[1] - RX
PA18 - PAD[2] - TX
48MHz clock
Baudrate - max 11.9MHz
*/
class USART
{
private:
volatile SercomUsart& usart;
const uint32_t baudrate;
public:
USART()
USART(volatile SercomUsart& usart, const uint32_t baudrate): usart(usart),
baudrate(baudrate)
{
}
......@@ -13,55 +34,42 @@ class USART
//Initialize SERCOM0 in UART mode
void init()
{
//Enable peripheral multiplexer on TX pin
PORT->Group[0].PINCFG[PIN_PA18].bit.PMUXEN = 1;
//Enable peripheral multiplexer on RX pin
PORT->Group[0].PINCFG[PIN_PA11].bit.PMUXEN = 1;
//PORT->Group[0].PINCFG[PIN_PA17].reg = PORT_PINCFG_INEN | PORT_PINCFG_PMUXEN;
//Select peripheral function C (SERCOM0) on TX and RX pin
//PMUX[n] - there are always 2 pins in one reg -> n=pin/2=10/2=5
PORT->Group[0].PMUX[8].reg = PORT_PMUX_PMUXO_C;
PORT->Group[0].PMUX[9].reg = PORT_PMUX_PMUXE_C;
//Enable peripheral multiplexer and select peripheral function C
PORT->Group[0].WRCONFIG.reg = PORT_WRCONFIG_HWSEL |
PORT_WRCONFIG_WRPINCFG |
PORT_WRCONFIG_WRPMUX |
PORT_WRCONFIG_PMUXEN |
PORT_WRCONFIG_PMUX(PORT_PMUX_PMUXO_C_Val) |
PORT_WRCONFIG_PINMASK((PORT_PA17 | PORT_PA18) >> 16);
//Setup clock
//CLK_SERCOMx_APB - enabled by default it's not true, it's disabled!!!
//GCLK_SERCOMx_CORE - needs to be enabled for master operation
//GCLK_SERCOMx_SLOW - needs to be enabled for certain functions
//Enable CLK_SERCOM0_APB
PM->APBCMASK.bit.SERCOM1_ = 1;
//Enable GCLK_SERCOMx_CORE
//Enable GCLK5 for SERCOM 0 - source internal 1MHz, no division
GCLK->GENDIV.reg = GCLK_GENDIV_DIV(1) | GCLK_GENDIV_ID(5);
GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSC8M | 0x05;
while(GCLK->STATUS.bit.SYNCBUSY) ;;
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK5 | GCLK_CLKCTRL_ID_SERCOM1_CORE;
//Asynchronous, PAD[1] RX, PAD[2] TX, internal clock
SERCOM1->USART.CTRLA.reg = (0x01 << SERCOM_USART_CTRLA_RXPO_Pos) | (0x01 << SERCOM_USART_CTRLA_TXPO_Pos) | SERCOM_USART_CTRLA_MODE_USART_INT_CLK |SERCOM_USART_CTRLA_DORD;
usart.CTRLA.reg = SERCOM_USART_CTRLA_RXPO(1) |
SERCOM_USART_CTRLA_TXPO |
SERCOM_USART_CTRLA_MODE_USART_INT_CLK |
SERCOM_USART_CTRLA_DORD;
//Enable RX, TX, 1 stop bit, 8bit data
SERCOM1->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN;
usart.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN;
//Baudrate 9600, for TX is used division by 16
SERCOM1->USART.BAUD.reg = 55470;
//Baudrate 115200, for TX is used division by 16
usart.BAUD.reg = static_cast<uint32_t>(65536.0 * (1.0 - 16.0 * (static_cast<float>(baudrate)/static_cast<float>(SystemCoreClock))));
//Enable SERCOM0, wait for synchronization
SERCOM1->USART.CTRLA.bit.ENABLE = 1;
//while (SERCOM0->USART.SYNCBUSY.bit.ENABLE) ;;
while (SERCOM1->USART.STATUS.bit.SYNCBUSY) ;;
usart.CTRLA.bit.ENABLE = 1;
while (usart.STATUS.bit.SYNCBUSY) ;;
}
void send(const char c)
{
while (!SERCOM1->USART.INTFLAG.bit.DRE) ;;
while (!usart.INTFLAG.bit.DRE) ;;
SERCOM1->USART.DATA.reg = c;
usart.DATA.reg = c;
}
void send(const char* s)
......
#include "sam.h"
#include "ADC_class.h"
/*
ADC_Handler()
{
if (ADC->INTFLAG.bit.RESRDY)
}
*/
\ No newline at end of file
......@@ -21,42 +21,15 @@
#include "IRQ_test.h"
#include "EEPROM_25AA02E48.h"
#include "Debug.h"
//Default clock is 8MHz internal with prescaler to 1MHz
//SERCOM0 - SPI
//SERCOM1 - UART
USART uart;
Output led(PORT->Group[0], PIN_PA06);
adc_class adc;
char znak;
/*
extern "C"
{
int _write(int fd, const void* buff, size_t count);
}
int _write(int fd, const void* buff, size_t count)
{
size_t CharCnt = 0;
while (count--)
{
if (*buff == '\n') uart.send('\r');
uart.send(*buff);
buff++;
CharCnt++;
}
return CharCnt;
}
*/
void TC0_Handler()
{
......@@ -73,6 +46,11 @@ void TC0_Handler()
}
}
void ADC_Handler()
{
adc.irq_handler();
}
int main(void)
{
/* Initialize the SAM system */
......@@ -80,6 +58,10 @@ int main(void)
sys.init_clock();