• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

blues / note-arduino / 13460018435

21 Feb 2025 03:32PM CUT coverage: 94.831%. Remained the same
13460018435

Pull #133

github

web-flow
Merge 241963008 into be22b4c5e
Pull Request #133: chore: Add c_cpp_properties.json

104 of 127 branches covered (81.89%)

Branch coverage included in aggregate %.

318 of 318 relevant lines covered (100.0%)

16.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.21
/src/NoteI2c_Arduino.cpp
1
#include "NoteI2c_Arduino.hpp"
2

3
#if defined(NOTE_C_LOW_MEM)
4
static const char *i2cerr = "i2c {io}";
5
#endif
6

7
NoteI2c *
8
make_note_i2c (
7✔
9
    NoteI2c::param_t i2c_parameters_
10
)
11
{
12
    static NoteI2c * note_i2c = nullptr;
13
    if (!i2c_parameters_) {
7✔
14
        if (note_i2c) {
3!
15
            delete note_i2c;
3!
16
            note_i2c = nullptr;
3✔
17
        }
18
    } else if (!note_i2c) {
4✔
19
        note_i2c = new NoteI2c_Arduino(*reinterpret_cast<TwoWire *>(i2c_parameters_));
3!
20
    }
21
    return note_i2c;
7✔
22
}
23

24
NoteI2c_Arduino::NoteI2c_Arduino
38✔
25
(
26
    TwoWire & i2c_bus_
27
) :
38✔
28
    _i2cPort(i2c_bus_)
38✔
29
{
30
    _i2cPort.begin();
38!
31
}
38✔
32

33
NoteI2c_Arduino::~NoteI2c_Arduino (
38✔
34
    void
35
)
38✔
36
{
37
#if WIRE_HAS_END
38
    _i2cPort.end();
38✔
39
#endif
40
}
38✔
41

42
const char *
43
NoteI2c_Arduino::receive (
22✔
44
    uint16_t device_address_,
45
    uint8_t * buffer_,
46
    uint16_t requested_byte_count_,
47
    uint32_t * available_
48
)
49
{
50
    const char *result = nullptr;
22✔
51

52
    const size_t retry_count = 3;
22✔
53
    size_t i = 0;
22✔
54
    do {
55
        uint8_t transmission_error = 0;
76✔
56

57
        // Request response data from Notecard
58
        _i2cPort.beginTransmission(static_cast<uint8_t>(device_address_));
76✔
59
        _i2cPort.write(static_cast<uint8_t>(0));
76✔
60
        _i2cPort.write(static_cast<uint8_t>(requested_byte_count_));
76✔
61
        transmission_error = _i2cPort.endTransmission();
76✔
62

63
        switch (transmission_error) {
76✔
64
        case 0:
43✔
65
            // I2C transmission was successful
66
            result = nullptr;
43✔
67
            break;
43✔
68
        case 1:
13✔
69
            result = ERRSTR("i2c: data too long to fit in transmit buffer {io}",i2cerr);
13✔
70
            break;
13✔
71
        case 2:
4✔
72
            result = ERRSTR("i2c: received NACK on transmit of address {io}",i2cerr);
4✔
73
            break;
4✔
74
        case 3:
4✔
75
            result = ERRSTR("i2c: received NACK on transmit of data {io}",i2cerr);
4✔
76
            break;
4✔
77
        case 4:
4✔
78
            result = ERRSTR("i2c: unknown error on TwoWire::endTransmission() {io}",i2cerr);
4✔
79
            break;
4✔
80
        case 5:
4✔
81
            result = ERRSTR("i2c: timeout {io}",i2cerr);
4✔
82
            break;
4✔
83
        default:
4✔
84
            result = ERRSTR("i2c: unknown error encounter during I2C transmission {io}",i2cerr);
4✔
85
        }
86

87
        // Read and cache response from Notecard
88
        if (!transmission_error) {
76✔
89
            // Delay briefly ensuring that the Notecard can
90
            // deliver the data in real-time to the I2C ISR
91
            ::delay(2);
43✔
92

93
            const int request_length = requested_byte_count_ + NoteI2c::REQUEST_HEADER_SIZE;
43✔
94
            const int response_length = _i2cPort.requestFrom((int)device_address_, request_length);
43✔
95
            if (!response_length) {
43✔
96
                result = ERRSTR("serial-over-i2c: no response to read request {io}",i2cerr);
15✔
97
            } else if (response_length != request_length) {
28✔
98
                result = ERRSTR("serial-over-i2c: unexpected raw byte count {io}",i2cerr);
8✔
99
            } else {
100
                // Ensure available byte count is within expected range
101
                static const size_t AVAILABLE_MAX = (NoteI2c::REQUEST_MAX_SIZE - NoteI2c::REQUEST_HEADER_SIZE);
102
                uint32_t available = _i2cPort.read();
20✔
103
                if (available > AVAILABLE_MAX) {
20✔
104
                    result = ERRSTR("serial-over-i2c: available byte count greater than max allowed {io}",i2cerr);
8✔
105
                } else if (requested_byte_count_ != static_cast<uint8_t>(_i2cPort.read())) {
12✔
106
                    // Ensure protocol response length matches size request
107
                    result = ERRSTR("serial-over-i2c: unexpected protocol byte count {io}",i2cerr);
8✔
108
                } else {
109
                    // Update available with remaining bytes
110
                    *available_ = available;
4✔
111

112
                    for (size_t i = 0 ; i < requested_byte_count_ ; ++i) {
51✔
113
                        //TODO: Perf test against indexed buffer reads
114
                        *buffer_++ = _i2cPort.read();
47✔
115
                    }
116
                    result = nullptr;
4✔
117
                    break;
4✔
118
                }
119
            }
120
        }
121

122
        // Flash stalls have been observed on the Notecard ESP. Delaying
123
        // between retries provides time for the Notecard to recover from
124
        // the resource contention.
125
        ::delay(1000);
72✔
126
        NOTE_C_LOG_ERROR(result);
127
        NOTE_C_LOG_WARN("serial-over-i2c: reattempting to read Notecard response");
128
    } while (result && (i++ < retry_count));
72!
129

130
    return result;
22✔
131
}
132

