Lisez l'article ...
Pinedio Stack BL604 est la nouvelle carte de microcontrôleur de PINE64, basée sur le BL604 RISC-V + WiFi + Bluetooth LE.
(Disponible n'importe quel jour maintenant!)
La pile Pinedio est remplie de fonctionnalités de fonctions ...
Affichage LCD Color ST7789
(240 x 240 pixels)
Panneau tactile CST816S
(Connecté sur I2C)
SEMTECH SX1262 LORA TRANSPERIVER
(Fonctionne avec Lorawan)
Récepteur GPS / GPS à 6558
Unité de gestion de l'alimentation SGM40561
Capteur de fréquence cardiaque, accéléromètre, boussole, vibrateur
SPI Flash, port de débogage JTAG, bouton-poussoir
2,4 GHz WiFi, Bluetooth LE
(Merci à BL604)
Ce qui en fait un gadget incroyable pour l'éducation IoT !
Le code source pour Apache Nuttx RTOS sur Pinedio Stack est là ...
lupyuen / incubateur-nuttx (branche de Pinedio)
Lupyuen / Incubator-Nuttx-Apps (branche Pinedio)
NUTTX Build Config pour Pinedio Stack BL604 ...
Pour télécharger, configurer et construire Nuttx pour Pinedio Stack BL604 ...
mkdir nuttx
cd nuttx
git clone --recursive --branch pinedio https://github.com/lupyuen/incubator-nuttx nuttx
git clone --recursive --branch pinedio https://github.com/lupyuen/incubator-nuttx-apps apps
cd nuttx
./tools/configure.sh bl602evb:pinedio
make(Voir le journal de construction)
Suivez les mises à jour sur Twitter
Acordant au schéma Pinedio Stack ...
Pinedio Stack Schéma (2021-09-15)
Schéma de plinthe Pinedio Stack (2021-09-27)
Le bus SPI est partagé par ...
Contrôleur d'affichage ST7789
SEMTECH SX1262 LORA TRANSPERIVER
SPI Flash
Voici les numéros BL604 GPIO pour le bus SPI partagé ...
| Fonction | GPIO |
|---|---|
| Spi mosi | 13 |
| SPI MISO | 0 |
| SPI SCK | 11 |
| SPI CS (inutilisé) | 8 |
(Source)
Pour éviter la diaphonie, nous sélectionnons chaque dispositif SPI en retournant sa broche de sélection de puce de haut à bas ...
| Dispositif SPI | ID de dispositif | Échanger le miso / mosi | Sélection de puce |
|---|---|---|---|
| Affichage ST7789 | 0x40000 | Non | 20 |
| Émetteur-récepteur SX1262 | 1 | Oui | 15 |
| SPI Flash | 2 | Oui | 14 |
| (Périphérique par défaut) | -1 | Oui | 8 (inutilisé) |
(Source)
NUTTX Auto-Asignes 0x40000 comme ID de périphérique SPI pour ST7789 Affichage. (Voir ceci)
Nous avons nous-mêmes attribué les autres ID de l'appareil SPI.
L'ID de périphérique -1 est conçu comme une chute pour attraper tous les périphériques SPI qui ne correspondent pas aux ID de périphérique. Cela fonctionne également pour des configurations SPI simples où l'ID de périphérique n'est pas nécessaire.
Selon le manuel de référence BL602 (Tableau 3.1 "DESCRIPTION DE LA PIN", page 26) ...
GPIO 13 est Mosi
GPIO 0 est le miso
Mais en raison d'une bizarrerie BL602 SPI, nous devons échanger le miso et le mosi pour obtenir ce comportement. C'est pourquoi la colonne "Swap Miso / Mosi" est marquée "Oui" pour l'émetteur-récepteur SX1262 et SPI Flash.
Le contrôleur d'affichage ST7789 est câblé différemment ...
ST7789 reçoit des données SPI sur GPIO 0
ST7789 Data / Command Pin est connecté sur GPIO 13
(Élevé pour les données ST7789, bas pour les commandes ST7789)
La direction des données SPI est retournée pour ST7789. C'est pourquoi la colonne "Swap Miso / Mosi" est marquée "Non" pour le contrôleur d'affichage ST7789.
Nous représentons la table de périphérique SPI ci-dessus dans NUTTX sous forme de tableau INT plat ...
| Dispositif SPI | ID de dispositif | Échanger le miso / mosi | Sélection de puce |
|---|---|---|---|
| Affichage ST7789 | 0x40000 | 0 | 20 |
| Émetteur-récepteur SX1262 | 1 | 1 | 15 |
| SPI Flash | 2 | 1 | 14 |
| (Périphérique par défaut) | -1 | 1 | 8 |
(Source)
Voici le code source ...
#ifdef CONFIG_BL602_SPI0
/* SPI Device Table: SPI Device ID, Swap MISO/MOSI, Chip Select */
static const int32_t bl602_spi_device_table [] =
{
#ifdef BOARD_LCD_DEVID /* ST7789 Display */
BOARD_LCD_DEVID , BOARD_LCD_SWAP , BOARD_LCD_CS ,
#endif /* BOARD_LCD_DEVID */
#ifdef BOARD_SX1262_DEVID /* LoRa SX1262 */
BOARD_SX1262_DEVID , BOARD_SX1262_SWAP , BOARD_SX1262_CS ,
#endif /* BOARD_SX1262_DEVID */
#ifdef BOARD_FLASH_DEVID /* SPI Flash */
BOARD_FLASH_DEVID , BOARD_FLASH_SWAP , BOARD_FLASH_CS ,
#endif /* BOARD_FLASH_DEVID */
/* Must end with Default SPI Device */
-1 , 1 , BOARD_SPI_CS , /* Swap MISO/MOSI */
};
#endif /* CONFIG_BL602_SPI0 */(Source)
Les colonnes de la table du périphérique SPI ...
/* Columns in the SPI Device Table */
#define DEVID_COL 0 /* SPI Device ID */
#define SWAP_COL 1 /* 1 if MISO/MOSI should be swapped, else 0 */
#define CS_COL 2 /* SPI Chip Select Pin */
#define NUM_COLS 3 /* Number of columns in SPI Device Table */(Source)
Voici les fonctions pour accéder à la table des périphériques SPI ...
BL602_SPI_GET_DEVICE: Recherchez un appareil dans la table de périphérique SPI
BL602_SPI_DESELECT_DEVICES: Désélectionnez tous les appareils dans la table du périphérique SPI
BL602_SPI_VALIDAD_DEVICES: Validez les appareils dans la table de périphérique SPI
Le tableau des périphériques SPI ci-dessus fait référence aux définitions de broches suivantes ...
/* SPI for PineDio Stack: Chip Select (unused), MOSI, MISO, SCK */
#define BOARD_SPI_CS (GPIO_INPUT | GPIO_PULLUP | GPIO_FUNC_SPI | GPIO_PIN8) /* Unused */
#define BOARD_SPI_MOSI (GPIO_INPUT | GPIO_PULLUP | GPIO_FUNC_SPI | GPIO_PIN13)
#define BOARD_SPI_MISO (GPIO_INPUT | GPIO_PULLUP | GPIO_FUNC_SPI | GPIO_PIN0)
#define BOARD_SPI_CLK (GPIO_INPUT | GPIO_PULLUP | GPIO_FUNC_SPI | GPIO_PIN11)
#ifdef CONFIG_LCD_ST7789
/* ST7789 for PineDio Stack: Chip Select, Reset and Backlight */
#define BOARD_LCD_DEVID SPIDEV_DISPLAY(0) /* SPI Device ID: 0x40000 */
#define BOARD_LCD_SWAP 0 /* Don't swap MISO/MOSI */
#define BOARD_LCD_BL_INVERT /* Backlight is active when Low */
#define BOARD_LCD_CS (GPIO_OUTPUT | GPIO_PULLUP | GPIO_FUNC_SWGPIO | GPIO_PIN20)
#define BOARD_LCD_RST (GPIO_OUTPUT | GPIO_PULLUP | GPIO_FUNC_SWGPIO | GPIO_PIN3)
#define BOARD_LCD_BL (GPIO_OUTPUT | GPIO_PULLUP | GPIO_FUNC_SWGPIO | GPIO_PIN21)
#endif /* CONFIG_LCD_ST7789 */
/* SX1262 for PineDio Stack: Chip Select */
#define BOARD_SX1262_DEVID 1 /* SPI Device ID */
#define BOARD_SX1262_SWAP 1 /* Swap MISO/MOSI */
#define BOARD_SX1262_CS (GPIO_OUTPUT | GPIO_PULLUP | GPIO_FUNC_SWGPIO | GPIO_PIN15)
/* SPI Flash for PineDio Stack: Chip Select */
#define BOARD_FLASH_DEVID 2 /* SPI Device ID */
#define BOARD_FLASH_SWAP 1 /* Swap MISO/MOSI */
#define BOARD_FLASH_CS (GPIO_OUTPUT | GPIO_PULLUP | GPIO_FUNC_SWGPIO | GPIO_PIN14)(Source)
BL602 NUTTX SPI Driver recherche la table du périphérique SPI vers 1️⃣ Swap Miso et Mosi broches 2️⃣ Flip the Chip Select épingles. C'est ainsi que nous sélectionnons et désélectionnons chaque appareil SPI ...
// Enable/disable the SPI chip select
static void bl602_spi_select ( struct spi_dev_s * dev , uint32_t devid ,
bool selected )
{
const int32_t * spidev ;
spiinfo ( "devid: %lu, CS: %sn" , devid , selected ? "select" : "free" );
/* get device from SPI Device Table */
spidev = bl602_spi_get_device ( devid );
DEBUGASSERT ( spidev != NULL );
/* swap MISO and MOSI if needed */
if ( selected )
{
bl602_swap_spi_0_mosi_with_miso ( spidev [ SWAP_COL ]);
}
/* set Chip Select */
bl602_gpiowrite ( spidev [ CS_COL ], ! selected );
#ifdef CONFIG_SPI_CMDDATA
/* revert MISO and MOSI from GPIO Pins to SPI Pins */
if (! selected )
{
bl602_configgpio ( BOARD_SPI_MISO );
bl602_configgpio ( BOARD_SPI_MOSI );
}
#endif
}(Source)
bl602_spi_select est appelé après avoir verrouillé le bus SPI.
NUTTX RTOS utilise MISO comme broche de données / commande ST7789 ... mais ST7789 est câblé "vers l'arrière" sur Pinedio Stack BL604! Nous utilisons MOSI comme broche de données / commande ST7789 à la place.
Voici comment nous retournons la broche de données / commande ST7789 en fonction du swap miso / mosi ...
#ifdef CONFIG_SPI_CMDDATA
static int bl602_spi_cmddata ( struct spi_dev_s * dev ,
uint32_t devid , bool cmd )
{
spiinfo ( "devid: %" PRIu32 " CMD: %sn" , devid , cmd ? "command" :
"data" );
if ( devid == SPIDEV_DISPLAY ( 0 ))
{
const int32_t * spidev ;
gpio_pinset_t dc ;
gpio_pinset_t gpio ;
int ret ;
/* get device from SPI Device Table */
spidev = bl602_spi_get_device ( devid );
DEBUGASSERT ( spidev != NULL );
/* if MISO/MOSI are swapped, DC is MISO, else MOSI */
dc = spidev [ SWAP_COL ] ? BOARD_SPI_MISO : BOARD_SPI_MOSI ;
/* reconfigure DC from SPI Pin to GPIO Pin */
gpio = ( dc & GPIO_PIN_MASK )
| GPIO_OUTPUT | GPIO_PULLUP | GPIO_FUNC_SWGPIO ;
ret = bl602_configgpio ( gpio );
if ( ret < 0 )
{
spierr ( "Failed to configure MISO as GPIOn" );
DEBUGPANIC ();
return ret ;
}
/* set DC to high (data) or low (command) */
bl602_gpiowrite ( gpio , ! cmd );
return OK ;
}
spierr ( "SPI cmddata not supportedn" );
DEBUGPANIC ();
return - ENODEV ;
}
#endif(Source)
Au démarrage de Nuttx, nous désélectionnons tous les appareils SPI ... en renversant leurs broches de puce à haut ...
static void bl602_spi_init ( struct spi_dev_s * dev )
{
struct bl602_spi_priv_s * priv = ( struct bl602_spi_priv_s * ) dev ;
const struct bl602_spi_config_s * config = priv -> config ;
/* Initialize the SPI semaphore that enforces mutually exclusive access */
nxsem_init ( & priv -> exclsem , 0 , 1 );
bl602_configgpio ( BOARD_SPI_CS );
bl602_configgpio ( BOARD_SPI_MOSI );
bl602_configgpio ( BOARD_SPI_MISO );
bl602_configgpio ( BOARD_SPI_CLK );
/* set master mode */
bl602_set_spi_0_act_mode_sel ( 1 );
/* swap MOSI with MISO to be consistent with BL602 Reference Manual */
bl602_swap_spi_0_mosi_with_miso ( 1 );
/* spi cfg reg:
* cr_spi_deg_en 1
* cr_spi_m_cont_en 0
* cr_spi_byte_inv 0
* cr_spi_bit_inv 0
*/
modifyreg32 ( BL602_SPI_CFG , SPI_CFG_CR_M_CONT_EN
| SPI_CFG_CR_BYTE_INV | SPI_CFG_CR_BIT_INV ,
SPI_CFG_CR_DEG_EN );
/* disable rx ignore */
modifyreg32 ( BL602_SPI_CFG , SPI_CFG_CR_RXD_IGNR_EN , 0 );
bl602_spi_setfrequency ( dev , config -> clk_freq );
bl602_spi_setbits ( dev , 8 );
bl602_spi_setmode ( dev , config -> mode );
/* spi fifo clear */
modifyreg32 ( BL602_SPI_FIFO_CFG_0 , SPI_FIFO_CFG_0_RX_CLR
| SPI_FIFO_CFG_0_TX_CLR , 0 );
/* deselect all spi devices */
bl602_spi_deselect_devices ();
}(Source)
L'affichage ST7789 jouera-t-il bien avec Lora SX1262 sur Pinedio Stack BL604? YEP SX1262 fonctionne correctement sur le bus SPI partagé!
Pinedio Stack Boots et rend un écran rose ...
gpio_pin_register: Registering /dev/gpio0
gpio_pin_register: Registering /dev/gpio1
gpint_enable: Disable the interrupt
gpio_pin_register: Registering /dev/gpio2
bl602_gpio_set_intmod: ****gpio_pin=115, int_ctlmod=1, int_trgmod=0
spi_test_driver_register: devpath=/dev/spitest0, spidev=0
st7789_sleep: sleep: 0
st7789_sendcmd: cmd: 0x11
st7789_sendcmd: OK
st7789_bpp: bpp: 16
st7789_sendcmd: cmd: 0x3a
st7789_sendcmd: OK
st7789_setorientation:
st7789_sendcmd: cmd: 0x36
st7789_sendcmd: OK
st7789_display: on: 1
st7789_sendcmd: cmd: 0x29
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x21
st7789_sendcmd: OK
st7789_fill: color: 0xaaaa
st7789_sendcmd: cmd: 0x2b
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2a
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2c
st7789_sendcmd: OK
board_lcd_getdev: SPI port 0 bound to LCD 0
st7789_getplaneinfo: planeno: 0 bpp: 16
Nous exécutons l'application spi_test2 pour tester SX1262 ...
NuttShell (NSH) NuttX-10.2.0-RC0
nsh>
nsh> ?
help usage: help [-v] [<cmd>]
? cat help ls uname
Builtin Apps:
tinycbor_test spi_test nsh
lorawan_test timer sensortest
sx1262_test bl602_adc_test ikea_air_quality_sensor
bas spi_test2 gpio
sh getprime
lvgldemo hello
nsh> spi_test2
spi_test_driver_open:
gpout_write: Writing 0
spi_test_driver_write: buflen=2
spi_test_driver_configspi:
spi_test_driver_read: buflen=256
gpout_write: Writing 1
Get Status: received
a2 22
SX1262 Status is 2
gpout_write: Writing 0
spi_test_driver_write: buflen=5
spi_test_driver_configspi:
spi_test_driver_read: buflen=256
gpout_write: Writing 1
Read Register 8: received
a2 a2 a2 a2 80
SX1262 Register 8 is 0x80
SX1262 Renvoie la valeur du registre 0x80, ce qui est correct!
Ensuite, nous exécutons l'application de démonstration LVGL ...
spi_test_driver_close:
nsh> lvgldemo
fbdev_init: Failed to open /dev/fb0: 2
st7789_getvideoinfo: fmt: 11 xres: 240 yres: 240 nplanes: 1
lcddev_init: VideoInfo:
fmt: 11
xres: 240
yres: 240
nplanes: 1
lcddev_init: PlaneInfo (plane 0):
bpp: 16
st7789_putarea: row_start: 0 row_end: 19 col_start: 0 col_end: 239
st7789_sendcmd: cmd: 0x2b
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2a
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2c
st7789_sendcmd: OK
st7789_putarea: row_start: 20 row_end: 39 col_start: 0 col_end: 239
st7789_sendcmd: cmd: 0x2b
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2a
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2c
st7789_sendcmd: OK
st7789_putarea: row_start: 40 row_end:59 col_start: 0 col_end: 239
st7789_sendcmd: cmd: 0x2b
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2a
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2c
st7789_sendcmd: OK
st7789_putarea: row_start: 60 row_end: 79 col_start: 0 col_end: 239
st7789_sendcmd: cmd: 0x2b
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2a
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2c
st7789_sendcmd: OK
st7789_putarea: row_start: 80 row_end: 99 col_start: 0 col_end: 239
st7789_sendcmd: cmd: 0x2b
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2a
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2c
st7789_sendcmd: OK
st7789_putarea: row_start: 100 row_end: 119 col_start: 0 col_end: 239
st7789_sendcmd: cmd: 0x2b
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2a
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2c
st7789_sendcmd: OK
st7789_putarea: row_start: 120 row_end: 139 col_start: 0 col_end: 239
st7789_sendcmd: cmd: 0x2b
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2a
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2c
st7789_sendcmd: OK
st7789_putarea: row_start: 140 row_end: 159 col_start: 0 col_end: 239
st7789_sendcmd: cmd: 0x2b
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2a
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2c
st7789_sendcmd: OK
st7789_putarea: row_start: 160 row_end: 179 col_start: 0 col_end: 239
st7789_sendcmd: cmd: 0x2b
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2a
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2c
st7789_sendcmd: OK
st7789_putarea: row_start: 180 row_end: 199 col_start: 0 col_end: 239
st7789_sendcmd: cmd: 0x2b
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2a
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2c
st7789_sendcmd: OK
st7789_putarea: row_start: 200 row_end: 219 col_start: 0 col_end: 239
st7789_sendcmd: cmd: 0x2b
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2a
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2c
st7789_sendcmd: OK
st7789_putarea: row_start: 220 row_end: 239 col_start: 0 col_end: 239
st7789_sendcmd: cmd: 0x2b
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2a
st7789_sendcmd: OK
st7789_sendcmd: cmd: 0x2c
st7789_sendcmd: OK
monitor_cb: 57600 px refreshed in 1110 ms
Qui rend correctement l'écran de démonstration LVGL sur ST7789!
Il y a une condition de course potentielle si nous utilisons le pilote SX1262 simultanément avec le pilote ST7789 ...
Pendant la transmission LORA, le pilote SX1262 appelle ioctl() pour retourner la puce SX1262 Sélectionnez pour Low
(Voir ceci)
Le pilote SX1262 appelle le pilote de test SPI /dev/spitest0 , qui verrouille ( SPI_LOCK ) et sélectionne ( SPI_SELECT ) le bus SPI (avec ID de périphérique SPI 0)
(Voir ceci)
Notez que les appels vers ioctl() et SPI_LOCK / SPI_SELECT ne sont pas atomiques
Si le pilote ST7789 est actif entre les appels vers ioctl() et SPI_LOCK / SPI_SELECT , SX1262 Chip Select et ST7789 Chip Select seront bas
Cela pourrait transmettre des ordures à SX1262
Pour résoudre ce problème, nous enregistrerons un nouveau pilote de test SPI /dev/spitest1 avec ID de périphérique SPI 1.
Le pilote LORA accédera alors /dev/spitest1 , qui sera SPI_LOCK et SPI_SELECT le bus SPI (avec SPI Device ID 1).
Étant donné que l'ID de périphérique SPI est 1, SPI_SELECT retourne la puce SX1262 Sélectionner à Low.
BL602 / BL604 Talks à l'affichage ST7789 en mode SPI 1 ou 3 ... dépend si le miso / mosi est échangé
#ifdef CONFIG_BL602_SPI0
#include "../boards/risc-v/bl602/bl602evb/include/board.h"
#endif /* CONFIG_BL602_SPI0 */
#ifdef CONFIG_LCD_ST7789
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Verify that all configuration requirements have been met */
#ifdef CONFIG_BL602_SPI0
# if defined( BOARD_LCD_SWAP ) && BOARD_LCD_SWAP == 0 /* If MISO/MOSI not swapped... */
# warning Using SPI Mode 1 for ST7789 on BL602 (MISO/MOSI not swapped)
# define CONFIG_LCD_ST7789_SPIMODE SPIDEV_MODE1 /* SPI Mode 1: Workaround for BL602 */
# else
# warning Using SPI Mode 3 for ST7789 on BL602 (MISO/MOSI swapped)
# define CONFIG_LCD_ST7789_SPIMODE SPIDEV_MODE3 /* SPI Mode 3: Workaround for BL602 */
# endif /* BOARD_LCD_SWAP */
#else
# ifndef CONFIG_LCD_ST7789_SPIMODE
# define CONFIG_LCD_ST7789_SPIMODE SPIDEV_MODE0
# endif /* CONFIG_LCD_ST7789_SPIMODE */
#endif /* CONFIG_BL602_SPI0 */(Source)
L'affichage ST7789 fonctionne OK à la fréquence SPI 4 MHz. Peut-être pouvons-nous aller plus haut?
CONFIG_LCD_ST7789_FREQUENCY=4000000
(Source)
L'application de test LVGL est là ...
Pour exécuter l'application, entrez ceci sur le shell Nuttx ...
lvgltestVoici le code qui rend l'écran ...
// Create the LVGL Widgets that will be rendered on the display
static void create_widgets ( void )
{
// Get the Active Screen
lv_obj_t * screen = lv_scr_act ();
// Create a Label Widget
lv_obj_t * label = lv_label_create ( screen , NULL );
// Wrap long lines in the label text
lv_label_set_long_mode ( label , LV_LABEL_LONG_BREAK );
// Interpret color codes in the label text
lv_label_set_recolor ( label , true);
// Center align the label text
lv_label_set_align ( label , LV_LABEL_ALIGN_CENTER );
// Set the label text and colors
lv_label_set_text (
label ,
"#ff0000 HELLO# " // Red Text
"#00ff00 PINEDIO# " // Green Text
"#0000ff STACK!# " // Blue Text
);
// Set the label width
lv_obj_set_width ( label , 200 );
// Align the label to the center of the screen, shift 30 pixels up
lv_obj_align ( label , NULL , LV_ALIGN_CENTER , 0 , -30 );
#ifdef CONFIG_USE_LV_CANVAS // LVGL Canvas Demo
// Create the Canvas
lv_obj_t * canvas = lv_canvas_create ( screen , NULL );
// Set the Canvas Buffer (Warning: Might take a lot of RAM!)
static lv_color_t cbuf [ LV_CANVAS_BUF_SIZE_TRUE_COLOR ( CANVAS_WIDTH , CANVAS_HEIGHT )];
lv_canvas_set_buffer ( canvas , cbuf , CANVAS_WIDTH , CANVAS_HEIGHT , LV_IMG_CF_TRUE_COLOR );
// Align the canvas to the center of the screen, shift 50 pixels down
lv_obj_align ( canvas , NULL , LV_ALIGN_CENTER , 0 , 50 );
// Fill the canvas with white
lv_canvas_fill_bg ( canvas , LV_COLOR_WHITE , LV_OPA_TRANSP );
// Create a Rounded Rectangle
lv_draw_rect_dsc_t rect_dsc ;
lv_draw_rect_dsc_init ( & rect_dsc );
rect_dsc . radius = 10 ; // Corner Radius
rect_dsc . bg_opa = LV_OPA_COVER ; // Opacity: Opaque
rect_dsc . bg_grad_dir = LV_GRAD_DIR_HOR ; // Gradient Direction: Horizontal
rect_dsc . bg_color = LV_COLOR_BLUE ; // From Blue
rect_dsc . bg_grad_color = LV_COLOR_GREEN ; // To Green
rect_dsc . border_width = 2 ; // Border Width
rect_dsc . border_opa = LV_OPA_90 ; // Border Opacity: 90%
rect_dsc . border_color = LV_COLOR_SILVER ; // Border Color
rect_dsc . shadow_width = 5 ; // Shadow Width
rect_dsc . shadow_ofs_x = 5 ; // Shadow Offset X
rect_dsc . shadow_ofs_y = 5 ; // Shadow Offset Y
// Draw the Rounded Rectangle to the canvas
lv_canvas_draw_rect ( canvas , 0 , 0 , 95 , 95 , & rect_dsc );
#endif // CONFIG_USE_LV_CANVAS
#ifdef CONFIG_EXAMPLES_LVGLTEST_MESSAGEBOX // LVGL Message Box Demo
// Create a Message Box Widget
lv_obj_t * msgbox = lv_msgbox_create ( screen , NULL );
// Set the Message Box Text
lv_msgbox_set_text ( msgbox , "Hello PineDio Stack!" );
// Define the Message Box Buttons
static const char * btns [] = { "Cancel" , "OK" , "" };
// Add the buttons to the Message Box
lv_msgbox_add_btns ( msgbox , btns );
#endif // CONFIG_EXAMPLES_LVGLTEST_MESSAGEBOX
}(Source)
Pour rendre notre propre texte et graphiques, modifiez ce fichier source et modifiez le code ci-dessus ...
apps/examples/lvgltest/lvgltest.c
Pour exécuter l'application, entrez ceci sur le shell Nuttx ...
lvgldemo Pour modifier le message dans l'application de démonstration lvgl, modifiez apps/examples/lvgldemo/lv_demos/src/lv_demo_widgets/lv_demo_widgets.c ...
static void controls_create ( lv_obj_t * parent )
{
lv_page_set_scrl_layout ( parent , LV_LAYOUT_PRETTY_TOP );
lv_disp_size_t disp_size = lv_disp_get_size_category ( NULL );
lv_coord_t grid_w = lv_page_get_width_grid ( parent , disp_size <= LV_DISP_SIZE_SMALL ? 1 : 2 , 1 );
#if LV_DEMO_WIDGETS_SLIDESHOW == 0
static const char * btns [] = { "PineDio" , "Stack" , "" };
lv_obj_t * m = lv_msgbox_create ( lv_scr_act (), NULL );
lv_msgbox_add_btns ( m , btns );
lv_obj_t * btnm = lv_msgbox_get_btnmatrix ( m );
lv_btnmatrix_set_btn_ctrl ( btnm , 1 , LV_BTNMATRIX_CTRL_CHECK_STATE );
#endif Pour tester Lora sur Pinedio Stack, modifiez sx1262_test_main.c à ...
apps/examples/sx1262_test/sx1262_test_main.c
Et mettre à jour les paramètres LORA ...
Lorawan travaille bien sur le bus SPI partagé Yay! Pinedio Stack se connecte à Lorawan Gateway (ChirpStack) et envoie des paquets de données.
(Le capteur de température interne sur ADC fonctionne bien aussi)
N'oubliez pas de désactiver la journalisation de toutes les informations car elle affecte les minuteries de Lorawan.
Voici comment nous définissons les paramètres de Lorawan ...
"Device EUI, rejoignez l'EUI et la clé d'application"
"Fréquence de Lorawan"
NuttShell (NSH) NuttX-10.2.0-RC0
nsh> lorawan_test
init_entropy_pool
offset = 2228
temperature = 31.600670 Celsius
offset = 2228
temperature = 31.084742 Celsius
offset = 2228
temperature = 32.890495 Celsius
offset = 2228
temperature = 33.535404 Celsius
###### ===================================== ######
Application name : lorawan_test
Application version: 1.2.0
GitHub base version: 5.0.0
###### ===================================== ######
init_event_queue
TimerInit: 0x4201c750
callout_handler: lock
TimerInit: 0x4201c76c
TimerInit: 0x4201c788
TimerInit: 0x4201c804
TimerInit: 0x4201c8b8
TimerInit: 0x4201c8d4
TimerInit: 0x4201c8f0
TimerInit: 0x4201c90c
TODO: RtcGetCalendarTime
TODO: SX126xReset
init_gpio
DIO1 pintype before=5
init_gpio: change DIO1 to Trigger GPIO Interrupt on Rising Edge
gpio_ioctl: Requested pintype 8, but actual pintype 5
DIO1 pintype after=5
Starting process_dio1
process_dio1 started
process_dio1: event=0x4201b878
init_spi
SX126xSetTxParams: power=22, rampTime=7
SX126xSetPaConfig: paDutyCycle=4, hpMax=7, deviceSel=0, paLut=1
TimerInit: 0x4201b850
TimerInit: 0x4201b7bc
RadioSetModem
RadioSetModem
RadioSetPublicNetwork: public syncword=3444
RadioSleep
DIO1 add event
TODO: EepromMcuReadBuffer
TODO: EepromMcuReadBuffer
TODO: EepromMcuReadBuffer
TODO: EepromMcuReadBuffer
TODO: EepromMcuReadBuffer
TODO: EepromMcuReadBuffer
TODO: EepromMcuReadBuffer
TODO: EepromMcuReadBuffer
RadioSetModem
RadioSetPublicNetwork: public syncword=3444
DevEui : 4B-C1-5E-E7-37-7B-B1-5B
JoinEui : 00-00-00-00-00-00-00-00
Pin : 00-00-00-00
TimerInit: 0x4201c3a8
TimerInit: 0x4201c3c4
TimerInit: 0x4201c288
TODO: RtcGetCalendarTime
TODO: RtcBkupRead
TODO: RtcBkupRead
RadioSetChannel: freq=923200000
RadioSetTxConfig: modem=1, power=13, fdev=0, bandwidth=0, datarate=10, coderate= 1, preambleLen=8, fixLen=0, crcOn=1, freqHopOn=0, hopPeriod=0, iqInverted=0, tim eout=4000
RadioSetTxConfig: SpreadingFactor=10, Bandwidth=4, CodingRate=1, LowDatarateOpti mize=0, PreambleLength=8, HeaderType=0, PayloadLength=255, CrcMode=1, InvertIQ=0
RadioStandby
RadioSetModem
SX126xSetTxParams: power=13, rampTime=7
SX126xSetPaConfig: paDutyCycle=4, hpMax=7, deviceSel=0, paLut=1
SecureElementRandomNumber: 0xa8c2a6e7
RadioSend: size=23
00 00 00 00 00 00 00 00 00 5b b1 7b 37 e7 5e c1 4b e7 a6 80 b1 e0 e4
RadioSend: PreambleLength=8, HeaderType=0, PayloadLength=23, CrcMode=1, InvertIQ =0
TimerStop: 0x4201b850
TimerStart2: 0x4201b850, 4000 ms
callout_reset: evq=0x42013250, ev=0x4201b850
###### =========== MLME-Request ============ ######
###### MLME_JOIN ######
###### ===================================== ######
STATUS : OK
StartTxProcess
TimerInit: 0x42015b7c
TimerSetValue: 0x42015b7c, 42249 ms
OnTxTimerEvent: timeout in 42249 ms, event=0
TimerStop: 0x42015b7c
TimerSetValue: 0x42015b7c, 42249 ms
TimerStart: 0x42015b7c
TimerStop: 0x42015b7c
TimerStart2: 0x42015b7c, 42249 ms
callout_reset: evq=0x42013250, ev=0x42015b7c
handle_event_queue
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
RadioOnDioIrq
RadioIrqProcess
DIO1 add event
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
IRQ_TX_DONE
TimerStop: 0x4201b850
TODO: RtcGetCalendarTime
TODO: RtcBkupRead
RadioOnDioIrq
RadioIrqProcess
RadioSleep
DIO1 add event
TimerSetValue: 0x4201c76c, 4988 ms
TimerStart: 0x4201c76c
TimerStop: 0x4201c76c
TimerStart2: 0x4201c76c, 4988 ms
callout_reset: evq=0x42013250, ev=0x4201c76c
TimerSetValue: 0x4201c788, 5988 ms
TimerStart: 0x4201c788
TimerStop: 0x4201c788
TimerStart2: 0x4201c788, 5988 ms
callout_reset: evq=0x42013250, ev=0x4201c788
TODO: RtcGetCalendarTime
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
RadioOnDioIrq
RadioIrqProcess
callout_handler: unlock
callout_handler: evq=0x42013250, ev=0x4201c76c
callout_handler: lock
handle_event_queue: ev=0x4201c76c
TimerStop: 0x4201c76c
RadioStandby
RadioSetChannel: freq=923200000
RadioSetRxConfig
RadioStandby
RadioSetModem
RadioSetRxConfig done
RadioRx
TimerStop: 0x4201b7bc
TimerStart2: 0x4201b7bc, 3000 ms
callout_reset: evq=0x42013250, ev=0x4201b7bc
RadioOnDioIrq
RadioIrqProcess
DIO1 add event
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
IRQ_PREAMBLE_DETECTED
RadioOnDioIrq
RadioIrqProcess
DIO1 add event
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
IRQ_HEADER_VALID
RadioOnDioIrq
RadioIrqProcess
DIO1 add event
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
IRQ_RX_DONE
TimerStop: 0x4201b7bc
RadioOnDioIrq
RadioIrqProcess
RadioSleep
DIO1 add event
TimerStop: 0x4201c788
OnTxData
###### =========== MLME-Confirm ============ ######
STATUS : OK
OnJoinRequest
###### =========== JOINED ============ ######
OTAA
DevAddr : 01097710
DATA RATE : DR_2
TODO: EepromMcuWriteBuffer
TODO: EepromMcuWriteBuffer
TODO: EepromMcuWriteBuffer
TODO: EepromMcuWriteBuffer
TODO: EepromMcuWriteBuffer
TODO: EepromMcuWriteBuffer
UplinkProcess
PrepareTxFrame: Transmit to LoRaWAN: Hi NuttX (9 bytes)
PrepareTxFrame: status=0, maxSize=11, currentSize=11
LmHandlerSend: Data frame
TODO: RtcGetCalendarTime
TODO: RtcBkupRead
RadioSetChannel: freq=923200000
RadioSetTxConfig: modem=1, power=13, fdev=0, bandwidth=0, datarate=9, coderate=1 , preambleLen=8, fixLen=0, crcOn=1, freqHopOn=0, hopPeriod=0, iqInverted=0, time out=4000
RadioSetTxConfig: SpreadingFactor=9, Bandwidth=4, CodingRate=1, LowDatarateOptim ize=0, PreambleLength=8, HeaderType=0, PayloadLength=128, CrcMode=1, InvertIQ=0
RadioStandby
RadioSetModem
SX126xSetTxParams: power=13, rampTime=7
SX126xSetPaConfig: paDutyCycle=4, hpMax=7, deviceSel=0, paLut=1
RadioSend: size=22
40 10 77 09 01 00 01 00 01 a5 12 b3 cc a2 27 27 57 dc c3 a7 eb ae
RadioSend: PreambleLength=8, HeaderType=0, PayloadLength=22, CrcMode=1, InvertIQ =0
TimerStop: 0x4201b850
TimerStart2: 0x4201b850, 4000 ms
callout_reset: evq=0x42013250, ev=0x4201b850
###### =========== MCPS-Request ============ ######
###### MCPS_UNCONFIRMED ######
###### ===================================== ######
STATUS : OK
PrepareTxFrame: Transmit OK
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
RadioOnDioIrq
RadioIrqProcess
DIO1 add event
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
IRQ_TX_DONE
TimerStop: 0x4201b850
TODO: RtcGetCalendarTime
TODO: RtcBkupRead
RadioOnDioIrq
RadioIrqProcess
RadioSleep
DIO1 add event
TimerSetValue: 0x4201c76c, 980 ms
TimerStart: 0x4201c76c
TimerStop: 0x4201c76c
TimerStart2: 0x4201c76c, 980 ms
callout_reset: evq=0x42013250, ev=0x4201c76c
TimerSetValue: 0x4201c788, 1988 ms
TimerStart: 0x4201c788
TimerStop: 0x4201c788
TimerStart2: 0x4201c788, 1988 ms
callout_reset: evq=0x42013250, ev=0x4201c788
TODO: RtcGetCalendarTime
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
RadioOnDioIrq
RadioIrqProcess
callout_handler: unlock
callout_handler: evq=0x42013250, ev=0x4201c76c
callout_handler: lock
handle_event_queue: ev=0x4201c76c
TimerStop: 0x4201c76c
RadioStandby
RadioSetChannel: freq=923200000
RadioSetRxConfig
RadioStandby
RadioSetModem
RadioSetRxConfig done
RadioRx
TimerStop: 0x4201b7bc
TimerStart2: 0x4201b7bc, 3000 ms
callout_reset: evq=0x42013250, ev=0x4201b7bc
RadioOnDioIrq
RadioIrqProcess
DIO1 add event
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
IRQ_RX_TX_TIMEOUT
TimerStop: 0x4201b7bc
RadioOnDioIrq
RadioIrqProcess
RadioSleep
DIO1 add event
TimerStop: 0x4201c788
TimerStop: 0x4201c750
OnTxData
###### =========== MCPS-Confirm ============ ######
STATUS : OK
###### ===== UPLINK FRAME 1 ===== ######
CLASS : A
TX PORT : 1
TX DATA : UNCONFIRMED
48 69 20 4E 75 74 74 58 00
DATA RATE : DR_3
U/L FREQ : 923200000
TX POWER : 0
CHANNEL MASK: 0003
TODO: EepromMcuWriteBuffer
TODO: EepromMcuWriteBuffer
UplinkProcess
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
RadioOnDioIrq
RadioIrqProcess
UplinkProcess
callout_handler: unlock
callout_handler: evq=0x42013250, ev=0x42015b7c
callout_handler: lock
handle_event_queue: ev=0x42015b7c
OnTxTimerEvent: timeout in 42249 ms, event=0x42015b7c
TimerStop: 0x42015b7c
TimerSetValue: 0x42015b7c, 42249 ms
TimerStart: 0x42015b7c
TimerStop: 0x42015b7c
TimerStart2: 0x42015b7c, 42249 ms
callout_reset: evq=0x42013250, ev=0x42015b7c
RadioOnDioIrq
RadioIrqProcess
UplinkProcess
PrepareTxFrame: Transmit to LoRaWAN: Hi NuttX (9 bytes)
PrepareTxFrame: status=0, maxSize=53, currentSize=53
LmHandlerSend: Data frame
TODO: RtcGetCalendarTime
TODO: RtcBkupRead
RadioSetChannel: freq=923200000
RadioSetTxConfig: modem=1, power=13, fdev=0, bandwidth=0, datarate=9, coderate=1, preambleLen=8, fixLen=0, crcOn=1, freqHopOn=0, hopPeriod=0, iqInverted=0, timeout=4000
RadioSetTxConfig: SpreadingFactor=9, Bandwidth=4, CodingRate=1, LowDatarateOptimize=0, PreambleLength=8, HeaderType=0, PayloadLength=128, CrcMode=1, InvertIQ=0
RadioStandby
RadioSetModem
SX126xSetTxParams: power=13, rampTime=7
SX126xSetPaConfig: paDutyCycle=4, hpMax=7, deviceSel=0, paLut=1
RadioSend: size=22
40 10 77 09 01 00 02 00 01 ad b9 67 e6 1c 34 05 2d f3 d3 b5 c7 16
RadioSend: PreambleLength=8, HeaderType=0, PayloadLength=22, CrcMode=1, InvertIQ=0
TimerStop: 0x4201b850
TimerStart2: 0x4201b850, 4000 ms
callout_reset: evq=0x42013250, ev=0x4201b850
###### =========== MCPS-Request ============ ######
###### MCPS_UNCONFIRMED ######
###### ===================================== ######
STATUS : OK
PrepareTxFrame: Transmit OK
DIO1 add event
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
IRQ_TX_DONE
TimerStop: 0x4201b850
TODO: RtcGetCalendarTime
TODO: RtcBkupRead
RadioOnDioIrq
RadioIrqProcess
RadioSleep
DIO1 add event
TimerSetValue: 0x4201c76c, 980 ms
TimerStart: 0x4201c76c
TimerStop: 0x4201c76c
TimerStart2: 0x4201c76c, 980 ms
callout_reset: evq=0x42013250, ev=0x4201c76c
TimerSetValue: 0x4201c788, 1988 ms
TimerStart: 0x4201c788
TimerStop: 0x4201c788
TimerStart2: 0x4201c788, 1988 ms
callout_reset: evq=0x42013250, ev=0x4201c788
TODO: RtcGetCalendarTime
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
RadioOnDioIrq
RadioIrqProcess
callout_handler: unlock
callout_handler: evq=0x42013250, ev=0x4201c76c
callout_handler: lock
handle_event_queue: ev=0x4201c76c
TimerStop: 0x4201c76c
RadioStandby
RadioSetChannel: freq=923200000
RadioSetRxConfig
RadioStandby
RadioSetModem
RadioSetRxConfig done
RadioRx
TimerStop: 0x4201b7bc
TimerStart2: 0x4201b7bc, 3000 ms
callout_reset: evq=0x42013250, ev=0x4201b7bc
RadioOnDioIrq
RadioIrqProcess
DIO1 add event
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
IRQ_RX_TX_TIMEOUT
TimerStop: 0x4201b7bc
RadioOnDioIrq
RadioIrqProcess
RadioSleep
DIO1 add event
TimerStop: 0x4201c788
TimerStop: 0x4201c750
OnTxData
###### =========== MCPS-Confirm ============ ######
STATUS : OK
###### ===== UPLINK FRAME 2 ===== ######
CLASS : A
TX PORT : 1
TX DATA : UNCONFIRMED
48 69 20 4E 75 74 74 58 00
DATA RATE : DR_3
U/L FREQ : 923200000
TX POWER : 0
CHANNEL MASK: 0003
TODO: EepromMcuWriteBuffer
TODO: EepromMcuWriteBuffer
UplinkProcess
handle_event_queue: ev=0x4201b878
RadioOnDioIrq
RadioIrqProcess
RadioOnDioIrq
RadioIrqProcess
UplinkProcess
TODO: Voir Pinedio-Stack-selftest / Drivers / CST816S.C
TODO: Voir Pinedio-Stack-selftest / Pushbutton.c
TODO: Voir Pinedio-Stack-selftest / Acceleromment.c
TODO: Voir Pinedio-Stack-selftest / Battery.c
FAIRE
TODO: Nuttx a une application de démonstration GPS ...
applications / exemples / gps / gps_main.c
Et un analyseur GPS ...
applications / gpsutils