10.2 C Source Code
configure.c
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/cpufunc.h>
#include "timer_callback.h"
#include "spi.h"
#include "pins.h"
void init_sysclock(void);
void init_tcb0(void);
#define PORTB_PIN2CTRL _SFR_MEM8(0x0432)
void initializePeripherals() {
init_sysclock();
init_tcb0();
init_spi0();
PORTB_PIN2CTRL |= 0x8;
}
void init_sysclock(void)
{
CPU_CCP = 0xD8;
CLKCTRL_MCLKCTRLB = 0x00;
}
void init_tcb0(void)
{
TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc; // base clock 16Mhz / 2 = 8 MHz
TCB0.CTRLB = 0x00; // all the defaults
TCB0.CCMP = 7999; // 8Mhz / 8000 = 1 kHz
TCB0.INTCTRL = 0x01; // enable interrupt
TCB0.CTRLA |= 0x01; // enable timer
}
main.c
/*
* File: main.c
*/
#include <stdio.h>
#include <stdlib.h>
#include "configure.h"
#include <avr/interrupt.h>
int main(int argc, char** argv)
{
initializePeripherals();
sei(); //set global interrupt flag
while(1) ;
}
sine_app.c
/*
* There are two waveforms in this application:
* 1. sine wave
* 2. triangle wave
*
* There are two global variables for control in this application:
* - amp_factor - this defines the amplitude of the waveform
* - wave_select - this defines the waveform selection.
* It can either be 0 for sine or 1 for triangle.
*/
#include <stdio.h>
#include "timer_callback.h"
#include "spi.h"
#include "memutil.h"
int amp_factor = 1;
int wave_select = 0;
int counter = 0;
int sine[] = {
0x2b,0x2d,0x30,0x32,0x35,0x38,0x3a,0x3d,
0x3f,0x41,0x43,0x46,0x48,0x49,0x4b,0x4d,
0x4e,0x50,0x51,0x52,0x53,0x54,0x54,0x55,
0x55,0x55,0x55,0x55,0x54,0x54,0x53,0x52,
0x51,0x50,0x4e,0x4d,0x4b,0x49,0x48,0x46,
0x43,0x41,0x3f,0x3d,0x3a,0x38,0x35,0x32,
0x30,0x2d,0x2b,0x28,0x25,0x23,0x20,0x1d,
0x1b,0x18,0x16,0x14,0x12,0xf,0xd,0xc,
0xa,0x8,0x7,0x5,0x4,0x3,0x2,0x1,
0x1,0x0,0x0,0x0,0x0,0x0,0x1,0x1,
0x2,0x3,0x4,0x5,0x7,0x8,0xa,0xc,
0xd,0xf,0x12,0x14,0x16,0x18,0x1b,0x1d,
0x20,0x23,0x25,0x28,0x2b
};
int tri_1k[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
struct
{
int cnt;
int *amp;
} waveform[] =
{
{LEN(sine), sine},
{LEN(tri_1k), tri_1k}
};
void timer_callback()
{
uint8_t sample = (amp_factor * waveform[wave_select].amp[counter]) & 0x7F;
if (++counter >= waveform[wave_select].cnt) {
counter = 0;
}
select_dgi_spi();
tx_spi0(0x03);
tx_spi0(sample);
tx_spi0(0xFC);
deselect_dgi_spi();
}
spi.c
#include <avr/io.h>
#include "spi.h"
#include "pins.h"
void init_spi0(void)
{
VPORTA.DIR |= (1 << MOSI_PIN) | (1 << SCK_PIN);
VPORTF.DIR |= (1 << CS_PIN);
SPI0.CTRLA = 0 << SPI_CLK2X_bp | 0 << SPI_DORD_bp | 1 << SPI_MASTER_bp | SPI_PRESC_DIV64_gc;
SPI0.CTRLB = (1 << SPI_SSD_bp); // disable SS#
SPI0.CTRLA |= 1 << SPI_ENABLE_bp;
}
void select_dgi_spi(void)
{
VPORTF.OUT &= ~(1 << CS_PIN);
}
void deselect_dgi_spi(void)
{
VPORTF.OUT |= (1 << CS_PIN);
}
void tx_spi0(uint8_t tx_byte)
{
uint8_t tx_rdy = 0;
SPI0.DATA = tx_byte;
while(!tx_rdy)
tx_rdy = (SPI0.INTFLAGS & SPI_IF_bm );
}
void tx_string_spi0(char* tx_string)
{
while (*tx_string)
tx_spi0(*(tx_string++));
}
void tx_data_spi0(uint8_t tx_byte[], int length)
{
while (length--)
tx_spi0(*(tx_byte++));
}
timer_loop.c
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/cpufunc.h>
#include "timer_callback.h"
unsigned char period = 1;
unsigned char tick = 0;
ISR(TCB0_INT_vect)
{
TCB0.INTFLAGS = 0x01;
if (++tick > period) {
tick = 0;
timer_callback();
}
}