Skip to content

Commit 2ccd441

Browse files
author
Jim Lindblom
committed
Updating cores to match 1.6.5 Arduino samd definitions.
1 parent 720cfc1 commit 2ccd441

19 files changed

+417
-185
lines changed

sparkfun/samd/cores/arduino/HardwareSerial.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class HardwareSerial : public Stream
6868
{
6969
public:
7070
virtual void begin(unsigned long);
71+
virtual void begin(unsigned long baudrate, uint16_t config);
7172
virtual void end();
7273
virtual int available(void) = 0;
7374
virtual int peek(void) = 0;

sparkfun/samd/cores/arduino/Print.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ size_t Print::println(const Printable& x)
188188

189189
// Private Methods /////////////////////////////////////////////////////////////
190190

191-
size_t Print::printNumber(unsigned long n, uint8_t base) {
191+
size_t Print::printNumber(unsigned long n, uint8_t base)
192+
{
192193
char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
193194
char *str = &buf[sizeof(buf) - 1];
194195

@@ -198,9 +199,9 @@ size_t Print::printNumber(unsigned long n, uint8_t base) {
198199
if (base < 2) base = 10;
199200

200201
do {
201-
unsigned long m = n;
202+
char c = n % base;
202203
n /= base;
203-
char c = m - base * n;
204+
204205
*--str = c < 10 ? c + '0' : c + 'A' - 10;
205206
} while(n);
206207

sparkfun/samd/cores/arduino/SERCOM.cpp

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -43,28 +43,21 @@ void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint
4343

4444
if ( mode == UART_INT_CLOCK )
4545
{
46-
uint16_t sampleRateValue ;
46+
uint16_t sampleRateValue;
4747

48-
if ( sampleRate == SAMPLE_RATE_x16 )
49-
{
50-
sampleRateValue = 16 ;
51-
}
52-
else
53-
{
54-
if ( sampleRate == SAMPLE_RATE_x8 )
55-
{
56-
sampleRateValue = 8 ;
57-
}
58-
else
59-
{
60-
sampleRateValue = 3 ;
61-
}
48+
if (sampleRate == SAMPLE_RATE_x16) {
49+
sampleRateValue = 16;
50+
} else {
51+
sampleRateValue = 8;
6252
}
6353

64-
// Asynchronous arithmetic mode
65-
// 65535 * ( 1 - sampleRateValue * baudrate / SystemCoreClock);
66-
// 65535 - 65535 * (sampleRateValue * baudrate / SystemCoreClock));
67-
sercom->USART.BAUD.reg = 65535.0f * ( 1.0f - (float)(sampleRateValue) * (float)(baudrate) / (float)(SystemCoreClock));
54+
// Asynchronous fractional mode (Table 24-2 in datasheet)
55+
// BAUD = fref / (sampleRateValue * fbaud)
56+
// (multiply by 8, to calculate fractional piece)
57+
uint32_t baudTimes8 = (SystemCoreClock * 8) / (sampleRateValue * baudrate);
58+
59+
sercom->USART.BAUD.FRAC.FP = (baudTimes8 % 8);
60+
sercom->USART.BAUD.FRAC.BAUD = (baudTimes8 / 8);
6861
}
6962
}
7063
void SERCOM::initFrame(SercomUartCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits)
@@ -112,7 +105,7 @@ void SERCOM::enableUART()
112105
void SERCOM::flushUART()
113106
{
114107
// Wait for transmission to complete
115-
while(sercom->USART.INTFLAG.bit.DRE != SERCOM_USART_INTFLAG_DRE);
108+
while(!sercom->USART.INTFLAG.bit.TXC);
116109
}
117110

118111
void SERCOM::clearStatusUART()
@@ -168,8 +161,8 @@ uint8_t SERCOM::readDataUART()
168161

169162
int SERCOM::writeDataUART(uint8_t data)
170163
{
171-
//Flush UART buffer
172-
flushUART();
164+
// Wait for data register to be empty
165+
while(!isDataRegisterEmptyUART());
173166

174167
//Put data into DATA register
175168
sercom->USART.DATA.reg = (uint16_t)data;
@@ -262,6 +255,11 @@ void SERCOM::setDataOrderSPI(SercomDataOrder dataOrder)
262255
enableSPI();
263256
}
264257

258+
SercomDataOrder SERCOM::getDataOrderSPI()
259+
{
260+
return (sercom->SPI.CTRLA.bit.DORD ? LSB_FIRST : MSB_FIRST);
261+
}
262+
265263
void SERCOM::setBaudrateSPI(uint8_t divider)
266264
{
267265
//Can't divide by 0
@@ -410,14 +408,12 @@ void SERCOM::initSlaveWIRE( uint8_t ucAddress )
410408
// Set slave mode
411409
sercom->I2CS.CTRLA.bit.MODE = I2C_SLAVE_OPERATION ;
412410

413-
// Enable Quick Command
414-
sercom->I2CM.CTRLB.bit.QCEN = 1 ;
415-
416411
sercom->I2CS.ADDR.reg = SERCOM_I2CS_ADDR_ADDR( ucAddress & 0x7Ful ) | // 0x7F, select only 7 bits
417-
SERCOM_I2CS_ADDR_ADDRMASK( 0x3FFul ) ; // 0x3FF all bits set
412+
SERCOM_I2CS_ADDR_ADDRMASK( 0x00ul ) ; // 0x00, only match exact address
418413

419414
// Set the interrupt register
420-
sercom->I2CS.INTENSET.reg = SERCOM_I2CS_INTENSET_AMATCH | // Address Match
415+
sercom->I2CS.INTENSET.reg = SERCOM_I2CS_INTENSET_PREC | // Stop
416+
SERCOM_I2CS_INTENSET_AMATCH | // Address Match
421417
SERCOM_I2CS_INTENSET_DRDY ; // Data Ready
422418

423419
while ( sercom->I2CM.SYNCBUSY.bit.SYSOP != 0 )
@@ -450,23 +446,35 @@ void SERCOM::initMasterWIRE( uint32_t baudrate )
450446

451447
void SERCOM::prepareNackBitWIRE( void )
452448
{
453-
// Send a NACK
454-
sercom->I2CM.CTRLB.bit.ACKACT = 1;
449+
if(isMasterWIRE()) {
450+
// Send a NACK
451+
sercom->I2CM.CTRLB.bit.ACKACT = 1;
452+
} else {
453+
sercom->I2CS.CTRLB.bit.ACKACT = 1;
454+
}
455455
}
456456

457457
void SERCOM::prepareAckBitWIRE( void )
458458
{
459-
// Send an ACK
460-
sercom->I2CM.CTRLB.bit.ACKACT = 0;
459+
if(isMasterWIRE()) {
460+
// Send an ACK
461+
sercom->I2CM.CTRLB.bit.ACKACT = 0;
462+
} else {
463+
sercom->I2CS.CTRLB.bit.ACKACT = 0;
464+
}
461465
}
462466

463-
void SERCOM::prepareCommandBitsWire(SercomMasterCommandWire cmd)
467+
void SERCOM::prepareCommandBitsWire(uint8_t cmd)
464468
{
465-
sercom->I2CM.CTRLB.bit.CMD = cmd;
469+
if(isMasterWIRE()) {
470+
sercom->I2CM.CTRLB.bit.CMD = cmd;
466471

467-
while(sercom->I2CM.SYNCBUSY.bit.SYSOP)
468-
{
469-
// Waiting for synchronization
472+
while(sercom->I2CM.SYNCBUSY.bit.SYSOP)
473+
{
474+
// Waiting for synchronization
475+
}
476+
} else {
477+
sercom->I2CS.CTRLB.bit.CMD = cmd;
470478
}
471479
}
472480

@@ -475,8 +483,8 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag
475483
// 7-bits address + 1-bits R/W
476484
address = (address << 0x1ul) | flag;
477485

478-
// Wait idle bus mode
479-
while ( !isBusIdleWIRE() );
486+
// Wait idle or owner bus mode
487+
while ( !isBusIdleWIRE() && !isBusOwnerWIRE() );
480488

481489
// Send start and address
482490
sercom->I2CM.ADDR.bit.ADDR = address;
@@ -570,6 +578,11 @@ bool SERCOM::isBusIdleWIRE( void )
570578
return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_IDLE_STATE;
571579
}
572580

581+
bool SERCOM::isBusOwnerWIRE( void )
582+
{
583+
return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_OWNER_STATE;
584+
}
585+
573586
bool SERCOM::isDataReadyWIRE( void )
574587
{
575588
return sercom->I2CS.INTFLAG.bit.DRDY;

sparkfun/samd/cores/arduino/SERCOM.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,8 @@ typedef enum
8686

8787
typedef enum
8888
{
89-
SAMPLE_RATE_x16 = 0, //Arithmetic
90-
SAMPLE_RATE_x8 = 0x2, //Arithmetic
91-
SAMPLE_RATE_x3 = 0x3 //Arithmetic
89+
SAMPLE_RATE_x16 = 0x1, //Fractional
90+
SAMPLE_RATE_x8 = 0x3, //Fractional
9291
} SercomUartSampleRate;
9392

9493
typedef enum
@@ -173,6 +172,7 @@ class SERCOM
173172
void enableSPI( void ) ;
174173
void disableSPI( void ) ;
175174
void setDataOrderSPI(SercomDataOrder dataOrder) ;
175+
SercomDataOrder getDataOrderSPI( void ) ;
176176
void setBaudrateSPI(uint8_t divider) ;
177177
void setClockModeSPI(SercomSpiClockMode clockMode) ;
178178
void writeDataSPI(uint8_t data) ;
@@ -191,13 +191,14 @@ class SERCOM
191191
void disableWIRE( void );
192192
void prepareNackBitWIRE( void ) ;
193193
void prepareAckBitWIRE( void ) ;
194-
void prepareCommandBitsWire(SercomMasterCommandWire cmd);
194+
void prepareCommandBitsWire(uint8_t cmd);
195195
bool startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag) ;
196196
bool sendDataMasterWIRE(uint8_t data) ;
197197
bool sendDataSlaveWIRE(uint8_t data) ;
198198
bool isMasterWIRE( void ) ;
199199
bool isSlaveWIRE( void ) ;
200200
bool isBusIdleWIRE( void ) ;
201+
bool isBusOwnerWIRE( void ) ;
201202
bool isDataReadyWIRE( void ) ;
202203
bool isStopDetectedWIRE( void ) ;
203204
bool isRestartDetectedWIRE( void ) ;

sparkfun/samd/cores/arduino/Stream.cpp

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include "Stream.h"
2727

2828
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
29-
#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
3029

3130
// private method to read stream with timeout
3231
int Stream::timedRead()
@@ -54,14 +53,30 @@ int Stream::timedPeek()
5453

5554
// returns peek of the next digit in the stream or -1 if timeout
5655
// discards non-numeric characters
57-
int Stream::peekNextDigit()
56+
int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal)
5857
{
5958
int c;
6059
while (1) {
6160
c = timedPeek();
62-
if (c < 0) return c; // timeout
63-
if (c == '-') return c;
64-
if (c >= '0' && c <= '9') return c;
61+
62+
if( c < 0 ||
63+
c == '-' ||
64+
(c >= '0' && c <= '9') ||
65+
(detectDecimal && c == '.')) return c;
66+
67+
switch( lookahead ){
68+
case SKIP_NONE: return -1; // Fail code.
69+
case SKIP_WHITESPACE:
70+
switch( c ){
71+
case ' ':
72+
case '\t':
73+
case '\r':
74+
case '\n': break;
75+
default: return -1; // Fail code.
76+
}
77+
case SKIP_ALL:
78+
break;
79+
}
6580
read(); // discard non-numeric
6681
}
6782
}
@@ -107,68 +122,55 @@ bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t
107122
}
108123
}
109124

110-
111125
// returns the first valid (long) integer value from the current position.
112-
// initial characters that are not digits (or the minus sign) are skipped
113-
// function is terminated by the first character that is not a digit.
114-
long Stream::parseInt()
115-
{
116-
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
117-
}
118-
119-
// as above but a given skipChar is ignored
120-
// this allows format characters (typically commas) in values to be ignored
121-
long Stream::parseInt(char skipChar)
126+
// lookahead determines how parseInt looks ahead in the stream.
127+
// See LookaheadMode enumeration at the top of the file.
128+
// Lookahead is terminated by the first character that is not a valid part of an integer.
129+
// Once parsing commences, 'ignore' will be skipped in the stream.
130+
long Stream::parseInt(LookaheadMode lookahead, char ignore)
122131
{
123132
bool isNegative = false;
124133
long value = 0;
125134
int c;
126135

127-
c = peekNextDigit();
136+
c = peekNextDigit(lookahead, false);
128137
// ignore non numeric leading characters
129138
if(c < 0)
130139
return 0; // zero returned if timeout
131140

132141
do{
133-
if(c == skipChar)
134-
; // ignore this charactor
142+
if(c == ignore)
143+
; // ignore this character
135144
else if(c == '-')
136145
isNegative = true;
137146
else if(c >= '0' && c <= '9') // is c a digit?
138147
value = value * 10 + c - '0';
139148
read(); // consume the character we got with peek
140149
c = timedPeek();
141150
}
142-
while( (c >= '0' && c <= '9') || c == skipChar );
151+
while( (c >= '0' && c <= '9') || c == ignore );
143152

144153
if(isNegative)
145154
value = -value;
146155
return value;
147156
}
148157

149-
150158
// as parseInt but returns a floating point value
151-
float Stream::parseFloat()
159+
float Stream::parseFloat(LookaheadMode lookahead, char ignore)
152160
{
153-
return parseFloat(NO_SKIP_CHAR);
154-
}
155-
156-
// as above but the given skipChar is ignored
157-
// this allows format characters (typically commas) in values to be ignored
158-
float Stream::parseFloat(char skipChar){
159161
bool isNegative = false;
160162
bool isFraction = false;
161163
long value = 0;
162-
char c;
164+
int c;
163165
float fraction = 1.0;
164166

165-
c = peekNextDigit();
167+
c = peekNextDigit(lookahead, true);
166168
// ignore non numeric leading characters
167169
if(c < 0)
168170
return 0; // zero returned if timeout
169171

170172
do{
171-
if(c == skipChar)
173+
if(c == ignore)
172174
; // ignore
173175
else if(c == '-')
174176
isNegative = true;
@@ -182,7 +184,7 @@ float Stream::parseFloat(char skipChar){
182184
read(); // consume the character we got with peek
183185
c = timedPeek();
184186
}
185-
while( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
187+
while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || c == ignore );
186188

187189
if(isNegative)
188190
value = -value;

0 commit comments

Comments
 (0)