Commit 1f6c04ff authored by Jake Read's avatar Jake Read

add SPI alive and doc

parent 39617406
......@@ -326,4 +326,179 @@ So this shortened motor wires did seem to really kill the problem. Fin.
We're going to do this on the ATSAMD51, now. I have a v0.3 board here (which will shortly be rev'd to 0.31 due to a few already apparent mistakes, welp) and I can program it. I'm in the process of checking all of the hardware so that I can go forward with a new board order, knowing a bit better that I'll be o-k with that set.
So! I want to set up the project and check my clock settings and interrupts for good measure.
\ No newline at end of file
I've got the PWM up, and it's running as expected. Nice.
```C
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);
}
}
```
![atsamd51 pwm](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/programming-pwm-alive-atsamd51.png)
![atsamd51 pwm](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/programming-pwm-alive-atsamd51-picture.jpg)
Next up is the SPI wakeup.
Great, this is running as well.
```C
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);
/* BEGIN SPI SETUP */
// PA04, SER0-0, SPI_MISO
// PA05, SER0-1, SPI_SCK
// PA06, SER0-2, SPI_CSN
// PA07, SER0-3, SPI_MOSI
PORT->Group[0].DIRCLR.reg |= (uint32_t)(1 << 4);
PORT->Group[0].DIRSET.reg |= (uint32_t)(1 << 5) | (uint32_t)(1 << 6) | (uint32_t)(1 << 7);
PORT->Group[0].PINCFG[4].bit.PMUXEN = 1;
PORT->Group[0].PMUX[4>>1].reg |= PORT_PMUX_PMUXE(0x3); // on peripheral D
PORT->Group[0].PINCFG[5].bit.PMUXEN = 1;
PORT->Group[0].PMUX[5>>1].reg |= PORT_PMUX_PMUXO(0x3); // on peripheral D
PORT->Group[0].PINCFG[6].bit.PMUXEN = 1;
PORT->Group[0].PMUX[6>>1].reg |= PORT_PMUX_PMUXE(0x3); // on peripheral D
PORT->Group[0].PINCFG[7].bit.PMUXEN = 1;
PORT->Group[0].PMUX[7>>1].reg |= PORT_PMUX_PMUXO(0x3); // on peripheral D
// setup clocks to sercom
MCLK->APBAMASK.reg |= MCLK_APBAMASK_SERCOM0; // at 15.8.9
GCLK->GENCTRL[6].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | GCLK_GENCTRL_GENEN;
while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL6);
GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK6;
// TCC0_GCLK_ID
// Some registers can't be written unless CTRL.ENABLE = 0:
// CTRLA, CTRLB, BAD and ADDR
// (1) set to master
SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_MODE(0x3); // 0x2 or 0x3, slave or master
// SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_CPHA | SERCOM_SPI_CTRLA_CPOL; // clock phase and polarity
// (2) set pin configurations
SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_DIPO(0x0) | SERCOM_SPI_CTRLA_DOPO(0x2); // pin selections, see 35.8.1 bits 21:20 and 17:16, pg. 910
// (3) set character size, data direction
//SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_DORD; // 0 MSB, 1 LSB
//SERCOM0->SPI.CTRLB.reg |= SERCOM_SPI_CTRLB_CHSIZE(0x0); // 8 bits character - 0x0, so no need to set
// (4) setup baud rate
// f_baud = f_ref / (2 * (BAUD +1)) so BAUD = f_ref / (2 * f_baud) - 1
SERCOM0->SPI.BAUD.reg |= SERCOM_SPI_BAUD_BAUD(126);
SERCOM0->SPI.CTRLB.reg |= SERCOM_SPI_CTRLB_MSSEN | SERCOM_SPI_CTRLB_RXEN; // slave select hardware yes
SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;
while (1)
{
while(!(SERCOM0->SPI.INTFLAG.bit.DRE));
SERCOM0->SPI.DATA.reg = SERCOM_SPI_DATA_DATA(80);
PORT->Group[1].OUTTGL.reg = (uint32_t)(1 << 9); // i-v, to check we made it thru setup
}
}
```
![atsamd51 spi](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/programming-spi-alive-atsamd51.png)
Now we do v0.31 board, new step board, etc. Go team, big day.
\ No newline at end of file
......@@ -11,16 +11,7 @@
// 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);
void pwmsetup(void){
/* TCC SETUP */
// from 49.6.2.1
// a few registers are protected - and can only be updated when
......@@ -80,19 +71,93 @@ int main(void)
TCC0->COUNT.reg = 0;
TCC0->CC[0].reg = 12; // '3'
TCC0->CC[1].reg = 24; // '2'
TCC0->CC[2].reg = 48; // '1'
TCC0->CC[0].reg = 0; // '3'
TCC0->CC[1].reg = 0; // '2'
TCC0->CC[2].reg = 0; // '1'
TCC0->CC[3].reg = 0;
// (4) Enable with CTRLA.ENABLE
TCC0->CTRLA.bit.ENABLE = 1;
while(TCC0->SYNCBUSY.bit.ENABLE);
}
void pwmupdate(uint32_t one, uint32_t two, uint32_t three){
TCC0->CC[0].reg = three; // '3'
TCC0->CC[1].reg = two; // '2'
TCC0->CC[2].reg = one; // '1'
}
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);
/* BEGIN SPI SETUP */
// PA04, SER0-0, SPI_MISO
// PA05, SER0-1, SPI_SCK
// PA06, SER0-2, SPI_CSN
// PA07, SER0-3, SPI_MOSI
PORT->Group[0].DIRCLR.reg |= (uint32_t)(1 << 4);
PORT->Group[0].DIRSET.reg |= (uint32_t)(1 << 5) | (uint32_t)(1 << 6) | (uint32_t)(1 << 7);
PORT->Group[0].PINCFG[4].bit.PMUXEN = 1;
PORT->Group[0].PMUX[4>>1].reg |= PORT_PMUX_PMUXE(0x3); // on peripheral D
PORT->Group[0].PINCFG[5].bit.PMUXEN = 1;
PORT->Group[0].PMUX[5>>1].reg |= PORT_PMUX_PMUXO(0x3); // on peripheral D
PORT->Group[0].PINCFG[6].bit.PMUXEN = 1;
PORT->Group[0].PMUX[6>>1].reg |= PORT_PMUX_PMUXE(0x3); // on peripheral D
PORT->Group[0].PINCFG[7].bit.PMUXEN = 1;
PORT->Group[0].PMUX[7>>1].reg |= PORT_PMUX_PMUXO(0x3); // on peripheral D
// setup clocks to sercom
MCLK->APBAMASK.reg |= MCLK_APBAMASK_SERCOM0; // at 15.8.9
GCLK->GENCTRL[6].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | GCLK_GENCTRL_GENEN;
while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL6);
GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK6;
// TCC0_GCLK_ID
// Some registers can't be written unless CTRL.ENABLE = 0:
// CTRLA, CTRLB, BAD and ADDR
// (1) set to master
SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_MODE(0x3); // 0x2 or 0x3, slave or master
// SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_CPHA | SERCOM_SPI_CTRLA_CPOL; // clock phase and polarity
// (2) set pin configurations
SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_DIPO(0x0) | SERCOM_SPI_CTRLA_DOPO(0x2); // pin selections, see 35.8.1 bits 21:20 and 17:16, pg. 910
// (3) set character size, data direction
//SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_DORD; // 0 MSB, 1 LSB
//SERCOM0->SPI.CTRLB.reg |= SERCOM_SPI_CTRLB_CHSIZE(0x0); // 8 bits character - 0x0, so no need to set
// (4) setup baud rate
// f_baud = f_ref / (2 * (BAUD +1)) so BAUD = f_ref / (2 * f_baud) - 1
SERCOM0->SPI.BAUD.reg |= SERCOM_SPI_BAUD_BAUD(126);
SERCOM0->SPI.CTRLB.reg |= SERCOM_SPI_CTRLB_MSSEN | SERCOM_SPI_CTRLB_RXEN; // slave select hardware yes
SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;
while (1)
{
PORT->Group[1].OUTTGL.reg = (uint32_t)(1 << 9);
while(!(SERCOM0->SPI.INTFLAG.bit.DRE));
SERCOM0->SPI.DATA.reg = SERCOM_SPI_DATA_DATA(80);
PORT->Group[1].OUTTGL.reg = (uint32_t)(1 << 9); // i-v, to check we made it thru setup
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment