main.c 2.93 KB
Newer Older
Jake Read's avatar
Jake Read committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
/*
 * mkbldcdriver-v03.c
 *
 * Created: 1/14/2018 8:20:39 PM
 * Author : Jake
 */ 


#include "sam.h"
#include <stdio.h>

// stlb is PA23

int main(void)
{
    /* Initialize the SAM system */
    SystemInit();
	
	PORT->Group[1].DIRSET.reg |= (uint32_t)(1 << 9);
	PORT->Group[0].DIRSET.reg |= (uint32_t)(1 << 23);
	
	SysTick_Config(5000000);
	
	/* TCC SETUP */
	// from 49.6.2.1
	// a few registers are protected - and can only be updated when
	// TCCn.CTRLA.ENABLE = 0
	// FCTRLA and FCTRLB, WEXCTRL, DRVCTRL, and EVCTRL
	
	// (4) Configure Output Pin with PORT->Group[n].DIRSET.reg
	// PA8 PA9 PA10 PA12, PB10 PB11
	// 32.9.13
	PORT->Group[0].DIRSET.reg |= (uint32_t)(1 << 8) | (uint32_t)(1 << 9) | (uint32_t)(1 << 10) | (uint32_t)(1 << 12);
	PORT->Group[1].DIRSET.reg |= (uint32_t)(1 << 10) | (uint32_t)(1 << 11);
	
	// 1 lo / hi
	PORT->Group[0].PINCFG[10].bit.PMUXEN = 1;
	PORT->Group[0].PMUX[10>>1].reg |= PORT_PMUX_PMUXE(0x5);  // on peripheral F
	PORT->Group[0].PINCFG[12].bit.PMUXEN = 1;
	PORT->Group[0].PMUX[12>>1].reg |= PORT_PMUX_PMUXE(0x5); 
	
	// 2 lo / hi
	PORT->Group[0].PINCFG[9].bit.PMUXEN = 1;
	PORT->Group[0].PMUX[9>>1].reg |= PORT_PMUX_PMUXO(0x5);  // on peripheral F
	PORT->Group[1].PINCFG[11].bit.PMUXEN = 1;
	PORT->Group[1].PMUX[11>>1].reg |= PORT_PMUX_PMUXO(0x5);
	
	// 3 lo / hi
	PORT->Group[0].PINCFG[8].bit.PMUXEN = 1;
	PORT->Group[0].PMUX[8>>1].reg |= PORT_PMUX_PMUXE(0x5);  // on peripheral F
	PORT->Group[1].PINCFG[10].bit.PMUXEN = 1;
	PORT->Group[1].PMUX[10>>1].reg |= PORT_PMUX_PMUXE(0x5);
	
	// (1) enable the TCC Bus Clock - CLK_TCCn_APB
	// https://www.eevblog.com/forum/microcontrollers/atmel-sam-d-tc-and-tcc-(no-asf)/
	
	TCC0->CTRLA.bit.ENABLE = 0;
	
	MCLK->APBBMASK.reg |= MCLK_APBBMASK_TCC0; // at 15.8.9
	
	GCLK->GENCTRL[5].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | GCLK_GENCTRL_GENEN;
	while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL5);
	
	GCLK->PCHCTRL[TCC0_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK5;
	
	TCC0->CTRLA.reg |= TCC_CTRLA_PRESCALER_DIV8 | TCC_CTRLA_PRESCSYNC_PRESC |TCC_CTRLA_RESOLUTION(0);
	
	// (2) Select Waveform Generation operation in the WAVE register WAVE.WAVEGEN
	// we want dual slope pwm
		
	TCC0->WAVE.reg = TCC_WAVE_WAVEGEN_DSBOTH; // 'dual slope both' - updates on both hi and lo of slope ?
		
	// (3) We want OTMX - Output Matrix Channel Pin Routing Configuration - at 0x0
	
	TCC0->WEXCTRL.reg = TCC_WEXCTRL_DTHS(1) | TCC_WEXCTRL_DTLS(1) | 
						TCC_WEXCTRL_DTIEN1 | TCC_WEXCTRL_DTIEN2 | TCC_WEXCTRL_DTIEN3 | TCC_WEXCTRL_DTIEN0 |
						TCC_WEXCTRL_OTMX(0);
						
	TCC0->PER.reg = TCC_PER_PER(256); // 18 bit
	
	TCC0->COUNT.reg = 0;
	
	TCC0->CC[0].reg = 12; // '3'
	TCC0->CC[1].reg = 24; // '2'
	TCC0->CC[2].reg = 48; // '1'
	TCC0->CC[3].reg = 0;
	
	// (4) Enable with CTRLA.ENABLE
	
	TCC0->CTRLA.bit.ENABLE = 1;
	while(TCC0->SYNCBUSY.bit.ENABLE);

    while (1) 
    {
		PORT->Group[1].OUTTGL.reg = (uint32_t)(1 << 9);
    }
}

void SysTick_Handler(void){
	PORT->Group[0].OUTTGL.reg = (uint32_t)(1 << 23);
}