Leia o artigo ...
A pilha PinEnio BL604 é a mais nova placa de microcontrolador do Pine64, baseada no BL604 RISC-V + WIFI + Bluetooth do Bouffalo Lab .
(Disponível a qualquer dia agora!)
A pilha PinEnio está cheia de recursos de recursos ...
ST7789 Display LCD colorido
(240 x 240 pixels)
Painel de toque do CST816S
(Conectado no i2c)
Semtech SX1262 Lora Transceptor
(Trabalha com Lorawan)
Receptor de GPS / GNSS at6558
SGM40561 Unidade de gerenciamento de energia
Sensor de frequência cardíaca, acelerômetro, bússola, vibrador
SPI Flash, porta de depuração JTAG, botão
2,4 GHz wifi, Bluetooth LE
(Graças ao BL604)
O que o torna um gadget incrível para a educação da IoT !
O código -fonte do Apache Nuttx RTOs na pilha PinEmio está aqui ...
Lupyuen/Incubator-NUTTX (filial PinEmio)
Lupyuen/incubadora-Nuttx-Apps (filial PinEmio)
Nuttx Build Config para pilha PinEnio BL604 ...
Para baixar, configurar e construir Nuttx para pilha PinEnio 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(Veja o log de compilação)
Siga as atualizações no Twitter
Acordando ao esquema de pilha de Pinedo ...
PINEDIO PACKSATIC (2021-09-15)
Pinuntio Stack Baseboard Schematic (2021-09-27)
O ônibus SPI é compartilhado por ...
ST7789 Controlador de exibição
Semtech SX1262 Lora Transceptor
Flash spi
Aqui estão os números BL604 GPIO para o ônibus SPI compartilhado ...
| Função | Gpio |
|---|---|
| Spi mosi | 13 |
| Miso spi | 0 |
| Spi sck | 11 |
| SPI CS (não utilizado) | 8 |
(Fonte)
Para impedir a diafonia, selecionamos cada dispositivo SPI lançando seu pino de seleção de chip de alto a baixo ...
| Dispositivo SPI | ID do dispositivo | Troque missô/mosi | CHIP SELECT |
|---|---|---|---|
| ST7789 Display | 0x40000 | Não | 20 |
| Transceptor SX1262 | 1 | Sim | 15 |
| Flash spi | 2 | Sim | 14 |
| (Dispositivo padrão) | -1 | Sim | 8 (não utilizado) |
(Fonte)
Nuttx auto-atribui 0x40000 como o ID do dispositivo SPI para exibição ST7789. (Veja isso)
Atribuímos o outro dispositivo SPI Ids nós mesmos.
O ID do dispositivo -1 é uma queda para capturar todos os dispositivos SPI que não correspondem aos IDs do dispositivo. Isso também funciona para configurações simples de SPI, onde o ID do dispositivo não é necessário.
De acordo com o Manual de Referência BL602 (Tabela 3.1 "Descrição do Pino", página 26) ...
GPIO 13 é mosi
Gpio 0 é miso
Mas, devido a um BL602 SPI Quirk, precisamos trocar Miso e Mosi para obter esse comportamento. É por isso que a coluna "Swap miso / mosi" está marcada "sim" para transceptor SX1262 e flash spi.
ST7789 O controlador de exibição está conectado de maneira diferente ...
ST7789 recebe dados SPI no GPIO 0
ST7789 Pino de dados / comando está conectado no GPIO 13
(Alta para dados ST7789, comandos baixos para ST7789)
A direção dos dados do SPI é invertida para ST7789. É por isso que a coluna "Swap miso / mosi" está marcada "não" para o ST7789 Display Controller.
Representamos a tabela de dispositivos SPI acima em Nuttx como uma matriz plana INT ...
| Dispositivo SPI | ID do dispositivo | Troque missô/mosi | CHIP SELECT |
|---|---|---|---|
| ST7789 Display | 0x40000 | 0 | 20 |
| Transceptor SX1262 | 1 | 1 | 15 |
| Flash spi | 2 | 1 | 14 |
| (Dispositivo padrão) | -1 | 1 | 8 |
(Fonte)
Aqui está o código -fonte ...
#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 */(Fonte)
As colunas da tabela de dispositivos 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 */(Fonte)
Aqui estão as funções para acessar a tabela de dispositivos SPI ...
bl602_spi_get_device: procure um dispositivo na tabela de dispositivos SPI
BL602_SPI_DESELECT_DEVICES: Desmarque todos os dispositivos na tabela de dispositivos SPI
BL602_SPI_VALIDA_DEVICES: Validar os dispositivos na tabela de dispositivos SPI
A tabela de dispositivos SPI acima refere -se às seguintes definições de pinos ...
/* 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)(Fonte)
O driver BL602 Nuttx SPI procura a tabela de dispositivos SPI para 1ind, trocar o miso e os pinos Mosi 2️⃣ Vire os pinos de seleção do chip. É assim que selecionamos e desmaremos cada dispositivo 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
}(Fonte)
bl602_spi_select é chamado após travar o barramento SPI.
O Nuttx RTOS usa o miso como o pino de dados / comando st7789 ... mas o ST7789 está conectado "para trás" na pilha de pininhas BL604! Usamos o MOSI como o pino de dados / comando ST7789.
Veja como virar o pino de dados / comando st7789, dependendo da troca de 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(Fonte)
Na Startup Nuttx, desmarcamos todos os dispositivos SPI ... lançando seus pinos selecionados de chips altos ...
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 ();
}(Fonte)
O ST7789 exibirá o bom com o LORA SX1262 na pilha PinINETIO BL604? Sim SX1262 funciona bem no ônibus SPI compartilhado!
Botas de pilha de Piningio e renderiza uma tela rosa ...
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
Executamos o aplicativo spi_test2 para testar 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 Retorna o valor do registro 0x80, o que está correto!
Então executamos o aplicativo de demonstração 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
O que renderiza a tela de demonstração LVGL no ST7789 corretamente!
Existe uma condição de corrida em potencial se usarmos o driver SX1262 simultaneamente com o driver ST7789 ...
Durante a transmissão do LORA, o driver SX1262 chama ioctl() para flip sx1262 chip selecionar para baixo
(Veja isso)
O driver SX1262 chama o driver de teste SPI /dev/spitest0 , que bloqueia ( SPI_LOCK ) e seleciona ( SPI_SELECT ) o barramento SPI (com ID do dispositivo SPI 0)
(Veja isso)
Observe que as chamadas para ioctl() e SPI_LOCK / SPI_SELECT não são atômicas
Se o driver ST7789 estiver ativo entre as chamadas para ioctl() e SPI_LOCK / SPI_SELECT , o chip SX1262 SELECT e o chip ST7789 Select serão invertidos para baixo
Isso pode transmitir lixo para SX1262
Para resolver esse problema, registraremos um novo driver de teste SPI /dev/spitest1 com ID do dispositivo SPI 1.
O driver Lora acessará /dev/spitest1 , que SPI_LOCK e SPI_SELECT o barramento SPI (com ID do dispositivo SPI 1).
Como o ID do dispositivo SPI é 1, SPI_SELECT girará o chip SX1262 Selecionar para baixo.
BL602 / BL604 fala com ST7789 Exibir no modo SPI 1 ou 3 ... depende se miso / mosi são trocados
#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 */(Fonte)
ST7789 Exibir o OK na Frequência SPI 4 MHz. Talvez possamos subir mais?
CONFIG_LCD_ST7789_FREQUENCY=4000000
(Fonte)
O aplicativo de teste LVGL está aqui ...
Para executar o aplicativo, insira isso no shell do Nuttx ...
lvgltestAqui está o código que renderiza a tela ...
// 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
}(Fonte)
Para renderizar nosso próprio texto e gráficos, edite este arquivo de origem e altere o código acima ...
apps/examples/lvgltest/lvgltest.c
Para executar o aplicativo, insira isso no shell do Nuttx ...
lvgldemo Para alterar a mensagem no aplicativo de demonstração lvgl, editar 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 Para testar o Lora no PinEmio Stack, edite sx1262_test_main.c em ...
apps/examples/sx1262_test/sx1262_test_main.c
E atualize os parâmetros da Lora ...
Lorawan funciona bem no ônibus SPI compartilhado Yay! A pilha PinEnio se conecta ao gateway de Lorawan (Chirpstack) e envia pacotes de dados.
(O sensor de temperatura interno no ADC também funciona bem)
Lembre -se de desativar todas as informações do registro de informações porque afeta os temporizadores de Lorawan.
Veja como definimos os parâmetros de Lorawan ...
"Dispositivo EUI, junte -se à Chave EUI e App"
"Frequência 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: consulte PinEnio-Stack-Selftest/Drivers/CST816s.c
TODO: consulte PinEnio-Stack-Selftest/PushButton.c
TODO: consulte PinEnio-Stack-Selftest/acelerômetro.c
TODO: consulte PinEmio-Stack-Selftest/Battery.c
PENDÊNCIA
TODO: Nuttx tem um aplicativo de demonstração GPS ...
APPS/EXEMPLOS/GPS/GPS_MAIN.C
E um analisador de GPS ...
APPS/GPSUTILS