source: rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/SERCOM.cpp@ 175

Last change on this file since 175 was 175, checked in by ertl-honda, 8 years ago

ライブラリを Arduino IDE 1.7.9 にupdate

File size: 16.4 KB
Line 
1/*
2 Copyright (c) 2014 Arduino. All right reserved.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 See the GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17*/
18
19#include "SERCOM.h"
20#include "variant.h"
21
22
23SERCOM::SERCOM(Sercom* s)
24{
25 sercom = s;
26}
27
28/* =========================
29 * ===== Sercom UART
30 * =========================
31*/
32void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate)
33{
34 initClockNVIC();
35 resetUART();
36
37 //Setting the CTRLA register
38 sercom->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE(mode) |
39 SERCOM_USART_CTRLA_SAMPR(sampleRate);
40
41 //Setting the Interrupt register
42 sercom->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC | //Received complete
43 SERCOM_USART_INTENSET_ERROR; //All others errors
44
45 if ( mode == UART_INT_CLOCK )
46 {
47 uint16_t sampleRateValue;
48
49 if (sampleRate == SAMPLE_RATE_x16) {
50 sampleRateValue = 16;
51 } else {
52 sampleRateValue = 8;
53 }
54
55 // Asynchronous fractional mode (Table 24-2 in datasheet)
56 // BAUD = fref / (sampleRateValue * fbaud)
57 // (multiply by 8, to calculate fractional piece)
58 uint32_t baudTimes8 = (SystemCoreClock * 8) / (sampleRateValue * baudrate);
59
60 sercom->USART.BAUD.FRAC.FP = (baudTimes8 % 8);
61 sercom->USART.BAUD.FRAC.BAUD = (baudTimes8 / 8);
62 }
63}
64void SERCOM::initFrame(SercomUartCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits)
65{
66 //Setting the CTRLA register
67 sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_FORM( (parityMode == SERCOM_NO_PARITY ? 0 : 1) ) |
68 dataOrder << SERCOM_USART_CTRLA_DORD_Pos;
69
70 //Setting the CTRLB register
71 sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_CHSIZE(charSize) |
72 nbStopBits << SERCOM_USART_CTRLB_SBMODE_Pos |
73 (parityMode == SERCOM_NO_PARITY ? 0 : parityMode) << SERCOM_USART_CTRLB_PMODE_Pos; //If no parity use default value
74}
75
76void SERCOM::initPads(SercomUartTXPad txPad, SercomRXPad rxPad)
77{
78 //Setting the CTRLA register
79 sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_TXPO(txPad) |
80 SERCOM_USART_CTRLA_RXPO(rxPad);
81
82 // Enable Transceiver and Receiver
83 sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_RXEN ;
84}
85
86void SERCOM::resetUART()
87{
88 // Start the Software Reset
89 sercom->USART.CTRLA.bit.SWRST = 1 ;
90
91 while ( sercom->USART.CTRLA.bit.SWRST || sercom->USART.SYNCBUSY.bit.SWRST )
92 {
93 // Wait for both bits Software Reset from CTRLA and SYNCBUSY coming back to 0
94 }
95}
96
97void SERCOM::enableUART()
98{
99 //Setting the enable bit to 1
100 sercom->USART.CTRLA.bit.ENABLE = 0x1u;
101
102 //Wait for then enable bit from SYNCBUSY is equal to 0;
103 while(sercom->USART.SYNCBUSY.bit.ENABLE);
104}
105
106void SERCOM::flushUART()
107{
108 // Wait for transmission to complete
109 while(!sercom->USART.INTFLAG.bit.TXC);
110}
111
112void SERCOM::clearStatusUART()
113{
114 //Reset (with 0) the STATUS register
115 sercom->USART.STATUS.reg = SERCOM_USART_STATUS_RESETVALUE;
116}
117
118bool SERCOM::availableDataUART()
119{
120 //RXC : Receive Complete
121 return sercom->USART.INTFLAG.bit.RXC;
122}
123
124bool SERCOM::isUARTError()
125{
126 return sercom->USART.INTFLAG.bit.ERROR;
127}
128
129void SERCOM::acknowledgeUARTError()
130{
131 sercom->USART.INTFLAG.bit.ERROR = 1;
132}
133
134bool SERCOM::isBufferOverflowErrorUART()
135{
136 //BUFOVF : Buffer Overflow
137 return sercom->USART.STATUS.bit.BUFOVF;
138}
139
140bool SERCOM::isFrameErrorUART()
141{
142 //FERR : Frame Error
143 return sercom->USART.STATUS.bit.FERR;
144}
145
146bool SERCOM::isParityErrorUART()
147{
148 //PERR : Parity Error
149 return sercom->USART.STATUS.bit.PERR;
150}
151
152bool SERCOM::isDataRegisterEmptyUART()
153{
154 //DRE : Data Register Empty
155 return sercom->USART.INTFLAG.bit.DRE;
156}
157
158uint8_t SERCOM::readDataUART()
159{
160 return sercom->USART.DATA.bit.DATA;
161}
162
163int SERCOM::writeDataUART(uint8_t data)
164{
165 // Wait for data register to be empty
166 while(!isDataRegisterEmptyUART());
167
168 //Put data into DATA register
169 sercom->USART.DATA.reg = (uint16_t)data;
170 return 1;
171}
172
173/* =========================
174 * ===== Sercom SPI
175 * =========================
176*/
177void SERCOM::initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder)
178{
179 resetSPI();
180 initClockNVIC();
181
182 //Setting the CTRLA register
183 sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE_SPI_MASTER |
184 SERCOM_SPI_CTRLA_DOPO(mosi) |
185 SERCOM_SPI_CTRLA_DIPO(miso) |
186 dataOrder << SERCOM_SPI_CTRLA_DORD_Pos;
187
188 //Setting the CTRLB register
189 sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(charSize) |
190 SERCOM_SPI_CTRLB_RXEN; //Active the SPI receiver.
191
192
193}
194
195void SERCOM::initSPIslave(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder)
196{
197 resetSPI();
198 initClockNVIC();
199
200 sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE_SPI_SLAVE |
201 SERCOM_SPI_CTRLA_DOPO(mosi) | //provo a modificare
202 SERCOM_SPI_CTRLA_DIPO(miso) | //provo a modificare
203 dataOrder << SERCOM_SPI_CTRLA_DORD_Pos;
204
205 sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(charSize) |
206 SERCOM_SPI_CTRLB_RXEN; //Active the SPI receiver.
207
208}
209
210void SERCOM::initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate)
211{
212 //Extract data from clockMode
213 int cpha, cpol;
214
215 if((clockMode & (0x1ul)) == 0 )
216 cpha = 0;
217 else
218 cpha = 1;
219
220 if((clockMode & (0x2ul)) == 0)
221 cpol = 0;
222 else
223 cpol = 1;
224
225 //Setting the CTRLA register
226 sercom->SPI.CTRLA.reg |= ( cpha << SERCOM_SPI_CTRLA_CPHA_Pos ) |
227 ( cpol << SERCOM_SPI_CTRLA_CPOL_Pos );
228
229 //Synchronous arithmetic
230 sercom->SPI.BAUD.reg = calculateBaudrateSynchronous(baudrate);
231}
232
233void SERCOM::resetSPI()
234{
235 //Setting the Software Reset bit to 1
236 sercom->SPI.CTRLA.bit.SWRST = 1;
237
238 //Wait both bits Software Reset from CTRLA and SYNCBUSY are equal to 0
239 while(sercom->SPI.CTRLA.bit.SWRST || sercom->SPI.SYNCBUSY.bit.SWRST);
240}
241
242void SERCOM::enableSPI()
243{
244 //Setting the enable bit to 1
245 sercom->SPI.CTRLA.bit.ENABLE = 1;
246
247 while(sercom->SPI.SYNCBUSY.bit.ENABLE)
248 {
249 //Waiting then enable bit from SYNCBUSY is equal to 0;
250 }
251}
252
253void SERCOM::disableSPI()
254{
255 //Setting the enable bit to 0
256 sercom->SPI.CTRLA.bit.ENABLE = 0;
257
258 while(sercom->SPI.SYNCBUSY.bit.ENABLE)
259 {
260 //Waiting then enable bit from SYNCBUSY is equal to 0;
261 }
262}
263
264void SERCOM::setDataOrderSPI(SercomDataOrder dataOrder)
265{
266 //Register enable-protected
267 disableSPI();
268
269 sercom->SPI.CTRLA.bit.DORD = dataOrder;
270
271 enableSPI();
272}
273
274SercomDataOrder SERCOM::getDataOrderSPI()
275{
276 return (sercom->SPI.CTRLA.bit.DORD ? LSB_FIRST : MSB_FIRST);
277}
278
279void SERCOM::setBaudrateSPI(uint16_t divider)
280{
281 //Can't divide by 0
282 if(divider == 0)
283 return;
284
285 //Register enable-protected
286 disableSPI();
287
288 sercom->SPI.BAUD.reg = calculateBaudrateSynchronous( SERCOM_FREQ_REF / divider );
289
290 enableSPI();
291}
292
293void SERCOM::setClockModeSPI(SercomSpiClockMode clockMode)
294{
295 int cpha, cpol;
296 if((clockMode & (0x1ul)) == 0)
297 cpha = 0;
298 else
299 cpha = 1;
300
301 if((clockMode & (0x2ul)) == 0)
302 cpol = 0;
303 else
304 cpol = 1;
305
306 //Register enable-protected
307 disableSPI();
308
309 sercom->SPI.CTRLA.bit.CPOL = cpol;
310 sercom->SPI.CTRLA.bit.CPHA = cpha;
311
312 enableSPI();
313}
314
315void SERCOM::writeDataSPI(uint8_t data)
316{
317 while( sercom->SPI.INTFLAG.bit.DRE == 0 )
318 {
319 // Waiting Data Registry Empty
320 }
321 sercom->SPI.DATA.bit.DATA = data; // Writing data into Data register
322
323 while( sercom->SPI.INTFLAG.bit.TXC == 0 || sercom->SPI.INTFLAG.bit.DRE == 0 )
324 {
325 // Waiting Complete Transmission
326 }
327}
328
329uint16_t SERCOM::readDataSPI()
330{
331 while( sercom->SPI.INTFLAG.bit.DRE == 0 || sercom->SPI.INTFLAG.bit.RXC == 0 )
332 {
333 // Waiting Complete Reception
334 }
335
336 return sercom->SPI.DATA.bit.DATA; // Reading data
337}
338
339bool SERCOM::isBufferOverflowErrorSPI()
340{
341 return sercom->SPI.STATUS.bit.BUFOVF;
342}
343
344bool SERCOM::isDataRegisterEmptySPI()
345{
346 //DRE : Data Register Empty
347 return sercom->SPI.INTFLAG.bit.DRE;
348}
349
350//bool SERCOM::isTransmitCompleteSPI()
351//{
352// //TXC : Transmit complete
353// return sercom->SPI.INTFLAG.bit.TXC;
354//}
355//
356//bool SERCOM::isReceiveCompleteSPI()
357//{
358// //RXC : Receive complete
359// return sercom->SPI.INTFLAG.bit.RXC;
360//}
361
362uint8_t SERCOM::calculateBaudrateSynchronous(uint32_t baudrate)
363{
364 return SERCOM_FREQ_REF / (2 * baudrate) - 1;
365}
366
367
368/* =========================
369 * ===== Sercom WIRE
370 * =========================
371 */
372void SERCOM::resetWIRE()
373{
374 //I2CM OR I2CS, no matter SWRST is the same bit.
375
376 //Setting the Software bit to 1
377 sercom->I2CM.CTRLA.bit.SWRST = 1;
378
379 //Wait both bits Software Reset from CTRLA and SYNCBUSY are equal to 0
380 while(sercom->I2CM.CTRLA.bit.SWRST || sercom->I2CM.SYNCBUSY.bit.SWRST);
381}
382
383void SERCOM::enableWIRE()
384{
385 // I2C Master and Slave modes share the ENABLE bit function.
386
387 // Enable the I²C master mode
388 sercom->I2CM.CTRLA.bit.ENABLE = 1 ;
389
390 while ( sercom->I2CM.SYNCBUSY.bit.ENABLE != 0 )
391 {
392 // Waiting the enable bit from SYNCBUSY is equal to 0;
393 }
394
395 // Setting bus idle mode
396 sercom->I2CM.STATUS.bit.BUSSTATE = 1 ;
397
398 while ( sercom->I2CM.SYNCBUSY.bit.SYSOP != 0 )
399 {
400 // Wait the SYSOP bit from SYNCBUSY coming back to 0
401 }
402}
403
404void SERCOM::disableWIRE()
405{
406 // I2C Master and Slave modes share the ENABLE bit function.
407
408 // Enable the I²C master mode
409 sercom->I2CM.CTRLA.bit.ENABLE = 0 ;
410
411 while ( sercom->I2CM.SYNCBUSY.bit.ENABLE != 0 )
412 {
413 // Waiting the enable bit from SYNCBUSY is equal to 0;
414 }
415}
416
417void SERCOM::initSlaveWIRE( uint8_t ucAddress )
418{
419 // Initialize the peripheral clock and interruption
420 initClockNVIC() ;
421 resetWIRE() ;
422
423 // Set slave mode
424 sercom->I2CS.CTRLA.bit.MODE = I2C_SLAVE_OPERATION ;
425
426 sercom->I2CS.ADDR.reg = SERCOM_I2CS_ADDR_ADDR( ucAddress & 0x7Ful ) | // 0x7F, select only 7 bits
427 SERCOM_I2CS_ADDR_ADDRMASK( 0x3FFul ) ; // 0x3FF all bits set
428
429 // Set the interrupt register
430 sercom->I2CS.INTENSET.reg = SERCOM_I2CS_INTENSET_PREC | // Stop
431 SERCOM_I2CS_INTENSET_AMATCH | // Address Match
432 SERCOM_I2CS_INTENSET_DRDY ; // Data Ready
433
434 while ( sercom->I2CM.SYNCBUSY.bit.SYSOP != 0 )
435 {
436 // Wait the SYSOP bit from SYNCBUSY to come back to 0
437 }
438}
439
440void SERCOM::initMasterWIRE( uint32_t baudrate )
441{
442 // Initialize the peripheral clock and interruption
443 initClockNVIC() ;
444
445 resetWIRE() ;
446
447 // Set master mode and enable SCL Clock Stretch mode (stretch after ACK bit)
448 sercom->I2CM.CTRLA.reg = SERCOM_I2CM_CTRLA_MODE( I2C_MASTER_OPERATION )/* |
449 SERCOM_I2CM_CTRLA_SCLSM*/ ;
450
451 // Enable Smart mode and Quick Command
452 //sercom->I2CM.CTRLB.reg = SERCOM_I2CM_CTRLB_SMEN /*| SERCOM_I2CM_CTRLB_QCEN*/ ;
453
454
455 // Enable all interrupts
456// sercom->I2CM.INTENSET.reg = SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB | SERCOM_I2CM_INTENSET_ERROR ;
457
458 // Synchronous arithmetic baudrate
459 sercom->I2CM.BAUD.bit.BAUD = SystemCoreClock / ( 2 * baudrate) - 1 ;
460}
461
462void SERCOM::prepareNackBitWIRE( void )
463{
464 if(isMasterWIRE()) {
465 // Send a NACK
466 sercom->I2CM.CTRLB.bit.ACKACT = 1;
467 } else {
468 sercom->I2CS.CTRLB.bit.ACKACT = 1;
469 }
470}
471
472void SERCOM::prepareAckBitWIRE( void )
473{
474 if(isMasterWIRE()) {
475 // Send an ACK
476 sercom->I2CM.CTRLB.bit.ACKACT = 0;
477 } else {
478 sercom->I2CS.CTRLB.bit.ACKACT = 0;
479 }
480}
481
482void SERCOM::prepareCommandBitsWire(uint8_t cmd)
483{
484 if(isMasterWIRE()) {
485 sercom->I2CM.CTRLB.bit.CMD = cmd;
486
487 while(sercom->I2CM.SYNCBUSY.bit.SYSOP)
488 {
489 // Waiting for synchronization
490 }
491 } else {
492 sercom->I2CS.CTRLB.bit.CMD = cmd;
493 }
494}
495
496bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag)
497{
498 // 7-bits address + 1-bits R/W
499 address = (address << 0x1ul) | flag;
500
501
502 // Wait idle or owner bus mode
503 while ( !isBusIdleWIRE() && !isBusOwnerWIRE() );
504
505 // Send start and address
506 sercom->I2CM.ADDR.bit.ADDR = address;
507
508
509 // Address Transmitted
510 if ( flag == WIRE_WRITE_FLAG ) // Write mode
511 {
512 while( !sercom->I2CM.INTFLAG.bit.MB )
513 {
514 // Wait transmission complete
515 }
516 }
517 else // Read mode
518 {
519 while( !sercom->I2CM.INTFLAG.bit.SB )
520 {
521 // If the slave NACKS the address, the MB bit will be set.
522 // In that case, send a stop condition and return false.
523 if (sercom->I2CM.INTFLAG.bit.MB) {
524 sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition
525 return false;
526 }
527 // Wait transmission complete
528 }
529
530 // Clean the 'Slave on Bus' flag, for further usage.
531 //sercom->I2CM.INTFLAG.bit.SB = 0x1ul;
532 }
533
534
535 //ACK received (0: ACK, 1: NACK)
536 if(sercom->I2CM.STATUS.bit.RXNACK)
537 {
538 return false;
539 }
540 else
541 {
542 return true;
543 }
544}
545
546bool SERCOM::sendDataMasterWIRE(uint8_t data)
547{
548 //Send data
549 sercom->I2CM.DATA.bit.DATA = data;
550
551 //Wait transmission successful
552 while(!sercom->I2CM.INTFLAG.bit.MB) {
553
554 // If a bus error occurs, the MB bit may never be set.
555 // Check the bus error bit and bail if it's set.
556 if (sercom->I2CM.STATUS.bit.BUSERR) {
557 return false;
558 }
559 }
560
561 //Problems on line? nack received?
562 if(sercom->I2CM.STATUS.bit.RXNACK)
563 return false;
564 else
565 return true;
566}
567
568bool SERCOM::sendDataSlaveWIRE(uint8_t data)
569{
570 //Send data
571 sercom->I2CS.DATA.bit.DATA = data;
572
573 //Wait data transmission successful
574 while(!sercom->I2CS.INTFLAG.bit.DRDY);
575
576 //Problems on line? nack received?
577 if(sercom->I2CS.STATUS.bit.RXNACK)
578 return false;
579 else
580 return true;
581}
582
583bool SERCOM::isMasterWIRE( void )
584{
585 return sercom->I2CS.CTRLA.bit.MODE == I2C_MASTER_OPERATION;
586}
587
588bool SERCOM::isSlaveWIRE( void )
589{
590 return sercom->I2CS.CTRLA.bit.MODE == I2C_SLAVE_OPERATION;
591}
592
593bool SERCOM::isBusIdleWIRE( void )
594{
595 return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_IDLE_STATE;
596}
597
598bool SERCOM::isBusOwnerWIRE( void )
599{
600 return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_OWNER_STATE;
601}
602
603bool SERCOM::isDataReadyWIRE( void )
604{
605 return sercom->I2CS.INTFLAG.bit.DRDY;
606}
607
608bool SERCOM::isStopDetectedWIRE( void )
609{
610 return sercom->I2CS.INTFLAG.bit.PREC;
611}
612
613bool SERCOM::isRestartDetectedWIRE( void )
614{
615 return sercom->I2CS.STATUS.bit.SR;
616}
617
618bool SERCOM::isAddressMatch( void )
619{
620 return sercom->I2CS.INTFLAG.bit.AMATCH;
621}
622
623bool SERCOM::isMasterReadOperationWIRE( void )
624{
625 return sercom->I2CS.STATUS.bit.DIR;
626}
627
628bool SERCOM::isRXNackReceivedWIRE( void )
629{
630 return sercom->I2CM.STATUS.bit.RXNACK;
631}
632
633int SERCOM::availableWIRE( void )
634{
635 if(isMasterWIRE())
636 return sercom->I2CM.INTFLAG.bit.SB;
637 else
638 return sercom->I2CS.INTFLAG.bit.DRDY;
639}
640
641uint8_t SERCOM::readDataWIRE( void )
642{
643 if(isMasterWIRE())
644 {
645 while( sercom->I2CM.INTFLAG.bit.SB == 0 )
646 {
647 // Waiting complete receive
648 }
649
650 return sercom->I2CM.DATA.bit.DATA ;
651 }
652 else
653 {
654 return sercom->I2CS.DATA.reg ;
655 }
656}
657
658
659void SERCOM::initClockNVIC( void )
660{
661 uint8_t clockId = 0;
662 IRQn_Type IdNvic=PendSV_IRQn ; // Dummy init to intercept potential error later
663
664 if(sercom == SERCOM0)
665 {
666 clockId = GCM_SERCOM0_CORE;
667 IdNvic = SERCOM0_IRQn;
668 }
669 else if(sercom == SERCOM1)
670 {
671 clockId = GCM_SERCOM1_CORE;
672 IdNvic = SERCOM1_IRQn;
673 }
674 else if(sercom == SERCOM2)
675 {
676 clockId = GCM_SERCOM2_CORE;
677 IdNvic = SERCOM2_IRQn;
678 }
679 else if(sercom == SERCOM3)
680 {
681 clockId = GCM_SERCOM3_CORE;
682 IdNvic = SERCOM3_IRQn;
683 }
684 else if(sercom == SERCOM4)
685 {
686 clockId = GCM_SERCOM4_CORE;
687 IdNvic = SERCOM4_IRQn;
688 }
689 else if(sercom == SERCOM5)
690 {
691 clockId = GCM_SERCOM5_CORE;
692 IdNvic = SERCOM5_IRQn;
693 }
694
695 if ( IdNvic == PendSV_IRQn )
696 {
697 // We got a problem here
698 return ;
699 }
700
701 // Setting NVIC
702 NVIC_EnableIRQ(IdNvic);
703 NVIC_SetPriority (IdNvic, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority */
704
705 //Setting clock
706 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOMx)
707 GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source
708 GCLK_CLKCTRL_CLKEN ;
709
710 while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
711 {
712 /* Wait for synchronization */
713 }
714}
Note: See TracBrowser for help on using the repository browser.