133
bool
134
NoteI2c_Arduino::reset (
3✔
135
    uint16_t device_address_
136
)
137
{
138
    (void)device_address_;
139
#if WIRE_HAS_END
140
    _i2cPort.end();
3✔
141
#endif
142
    _i2cPort.begin();
3✔
143
    return true;
3✔
144
}
145

146
const char *
147
NoteI2c_Arduino::transmit (
8✔
148
    uint16_t device_address_,
149
    uint8_t * buffer_,
150
    uint16_t size_
151
)
152
{
153
    const char * result = nullptr;
8✔
154
    uint8_t transmission_error = 0;
8✔
155

156
    _i2cPort.beginTransmission(static_cast<uint8_t>(device_address_));
8✔
157
    _i2cPort.write(static_cast<uint8_t>(size_));
8✔
158
    _i2cPort.write(buffer_, size_);
8✔
159
    transmission_error = _i2cPort.endTransmission();
8✔
160

161
    if (transmission_error) {
8✔
162
        switch (transmission_error) {
6✔
163
        case 1:
1✔
164
            result = ERRSTR("i2c: data too long to fit in transmit buffer {io}",i2cerr);
1✔
165
            break;
1✔
166
        case 2:
1✔
167
            result = ERRSTR("i2c: received NACK on transmit of address {io}",i2cerr);
1✔
168
            break;
1✔
169
        case 3:
1✔
170
            result = ERRSTR("i2c: received NACK on transmit of data {io}",i2cerr);
1✔
171
            break;
1✔
172
        case 4:
1✔
173
            result = ERRSTR("i2c: unknown error on TwoWire::endTransmission() {io}",i2cerr);
1✔
174
            break;
1✔
175
        case 5:
1✔
176
            result = ERRSTR("i2c: timeout {io}",i2cerr);
1✔
177
            break;
1✔
178
        default:
1✔
179
            result = ERRSTR("i2c: unknown error encounter during I2C transmission {io}",i2cerr);
1✔
180
        }
181
    }
182

183
    return result;
8✔
184
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc