* Initial release for SX1302 CoreCell Reference Design.
This commit is contained in:
Michael Coracin 2019-07-12 15:40:13 +02:00
commit 4c61c5d48e
79 changed files with 30157 additions and 0 deletions

View file

@ -0,0 +1,930 @@
[
{
"id": "bf64d63f.630868",
"type": "tab",
"label": "SX1302 register C header",
"disabled": false,
"info": ""
},
{
"id": "d60daf5.ed6835",
"type": "file in",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/common.json",
"format": "utf8",
"chunk": false,
"sendError": true,
"x": 390,
"y": 160,
"wires": [
[
"ab571926.a8a0a8"
]
]
},
{
"id": "ab571926.a8a0a8",
"type": "json",
"z": "bf64d63f.630868",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 660,
"y": 160,
"wires": [
[
"2efaa7ec.1e3158"
]
]
},
{
"id": "3e749686.017e32",
"type": "inject",
"z": "bf64d63f.630868",
"name": "common",
"topic": "common",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 110,
"y": 160,
"wires": [
[
"d60daf5.ed6835"
]
]
},
{
"id": "a8c02e96.c069",
"type": "inject",
"z": "bf64d63f.630868",
"name": "Init",
"topic": "",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 100,
"y": 40,
"wires": [
[
"13cca583.8beb3a"
]
]
},
{
"id": "13cca583.8beb3a",
"type": "function",
"z": "bf64d63f.630868",
"name": "Init global variables",
"func": "var reg_c = 'const struct lgw_reg_s loregs[LGW_TOTALREGS+1] = {' + '\\n';\n\nvar reg_desc;\nreg_desc = '\\n/* -------------------------------------------------------------------------- */\\n';\nreg_desc += '/* --- REGISTER DESCRIPTIONS ------------------------------------------------\\n';\n\nflow.set('tx_top_macro', '');\nflow.set('reg_h', '');\nflow.set('reg_c', reg_c);\nflow.set('reg_desc', reg_desc);\nflow.set('reg_count', 0);\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 290,
"y": 40,
"wires": [
[
"d040198e.3a7208"
]
]
},
{
"id": "d040198e.3a7208",
"type": "debug",
"z": "bf64d63f.630868",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 500,
"y": 40,
"wires": []
},
{
"id": "12128a9a.ea5e35",
"type": "file in",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/agc_mcu.json",
"format": "utf8",
"chunk": false,
"sendError": true,
"x": 390,
"y": 220,
"wires": [
[
"d6c34db.5471fb"
]
]
},
{
"id": "d6c34db.5471fb",
"type": "json",
"z": "bf64d63f.630868",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 660,
"y": 220,
"wires": [
[
"2efaa7ec.1e3158"
]
]
},
{
"id": "c7ba4afe.f6229",
"type": "inject",
"z": "bf64d63f.630868",
"name": "agc_mcu",
"topic": "agc_mcu",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 110,
"y": 220,
"wires": [
[
"12128a9a.ea5e35"
]
]
},
{
"id": "917cf46c.ceaa48",
"type": "inject",
"z": "bf64d63f.630868",
"name": "Create files",
"topic": "",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 110,
"y": 940,
"wires": [
[
"67447ab8.c38edc"
]
]
},
{
"id": "67447ab8.c38edc",
"type": "function",
"z": "bf64d63f.630868",
"name": "Write header file",
"func": "var reg_count = flow.get('reg_count') || 0;\n\nvar reg_h = flow.get('reg_h') || '';\nreg_h += '\\n#define LGW_TOTALREGS ' + reg_count + '\\n';\n\nvar reg_c = flow.get('reg_c') || '';\nreg_c += ' {0,0,0,0,0,0,0,0}\\n'\nreg_c += '};';\n\nvar reg_desc = flow.get('reg_desc') || '';\nreg_desc += \"\\n*/\";\n\nvar tx_top_macro = flow.get('tx_top_macro') || '';\n\n// write all to file\nvar file = reg_h + '\\n' + tx_top_macro + '\\n' + reg_c + '\\n' + reg_desc;\nmsg.payload = file;\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 290,
"y": 940,
"wires": [
[
"b1b0d974.6ae61"
]
]
},
{
"id": "b1b0d974.6ae61",
"type": "file",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/sx1302_reg.h",
"appendNewline": true,
"createDir": false,
"overwriteFile": "true",
"x": 620,
"y": 940,
"wires": []
},
{
"id": "aae4ac70.472438",
"type": "debug",
"z": "bf64d63f.630868",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 1160,
"y": 280,
"wires": []
},
{
"id": "1450f6f8.1be259",
"type": "file in",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/rif_top_mux.json",
"format": "utf8",
"chunk": false,
"sendError": true,
"x": 420,
"y": 100,
"wires": [
[
"5c712585.37aeec"
]
]
},
{
"id": "5c712585.37aeec",
"type": "json",
"z": "bf64d63f.630868",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 700,
"y": 100,
"wires": [
[
"8bbc1d63.391468"
]
]
},
{
"id": "a48ebe9c.34b028",
"type": "inject",
"z": "bf64d63f.630868",
"name": "rif_top_mux",
"topic": "",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 120,
"y": 100,
"wires": [
[
"1450f6f8.1be259"
]
]
},
{
"id": "8bbc1d63.391468",
"type": "function",
"z": "bf64d63f.630868",
"name": "JSON Parse Base Addresses",
"func": "var reg_h = flow.get('reg_h') || '';\n\nvar prefix = 'SX1302_REG_';\nvar postfix = '_BASE_ADDR';\nvar line = '';\n\nfor(var item in msg.payload.map)\n{\n var base_addr = msg.payload.map[item].addr;\n line += '#define ' + prefix + item.toUpperCase() + postfix + ' 0x' + base_addr.toString(16) + '\\n'\n}\n//console.log(line);\n\nreg_h += line + '\\n';\n\nflow.set('reg_h', reg_h);\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 920,
"y": 100,
"wires": [
[
"9494d0f2.75b628"
]
]
},
{
"id": "9494d0f2.75b628",
"type": "debug",
"z": "bf64d63f.630868",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 1160,
"y": 100,
"wires": []
},
{
"id": "2d9b9bf2.6b3bb4",
"type": "file in",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/clk_ctrl.json",
"format": "utf8",
"chunk": false,
"sendError": true,
"x": 380,
"y": 280,
"wires": [
[
"7efa17e6.f8b68"
]
]
},
{
"id": "7efa17e6.f8b68",
"type": "json",
"z": "bf64d63f.630868",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 660,
"y": 280,
"wires": [
[
"2efaa7ec.1e3158"
]
]
},
{
"id": "5883ebc9.2fede4",
"type": "inject",
"z": "bf64d63f.630868",
"name": "clk_ctrl",
"topic": "clk_ctrl",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 100,
"y": 280,
"wires": [
[
"2d9b9bf2.6b3bb4"
]
]
},
{
"id": "54a46dd.945aa14",
"type": "file in",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/tx_top.json",
"format": "utf8",
"chunk": false,
"sendError": true,
"x": 380,
"y": 340,
"wires": [
[
"5ae327f2.618788"
]
]
},
{
"id": "5ae327f2.618788",
"type": "json",
"z": "bf64d63f.630868",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 660,
"y": 340,
"wires": [
[
"2efaa7ec.1e3158"
]
]
},
{
"id": "ca4d9728.057d68",
"type": "inject",
"z": "bf64d63f.630868",
"name": "tx_top_a",
"topic": "tx_top_a",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 110,
"y": 340,
"wires": [
[
"54a46dd.945aa14"
]
]
},
{
"id": "50b73755.13ee",
"type": "file in",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/tx_top.json",
"format": "utf8",
"chunk": false,
"sendError": true,
"x": 380,
"y": 400,
"wires": [
[
"ce78d3ce.e6bf18"
]
]
},
{
"id": "ce78d3ce.e6bf18",
"type": "json",
"z": "bf64d63f.630868",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 660,
"y": 400,
"wires": [
[
"2efaa7ec.1e3158"
]
]
},
{
"id": "4791c4e5.60b12c",
"type": "inject",
"z": "bf64d63f.630868",
"name": "tx_top_b",
"topic": "tx_top_b",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 110,
"y": 400,
"wires": [
[
"50b73755.13ee"
]
]
},
{
"id": "2efaa7ec.1e3158",
"type": "function",
"z": "bf64d63f.630868",
"name": "JSON to C header",
"func": "var reg_h = flow.get('reg_h') || '';\nvar reg_c = flow.get('reg_c') || '';\nvar reg_desc = flow.get('reg_desc') || '';\nvar reg_count = flow.get('reg_count') || 0;\nvar tx_top_macro = flow.get('tx_top_macro') || '';\n\nvar rif = msg.topic;\nvar prefix = 'SX1302_REG_';\nvar base_addr = prefix + rif.toUpperCase() + '_BASE_ADDR';\n\n// register definition\nvar page = '';\nvar addr = '';\nvar offs = '';\nvar sign = '';\nvar leng = '';\nvar rdon = '';\nvar dflt = '';\nvar chck = '';\nvar reg_comment = '';\nvar desc = '';\nvar flags;\n\nfor(var register in msg.payload)\n{\n //console.log(register);\n for(var field in msg.payload[register].fields)\n {\n //console.log(' ' + field);\n page = '0';\n addr = base_addr + '+' + msg.payload[register].addr;\n offs = msg.payload[register].fields[field].pos;\n if(msg.payload[register].fields[field].hasOwnProperty('signed'))\n {\n console.log(msg.payload[register].fields[field].signed);\n if(msg.payload[register].fields[field].signed === true)\n {\n sign = '1';\n }\n else\n {\n sign = '0';\n }\n }\n else\n {\n sign = '0';\n }\n leng = msg.payload[register].fields[field].width;\n rdon = (msg.payload[register].fields[field].readonly === false) ? '0' : '1';\n dflt = msg.payload[register].fields[field].value;\n flags = msg.payload[register].fields[field].flags;\n desc = msg.payload[register].fields[field].desc;\n //desc = desc.replace(/(?:\\r\\n|\\r|\\n)/g, ' / ');\n if (flags.length > 0)\n {\n for (var i_flag of flags) {\n console.log(i_flag);\n }\n //if(['pulse','w0clr','w1clr','interrupt'].includes(flags))\n if (flags.includes('pulse') || flags.includes('w0clr') || flags.includes('w1clr') || flags.includes('interrupt'))\n {\n console.log('non-checkable register');\n check = 0;\n }\n else\n {\n check = 1;\n }\n }\n else\n {\n check = 1;\n }\n reg_comment = (rif + '_' + register + '_' + field).toUpperCase();\n\n reg_h += '#define ' + prefix + reg_comment + ' ' + reg_count + '\\n';\n reg_c += ' '; // indent\n reg_c += '{' + page + ',' + addr + ',' + offs + ',' + sign + ',' + leng + ',' + rdon + ',' + check + ',' + dflt + '}, // ' + reg_comment + '\\n';\n reg_desc += '\\n' + reg_comment + ':\\n' + desc + '\\n';\n \n if (msg.topic === 'tx_top_a')\n {\n tx_top_macro += '#define ' + prefix + 'TX_TOP' + '_' + register.toUpperCase() + '_' + field.toUpperCase() + '(rf_chain) ((rf_chain == 0) ? \\\\\\n ' + prefix + 'TX_TOP_A' + '_' + register.toUpperCase() + '_' + field.toUpperCase() + ' : \\\\\\n ' + prefix + 'TX_TOP_B' + '_' + register.toUpperCase() + '_' + field.toUpperCase() + ')\\n';\n }\n \n reg_count += 1;\n }\n}\n\n//console.log(reg_h);\n//console.log(reg_c);\n\nflow.set('reg_count', reg_count);\nflow.set('reg_h', reg_h);\nflow.set('reg_c', reg_c);\nflow.set('reg_desc', reg_desc);\nflow.set('tx_top_macro', tx_top_macro);\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 940,
"y": 280,
"wires": [
[
"aae4ac70.472438"
]
]
},
{
"id": "ab7535a2.47b2e8",
"type": "file in",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/gpio.json",
"format": "utf8",
"chunk": false,
"sendError": true,
"x": 370,
"y": 460,
"wires": [
[
"6017e95e.37841"
]
]
},
{
"id": "6017e95e.37841",
"type": "json",
"z": "bf64d63f.630868",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 660,
"y": 460,
"wires": [
[
"2efaa7ec.1e3158"
]
]
},
{
"id": "626f34eb.dac1f4",
"type": "inject",
"z": "bf64d63f.630868",
"name": "gpio",
"topic": "gpio",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 100,
"y": 460,
"wires": [
[
"ab7535a2.47b2e8"
]
]
},
{
"id": "f6871b6f.167d",
"type": "file in",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/timestamp.json",
"format": "utf8",
"chunk": false,
"sendError": true,
"x": 390,
"y": 520,
"wires": [
[
"d1c6c905.bbf6a"
]
]
},
{
"id": "d1c6c905.bbf6a",
"type": "json",
"z": "bf64d63f.630868",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 660,
"y": 520,
"wires": [
[
"2efaa7ec.1e3158"
]
]
},
{
"id": "128c968f.34cc09",
"type": "inject",
"z": "bf64d63f.630868",
"name": "timestamp",
"topic": "timestamp",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 110,
"y": 520,
"wires": [
[
"f6871b6f.167d"
]
]
},
{
"id": "38f6ab4d.eba4b4",
"type": "file in",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/rx_top.json",
"format": "utf8",
"chunk": false,
"sendError": true,
"x": 380,
"y": 580,
"wires": [
[
"f464e634.1500a8"
]
]
},
{
"id": "f464e634.1500a8",
"type": "json",
"z": "bf64d63f.630868",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 660,
"y": 580,
"wires": [
[
"2efaa7ec.1e3158"
]
]
},
{
"id": "4dd5087.c34c178",
"type": "inject",
"z": "bf64d63f.630868",
"name": "rx_top",
"topic": "rx_top",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 100,
"y": 580,
"wires": [
[
"38f6ab4d.eba4b4"
]
]
},
{
"id": "28e533a1.3ef5ac",
"type": "file in",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/arb_mcu.json",
"format": "utf8",
"chunk": false,
"sendError": true,
"x": 390,
"y": 640,
"wires": [
[
"3c2109da.3df84e"
]
]
},
{
"id": "3c2109da.3df84e",
"type": "json",
"z": "bf64d63f.630868",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 660,
"y": 640,
"wires": [
[
"2efaa7ec.1e3158"
]
]
},
{
"id": "c3a46357.bf67c",
"type": "inject",
"z": "bf64d63f.630868",
"name": "arb_mcu",
"topic": "arb_mcu",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 110,
"y": 640,
"wires": [
[
"28e533a1.3ef5ac"
]
]
},
{
"id": "b3ed4e4f.fbd358",
"type": "file in",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/radio_fe.json",
"format": "utf8",
"chunk": false,
"sendError": true,
"x": 390,
"y": 700,
"wires": [
[
"37f7e33f.14dc6c"
]
]
},
{
"id": "37f7e33f.14dc6c",
"type": "json",
"z": "bf64d63f.630868",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 660,
"y": 700,
"wires": [
[
"2efaa7ec.1e3158"
]
]
},
{
"id": "e9006ee1.8d154",
"type": "inject",
"z": "bf64d63f.630868",
"name": "radio_fe",
"topic": "radio_fe",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 110,
"y": 700,
"wires": [
[
"b3ed4e4f.fbd358"
]
]
},
{
"id": "7c16420a.7b8634",
"type": "file in",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/otp.json",
"format": "utf8",
"chunk": false,
"sendError": true,
"x": 360,
"y": 760,
"wires": [
[
"4e1e58e8.d72998"
]
]
},
{
"id": "4e1e58e8.d72998",
"type": "json",
"z": "bf64d63f.630868",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 650,
"y": 760,
"wires": [
[
"2efaa7ec.1e3158"
]
]
},
{
"id": "cdd63a9c.be8f4",
"type": "inject",
"z": "bf64d63f.630868",
"name": "otp",
"topic": "otp",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 100,
"y": 760,
"wires": [
[
"7c16420a.7b8634"
]
]
},
{
"id": "9ac5ddf6.e47048",
"type": "file in",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/rx_top_lora_service_fsk.json",
"format": "utf8",
"chunk": false,
"sendError": true,
"x": 500,
"y": 820,
"wires": [
[
"5a5536dc.db687"
]
]
},
{
"id": "5a5536dc.db687",
"type": "json",
"z": "bf64d63f.630868",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 800,
"y": 820,
"wires": [
[
"2efaa7ec.1e3158"
]
]
},
{
"id": "c5ffdcfa.19ea28",
"type": "inject",
"z": "bf64d63f.630868",
"name": "rx_top_lora_service_fsk",
"topic": "rx_top_lora_service_fsk",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 150,
"y": 820,
"wires": [
[
"9ac5ddf6.e47048"
]
]
},
{
"id": "b5897d4d.0628c",
"type": "file in",
"z": "bf64d63f.630868",
"name": "",
"filename": "/home/mcoracin/SHARE/sx1302_reg/capture_ram.json",
"format": "utf8",
"chunk": false,
"sendError": true,
"x": 410,
"y": 880,
"wires": [
[
"753bfa61.c8068c"
]
]
},
{
"id": "753bfa61.c8068c",
"type": "json",
"z": "bf64d63f.630868",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 680,
"y": 880,
"wires": [
[
"2efaa7ec.1e3158"
]
]
},
{
"id": "6ca97d0.d189b84",
"type": "inject",
"z": "bf64d63f.630868",
"name": "capture_ram",
"topic": "capture_ram",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 120,
"y": 880,
"wires": [
[
"b5897d4d.0628c"
]
]
},
{
"id": "56ed912a.91d118",
"type": "trigger",
"z": "bf64d63f.630868",
"op1": "1",
"op2": "0",
"op1type": "val",
"op2type": "val",
"duration": "250",
"extend": "false",
"units": "ms",
"reset": "",
"bytopic": "all",
"name": "",
"x": 1020,
"y": 500,
"wires": [
[]
]
}
]

