Skip to content

Commit 1eaa6bf

Browse files
committed
Add Mixed Serial library to save the boards :)
Flash nina firmware with ./esptool.py --baud 115200 -p /dev/ttyACM0 write_flash 0x0 NINA_W102.bin
1 parent bef66cd commit 1eaa6bf

File tree

7 files changed

+392
-8
lines changed

7 files changed

+392
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
SerialNINAPassthrough - Use esptool to flash the u-blox NINA (ESP32) module
3+
Arduino MKR WiFi 1010, Arduino MKR Vidor 4000, and Arduino UNO WiFi Rev.2.
4+
5+
Copyright (c) 2018 Arduino SA. All rights reserved.
6+
7+
This library is free software; you can redistribute it and/or
8+
modify it under the terms of the GNU Lesser General Public
9+
License as published by the Free Software Foundation; either
10+
version 2.1 of the License, or (at your option) any later version.
11+
12+
This library is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
Lesser General Public License for more details.
16+
17+
You should have received a copy of the GNU Lesser General Public
18+
License along with this library; if not, write to the Free Software
19+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20+
*/
21+
22+
#ifdef ARDUINO_SAMD_MKRVIDOR4000
23+
#include <VidorPeripherals.h>
24+
25+
unsigned long baud = 119400;
26+
#else
27+
unsigned long baud = 115200;
28+
#endif
29+
30+
int rts = -1;
31+
int dtr = -1;
32+
33+
#include <MixedSerial.h>
34+
35+
#undef SerialNina
36+
//SoftwareSerial SerialNina(29, 30);
37+
MixedSerial SerialNina(Serial2, 30);
38+
39+
void setup() {
40+
Serial.begin(baud);
41+
while (!Serial) {}
42+
43+
#ifdef ARDUINO_SAMD_MKRVIDOR4000
44+
FPGA.begin();
45+
#endif
46+
47+
SerialNina.begin(baud);
48+
49+
#ifdef ARDUINO_SAMD_MKRVIDOR4000
50+
FPGA.pinMode(FPGA_NINA_GPIO0, OUTPUT);
51+
FPGA.pinMode(FPGA_SPIWIFI_RESET, OUTPUT);
52+
#else
53+
pinMode(NINA_GPIO0, OUTPUT);
54+
pinMode(NINA_RESETN, OUTPUT);
55+
#endif
56+
57+
digitalWrite(NINA_GPIO0, HIGH);
58+
59+
digitalWrite(NINA_RESETN, HIGH);
60+
delay(100);
61+
digitalWrite(NINA_RESETN, LOW);
62+
delay(100);
63+
digitalWrite(NINA_RESETN, HIGH);
64+
65+
#ifdef ARDUINO_AVR_UNO_WIFI_REV2
66+
// manually put the NINA in upload mode
67+
digitalWrite(NINA_GPIO0, LOW);
68+
69+
digitalWrite(NINA_RESETN, LOW);
70+
delay(100);
71+
digitalWrite(NINA_RESETN, HIGH);
72+
delay(100);
73+
digitalWrite(NINA_RESETN, LOW);
74+
#endif
75+
}
76+
77+
long last = 0;
78+
79+
void loop() {
80+
81+
/*
82+
if (last - millis() > 10000) {
83+
// manually put the NINA in upload mode
84+
digitalWrite(NINA_GPIO0, HIGH);
85+
86+
digitalWrite(NINA_RESETN, HIGH);
87+
delay(100);
88+
digitalWrite(NINA_RESETN, LOW);
89+
delay(100);
90+
digitalWrite(NINA_RESETN, HIGH);
91+
last = millis();
92+
}
93+
*/
94+
#ifndef ARDUINO_AVR_UNO_WIFI_REV2
95+
if (rts != Serial.rts()) {
96+
#ifdef ARDUINO_SAMD_MKRVIDOR4000
97+
FPGA.digitalWrite(FPGA_SPIWIFI_RESET, (Serial.rts() == 1) ? LOW : HIGH);
98+
#else
99+
digitalWrite(NINA_RESETN, Serial.rts() ? LOW : HIGH);
100+
#endif
101+
rts = Serial.rts();
102+
}
103+
104+
if (dtr != Serial.dtr()) {
105+
#ifdef ARDUINO_SAMD_MKRVIDOR4000
106+
FPGA.digitalWrite(FPGA_NINA_GPIO0, (Serial.dtr() == 1) ? HIGH : LOW);
107+
#else
108+
digitalWrite(NINA_GPIO0, (Serial.dtr() == 0) ? HIGH : LOW);
109+
#endif
110+
dtr = Serial.dtr();
111+
}
112+
#endif
113+
114+
if (Serial.available()) {
115+
SerialNina.write(Serial.read());
116+
}
117+
118+
if (SerialNina.available()) {
119+
Serial.write(SerialNina.read());
120+
}
121+
122+
#ifndef ARDUINO_AVR_UNO_WIFI_REV2
123+
// check if the USB virtual serial wants a new baud rate
124+
if (Serial.baud() != baud) {
125+
rts = -1;
126+
dtr = -1;
127+
128+
baud = Serial.baud();
129+
#ifndef ARDUINO_SAMD_MKRVIDOR4000
130+
SerialNina.begin(baud);
131+
#endif
132+
}
133+
#endif
134+
}

