I try to add focaltech touch driver to my board, the fts_ts_init() is worked, but the ->probe() not be called, I do not why. CONFIG_OF is opened.
Driver code:
static const struct i2c_device_id fts_ts_id[] = {
{FTS_DRIVER_NAME, 0},
{}
};
static const struct of_device_id fts_dt_match[] = {
{.compatible = "focaltech,fts", },
{}
};
MODULE_DEVICE_TABLE(of, fts_dt_match);
static struct i2c_driver fts_ts_driver = {
.probe = fts_ts_probe,
.remove = fts_ts_remove,
.driver = {
.name = FTS_DRIVER_NAME,
.owner = THIS_MODULE,
#if defined(CONFIG_PM) && FTS_PATCH_COMERR_PM
.pm = &fts_dev_pm_ops,
#endif
.of_match_table = of_match_ptr(fts_dt_match),
},
.id_table = fts_ts_id,
};
static int __init fts_ts_init(void)
{
int ret = 0;
FTS_FUNC_ENTER();
ret = i2c_add_driver(&fts_ts_driver);
printk("[FTS_TS] ret=%d\n", ret);
if (ret)
FTS_ERROR("Focaltech touch screen driver init failed!");
FTS_FUNC_EXIT();
return ret;
}
module_init(fts_ts_init);
Device Tree Source:
i2c4: i2c#0x10054000 {
compatible = "ingenic,x2000-i2c";
reg = <0x10054000 0x1000>;
interrupt-parent = <&core_intc>;
interrupts = <IRQ_I2C4>;
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
focaltech#38{
compatible = "focaltech,fts";
reg = <0x38>;
interrupt-parent = <&gpa>;
interrupts = <3 0x2>;
focaltech,reset-gpio = <&gpa 0 GPIO_ACTIVE_LOW >;
focaltech,irq-gpio = <&gpa 3 0x2 >;
focaltech,max-touch-number = <2>;
focaltech,display-coords = <0 0 800 480>;
status = "okay";
};
};
I try to write the node in /, and use a simple paltform drvier, of_match_table is the same, ->probe() is called.
Related
I´m trying to add OTA capability to this program from https://randomnerdtutorials.com/esp32-cam-video-streaming-web-server-camera-home-assistant/ using the code below (sorry for the huge code). The problem is when I add the line to enable OTA in the setup function, the ESP-CAM reboots after starting the stream in less than 10 seconds. Can you help me, please?
#include "esp_camera.h"
#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include "esp_timer.h"
#include "img_converters.h"
#include "Arduino.h"
#include "fb_gfx.h"
#include "soc/soc.h" // disable brownout problems
#include "soc/rtc_cntl_reg.h" // disable brownout problems
#include "esp_http_server.h"
// My WiFi credentials
#include <credentials.h>
const char* ssid = MY_SSID;
const char* password = MY_PASSWORD;
#define PART_BOUNDARY "123456789000000000000987654321"
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
httpd_handle_t camera_httpd = NULL;
httpd_handle_t stream_httpd = NULL;
static const char PROGMEM INDEX_HTML[] = R"rawliteral(
<html>
<head>
<title>ESP32-CAM Robot</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
img { width: auto ;
max-width: 100% ;
height: auto ;
}
</style>
</head>
<body>
<img src="" id="photo" >
<script>
document.getElementById("photo").src = window.location.href.slice(0, -1) + ":81/stream";
console.log(window.location.href.slice(0, -1) + ":81/stream")
</script>
</body>
</html>
)rawliteral";
void setup() {
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
Serial.begin(115200);
Serial.println("Booting");
Serial.setDebugOutput(false);
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
if(psramFound()){
config.frame_size = FRAMESIZE_VGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// Camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
// Wi-Fi connection
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Connection Failed! Rebooting...");
delay(5000);
ESP.restart();
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("Camera Stream Ready! Go to: http://");
Serial.println(WiFi.localIP());
// Start streaming web server
startCameraServer();
// Arduino OTA
ArduinoOTA.setHostname("CameraWideOTA");
ArduinoOTA
.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH)
type = "sketch";
else // U_SPIFFS
type = "filesystem";
// NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
Serial.println("Start updating " + type);
})
.onEnd([]() {
Serial.println("\nEnd");
})
.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
})
.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
}
void loop() {
ArduinoOTA.handle();
}
static esp_err_t index_handler(httpd_req_t *req){
Serial.println("***index_handler");
httpd_resp_set_type(req, "text/html");
return httpd_resp_send(req, (const char *)INDEX_HTML, strlen(INDEX_HTML));
}
static esp_err_t stream_handler(httpd_req_t *req){
Serial.println("***stream_handler");
camera_fb_t * fb = NULL;
esp_err_t res = ESP_OK;
size_t _jpg_buf_len = 0;
uint8_t * _jpg_buf = NULL;
char * part_buf[64];
res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
if(res != ESP_OK){
return res;
}
while(true){
ArduinoOTA.handle();
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
res = ESP_FAIL;
} else {
if(fb->width > 400){
if(fb->format != PIXFORMAT_JPEG){
bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
esp_camera_fb_return(fb);
fb = NULL;
if(!jpeg_converted){
Serial.println("JPEG compression failed");
res = ESP_FAIL;
}
} else {
_jpg_buf_len = fb->len;
_jpg_buf = fb->buf;
}
}
}
if(res == ESP_OK){
size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);
res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
}
if(res == ESP_OK){
res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
}
if(res == ESP_OK){
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
}
if(fb){
esp_camera_fb_return(fb);
fb = NULL;
_jpg_buf = NULL;
} else if(_jpg_buf){
free(_jpg_buf);
_jpg_buf = NULL;
}
if(res != ESP_OK){
break;
}
//Serial.printf("MJPG: %uB\n",(uint32_t)(_jpg_buf_len));
}
return res;
}
static esp_err_t cmd_handler(httpd_req_t *req){
Serial.println("***cmd_handler");
char* buf;
size_t buf_len;
char variable[32] = {0,};
buf_len = httpd_req_get_url_query_len(req) + 1;
if (buf_len > 1) {
buf = (char*)malloc(buf_len);
if(!buf){
httpd_resp_send_500(req);
return ESP_FAIL;
}
if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
if (httpd_query_key_value(buf, "go", variable, sizeof(variable)) == ESP_OK) {
} else {
free(buf);
httpd_resp_send_404(req);
return ESP_FAIL;
}
} else {
free(buf);
httpd_resp_send_404(req);
return ESP_FAIL;
}
free(buf);
} else {
httpd_resp_send_404(req);
return ESP_FAIL;
}
sensor_t * s = esp_camera_sensor_get();
int res = 0;
if(res){
return httpd_resp_send_500(req);
}
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
return httpd_resp_send(req, NULL, 0);
}
void startCameraServer(){
Serial.println("***startCameraServer");
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.server_port = 80;
httpd_uri_t index_uri = {
.uri = "/",
.method = HTTP_GET,
.handler = index_handler,
.user_ctx = NULL
};
httpd_uri_t cmd_uri = {
.uri = "/action",
.method = HTTP_GET,
.handler = cmd_handler,
.user_ctx = NULL
};
httpd_uri_t stream_uri = {
.uri = "/stream",
.method = HTTP_GET,
.handler = stream_handler,
.user_ctx = NULL
};
if (httpd_start(&camera_httpd, &config) == ESP_OK) {
httpd_register_uri_handler(camera_httpd, &index_uri);
httpd_register_uri_handler(camera_httpd, &cmd_uri);
}
config.server_port += 1;
config.ctrl_port += 1;
if (httpd_start(&stream_httpd, &config) == ESP_OK) {
httpd_register_uri_handler(stream_httpd, &stream_uri);
}
}
The backtrace, as romkey sugested is:
Backtrace: 0x4008e32c:0x3ffb1e50 0x4008e5a5:0x3ffb1e70 0x40153ab7:0x3ffb1e90 0x40153afe:0x3ffb1eb0 0x401531d7:0x3ffb1ed0 0x4015350e:0x3ffb1ef0 0x40153275:0x3ffb1f10 0x400d2e39:0x3ffb1f30 0x400d4059:0x3ffb1f70 0x400d13be:0x3ffb1f90 0x400d55f9:0x3ffb1fb0 0x40090236:0x3ffb1fd0
The results presented by the ESP Exception Decoder tool is:
Decoding stack results
0x4008e32c: invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 156
0x4008e5a5: abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 171
0x40153ab7: __cxxabiv1::__terminate(void (*)()) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc line 47
0x40153afe: std::terminate() at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc line 57
0x401531d7: __cxxabiv1::__cxa_throw(void*, std::type_info*, void (*)(void*)) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_throw.cc line 87
0x4015350e: operator new(unsigned int) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/new_op.cc line 54
0x40153275: operator new[](unsigned int) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/new_opv.cc line 32
0x400d2e39: WiFiUDP::parsePacket() at /home/meslin/.arduino15/packages/esp32/hardware/esp32/1.0.6/libraries/WiFi/src/WiFiUdp.cpp line 210
0x400d4059: ArduinoOTAClass::handle() at /home/meslin/.arduino15/packages/esp32/hardware/esp32/1.0.6/libraries/ArduinoOTA/src/ArduinoOTA.cpp line 379
0x400d13be: loop() at /home/meslin/Desktop/sketch_apr11a/sketch_apr11a.ino line 163
0x400d55f9: loopTask(void*) at /home/meslin/.arduino15/packages/esp32/hardware/esp32/1.0.6/cores/esp32/main.cpp line 23
0x40090236: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143
I am using the open62541 library [1.1.2-216-g50933d8].
Tell me how to add engineering units to my node?
Му Node create:
bool isOk = true;
UA_VariableAttributes valueAttr = UA_VariableAttributes_default;
UA_Variant_init(&valueAttr.value);
UA_Float valueVal = 0;
UA_Variant_setScalar(&valueAttr.value, &valueVal, &UA_TYPES[UA_TYPES_FLOAT]);
std::string description = "Value Params";
valueAttr.description = UA_LOCALIZEDTEXT(const_cast<char*>(lt), const_cast<char*>(description.c_str()));
valueAttr.displayName = UA_LOCALIZEDTEXT(const_cast<char*>(lt), const_cast<char*>("Value"));
if(UA_Server_addVariableNode(server, UA_NODEID_NULL,
getNodeId(),
UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
UA_QUALIFIEDNAME(nsIndexBrowser, const_cast<char*>("Value")),
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
valueAttr, nullptr, &value_) != UA_STATUSCODE_GOOD)
{
return isOk;
}
I tried to do this:
UA_EUInformation eu;
eu.namespaceUri = UA_STRING("somecompany.com");
eu.unitId = -1;
eu.displayName = UA_LOCALIZEDTEXT(const_cast<char*>(lt), const_cast<char*>(typeSigne_->getEUid().c_str()));
eu.description = UA_LOCALIZEDTEXT(const_cast<char*>(lt), const_cast<char*>(typeSigne_->getEUid().c_str()));
UA_StatusCode status = UA_Server_writeObjectProperty_scalar(server,
value_,
UA_QUALIFIEDNAME(nsIndexBrowser, "EngineeringUnits"),
&eu,
&UA_TYPES[UA_TYPES_EUINFORMATION]);
if(status != UA_STATUSCODE_GOOD)
{
return isOk;
}
But I got the error code UA_STATUSCODE_BADNOMATCH
I tried to do this:
UA_EUInformation eu;
eu.namespaceUri = UA_STRING("somecompany.com");
eu.unitId = -1;
eu.displayName = UA_LOCALIZEDTEXT(const_cast<char*>(lt), const_cast<char*>(typeSigne_->getEUid().c_str()));
eu.description = UA_LOCALIZEDTEXT(const_cast<char*>(lt), const_cast<char*>(typeSigne_->getEUid().c_str()));
UA_VariableAttributes enAttr = UA_VariableAttributes_default;
UA_VariableAttributes_init(&enAttr);
enAttr.dataType = UA_TYPES[UA_TYPES_EUINFORMATION].typeId;
enAttr.userWriteMask = UA_ACCESSLEVELMASK_READ;
UA_Variant_setScalarCopy(&enAttr.value, &eu, &UA_TYPES[UA_TYPES_EUINFORMATION]);
UA_StatusCode status = UA_Server_addVariableNode(server, UA_NODEID_NULL,
value_,
UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY),
UA_QUALIFIEDNAME(nsIndexBrowser, "EngineeringUnits"),
UA_NODEID_NUMERIC(0, UA_NS0ID_PROPERTYTYPE),
enAttr,
nullptr, &enUnitNodeUnits_);
if(status != UA_STATUSCODE_GOOD)
{
return isOk;
}
But I got the error code UA_STATUSCODE_BADTYPEMISMATCH
I also tried these examples https://groups.google.com/g/open62541/c/90dpSO2Wu7E/m/mNUknnRSCAAJ . They don't work.
And in general, I tried to add any properties to my object, but it didn't work out either (UA_STATUSCODE_BADTYPEMISMATCH).
I don't understand why I can't do it?
I am facing issue with calling to recvfrom function:
recvfrom(sock, dat, sizeof(dat), 0, (void *)&peername, &peernamelen);
Until this all functions are working.
Please let me know where I am making mistake. Should I use bind or not, or any mistake from this.
Output:
before sockname
after sockname
after sock
after setsockopt
after Bind
before recvfrom
My code:
struct sockaddr_can sockname = {
.can_family = AF_CAN,
.can_addr.j1939 = {
.addr = J1939_NO_ADDR,
.name = J1939_NO_NAME,
.pgn = J1939_NO_PGN,
},
}, peername = {
.can_family = AF_CAN,
.can_addr.j1939 = {
.addr = J1939_NO_ADDR,
.name = J1939_NO_NAME,
.pgn = J1939_NO_PGN,
},
};
uint8_t dat[128];
int valid_peername = 0;
unsigned int todo_send = 0;
int todo_recv = 0, todo_echo = 0, todo_prio = -1;
int todo_connect = 0, todo_names = 0, todo_wait = 0, todo_rebind = 0;
int todo_broadcast = 0, todo_promisc = 0;
int no_bind = 0,i;
printf("before sockname\n");
sockname.can_ifindex = if_nametoindex(CAN_SOCKET_NAME);
printf("after sockname\n");
sock = socket(PF_CAN, SOCK_DGRAM, CAN_J1939);
printf("after sock\n");
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &todo_broadcast, sizeof(todo_broadcast));
printf("after setsockopt\n");
ret = bind(sock, (void *)&sockname, sizeof(sockname));
if (ret < 0)
err(1, "bind()");
printf("after Bind\n");
while(1){
peernamelen = sizeof(peername);
printf("before recvfrom\n");
recvfrom(sock, dat, sizeof(dat), 0, (void *)&peername, &peernamelen);
printf("%02x %05x:", peername.can_addr.j1939.addr, peername.can_addr.j1939.pgn);
for (i = 0, j = 0; i < ret; ++i, j++) {
if (j == 8) {
printf("\n%05x ", i);
j = 0;
}
printf(" %02x", dat[i]);
}
printf("\n");
}
Please help me to solve this issue.
I have a custom board that is supposed to use a MIPI-DSI video signal from the allwinner R16, that is supposed to be received by the TI DLPC3433.
[R16] >>>>>>> MIPI-DSI >>>>>>>> [DLPC3433]
Here are the datasheets:
https://www.ti.com/lit/ds/symlink/dlpc3433.pdf?ts=1601313127857&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FDLPC3433
https://linux-sunxi.org/images/b/b3/R16_Datasheet_V1.4_%281%29.pdf
I want to properly configure the device tree. So far, I don't have a perfect indication that any video signal is being produced. What do I need to put in my device tree configuration to make it work? I am having trouble knowing exactly with documentation and examples. Where do I need to define the properties of the DLPC3433? And how would I define the properties for the DLPC3433?
Please see parts of the device tree below:
&i2c1 {
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins_a>;
clock-frequency = <100000>; /* i2c bus frequency 100 KHz */
status = "okay";
dsi_hdmi_bridge#4d {
compatible = "ite,it6263";
reg = <0x4d>;
reset-gpios = <&pio 4 9 GPIO_ACTIVE_LOW>; /* PE9 */
port {
it6263_in_dsi: endpoint {
clock-lanes = <4>;
data-lanes = <0 1 2 3>;
remote-endpoint = <&dsi_out_it6263>;
};
};
};
};
...
&tcon0 {
// compatible = "allwinner,sun8i-a33-tcon";
status = "okay";
};
&dsi {
// compatible = "allwinner,sun6i-a31-mipi-dsi";
status = "okay";
ports {
port#1 {
reg = <1>;
dsi_out_it6263: endpoint {
remote-endpoint = <&it6263_in_dsi>;
};
};
};
};
&dphy {
// compatible = "allwinner,sun6i-a31-mipi-dphy";
status = "okay";
};
And here is what that device tree includes from the sun8i-a33.dtsi
dsi: dsi#1ca0000 {
compatible = "allwinner,sun6i-a31-mipi-dsi";
reg = <0x01ca0000 0x1000>;
interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_MIPI_DSI>,
<&ccu CLK_DSI_SCLK>;
clock-names = "bus", "mod";
resets = <&ccu RST_BUS_MIPI_DSI>;
phys = <&dphy>;
phy-names = "dphy";
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
port#0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
dsi_in_tcon0: endpoint {
remote-endpoint = <&tcon0_out_dsi>;
};
};
};
};
dphy: d-phy#1ca1000 {
compatible = "allwinner,sun6i-a31-mipi-dphy";
reg = <0x01ca1000 0x1000>;
clocks = <&ccu CLK_BUS_MIPI_DSI>,
<&ccu CLK_DSI_DPHY>;
clock-names = "bus", "mod";
resets = <&ccu RST_BUS_MIPI_DSI>;
status = "disabled";
#phy-cells = <0>;
};
fe0: display-frontend#1e00000 {
compatible = "allwinner,sun8i-a33-display-frontend";
reg = <0x01e00000 0x20000>;
interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_DE_FE>, <&ccu CLK_DE_FE>,
<&ccu CLK_DRAM_DE_FE>;
clock-names = "ahb", "mod",
"ram";
resets = <&ccu RST_BUS_DE_FE>;
ports {
#address-cells = <1>;
#size-cells = <0>;
fe0_out: port#1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
fe0_out_be0: endpoint#0 {
reg = <0>;
remote-endpoint = <&be0_in_fe0>;
};
};
};
};
be0: display-backend#1e60000 {
compatible = "allwinner,sun8i-a33-display-backend";
reg = <0x01e60000 0x10000>, <0x01e80000 0x1000>;
reg-names = "be", "sat";
interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_DE_BE>, <&ccu CLK_DE_BE>,
<&ccu CLK_DRAM_DE_BE>, <&ccu CLK_BUS_SAT>;
clock-names = "ahb", "mod",
"ram", "sat";
resets = <&ccu RST_BUS_DE_BE>, <&ccu RST_BUS_SAT>;
reset-names = "be", "sat";
assigned-clocks = <&ccu CLK_DE_BE>;
assigned-clock-rates = <300000000>;
ports {
#address-cells = <1>;
#size-cells = <0>;
be0_in: port#0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
be0_in_fe0: endpoint#0 {
reg = <0>;
remote-endpoint = <&fe0_out_be0>;
};
};
be0_out: port#1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
be0_out_drc0: endpoint#0 {
reg = <0>;
remote-endpoint = <&drc0_in_be0>;
};
};
};
};
How do I send the messages through LoRaWAN?
static void PrepareTxFrame( uint8_t port )
{
switch( port ) {
case 10: {
int pos = 0;
pc.printf("Prepare message\n");
#if 0
uint32_t tempValue = ( uint32_t )( LightValue * 1000000.0 );
AppData[0] = LightMode;
AppData[1] = ( ( tempValue & 0xFF000000 ) >> 24 ) & 0xFF;
AppData[2] = ( ( tempValue & 0x00FF0000 ) >> 16 ) & 0xFF;
AppData[3] = ( ( tempValue & 0x0000FF00 ) >> 8 ) & 0xFF;
AppData[4] = ( tempValue & 0x000000FF );
#else
AppData[pos] = count;
pc.printf("\n\r");
pc.printf("The value of the counter is : %d", count);
count++;
pc.printf("\n\r");
time_t seconds = time(NULL);
printf("The time is %s", ctime(&seconds));
AppData[++pos] = seconds;
pc.printf("%d \n %d", AppData[0], AppData[1]);
pc.printf("\n\r");
#endif
pc.printf("Message Ready\n");
}
break;
case 15: {
int pos = 0;
AppData[pos++] = AppLedStateOn;
#if 0
if( IsTxConfirmed == true )
{
AppData[pos++] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
AppData[pos++] = LoRaMacDownlinkStatus.DownlinkCounter;
AppData[pos++] = LoRaMacDownlinkStatus.Rssi >> 8;
AppData[pos++] = LoRaMacDownlinkStatus.Rssi;
AppData[pos++] = LoRaMacDownlinkStatus.Snr;
}
#endif
AppDataSize = pos;
}
break;
case 224:
if( ComplianceTest.LinkCheck == true ) {
ComplianceTest.LinkCheck = false;
AppDataSize = 3;
AppData[0] = 5;
AppData[1] = ComplianceTest.DemodMargin;
AppData[2] = ComplianceTest.NbGateways;
ComplianceTest.State = 1;
} else {
switch( ComplianceTest.State ) {
case 4:
ComplianceTest.State = 1;
break;
case 1:
AppDataSize = 2;
AppData[0] = ComplianceTest.DownLinkCounter >> 8;
AppData[1] = ComplianceTest.DownLinkCounter;
break;
}
}
break;
default:
break;
}
}
/*!
* \brief
*
* Prepares the pay-load of the frame
*
* \retval [0: frame could be send, 1: error]
*/
static bool SendFrame( void )
{
McpsReq_t mcpsReq;
LoRaMacTxInfo_t txInfo;
if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
{
// Send empty frame in order to flush MAC commands
mcpsReq.Type = MCPS_UNCONFIRMED;
mcpsReq.Req.Unconfirmed.fBuffer = NULL;
mcpsReq.Req.Unconfirmed.fBufferSize = 0;
mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
LoRaMacUplinkStatus.Acked = false;
LoRaMacUplinkStatus.Port = 0;
LoRaMacUplinkStatus.Buffer = NULL;
LoRaMacUplinkStatus.BufferSize = 0;
SerialDisplayUpdateFrameType( false );
} else {
LoRaMacUplinkStatus.Acked = false;
LoRaMacUplinkStatus.Port = AppPort;
LoRaMacUplinkStatus.Buffer = AppData;
LoRaMacUplinkStatus.BufferSize = AppDataSize;
SerialDisplayUpdateFrameType( IsTxConfirmed );
if( IsTxConfirmed == false ) {
mcpsReq.Type = MCPS_UNCONFIRMED;
mcpsReq.Req.Unconfirmed.fPort = AppPort;
mcpsReq.Req.Unconfirmed.fBuffer = AppData;
mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize;
mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
} else {
mcpsReq.Type = MCPS_CONFIRMED;
mcpsReq.Req.Confirmed.fPort = AppPort;
mcpsReq.Req.Confirmed.fBuffer = AppData;
mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
mcpsReq.Req.Confirmed.NbTrials = 8;
mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
}
}
if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK ) {
return false;
}
return true;
}
Will the counter data and the time be sent? Also is the data in AppData the ones to be transmitted? I want the count and the timestamp to be sent every time the LoRa device transmits.
The payload to send (AppData) is given to the LoRaMAC layer through the MCPS (MAC Common Part Sublayer) request, e.g. for an unconfirmed frame:
mcpsReq.Req.Unconfirmed.fBuffer = AppData;
So physically (i.e. by RF), AppData is sent but it's encrypted and encapsulated before.
PrepareFrame() function builds the frame to send according to the PHYPayload scheme (See the "MAC Message Formats" part in the LoRaWAN™ Specification 1.0.2 document), following these fields:
MHDR (1 byte) Mac header
DevAddr (4 bytes) Address of the end-device
FCtrl (1 byte) Frame control
FCnt (2 bytes) Frame counter
FOpts (0 - 15 bytes) Frame options
FPort (0 - 1 byte) Port field
FRMPayload (0 - N bytes) MAC Frame Payload Encryption, your AppData encrypted
MIC (4 bytes) Message Integrity Code
FRMPayload is encrypted according to FPort. The encryption algorithm is based on AES 128.
If FPort = [1..255], the AppSKey key will be used to encrypt your payload.
Else (FPort = 0), it's encrypted by using the NwkSKey key.
See the LoRaMacPayloadEncrypt() function for more details.
PHYPayload will be encapsulated by the Radio PHY Layer and sent through RF.