View file

@ -0,0 +1,61 @@
### get external defined data
include ../../target.cfg
### constant symbols
ARCH ?=
CROSS_COMPILE ?=
CC := $(CROSS_COMPILE)gcc
AR := $(CROSS_COMPILE)ar
CFLAGS := -O2 -Wall -Wextra -std=c99 -I. -I../../libtools/inc
### linking options
LIBS := -ltinymt32
### general build targets
all: payload_crc payload_diff payload_gen
clean:
rm -f payload_crc payload_diff payload_gen
rm -f *.o
install:
ifneq ($(strip $(TARGET_IP)),)
ifneq ($(strip $(TARGET_DIR)),)
ifneq ($(strip $(TARGET_USR)),)
@echo "---- Copying payload tools files to $(TARGET_IP):$(TARGET_DIR)"
@ssh $(TARGET_USR)@$(TARGET_IP) "mkdir -p $(TARGET_DIR)"
@scp payload_crc $(TARGET_USR)@$(TARGET_IP):$(TARGET_DIR)
@scp payload_diff $(TARGET_USR)@$(TARGET_IP):$(TARGET_DIR)
@scp payload_gen $(TARGET_USR)@$(TARGET_IP):$(TARGET_DIR)
else
@echo "ERROR: TARGET_USR is not configured in target.cfg"
endif
else
@echo "ERROR: TARGET_DIR is not configured in target.cfg"
endif
else
@echo "ERROR: TARGET_IP is not configured in target.cfg"
endif
### rules
%.o : %.c
$(CC) -c $(CFLAGS) $< -o $@
### test programs
payload_crc: payload_crc.o
$(CC) $(CFLAGS) -o $@ $^
payload_diff: payload_diff.o
$(CC) $(CFLAGS) -o $@ $^
payload_gen: payload_gen.o
$(CC) $(CFLAGS) -L../../libtools -o $@ $^ $(LIBS)
### EOF

View file

@ -0,0 +1,110 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
/* -------------------------------------------------------------------------- */
/* --- SUBFUNCTIONS DECLARATION --------------------------------------------- */
static void usage(void);
uint16_t sx1302_lora_payload_crc(const uint8_t * data, uint8_t size);
void remove_spaces(char *str);
/* -------------------------------------------------------------------------- */
/* --- MAIN FUNCTION -------------------------------------------------------- */
int main(int argc, char ** argv)
{
int j;
uint8_t payload[255];
uint8_t payload_size;
uint16_t crc;
char hexstr[1024];
if (argc < 2) {
usage();
return -1;
}
/* Get payload hex string from command line */
memcpy(hexstr, argv[1], strlen(argv[1]));
hexstr[strlen(argv[1])] = '\0';
printf("Input hex string: %s\n", hexstr);
/* Remove spaces from the string if any */
remove_spaces(hexstr);
hexstr[strlen(hexstr)] = '\0';
printf("Removing spaces: %s\n", hexstr);
/* Convert hex string to byte array */
payload_size = strlen(hexstr) / 2;
for (j = 0; j < payload_size; j++) {
sscanf(hexstr + 2*j, "%02hhx", &payload[j]);
}
/* Compute CRC */
crc = sx1302_lora_payload_crc(payload, payload_size);
printf("Payload CRC_16: %04X\n", crc);
return 0;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void usage(void) {
printf("Missing payload hex string\n");
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void remove_spaces(char *str)
{
/* To keep track of non-space character count */
int count = 0;
/* Traverse the given string. If current character
is not space, then place it at index 'count++' */
for (int i = 0; str[i]; i++) {
if (str[i] != ' ') {
str[count++] = str[i]; /* here count is incremented */
}
}
str[count] = '\0';
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void lora_crc16(const char data, int *crc) {
int next = 0;
next = (((data>>0)&1) ^ ((*crc>>12)&1) ^ ((*crc>> 8)&1) ) ;
next += ((((data>>1)&1) ^ ((*crc>>13)&1) ^ ((*crc>> 9)&1) )<<1 ) ;
next += ((((data>>2)&1) ^ ((*crc>>14)&1) ^ ((*crc>>10)&1) )<<2 ) ;
next += ((((data>>3)&1) ^ ((*crc>>15)&1) ^ ((*crc>>11)&1) )<<3 ) ;
next += ((((data>>4)&1) ^ ((*crc>>12)&1) )<<4 ) ;
next += ((((data>>5)&1) ^ ((*crc>>13)&1) ^ ((*crc>>12)&1) ^ ((*crc>> 8)&1))<<5 ) ;
next += ((((data>>6)&1) ^ ((*crc>>14)&1) ^ ((*crc>>13)&1) ^ ((*crc>> 9)&1))<<6 ) ;
next += ((((data>>7)&1) ^ ((*crc>>15)&1) ^ ((*crc>>14)&1) ^ ((*crc>>10)&1))<<7 ) ;
next += ((((*crc>>0)&1) ^ ((*crc>>15)&1) ^ ((*crc>>11)&1) )<<8 ) ;
next += ((((*crc>>1)&1) ^ ((*crc>>12)&1) )<<9 ) ;
next += ((((*crc>>2)&1) ^ ((*crc>>13)&1) )<<10) ;
next += ((((*crc>>3)&1) ^ ((*crc>>14)&1) )<<11) ;
next += ((((*crc>>4)&1) ^ ((*crc>>15)&1) ^ ((*crc>>12)&1) ^ ((*crc>> 8)&1))<<12) ;
next += ((((*crc>>5)&1) ^ ((*crc>>13)&1) ^ ((*crc>> 9)&1) )<<13) ;
next += ((((*crc>>6)&1) ^ ((*crc>>14)&1) ^ ((*crc>>10)&1) )<<14) ;
next += ((((*crc>>7)&1) ^ ((*crc>>15)&1) ^ ((*crc>>11)&1) )<<15) ;
(*crc) = next;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
uint16_t sx1302_lora_payload_crc(const uint8_t * data, uint8_t size) {
int i;
int crc = 0;
for (i = 0; i < size; i++) {
lora_crc16(data[i], &crc);
}
//printf("CRC16: 0x%02X 0x%02X (%X)\n", (uint8_t)(crc >> 8), (uint8_t)crc, crc);
return (uint16_t)crc;
}

View file

@ -0,0 +1,116 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
/* -------------------------------------------------------------------------- */
/* --- MACROS --------------------------------------------------------------- */
#define TAKE_N_BITS_FROM(b, p, n) (((b) >> (p)) & ((1 << (n)) - 1))
/* -------------------------------------------------------------------------- */
/* --- SUBFUNCTIONS DECLARATION --------------------------------------------- */
static void usage(void);
void remove_spaces(char *str);
/* -------------------------------------------------------------------------- */
/* --- MAIN FUNCTION -------------------------------------------------------- */
int main(int argc, char ** argv)
{
int i, j;
uint8_t payload_a[255];
uint8_t payload_b[255];
uint8_t payload_diff[255];
uint8_t payload_size;
char hexstr[1024];
uint16_t nb_bits_diff = 0;
if (argc < 3) {
usage();
return -1;
}
if (strlen(argv[1]) != strlen(argv[2])) {
printf("ERROR: payloads A & B must have same size\n");
return -1;
}
/* Get payload A hex string from command line */
memcpy(hexstr, argv[1], strlen(argv[1]));
hexstr[strlen(argv[1])] = '\0';
printf("Input hex string: %s\n", hexstr);
/* Remove spaces from the string if any */
remove_spaces(hexstr);
hexstr[strlen(hexstr)] = '\0';
printf("Removing spaces: %s\n", hexstr);
/* Convert hex string to byte array */
payload_size = strlen(hexstr) / 2;
for (j = 0; j < payload_size; j++) {
sscanf(hexstr + 2*j, "%02hhx", &payload_a[j]);
}
/* Get payload B hex string from command line */
memcpy(hexstr, argv[2], strlen(argv[2]));
hexstr[strlen(argv[2])] = '\0';
printf("Input hex string: %s\n", hexstr);
/* Remove spaces from the string if any */
remove_spaces(hexstr);
hexstr[strlen(hexstr)] = '\0';
printf("Removing spaces: %s\n", hexstr);
/* Convert hex string to byte array */
for (j = 0; j < payload_size; j++) {
sscanf(hexstr + 2*j, "%02hhx", &payload_b[j]);
}
/* Count how many bits differs */
printf("Diff: ");
for (j = 0; j < payload_size; j++) {
payload_diff[j] = payload_a[j] ^ payload_b[j];
printf("%02X ", payload_diff[j]);
}
printf("\n");
for (j = 0; j < payload_size; j++) {
for (i = 7; i >= 0; i--) {
printf("%u", TAKE_N_BITS_FROM(payload_diff[j], i, 1));
if (TAKE_N_BITS_FROM(payload_diff[j], i, 1) == 1) {
nb_bits_diff += 1;
}
}
printf(" ");
}
printf("\n");
printf("%u bits flipped\n", nb_bits_diff);
return 0;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void usage(void) {
printf("Missing payload hex strings for a & b\n");
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void remove_spaces(char *str)
{
/* To keep track of non-space character count */
int count = 0;
/* Traverse the given string. If current character
is not space, then place it at index 'count++' */
for (int i = 0; str[i]; i++) {
if (str[i] != ' ') {
str[count++] = str[i]; /* here count is incremented */
}
}
str[count] = '\0';
}

View file

@ -0,0 +1,124 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "tinymt32.h"
/* -------------------------------------------------------------------------- */
/* --- SUBFUNCTIONS DECLARATION --------------------------------------------- */
static void usage(void);
void remove_spaces(char *str);
/* -------------------------------------------------------------------------- */
/* --- MAIN FUNCTION -------------------------------------------------------- */
int main(int argc, char ** argv)
{
int j;
uint8_t dev_id[4];
uint8_t payload[255];
uint8_t payload_size;
unsigned int packet_cnt;
tinymt32_t tinymt;
char hexstr[32];
if (argc < 4) {
usage();
return -1;
}
/* Get dev_id hex string from command line */
memcpy(hexstr, argv[1], strlen(argv[1]));
hexstr[strlen(argv[1])] = '\0';
/* Remove spaces from the string if any */
remove_spaces(hexstr);
hexstr[strlen(hexstr)] = '\0';
printf("Dev_id: %s\n", hexstr);
/* Convert hex string to byte array */
payload_size = strlen(hexstr) / 2;
for (j = 0; j < 4; j++) {
sscanf(hexstr + 2*j, "%02hhx", &dev_id[j]);
}
/* Get packet count from which generate the random payload */
packet_cnt = atoi(argv[2]);
/* Get packet payload size */
payload_size = (uint8_t)atoi(argv[3]);
/* Initialize the pseudo-random generator */
tinymt.mat1 = 0x8f7011ee;
tinymt.mat2 = 0xfc78ff1f;
tinymt.tmat = 0x3793fdff;
tinymt32_init(&tinymt, packet_cnt);
/* Construct packet */
payload[0] = dev_id[0];
payload[1] = dev_id[1];
payload[2] = dev_id[2];
payload[3] = dev_id[3];
payload[4] = (uint8_t)(packet_cnt >> 24);
payload[5] = (uint8_t)(packet_cnt >> 16);
payload[6] = (uint8_t)(packet_cnt >> 8);
payload[7] = (uint8_t)(packet_cnt >> 0);
for (j = 8; j < payload_size; j++) {
payload[j] = (uint8_t)tinymt32_generate_uint32(&tinymt);
}
for (j = 0; j < payload_size; j++) {
printf("%02X ", payload[j]);
}
printf("\n");
#if 0
for (packet_cnt = 0; packet_cnt < 10; packet_cnt++) {
tinymt32_init(&tinymt, (int)packet_cnt);
payload[0] = 0xCA;
payload[1] = 0xFE;
payload[2] = 0x12;
payload[3] = 0x34;
payload[4] = (uint8_t)(packet_cnt >> 24);
payload[5] = (uint8_t)(packet_cnt >> 16);
payload[6] = (uint8_t)(packet_cnt >> 8);
payload[7] = (uint8_t)(packet_cnt >> 0);
for (j = 8; j < 16; j++) {
payload[j] = (uint8_t)tinymt32_generate_uint32(&tinymt);
}
for (j = 0; j < 16; j++) {
printf("%02X ", payload[j]);
}
printf("\n");
}
#endif
return 0;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void usage(void) {
printf("Missing parameters: ./payload_gen dev_id pkt_cnt pkt_size\n");
printf(" dev_id: hex string for 4-bytes dev_id\n");
printf(" pkt_cnt: unsigned int used to initialize the pseudo-random generator\n");
printf(" pkt_size: paylaod size in bytes [0..255]\n");
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void remove_spaces(char *str)
{
/* To keep track of non-space character count */
int count = 0;
/* Traverse the given string. If current character
is not space, then place it at index 'count++' */
for (int i = 0; str[i]; i++) {
if (str[i] != ' ') {
str[count++] = str[i]; /* here count is incremented */
}
}
str[count] = '\0';
}

70
tools/reset_lgw.sh Executable file
View file

@ -0,0 +1,70 @@
#!/bin/sh
# This script is intended to be used on SX1302 CoreCell platform, it performs
# the following actions:
# - export/unpexort GPIO23 and GPIO18 used to reset the SX1302 chip and to enable the LDOs
#
# Usage examples:
# ./reset_lgw.sh stop
# ./reset_lgw.sh start
# GPIO mapping has to be adapted with HW
#
SX1302_RESET_PIN=23
SX1302_POWER_EN_PIN=18
WAIT_GPIO() {
sleep 0.1
}
init() {
# setup GPIOs
echo "$SX1302_RESET_PIN" > /sys/class/gpio/export; WAIT_GPIO
echo "$SX1302_POWER_EN_PIN" > /sys/class/gpio/export; WAIT_GPIO
# set GPIOs as output
echo "out" > /sys/class/gpio/gpio$SX1302_RESET_PIN/direction; WAIT_GPIO
echo "out" > /sys/class/gpio/gpio$SX1302_POWER_EN_PIN/direction; WAIT_GPIO
}
reset() {
echo "CoreCell reset through GPIO$SX1302_RESET_PIN..."
echo "CoreCell power enable through GPIO$SX1302_POWER_EN_PIN..."
# write output for SX1302 CoreCell power_enable and reset
echo "1" > /sys/class/gpio/gpio$SX1302_POWER_EN_PIN/value; WAIT_GPIO
echo "1" > /sys/class/gpio/gpio$SX1302_RESET_PIN/value; WAIT_GPIO
echo "0" > /sys/class/gpio/gpio$SX1302_RESET_PIN/value; WAIT_GPIO
}
term() {
# cleanup all GPIOs
if [ -d /sys/class/gpio/gpio$SX1302_RESET_PIN ]
then
echo "$SX1302_RESET_PIN" > /sys/class/gpio/unexport; WAIT_GPIO
fi
if [ -d /sys/class/gpio/gpio$SX1302_POWER_EN_PIN ]
then
echo "$SX1302_POWER_EN_PIN" > /sys/class/gpio/unexport; WAIT_GPIO
fi
}
case "$1" in
start)
term # just in case
init
reset
;;
stop)
reset
term
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
;;
esac
exit 0