閱讀文章...
Pinedio Stack BL604是Pine64的最新微控制器板,該板基於Bouffalo Lab的BL604 RISC-V + WiFi +藍牙LE SOC。
(現在有一天可用!)
Pinedio堆棧充滿了塞滿的功能...
ST7789顏色LCD顯示
(240 x 240像素)
CST816S觸摸面板
(通過I2C連接)
Semtech SX1262 Lora收發器
(與Lorawan合作)
AT6558 GPS / GNSS接收器
SGM40561電源管理單元
心率傳感器,加速度計,指南針,振動器
SPI Flash,JTAG調試端口,按鈕
2.4 GHz WiFi,藍牙LE
(感謝BL604)
這使其成為物聯網教育的令人難以置信的小工具!
pinedio堆棧上Apache Nuttx RTOS的源代碼在這裡...
lupyuen/uncubator-nuttx(pinedio分支)
lupyuen/incubator-nuttx-apps(pinedio分支)
nuttx build for pinedio stack bl604 ...
要下載,為Pinedio stack BL604配置和構建NUTTX ...
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(請參閱構建日誌)
關注Twitter上的更新
符合Pinedio堆棧示意圖...
Pinedio堆棧示意圖(2021-09-15)
Pinedio Stack踢腳線示意圖(2021-09-27)
SPI巴士由...共享
ST7789顯示控制器
Semtech SX1262 Lora收發器
SPI閃光燈
這是共享SPI總線的BL604 GPIO編號...
| 功能 | GPIO |
|---|---|
| Spi Mosi | 13 |
| Spi Miso | 0 |
| SPI SCK | 11 |
| SPI CS (未使用) | 8 |
(來源)
為了防止串擾,我們通過將其芯片銷量從高到低...進行翻轉,從而選擇每個SPI設備。
| SPI設備 | 設備ID | 交換味o/mosi | 芯片選擇 |
|---|---|---|---|
| ST7789顯示 | 0x40000 | 不 | 20 |
| SX1262收發器 | 1 | 是的 | 15 |
| SPI閃光燈 | 2 | 是的 | 14 |
| (默認設備) | -1 | 是的 | 8 (未使用) |
(來源)
NutTX自動分配0x40000作為ST7789顯示屏的SPI設備ID。 (請參閱此)
我們自己分配了其他SPI設備ID。
設備ID -1是捕獲所有與設備ID不匹配的SPI設備的秋季。這也適用於不需要設備ID的簡單SPI設置。
根據BL602參考手冊(表3.1“ PIN描述”,第26頁)...
GPIO 13是Mosi
GPIO 0是味o
但是由於BL602 SPI Quirk,我們需要交換MISO和MOSI以獲得這種行為。這就是為什麼SX1262收發器和SPI Flash標記“交換味o / mosi”列的原因。
ST7789顯示控制器的連接不同...
ST7789在GPIO 0接收SPI數據0
ST7789數據 /命令引腳連接在GPIO 13上
(用於ST7789數據的高度,ST7789命令低)
SPI數據的方向用於ST7789。這就是為什麼ST7789顯示器控制器標記“交換味o / mosi”列的原因。
我們表示NutTX中的上述SPI設備表作為平坦的int陣列...
| SPI設備 | 設備ID | 交換味o/mosi | 芯片選擇 |
|---|---|---|---|
| ST7789顯示 | 0x40000 | 0 | 20 |
| SX1262收發器 | 1 | 1 | 15 |
| SPI閃光燈 | 2 | 1 | 14 |
| (默認設備) | -1 | 1 | 8 |
(來源)
這是源代碼...
#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 */(來源)
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 */(來源)
這是訪問SPI設備表的功能...
bl602_spi_get_device:在SPI設備表中查找設備
BL602_SPI_DESELECT_DEVICES:取消選擇SPI設備表中的所有設備
bl602_spi_validate_devices:驗證SPI設備表中的設備
上面的SPI設備表是指以下引腳定義...
/* 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)(來源)
BL602 NUTTX SPI驅動程序將SPI設備桌抬高到1️⃣交換味o和Mosi Pins2️⃣翻轉芯片選擇銷。這就是我們選擇和取消選擇每個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
}(來源)
鎖定SPI總線後,將調用bl602_spi_select 。
NutTX RTO使用MISO作為ST7789數據 /命令引腳...但是ST7789在Pinedio stack BL604上接線“向後”!我們將MOSI改為使用ST7789數據 /命令引腳。
這是我們根據MISO / MOSI交換來翻轉ST7789數據 /命令別針的方式...
#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(來源)
在Nuttx啟動時,我們取消了所有SPI設備的選擇...通過翻轉其芯片精選的銷釘高...
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 ();
}(來源)
ST7789顯示屏會在Pinedio stack BL604上與Lora SX1262一起玩嗎? YEP SX1262在共享SPI巴士上運行正常!
Pinedio堆棧靴子和粉紅色的屏幕...
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
我們運行spi_test2應用程序來測試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返回寄存器值0x80,這是正確的!
然後我們運行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
它正確地在ST7789上呈現LVGL演示屏幕!
如果我們與ST7789驅動程序同時使用SX1262驅動程序,則可能會有潛在的比賽條件...
在Lora傳輸期間,SX1262驅動程序調用ioctl() flip SX1262芯片選擇為低
(請參閱此)
sx1262驅動程序調用SPI測試驅動程序/dev/spitest0 ,鎖定( SPI_LOCK )並選擇( SPI_SELECT )SPI BUS(帶SPI設備ID 0)
(請參閱此)
請注意,呼叫ioctl()和SPI_LOCK / SPI_SELECT不是原子
如果ST7789驅動程序在對ioctl()和SPI_LOCK / SPI_SELECT調用之間處於活動狀態,則SX1262芯片選擇和ST7789芯片選擇將被翻轉為低
這可能會將垃圾傳輸到SX1262
為了解決此問題,我們將使用SPI設備ID 1註冊新的SPI測試驅動程序/dev/spitest1 。
然後,Lora驅動程序將訪問/dev/spitest1 ,它將SPI_LOCK和SPI_SELECT SPI BUS(帶有SPI設備ID 1)。
由於SPI設備ID為1,因此SPI_SELECT將將SX1262芯片選擇為低。
BL602 / BL604在SPI模式1或3上與ST7789顯示...取決於MISO / MOSI是否交換
#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 */(來源)
ST7789顯示器在SPI頻率4 MHz時運行正常。也許我們可以走得更高?
CONFIG_LCD_ST7789_FREQUENCY=4000000
(來源)
LVGL測試應用在這裡...
要運行該應用程序,請在Nuttx shell ...
lvgltest這是呈現屏幕的代碼...
// 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
}(來源)
要渲染我們自己的文本和圖形,請編輯此源文件並更改上面的代碼...
apps/examples/lvgltest/lvgltest.c
要運行該應用程序,請在Nuttx shell ...
lvgldemo要更改LVGL演示應用中的消息,請編輯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要在pinedio堆棧上測試lora,請編輯sx1262_test_main.c at ...
apps/examples/sx1262_test/sx1262_test_main.c
並更新Lora參數...
Lorawan可以在共享的SPI巴士上工作! Pinedio堆棧連接到Lorawan Gateway(Chirpstack)並發送數據包。
(ADC上的內部溫度傳感器也可以正常運行)
請記住,禁用所有信息記錄,因為它會影響洛萬計時器。
這是我們設置Lorawan參數的方式...
“設備EUI,加入EUI和應用程序密鑰”
“ 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:請參閱pinedio-stack-selftest/drivers/cst816s.c
TODO:請參閱pinedio-stack-selftest/pushbutton.c
TODO:請參閱pinedio-stack-selftest/ACCELEREMETER.C
TODO:請參閱pinedio-stack-selftest/電池
托多
TODO:NUTTX有一個GPS演示應用...
應用程序/示例/gps/gps_main.c
和GPS解析器...
應用/gpsutils