libraries/MixedSerial/keywords.txt

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#######################################
2+
# Syntax Coloring Map for SoftwareSerial
3+
# (formerly NewSoftSerial)
4+
#######################################
5+
6+
#######################################
7+
# Datatypes (KEYWORD1)
8+
#######################################
9+
10+
SoftwareSerial KEYWORD1
11+
12+
#######################################
13+
# Methods and Functions (KEYWORD2)
14+
#######################################
15+
16+
begin KEYWORD2
17+
end KEYWORD2
18+
read KEYWORD2
19+
write KEYWORD2
20+
available KEYWORD2
21+
isListening KEYWORD2
22+
stopListening KEYWORD2
23+
overflow KEYWORD2
24+
flush KEYWORD2
25+
listen KEYWORD2
26+
peek KEYWORD2
27+
28+
#######################################
29+
# Constants (LITERAL1)
30+
#######################################
31+
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name=MixedSerial
2+
version=1.0
3+
author=Arduino
4+
maintainer=Arduino <info@arduino.cc>
5+
sentence=Enables serial communication on any digital pin.
6+
paragraph=The SoftwareSerial library has been developed to allow serial communication on any digital pin of the board, using software to replicate the functionality of the hardware UART. It is possible to have multiple software serial ports with speeds up to 115200 bps.
7+
category=Communication
8+
url=http://www.arduino.cc/en/Reference/SoftwareSerial
9+
architectures=samd
10+
+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
This file is part of the ArduinoECCX08 library.
3+
Copyright (c) 2019 Arduino SA. All rights reserved.
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+
This library is distributed in the hope that it will be useful,
9+
but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+
Lesser General Public License for more details.
12+
You should have received a copy of the GNU Lesser General Public
13+
License along with this library; if not, write to the Free Software
14+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15+
*/
16+
17+
#include <Arduino.h>
18+
#include "MixedSerial.h"
19+
#include <variant.h>
20+
#include <WInterrupts.h>
21+
22+
// Constructor
23+
MixedSerial::MixedSerial(Uart& _s, int _pinTX) :
24+
_rx_delay_centering(0),
25+
_rx_delay_intrabit(0),
26+
_rx_delay_stopbit(0),
27+
_tx_delay(0),
28+
uart(_s)
29+
{
30+
_transmitPin = _pinTX;
31+
}
32+
33+
// Destructor
34+
MixedSerial::~MixedSerial() {
35+
end();
36+
}
37+
38+
void MixedSerial::setTX(uint8_t tx) {
39+
// First write, then set output. If we do this the other way around,
40+
// the pin would be output low for a short while before switching to
41+
// output hihg. Now, it is input with pullup for a short while, which
42+
// is fine. With inverse logic, either order is fine.
43+
pinMode(tx, OUTPUT);
44+
_transmitBitMask = digitalPinToBitMask(tx);
45+
PortGroup * port = digitalPinToPort(tx);
46+
_transmitPortRegister = (PORT_OUT_Type*) portOutputRegister(port);
47+
}
48+
49+
void MixedSerial::begin(long speed) {
50+
51+
if (_tx_delay != 0) {
52+
return;
53+
}
54+
55+
uart.begin(speed);
56+
setTX(_transmitPin);
57+
58+
// Precalculate the various delays
59+
//Calculate the distance between bit in micro seconds
60+
uint32_t bit_delay = (uint32_t)(1000000) / (speed);
61+
62+
_tx_delay = bit_delay;
63+
}
64+
65+
void MixedSerial::end() {
66+
}
67+
68+
int MixedSerial::read() {
69+
return uart.read();
70+
}
71+
72+
73+
int MixedSerial::available() {
74+
return uart.available();
75+
}
76+
77+
78+
size_t MixedSerial::write(uint8_t b) {
79+
if (_tx_delay == 0) {
80+
setWriteError();
81+
return 0;
82+
}
83+
84+
// By declaring these as local variables, the compiler will put them
85+
// in registers _before_ disabling interrupts and entering the
86+
// critical timing sections below, which makes it a lot easier to
87+
// verify the cycle timings
88+
volatile PORT_OUT_Type *reg = _transmitPortRegister;
89+
uint32_t reg_mask = _transmitBitMask;
90+
uint32_t inv_mask = ~_transmitBitMask;
91+
uint16_t delay = _tx_delay;
92+
93+
noInterrupts();
94+
95+
reg->reg &= inv_mask;
96+
97+
delayMicroseconds(delay);
98+
99+
// Write each of the 8 bits
100+
for (uint8_t i = 0; i < 8; i++) {
101+
if (bitRead(b, i)) {
102+
reg->reg |= reg_mask; // send 1
103+
}
104+
else {
105+
reg->reg &= inv_mask; // send 0
106+
}
107+
delayMicroseconds(delay);
108+
}
109+
110+
// restore pin to natural state
111+
reg->reg |= reg_mask;
112+
113+
delayMicroseconds(delay);
114+
interrupts();
115+
116+
return 1;
117+
}
118+
119+
void MixedSerial::flush() {
120+
uart.flush();
121+
}
122+
123+
int MixedSerial::peek() {
124+
uart.peek();
125+
}
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
This file is part of the ArduinoECCX08 library.
3+
Copyright (c) 2019 Arduino SA. All rights reserved.
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+
This library is distributed in the hope that it will be useful,
9+
but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+
Lesser General Public License for more details.
12+
You should have received a copy of the GNU Lesser General Public
13+
License along with this library; if not, write to the Free Software
14+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15+
*/
16+
17+
#ifndef SoftwareSerial_h
18+
#define SoftwareSerial_h
19+
20+
#include <inttypes.h>
21+
#include <Stream.h>
22+
#include <Uart.h>
23+
#include <variant.h>
24+
25+
/******************************************************************************
26+
Definitions
27+
******************************************************************************/
28+
29+
class MixedSerial : public Stream {
30+
private:
31+
// per object data
32+
uint8_t _transmitPin;
33+
uint32_t _transmitBitMask;
34+
volatile PORT_OUT_Type *_transmitPortRegister;
35+
36+
// Expressed as 4-cycle delays (must never be 0!)
37+
uint16_t _rx_delay_centering;
38+
uint16_t _rx_delay_intrabit;
39+
uint16_t _rx_delay_stopbit;
40+
uint16_t _tx_delay;
41+
42+
uint16_t _buffer_overflow: 1;
43+
uint16_t _inverse_logic: 1;
44+
45+
// static data
46+
Uart& uart;
47+
48+
void tx_pin_write(uint8_t pin_state) __attribute__((__always_inline__));
49+
void setTX(uint8_t transmitPin);
50+
51+
public:
52+
// public methods
53+
MixedSerial(Uart& _s, int _pinTX);
54+
~MixedSerial();
55+
void begin(long speed);
56+
void end();
57+
int peek();
58+
59+
virtual size_t write(uint8_t byte);
60+
virtual int read();
61+
virtual int available();
62+
virtual void flush();
63+
operator bool() {
64+
return true;
65+
}
66+
67+
using Print::write;
68+
69+
// public only for easy access by interrupt handlers
70+
static inline void handle_interrupt() __attribute__((__always_inline__));
71+
};
72+
73+
#endif

0 commit comments

Comments
 (0)