Skip to content

Commit

Permalink
Merge pull request #1086 from MX682X/master
Browse files Browse the repository at this point in the history
Mainly fix for #1080 (pulseIn), and accidentaly the Wire edit that is already in the DxCore; added fix for #1090
  • Loading branch information
SpenceKonde authored Jul 28, 2024
2 parents 6844a18 + 9f2dc7a commit 6bf5473
Show file tree
Hide file tree
Showing 22 changed files with 1,076 additions and 1,388 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/compile-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ jobs:
- megaavr/libraries/USERSIG/examples/usersig_put
- megaavr/libraries/USERSIG/examples/usersig_read
- megaavr/libraries/Wire/examples/digital_potentiometer
- megaavr/libraries/Wire/examples/slave_write_read
- megaavr/libraries/Wire/examples/master_and_slave
- megaavr/libraries/Wire/examples/master_write_read
- megaavr/libraries/Wire/examples/slave_write
- megaavr/libraries/Wire/examples/slave_read
- megaavr/libraries/Wire/examples/master_write
- megaavr/libraries/Wire/examples/master_read
- megaavr/libraries/Wire/examples/slave_secondary_address
- megaavr/libraries/megaTinyCore/examples/ModernRevSer
- megaavr/libraries/megaTinyCore/examples/readTempVcc
Expand Down
16 changes: 8 additions & 8 deletions megaavr/cores/megatinycore/Arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -453,9 +453,9 @@ uint8_t PWMoutputTopin(uint8_t timer, uint8_t channel);
* 3/19/23: These are supposed to be macros, not inline functions
* Users have reported problems resulting from their being functions, even inline ones
*/
#define clockCyclesPerMicrosecond() ((F_CPU / 1000000UL))
#define clockCyclesToMicroseconds(__a__) (__a__ / clockCyclesPerMicrosecond())
#define microsecondsToClockCycles(__a__) (__a__ * clockCyclesPerMicrosecond())
#define clockCyclesPerMicrosecond() ((uint16_t)(F_CPU / 1000000UL))
#define clockCyclesToMicroseconds(__a__) ((uint32_t)((__a__) / clockCyclesPerMicrosecond()))
#define microsecondsToClockCycles(__a__) ((uint32_t)((__a__) * clockCyclesPerMicrosecond()))

// Currently DxCore has no cases where the millis timer isn't derived from system clock, but that will change
/* This becomes important when we support other timers for timekeeping. The Type D timer can be faster, requiring:
Expand Down Expand Up @@ -483,15 +483,15 @@ uint32_t microsecondsToMillisClockCycles(uint32_t microseconds);
*/
#ifdef MILLIS_USE_TIMERD0
#if (F_CPU == 20000000UL || F_CPU == 10000000UL ||F_CPU == 5000000UL)
#define millisClockCyclesPerMicrosecond() (20) // this always runs off the 20MHz oscillator
#define millisClockCyclesPerMicrosecond() ((uint16_t)(20)) // this always runs off the 20MHz oscillator
#else
#define millisClockCyclesPerMicrosecond() (16)
#define millisClockCyclesPerMicrosecond() ((uint16_t)(16))
#endif
#else
#define millisClockCyclesPerMicrosecond() (F_CPU / 1000000UL)
#define millisClockCyclesPerMicrosecond() ((uint16_t)((F_CPU / 1000000UL)))
#endif
#define millisClockCyclesToMicroseconds(__a__) (__a__ / millisClockCyclesPerMicrosecond())
#define microsecondsToMillisClockCycles(__a__) (__a__ * millisClockCyclesPerMicrosecond())
#define millisClockCyclesToMicroseconds(__a__) ((uint32_t)(__a__ / millisClockCyclesPerMicrosecond()))
#define microsecondsToMillisClockCycles(__a__) ((uint32_t)(__a__ * millisClockCyclesPerMicrosecond()))

/* Timers and Timer-like-things
* These are used for two things: Identifying the timer on a pin in
Expand Down
7 changes: 4 additions & 3 deletions megaavr/cores/megatinycore/wiring.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,10 @@ uint8_t __PeripheralControl = 0xFF;
#endif /* defined(MILLIS_USE_TIMER__) */
#endif /* defined(MILLIS_USE_TIMERRTC) */

#define ClockCyclesToMicroseconds(__a__) ((__a__) / (F_CPU / 1000000L))
#define FRACT_MAX (1000)
#define FRACT_INC (millisClockCyclesToMicroseconds(TIME_TRACKING_CYCLES_PER_OVF)%1000)
#define MILLIS_INC (millisClockCyclesToMicroseconds(TIME_TRACKING_CYCLES_PER_OVF)/1000)
#define FRACT_INC (ClockCyclesToMicroseconds(TIME_TRACKING_CYCLES_PER_OVF)%1000)
#define MILLIS_INC (ClockCyclesToMicroseconds(TIME_TRACKING_CYCLES_PER_OVF)/1000)

