Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkg: add QR Code generator package #16462

Merged
merged 3 commits into from May 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/Kconfig
Expand Up @@ -32,6 +32,7 @@ rsource "nanocbor/Kconfig"
rsource "nanopb/Kconfig"
rsource "qcbor/Kconfig"
rsource "qDSA/Kconfig"
rsource "qr-code-generator/Kconfig"
rsource "relic/Kconfig"
rsource "semtech-loramac/Kconfig"
rsource "talking_leds/Kconfig"
Expand Down
9 changes: 9 additions & 0 deletions pkg/qr-code-generator/Kconfig
@@ -0,0 +1,9 @@
# Copyright (c) 2021 Inria
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.

config PACKAGE_QR-CODE-GENERATOR
bool "QR Code generator"
depends on TEST_KCONFIG
11 changes: 11 additions & 0 deletions pkg/qr-code-generator/Makefile
@@ -0,0 +1,11 @@
PKG_NAME=qr-code-generator
PKG_URL=https://github.com/nayuki/QR-Code-generator
PKG_VERSION=71c75cfeb0f06788ebc43a39b704c39fcf5eba7c # v1.6.0
PKG_LICENSE=MIT

include $(RIOTBASE)/pkg/pkg.mk

CFLAGS += -Wno-type-limits

all:
$(QQ)"$(MAKE)" -C $(PKG_SOURCE_DIR)/c -f $(CURDIR)/$(PKG_NAME).mk
1 change: 1 addition & 0 deletions pkg/qr-code-generator/Makefile.include
@@ -0,0 +1 @@
INCLUDES += -I$(PKGDIRBASE)/qr-code-generator/c
11 changes: 11 additions & 0 deletions pkg/qr-code-generator/doc.txt
@@ -0,0 +1,11 @@
/**
* @defgroup pkg_qr-code-generator QR Code generator
* @ingroup pkg
* @brief QR Code generator library
*
* # License
*
* Licensed under MIT.
*
* @see https://github.com/nayuki/QR-Code-generator
*/
5 changes: 5 additions & 0 deletions pkg/qr-code-generator/qr-code-generator.mk
@@ -0,0 +1,5 @@
MODULE = qr-code-generator

SRC := qrcodegen.c

include $(RIOTBASE)/Makefile.base
11 changes: 11 additions & 0 deletions tests/pkg_qr-code-generator/Kconfig
@@ -0,0 +1,11 @@
config APPLICATION
bool
default y
imply MODULE_AUTO_INIT_SCREEN if BOARD_HAS_DISPLAY
imply MODULE_DISP_DEV if BOARD_HAS_DISPLAY
depends on TEST_KCONFIG

config BOARD_HAS_DISPLAY
bool
default y
depends on BOARD_PINETIME || BOARD_ADAFRUIT_CLUE || BOARD_STM32F429I_DISC1 || BOARD_STM32F429I_DISCO
13 changes: 13 additions & 0 deletions tests/pkg_qr-code-generator/Makefile
@@ -0,0 +1,13 @@
include ../Makefile.tests_common

USEPKG += qr-code-generator

MESSAGE_TO_ENCODE ?= "https://riot-os.org"

CFLAGS += -DMESSAGE_TO_ENCODE=\"$(MESSAGE_TO_ENCODE)\"

# This application provides a 'Kconfig' file and we want to explicitly disable
# Kconfig by default by setting this variable to empty
SHOULD_RUN_KCONFIG ?=

include $(RIOTBASE)/Makefile.include
5 changes: 5 additions & 0 deletions tests/pkg_qr-code-generator/Makefile.board.dep
@@ -0,0 +1,5 @@
# Boards with a screen can use disp_dev
leandrolanzieri marked this conversation as resolved.
Show resolved Hide resolved
ifneq (,$(filter stm32f429i-disc% pinetime adafruit-clue,$(BOARD)))
USEMODULE += auto_init_screen
USEMODULE += disp_dev
endif
1 change: 1 addition & 0 deletions tests/pkg_qr-code-generator/app.config.test
@@ -0,0 +1 @@
CONFIG_PACKAGE_QR-CODE-GENERATOR=y
92 changes: 92 additions & 0 deletions tests/pkg_qr-code-generator/main.c
@@ -0,0 +1,92 @@
/*
* Copyright (C) 2021 Inria
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup tests
* @{
*
* @file
* @brief Test application for the qr-code-generator package
*
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
*
* @}
*/

