Skip to content

Commit 17f2913

Browse files
Merge branch 'arduino:main' into benjamindannegard/api-documentation
2 parents 96df3e6 + 9006eab commit 17f2913

29 files changed

+428
-2378
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix and TextAnimation
2+
#include "ArduinoGraphics.h"
3+
#include "Arduino_LED_Matrix.h"
4+
#include "TextAnimation.h"
5+
6+
ArduinoLEDMatrix matrix;
7+
8+
// 100 frames maximum. Compute as maximum length of text you want to print (eg. 20 chars)
9+
// multiplied by font width (eg. 5 for Font_5x7), so 20 chars * 5 px = 100. If you enter lower
10+
// value (or your text get unexpectedly long), animation will be cut and end soon.
11+
TEXT_ANIMATION_DEFINE(anim, 100)
12+
13+
int counter;
14+
bool requestNext = false;
15+
16+
void setup() {
17+
pinMode(LED_BUILTIN, OUTPUT);
18+
19+
matrix.begin();
20+
matrix.beginDraw();
21+
22+
matrix.stroke(0xFFFFFFFF);
23+
matrix.textFont(Font_5x7);
24+
matrix.textScrollSpeed(60);
25+
matrix.setCallback(matrixCallback);
26+
27+
const char text[] = " UNO r4 ";
28+
matrix.beginText(0, 1, 0xFFFFFF);
29+
matrix.println(text);
30+
matrix.endTextAnimation(SCROLL_LEFT, anim);
31+
32+
matrix.loadTextAnimationSequence(anim);
33+
matrix.play();
34+
35+
// now animation play asynchronously. Will call matrixCallback once completed.
36+
}
37+
38+
void matrixCallback() {
39+
// callback is executed in IRQ and should run as fast as possible
40+
requestNext = true;
41+
}
42+
43+
void loop() {
44+
if (requestNext) {
45+
requestNext = false;
46+
47+
matrix.beginText(0, 1, 0xFFFFFF);
48+
matrix.print(" ");
49+
matrix.println(counter);
50+
matrix.endTextAnimation(SCROLL_RIGHT, anim);
51+
52+
if (counter++ >= 20) {
53+
counter = 0;
54+
}
55+
56+
matrix.loadTextAnimationSequence(anim);
57+
matrix.play();
58+
}
59+
60+
delay(500);
61+
digitalWrite(LED_BUILTIN, 0);
62+
delay(500);
63+
digitalWrite(LED_BUILTIN, 1);
64+
}

libraries/Arduino_LED_Matrix/src/Arduino_LED_Matrix.h

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,10 @@ static uint32_t reverse(uint32_t x)
141141
}
142142

143143
// TODO: this is dangerous, use with care
144-
#define loadSequence(frames) loadWrapper(frames, sizeof(frames))
145-
#define renderBitmap(bitmap, rows, columns) loadPixels(&bitmap[0][0], rows*columns)
144+
#define loadSequence(frames) loadWrapper(frames, sizeof(frames))
145+
#define renderBitmap(bitmap, rows, columns) loadPixels(&bitmap[0][0], rows*columns)
146+
#define endTextAnimation(scrollDirection, anim) endTextToAnimationBuffer(scrollDirection, anim ## _buf, sizeof(anim ## _buf), anim ## _buf_used)
147+
#define loadTextAnimationSequence(anim) loadWrapper(anim ## _buf, anim ## _buf_used)
146148

147149
static uint8_t __attribute__((aligned)) framebuffer[NUM_LEDS / 8];
148150

@@ -227,11 +229,11 @@ class ArduinoLEDMatrix
227229
return false;
228230
}
229231