struct sTimeMillis {
#if (defined(MILLIS_USE_TIMERB0) || defined(MILLIS_USE_TIMERB1) || defined(MILLIS_USE_TIMERB2) || defined(MILLIS_USE_TIMERB3) || defined(MILLIS_USE_TIMERB4)) // Now TCB as millis source does not need fraction
Expand Down Expand Up @@ -334,7 +335,7 @@ uint8_t __PeripheralControl = 0xFF;
"subi r24,%[LFRMAX]" "\n\t" // subtract FRACT_MAX and see if it is lower
"sbci r25,%[HFRMAX]" "\n\t" //

#if MILLIS_INC != 0 // (6 words / 4 - 5 clocks, branches were optimize to create minimal diversion)
#if MILLIS_INC > 0 // (6 words / 4 - 5 clocks, branches were optimize to create minimal diversion)
"brlo higher" "\n\t" // if FRAC_MAX was not reached,
"ldi r24, %[MIINC]" "\n\t" // load "normal" MILLIS_INC (0x00-MILLIS_INC)
"rjmp sub4" "\n\t" // avoid overwriting r24
Expand Down
2 changes: 1 addition & 1 deletion megaavr/cores/megatinycore/wiring_pulse.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)

// convert the timeout from microseconds to a number of times through
// the initial loop; it takes approximately 16 clock cycles per iteration
unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
unsigned long maxloops = (uint32_t)microsecondsToClockCycles(timeout) / 16;

unsigned long width = countPulseASM(portInputRegister(port), bit, stateMask, maxloops);

Expand Down
2 changes: 1 addition & 1 deletion megaavr/libraries/PTC/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ In order to ease the use of the PTC module, the ptc_add_* functions will initial

If a node is not sensitive enough, you can increase the Analog Gain (if it becomes too sensitive, an increase of the thresholds might be needed). However it is better to have a bigger node to begin with because the bigger the area, the higher is the capacitance delta.

### Global settings of the State-maschine
### Global settings of the State-machine
The state-machine, which changes the node's state between Calibration, touch, no touch, etc. uses some variables that are valid for all nodes, those are:
- `uint16_t force_recal_delta`. Each node has a threshold value that is used to calculate the delta. This Threshold value is drifting over time to adjust for environmental changes. If the threshold value drifts 512 +/- this value, a recalibration of CC is performed. Default: 150
- `uint8_t touched_detect_nom`. Number of consecutive Measurements (Conversions) that are above the touch threshold until the node becomes "touched". Default: 3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* This example creates four different sensing nodes. of two different types.
* PA4 and PA5 are the self-cap lines with PB0 acting as shield pin.
* PA6 and PA7 are the Y-Lines with PB1 acting as the X-line.
* PTC_CB_EVENT_CONV_MUTUAL_CMPL and
* PTC_CB_EVENT_CONV_MUTUAL_CMPL and
* PTC_CB_EVENT_CONV_SHIELD_CMPL can be used to change the type that is converted.
* This will create an interlaced conversion, but it is not mandatory to do so.
*/
Expand Down
16 changes: 15 additions & 1 deletion megaavr/libraries/Wire/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,18 @@ uint8_t checkPinLevels();
```
This function returns the level of the master TWI pins, depending on the used TWI module and port multiplexer settings. Bit 0 represents SDA line and bit 1 represents SCL line. This is useful on initialisation, where you want to make sure that all devices have their pins ready in open-drain mode. A value of 0x03 indicates that both lines have a HIGH level and the bus is ready.

#### `uint8_t masterTransmit()`
```c++
uint8_t masterTransmit(auto *length, uint8_t *buffer, uint8_t addr, uint8_t sendStop);
```
This functions allows to transmit a buffer of data without having to copy the data to the internal buffer of the library. This allows transmission lengths as long as the RAM size without having to define the TWI_BUFFER_SIZE in the platform.txt. The return value is the same as endTransmission(). length will be overwritten with the actual amount of written bytes.
#### `uint8_t masterReceive()`
```c++
uint8_t masterReceive(auto *length, uint8_t *buffer, uint8_t addr, uint8_t sendStop);
```
This functions allows to receive a buffer of data without having to copy the data from the internal buffer of the library. This allows transmission lengths as long as the RAM size without having to define the TWI_BUFFER_SIZE in the platform.txt. The return value is the same as endTransmission(). length will be overwritten with the actual amount of received bytes.

### Additional New Methods not available on all parts
These new methods are available exclusively for parts with certain specialized hardware; Most full-size parts support enableDualMode (but tinyAVR does not), while only the DA and DB-series parts have the second TWI interface that swapModule requires.
#### `void swapModule()`
Expand Down Expand Up @@ -323,6 +335,8 @@ When the second or third argument was used, `Wire.getIncomingAddress()` should b

If (and only if) the Master and Slave option is selected in the Tools -> Wire mode, the Wire interface can be enabled for both master and slave. Even when Dual Mode is used, the correct option must still be selected to enable acting as both master and slave.

The Arduino library defines the array lengths as `BUFFER_LENGTH`, however, this define name might create conflicts, as the name is quite arbitrary. The newest library version uses the name `TWI_BUFFER_LENGTH` instead. However, it is still backwards compatible, as the `BUFFER_LENGTH` is still applied, but a compiler warning is generated to notify about the change.

#### `void setClock()`
```c++
void setClock(uint32_t);
Expand Down Expand Up @@ -419,7 +433,7 @@ The implementation isn't identical, but the behaviour is unchanged, or is differ
#### Write Sequence
1. Master generates start condition.
2. Master clocks out the slave address with out read-bit set..
2. Master clocks out the slave address without read-bit set..
3. Slave detects and ACKs.
4. Master clocks out 1 or more data bytes as slave ACKs them.
5. Master generates a Stop Condition.
Expand Down

This file was deleted.

55 changes: 55 additions & 0 deletions megaavr/libraries/Wire/examples/master_read/master_read.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* Wire Master Read
* by MX682X
*
* Demonstrates use of the New Wire library
* Reads data from an I2C/TWI slave device
* Refer to the "Wire Slave Write" example for use with this
*
* This example takes the input from Serial. If the serial input is 'm' or 'M',
* this code requests 4 bytes from the slave with the address 0x54.
* When using together with the complementary example, the slave sends it's millis() value.
* This value is then sent to the serial monitor
*
* To use this, you need to connect the SCL and SDA pins of this device to the
* SCL and SDA pins of a second device running the Wire Slave Write example.
*
* Pullup resistors must be connected between both data lines and Vcc.
* See the Wire library README.md for more information.
*/

#define MySerial Serial

#include <Wire.h>

int8_t rxLen = 0;
int8_t len = 0;

void setup() {
Wire.begin(); // initialize master
MySerial.begin(115200);
}

void loop() {
if (MySerial.available() > 0) { // as soon as the first byte is received on Serial
char c = MySerial.read(); // read the data from serial.
if (c == 'm' || c == 'M') {
sendDataWire(); // send the data over I2C
}
len = 0; // since the data was sent, the position is 0 again
}
}

void sendDataWire() {
uint32_t ms;
if (4 == Wire.requestFrom(0x54, 4, 0x01)) { // request from slave
while (Wire.available()) {
ms = (uint32_t)Wire.read(); // read out 32-bit wide data
ms |= (uint32_t)Wire.read() << 8;
ms |= (uint32_t)Wire.read() << 16;
ms |= (uint32_t)Wire.read() << 24;
MySerial.println(ms); // print the milliseconds from Slave
}
} else {
MySerial.println("Wire.requestFrom() timed out!");
}
}
64 changes: 64 additions & 0 deletions megaavr/libraries/Wire/examples/master_write/master_write.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* Wire Master Write
* by MX682X
*
* Demonstrates use of the New Wire library
* Writes data to an I2C/TWI slave device
* Refer to the "Wire Slave Read" example for use with this
*
* Enter any data using serial monitor or other console followed by either or
* both of the line ending characters, and it will be sent to the slave, which
* should print it out on it's serial port.
*
* To use this, you need to connect the SCL and SDA pins of this device to the
* SCL and SDA pins of a second device running the Wire Slave Read example.
*
* Pullup resistors must be connected between both data lines and Vcc.
* See the Wire library README.md for more information.
*/

#include <Wire.h>

char input[32];
int8_t len = 0;

#define MySerial Serial // The serial port connected to the to the computer.

void setup() {
Wire.begin(); // initialize master
// MySerial.swap(1); // Remember to swap serial pins if you need to do that with your connections.
MySerial.begin(115200); // Use 115200 baud - this is the 2020's, and these are modern AVRs.
}

void loop() {
if (MySerial.available() > 0) { // as soon as the first byte is received on Serial
readFromSerial(); // read the data from the Serial interface
if (len > 0) { // after the while-loop, if there was useful data,
sendDataWire(); // send the data over I2C
}
len = 0; // since the data was sent, the position is 0 again
}
}

void readFromSerial() {
while (true) { // in an endless while-loop
while (MySerial.available() == 0);// means we've taken all the bytes in, and are still waiting for a cr/lf.
char c = MySerial.read(); // read the next char, now that there's one available.
if (c == '\n' || c == '\r') { // until a new line or carriage return is found
break; // if so, break the endless while-loop
} // otherwise
input[len] = c; // save the char
len++; // increment the position
if (len > 30) { // if there was too much data
break; // break the while-loop to avoid buffer overflow
}
}
}

void sendDataWire() {
Wire.beginTransmission(0x54); // prepare transmission to slave with address 0x54
for (uint8_t i = 0; i < len; i++) {
Wire.write(input[i]); // Write the received data to the bus buffer
}
Wire.write("\r\n"); // add new line and carriage return for the Serial monitor
Wire.endTransmission(); // finish transmission
}
Loading

0 comments on commit 6bf5473

Please sign in to comment.