#include <stdio.h>

#include <stdbool.h>
#include <stdint.h>
#include "qrcodegen.h"

#ifdef MODULE_DISP_DEV
#include "disp_dev.h"
#endif

#ifndef MESSAGE_TO_ENCODE
#define MESSAGE_TO_ENCODE "unknown"
#endif

static uint8_t qr0[qrcodegen_BUFFER_LEN_FOR_VERSION(2)];
static uint8_t buffer[qrcodegen_BUFFER_LEN_FOR_VERSION(2)];

int main(void)
{
if (!qrcodegen_encodeText(MESSAGE_TO_ENCODE,
buffer, qr0, qrcodegen_Ecc_MEDIUM,
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX,
qrcodegen_Mask_AUTO, true)) {
puts("Encoding error");
return -1;
}

int size = qrcodegen_getSize(qr0);

#ifdef MODULE_DISP_DEV
/* Use the first screen */
disp_dev_reg_t *disp_dev = disp_dev_reg_find_screen(0);
if (!disp_dev) {
puts("No screen found!");
return -1;
}
disp_dev_backlight_on();

uint16_t white = UINT16_MAX;
uint16_t black = 0;
for (uint16_t y = 0; y < disp_dev_height(disp_dev->dev); y++) {
for (uint16_t x = 0; x < disp_dev_width(disp_dev->dev); x++) {
disp_dev_map(disp_dev->dev, x, x, y, y, &black);
}
}

const uint8_t scale = disp_dev_height(disp_dev->dev) / size;
const uint8_t w_offset = (disp_dev_width(disp_dev->dev) - (size * scale)) / 2;
const uint8_t h_offset = (disp_dev_height(disp_dev->dev) - (size * scale)) / 2;
#endif

for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
#ifdef MODULE_DISP_DEV
for (int w = x * scale; w < (x + 1) * scale; w++) {
for (int h = y * scale; h < (y + 1) * scale; h++) {
if (qrcodegen_getModule(qr0, x, y)) {
disp_dev_map(disp_dev->dev,
w + w_offset, w + w_offset, h + h_offset, h + h_offset,
&white);
}
}
}
#endif
printf("%s", qrcodegen_getModule(qr0, x, y) ? "██" : " ");

}
puts("");
}

return 0;
}
49 changes: 49 additions & 0 deletions tests/pkg_qr-code-generator/tests/01-run.py
@@ -0,0 +1,49 @@
#!/usr/bin/env python3

# Copyright (C) 2021 Inria
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.

import sys
from testrunner import run


QR_CODE = (
"██████████████ ██████████ ██ ██████████████\n"
"██ ██ ██ ██ ████ ██ ██\n"
"██ ██████ ██ ████ ██ ████ ██ ██████ ██\n"
"██ ██████ ██ ████ ██ ██ ██████ ██\n"
"██ ██████ ██ ██████████ ████ ██ ██████ ██\n"
"██ ██ ██ ██ ████ ██ ██\n"
"██████████████ ██ ██ ██ ██ ██ ██████████████\n"
" ██ ██████ ██ \n"
" ████ ██ ████ ██████ ██████ ██ ██████████\n"
" ████ ██ ████████ ██ ████ ██\n"
" ██ ████████ ██ ██ ████ ██████\n"
"██████ ██ ██ ██ ██ ██ ██ \n"
" ████████ ██ ██ ██████ ██ ████\n"
" ██ ████ ██ ██ ██████ ██ ██\n"
"██ ██ ██ ████████ ██ ██ ██████\n"
" ██ ████ ████ ██ ██ ██ ██ ██ \n"
"██ ██ ██████ ████████████████ \n"
" ██████ ██ ████ ████ ████\n"
"██████████████ ████████ ████████ ██ ████ ████\n"
"██ ██ ██ ██████ ██ ████ ██\n"
"██ ██████ ██ ██████████ ████████████ ██\n"
"██ ██████ ██ ████ ██ ██ ████████ \n"
"██ ██████ ██ ██ ████ ██ ██ ██ ██\n"
"██ ██ ████ ██████████ ████ ██ \n"
"██████████████ ██ ██ ████ ████\n"
)


def testfunc(child):
for line in QR_CODE.split("\n"):
child.expect_exact(line)
print("\nSUCCESS")


if __name__ == "__main__":
sys.exit(run(testfunc))