230-
void loadPixels(uint8_t *arr, size_t size){
232+
static void loadPixelsToBuffer(uint8_t* arr, size_t size, uint32_t* dst) {
231233
uint32_t partialBuffer = 0;
232234
uint8_t pixelIndex = 0;
233235
uint8_t *frameP = arr;
234-
uint32_t *frameHolderP = _frameHolder;
236+
uint32_t *frameHolderP = dst;
235237
while (pixelIndex < size) {
236238
partialBuffer |= *frameP++;
237239
if ((pixelIndex + 1) % 32 == 0) {
@@ -240,6 +242,10 @@ class ArduinoLEDMatrix
240242
partialBuffer = partialBuffer << 1;
241243
pixelIndex++;
242244
}
245+
}
246+
247+
void loadPixels(uint8_t *arr, size_t size){
248+
loadPixelsToBuffer(arr, size, _frameHolder);
243249
loadFrame(_frameHolder);
244250
};
245251

@@ -255,9 +261,9 @@ class ArduinoLEDMatrix
255261

256262
void clear() {
257263
const uint32_t fullOff[] = {
258-
0x00000000,
259-
0x00000000,
260-
0x00000000
264+
0x00000000,
265+
0x00000000,
266+
0x00000000
261267
};
262268
loadFrame(fullOff);
263269
#ifdef MATRIX_WITH_ARDUINOGRAPHICS
@@ -280,16 +286,48 @@ class ArduinoLEDMatrix
280286
renderBitmap(_canvasBuffer, canvasHeight, canvasWidth);
281287
}
282288

283-
// display the drawing
289+
// display the drawing or capture it to buffer when rendering dynamic anymation
284290
void endDraw() {
285291
ArduinoGraphics::endDraw();
286-
renderBitmap(_canvasBuffer, canvasHeight, canvasWidth);
292+
293+
if (!captureAnimation) {
294+
renderBitmap(_canvasBuffer, canvasHeight, canvasWidth);
295+
} else {
296+
if (captureAnimationHowManyRemains >= 4) {
297+
loadPixelsToBuffer(&_canvasBuffer[0][0], sizeof(_canvasBuffer), captureAnimationFrame);
298+
captureAnimationFrame[3] = _textScrollSpeed;
299+
captureAnimationFrame += 4;
300+
captureAnimationHowManyRemains -= 16;
301+
}
302+
}
303+
}
304+
305+
void endTextToAnimationBuffer(int scrollDirection, uint32_t frames[][4], uint32_t howManyMax, uint32_t& howManyUsed) {
306+
captureAnimationFrame = &frames[0][0];
307+
captureAnimationHowManyRemains = howManyMax;
308+
309+
captureAnimation = true;
310+
ArduinoGraphics::textScrollSpeed(0);
311+
ArduinoGraphics::endText(scrollDirection);
312+
ArduinoGraphics::textScrollSpeed(_textScrollSpeed);
313+
captureAnimation = false;
314+
315+
howManyUsed = howManyMax - captureAnimationHowManyRemains;
316+
}
317+
318+
void textScrollSpeed(unsigned long speed) {
319+
ArduinoGraphics::textScrollSpeed(speed);
320+
_textScrollSpeed = speed;
287321
}
288322

289323
private:
324+
uint32_t* captureAnimationFrame = nullptr;
325+
uint32_t captureAnimationHowManyRemains = 0;
326+
bool captureAnimation = false;
290327
static const byte canvasWidth = 12;
291328
static const byte canvasHeight = 8;
292329
uint8_t _canvasBuffer[canvasHeight][canvasWidth] = {{0}};
330+
unsigned long _textScrollSpeed = 100;
293331
#endif
294332

295333
private:
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
#include "Arduino.h"
4+
5+
#if not __has_include("ArduinoGraphics.h")
6+
#error "TextAnimation work only when ArduinoGraphics is installed and used. Include ArduinoGraphics first."
7+
#endif
8+
9+
#define TEXT_ANIMATION_DECLARE(NAME, MAX_CHARS) \
10+
extern uint32_t NAME ## _buf[MAX_CHARS][4]; \
11+
extern uint32_t NAME ## _buf_used;
12+
13+
#define TEXT_ANIMATION_DEFINE(NAME, MAX_CHARS) \
14+
uint32_t NAME ## _buf[MAX_CHARS][4]; \
15+
uint32_t NAME ## _buf_used = 0;

libraries/SE05X/src/SE05X.cpp

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@
6969
SE05X_EC_SIGNATURE_RAW_LENGTH
7070

7171
#define SE05X_SHA256_LENGTH 32
72-
#define SE05X_SN_LENGTH 18
7372

7473
#define SE05X_TEMP_OBJECT 9999
7574

@@ -108,22 +107,35 @@ void SE05XClass::end()
108107
Se05x_API_SessionClose(&_se05x_session);
109108
}
110109

110+
int SE05XClass::serialNumber(byte sn[])
111+
{
112+
return serialNumber(sn, SE05X_SN_LENGTH);
113+
}
114+
115+
int SE05XClass::serialNumber(byte sn[], size_t length)
116+
{
117+
size_t uidLen = length;
118+
const int kSE05x_AppletResID_UNIQUE_ID = 0x7FFF0206;
119+
smStatus_t status;
120+
121+
status = Se05x_API_ReadObject(&_se05x_session, kSE05x_AppletResID_UNIQUE_ID, 0, length, sn, &uidLen);
122+
if (status != SM_OK || length != uidLen) {
123+
SMLOG_E("Error in Se05x_API_ReadObject \n");
124+
return 0;
125+
}
126+
return 1;
127+
}
128+
111129
String SE05XClass::serialNumber()
112130
{
113131
String result = (char*)NULL;
114132
byte UID[SE05X_SN_LENGTH];
115-
size_t uidLen = SE05X_SN_LENGTH;
116-
const int kSE05x_AppletResID_UNIQUE_ID = 0x7FFF0206,
117133

118-
status = Se05x_API_ReadObject(&_se05x_session, kSE05x_AppletResID_UNIQUE_ID, 0, uidLen, UID, &uidLen);
119-
if (status != SM_OK) {
120-
SMLOG_E("Error in Se05x_API_ReadObject \n");
121-
return "";
122-
}
134+
serialNumber(UID, sizeof(UID));
123135

124-
result.reserve(uidLen * 2);
136+
result.reserve(SE05X_SN_LENGTH * 2);
125137

126-
for (size_t i = 0; i < uidLen; i++) {
138+
for (size_t i = 0; i < SE05X_SN_LENGTH; i++) {
127139
byte b = UID[i];
128140

129141
if (b < 16) {
@@ -168,11 +180,11 @@ int SE05XClass::random(byte data[], size_t length)
168180
smStatus_t status;
169181
uint16_t offset = 0;
170182
uint16_t left = length;
171-
183+
172184
while (left > 0) {
173185
uint16_t chunk = (left > SE05X_MAX_CHUNK_SIZE) ? SE05X_MAX_CHUNK_SIZE : left;
174186
size_t max_buffer = chunk;
175-
187+
176188
status = Se05x_API_GetRandom(&_se05x_session, chunk, (data + offset), &max_buffer);
177189
if (status != SM_OK) {
178190
SMLOG_E("Error in Se05x_API_GetRandom \n");
@@ -337,7 +349,7 @@ int SE05XClass::beginSHA256()
337349
{
338350
smStatus_t status;
339351
SE05x_CryptoModeSubType_t subtype;
340-
352+
341353
subtype.digest = kSE05x_DigestMode_SHA256;
342354

343355
status = Se05x_API_CreateCryptoObject(&_se05x_session, kSE05x_CryptoObject_DIGEST_SHA256, kSE05x_CryptoContext_DIGEST, subtype);
@@ -357,7 +369,7 @@ int SE05XClass::beginSHA256()
357369
int SE05XClass::updateSHA256(const byte in[], size_t inLen)
358370
{
359371
smStatus_t status;
360-
372+
361373
status = Se05x_API_DigestUpdate(&_se05x_session, kSE05x_CryptoObject_DIGEST_SHA256, in, inLen);
362374
if (status != SM_OK) {
363375
SMLOG_E("Error in Se05x_API_DigestUpdate \n");
@@ -374,7 +386,7 @@ int SE05XClass::endSHA256(byte out[], size_t* outLen)
374386
if (*outLen < SE05X_SHA256_LENGTH) {
375387
SMLOG_E("Error in endSHA256 \n");
376388
*outLen = 0;
377-
return 0;
389+
return 0;
378390
}
379391

380392
status = Se05x_API_DigestFinal(&_se05x_session, kSE05x_CryptoObject_DIGEST_SHA256, NULL, 0, out, outLen);
@@ -530,7 +542,7 @@ int SE05XClass::ecdsaVerify(const byte message[], const byte signature[], const
530542
}
531543

532544
if (!deleteBinaryObject(SE05X_TEMP_OBJECT)) {
533-
SMLOG_E("ecdsaVerify failure deleting temporary object\n");
545+
SMLOG_E("ecdsaVerify failure deleting temporary object\n");
534546
return 0;
535547
}
536548

@@ -574,7 +586,7 @@ int SE05XClass::readBinaryObject(int objectId, byte data[], size_t dataMaxLen, s
574586
while (left > 0) {
575587
uint16_t chunk = (left > SE05X_MAX_CHUNK_SIZE) ? SE05X_MAX_CHUNK_SIZE : left;
576588
size_t max_buffer = chunk;
577-
589+
578590
status = Se05x_API_ReadObject(&_se05x_session, objectId, offset, chunk, (data + offset), &max_buffer);
579591
if (status != SM_OK) {
580592
SMLOG_E("Error in Se05x_API_ReadObject \n");
@@ -621,8 +633,6 @@ int SE05XClass::writeAESKey(int objectId, const byte data[], size_t length)
621633
{
622634
smStatus_t status;
623635
SE05x_Result_t result;
624-
uint16_t offset = 0;
625-
uint16_t size;
626636

627637
status = Se05x_API_CheckObjectExists(&_se05x_session, objectId, &result);
628638
if (status != SM_OK) {
@@ -635,9 +645,7 @@ int SE05XClass::writeAESKey(int objectId, const byte data[], size_t length)
635645
return 0;
636646
}
637647

638-
uint16_t left = length;
639-
640-
status = Se05x_API_WriteSymmKey(&_se05x_session, NULL, 3, objectId, NULL, data, length, kSE05x_INS_NA, kSE05x_SymmKeyType_AES);
648+
status = Se05x_API_WriteSymmKey(&_se05x_session, NULL, 3, objectId, SE05x_KeyID_KEK_NONE, data, length, kSE05x_INS_NA, kSE05x_SymmKeyType_AES);
641649

642650
if (status != SM_OK) {
643651
SMLOG_E("Error in Se05x_API_WriteSymmKey \n");
@@ -650,9 +658,6 @@ int SE05XClass::writeHMACKey(int objectId, const byte data[], size_t length)
650658
{
651659
smStatus_t status;
652660
SE05x_Result_t result;
653-
uint8_t exists = 0;
654-
uint16_t offset = 0;
655-
uint16_t size;
656661

657662
status = Se05x_API_CheckObjectExists(&_se05x_session, objectId, &result);
658663
if (status != SM_OK) {
@@ -662,7 +667,6 @@ int SE05XClass::writeHMACKey(int objectId, const byte data[], size_t length)
662667

663668
if (result == kSE05x_Result_SUCCESS) {
664669
SMLOG_E("Object exists \n");
665-
exists = 1;
666670
}
667671

668672
status = Se05x_API_WriteSymmKey(&_se05x_session, NULL, 0, objectId, SE05x_KeyID_KEK_NONE, data, length, kSE05x_INS_NA, kSE05x_SymmKeyType_HMAC);
@@ -784,9 +788,9 @@ int SE05XClass::getECKeyXyValuesFromDER(byte* derKey, size_t derLen, byte* rawKe
784788
if(*rawLen < SE05X_EC_KEY_RAW_LENGTH) {
785789
SMLOG_E("Error in getECKeyXyValuesFromDER \n");
786790
*rawLen = 0;
787-
return 0;
791+
return 0;
788792
}
789-
793+
790794
/* XY values are stored in the last 64 bytes of DER buffer */
791795
*rawLen = SE05X_EC_KEY_RAW_LENGTH;
792796
memcpy(rawKey, &derKey[derLen - SE05X_EC_KEY_RAW_LENGTH], SE05X_EC_KEY_RAW_LENGTH);
@@ -799,15 +803,15 @@ int SE05XClass::setECKeyXyVauesInDER(const byte* rawKey, size_t rawLen, byte* de
799803
if(rawLen != SE05X_EC_KEY_RAW_LENGTH) {
800804
SMLOG_E("Error in setECKeyXyVauesInDER invalid raw key\n");
801805
*derLen = 0;
802-
return 0;
806+
return 0;
803807
}
804808

805809
if(*derLen < SE05X_EC_KEY_DER_LENGTH) {
806810
SMLOG_E("Error in setECKeyXyVauesInDER buffer too small\n");
807811
*derLen = 0;
808-
return 0;
812+
return 0;
809813
}
810-
814+
811815
/* Copy header byte from 0 to 25 */
812816
memcpy(&derKey[0], &ecc_der_header_nist256[0], SE05X_EC_KEY_DER_HEADER_LENGTH);
813817
/* Add format byte */
@@ -827,13 +831,13 @@ int SE05XClass::getECSignatureRsValuesFromDER(byte* derSignature, size_t derLen,
827831
if ((derLen < SE05X_EC_SIGNATURE_MIN_DER_LENGTH) || (derLen > SE05X_EC_SIGNATURE_MAX_DER_LENGTH)) {
828832
SMLOG_E("Error in getECSignatureRsValuesFromDER invalid signature\n");
829833
*rawLen = 0;
830-
return 0;
834+
return 0;
831835
}
832836

833837
if (*rawLen < SE05X_EC_SIGNATURE_RAW_LENGTH) {
834838
SMLOG_E("Error in getECSignatureRsValuesFromDER buffer too small\n");
835839
*rawLen = 0;
836-
return 0;
840+
return 0;
837841
}
838842

839843
rLen = derSignature[3];
@@ -868,7 +872,7 @@ int SE05XClass::setECSignatureRsValuesInDER(const byte* rawSignature, size_t raw
868872
{
869873
/**
870874
* Always consider worst case with padding
871-
*
875+
*
872876
* | 0x30 0x46 0x02 0x21 0x00 | R values 32 bytes | 0x02 0x21 0x00 | S values 32 bytes |
873877
*
874878
*/

0 commit comments

Comments
 (0)