diff --git a/.gitignore b/.gitignore index 975faad..e69de29 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +0,0 @@ -ngham_platform.c \ No newline at end of file diff --git a/README.md b/README.md index c87c8d3..0991484 100644 --- a/README.md +++ b/README.md @@ -23,26 +23,30 @@ Content: | File/folder | Description | |:----------- |:----------- | +| documentation/ | More documentation. | | fec-3.0.1/ | FEC library by Phil Karn for Reed Solomon. (http://www.ka9q.net/code/fec/) | -| other/ | More documentation. | +| platform/ | User provided - MUST BE CUSTOMIZED. | +| ccsds_scrambler.h | Pre-generated array from scrambling polynomial. | +| crc_ccitt.h | CRC-code used in NGHam. | | ngham.h | The main NGHam encoder/decoder functions. | | ngham_packets.h | Declarations of the TX/RX packet structs etc. | -| ngham_platform.h | User provided code - MUST BE CUSTOMIZED. | -| crc_ccitt.h | CRC-code used in NGHam. | -| ccsds_scrambler.h | Pre-generated array from scrambling polynomial. | +| ngham_paths.h | User provided - MUST BE CUSTOMIZED. | +| ngham_spp.h | Serial port protocol for communication with the host. | +| ngham_spp_test.py | Python code for NGHAM SPP communication. | + Not finished: | File/folder | Description | |:----------- |:----------- | | ngham_extensions.h | An extension of the payload field in the NGHam radio protocol (enabled by a flag in the NGHam header). | -| ngham_spp.h | Serial port protocol for communication with the host. | -Usage: +Usage (for NGHam RF protocol): 1. Provide your own sync word correlator and GMSK (de)modulator. 2. The demodulator should start outputting data only after sync word is detected. -3. ngham_platform.h/c must be customized for the platform you are using. +3. Build all files in the root except "ngham_spp.c". From the folder "fec-3.0.1", build "decode_rs_char.c", "encode_rs_char.c" and "init_rs_char.c". +3. "ngham_paths.h" and the code in "platform/" must be customized. ``` // Initialize Reed Solomon arrays - only do this once! diff --git a/documentation/illustrations/ngham_block_v3.png b/documentation/illustrations/ngham_block_v3.png new file mode 100644 index 0000000..c6a910d Binary files /dev/null and b/documentation/illustrations/ngham_block_v3.png differ diff --git a/documentation/illustrations/ngham_block_v3.vsd b/documentation/illustrations/ngham_block_v3.vsd new file mode 100644 index 0000000..fd69b8e Binary files /dev/null and b/documentation/illustrations/ngham_block_v3.vsd differ diff --git a/other/illustrations/ngham_flow.vsd b/documentation/illustrations/ngham_flow.vsd similarity index 100% rename from other/illustrations/ngham_flow.vsd rename to documentation/illustrations/ngham_flow.vsd diff --git a/documentation/illustrations/ngham_spp.png b/documentation/illustrations/ngham_spp.png new file mode 100644 index 0000000..298e23e Binary files /dev/null and b/documentation/illustrations/ngham_spp.png differ diff --git a/documentation/illustrations/ngham_spp.vsd b/documentation/illustrations/ngham_spp.vsd new file mode 100644 index 0000000..f90c50b Binary files /dev/null and b/documentation/illustrations/ngham_spp.vsd differ diff --git a/other/ngham_protocol_description_0.1.docx b/documentation/ngham_protocol_description.docx similarity index 69% rename from other/ngham_protocol_description_0.1.docx rename to documentation/ngham_protocol_description.docx index 1675951..bf6ffcc 100644 Binary files a/other/ngham_protocol_description_0.1.docx and b/documentation/ngham_protocol_description.docx differ diff --git a/documentation/ngham_protocol_description.pdf b/documentation/ngham_protocol_description.pdf new file mode 100644 index 0000000..6cfa9c3 Binary files /dev/null and b/documentation/ngham_protocol_description.pdf differ diff --git a/other/sketchbooks_(for_own_reference)/ngham_extension_preliminary.txt b/documentation/sketchbooks_(for_own_reference)/ngham_extension_preliminary.txt similarity index 67% rename from other/sketchbooks_(for_own_reference)/ngham_extension_preliminary.txt rename to documentation/sketchbooks_(for_own_reference)/ngham_extension_preliminary.txt index c42376b..7e70f06 100644 --- a/other/sketchbooks_(for_own_reference)/ngham_extension_preliminary.txt +++ b/documentation/sketchbooks_(for_own_reference)/ngham_extension_preliminary.txt @@ -4,29 +4,28 @@ Multple types of data can be fitted inside a NGHam packet, by starting with a ne Extension data types: 0x00 Binary data of unknown type -0x01 Address +0x01 Ham address - everything after an adress belongs to the transmitting station 0x02 Statistics 0x03 Statistics for timing reference 0x04 Position 0x05 Voice 0x06 JPEG image +0x07 Repeated ham adress (originates from another station) ** Address ** -Size is 6-17 B - eg. LA3JPA to broadcast will be 10 B, LA1K to broadcast is 8B, LA1K123Y to LA1K100Y is 17B - * 2-7B source: 4 bit LEN (1-8), 4 bit SSID, LEN x 6 bit (chars), fill to n*8 - LA3JPA-3 - * 1-7B destination: 4 bit LEN (0-8, 0=broadcast), 4 bit SSID, LEN x 6 bit (chars), fill to n*8 - LA3JPA-3 +Size is 6-17 B - eg. LA3JPA to broadcast will be 8B, LA1K to broadcast is 6B, LA1K123Y to LA1K100Y is 16B + * 2-7B mycall: 4 bit LEN (1-8), 4 bit SSID, LEN x 6 bit (chars), fill to n*8 - LA3JPA-3 * 1B sequence number - * 1B extended fields, packet type: + * 1B fields, packet type: + 1b destcall_en - if this is not a broadcast packet, insert destination callsign 1b hopping_field_en 1b timeslot_field_en 1b connected_field_en - * 1B hopping: 1b reserved, 1b add_path_trace, 1b fill_in_hop_finished, 1b fill_in_hop_left, 2b hops_finished, 2b hops_left - If path_trace_en is set, fill_in_hops_finished+hops_finished callsigns follow (maximum 4): - 2-7B: 4 bit LEN (1-8), 4 bit SSID, LEN x 6 bit (chars), fill to n*8 - LA3JPA-3 + * 1-7B destcall: 4 bit LEN (1-8), 4 bit SSID, LEN x 6 bit (chars), fill to n*8 - LA3JPA-3 + * 1B hopping: 2b reserved, 1b fill_in_hop_finished, 1b fill_in_hop_total, 2b hops_finished, 2b hops_total (not including fill-in) * 2B timeslot information * 1B connected mode information: 0=cts, 1=rts, 2=ack, 3=nack - ** Position ** If address is enabled, use broadcast. Address size will therefore be 11 B. Wait one full timeslot period to generate adress book, then picks random free timeslot @@ -47,3 +46,9 @@ Takes less than 140 ms to transmit at 4800 baud. Will fit in 60 B payload size w * Comment * Icon ( * 2B timeslot information: 12b first timeslot, 4 b timeslot modulo (transmits every 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024) ) + + +Repeated packet: +Address +Repeated address +Position \ No newline at end of file diff --git a/other/sketchbooks_(for_own_reference)/rs_pic32_performance_test.txt b/documentation/sketchbooks_(for_own_reference)/rs_pic32_performance_test.txt similarity index 100% rename from other/sketchbooks_(for_own_reference)/rs_pic32_performance_test.txt rename to documentation/sketchbooks_(for_own_reference)/rs_pic32_performance_test.txt diff --git a/other/sketchbooks_(for_own_reference)/size_tag/B04350711.pdf b/documentation/sketchbooks_(for_own_reference)/size_tag/B04350711.pdf similarity index 100% rename from other/sketchbooks_(for_own_reference)/size_tag/B04350711.pdf rename to documentation/sketchbooks_(for_own_reference)/size_tag/B04350711.pdf diff --git a/other/sketchbooks_(for_own_reference)/size_tag/EN-1091620.pdf b/documentation/sketchbooks_(for_own_reference)/size_tag/EN-1091620.pdf similarity index 100% rename from other/sketchbooks_(for_own_reference)/size_tag/EN-1091620.pdf rename to documentation/sketchbooks_(for_own_reference)/size_tag/EN-1091620.pdf diff --git a/other/sketchbooks_(for_own_reference)/size_tag/Lexicodes.pdf b/documentation/sketchbooks_(for_own_reference)/size_tag/Lexicodes.pdf similarity index 100% rename from other/sketchbooks_(for_own_reference)/size_tag/Lexicodes.pdf rename to documentation/sketchbooks_(for_own_reference)/size_tag/Lexicodes.pdf diff --git a/other/sketchbooks_(for_own_reference)/size_tag/Pseudo_Noise_Sequences.pdf b/documentation/sketchbooks_(for_own_reference)/size_tag/Pseudo_Noise_Sequences.pdf similarity index 100% rename from other/sketchbooks_(for_own_reference)/size_tag/Pseudo_Noise_Sequences.pdf rename to documentation/sketchbooks_(for_own_reference)/size_tag/Pseudo_Noise_Sequences.pdf diff --git a/other/sketchbooks_(for_own_reference)/size_tag/codes.txt b/documentation/sketchbooks_(for_own_reference)/size_tag/codes.txt similarity index 100% rename from other/sketchbooks_(for_own_reference)/size_tag/codes.txt rename to documentation/sketchbooks_(for_own_reference)/size_tag/codes.txt diff --git a/other/sketchbooks_(for_own_reference)/size_tag/ibmrd0401F.pdf b/documentation/sketchbooks_(for_own_reference)/size_tag/ibmrd0401F.pdf similarity index 100% rename from other/sketchbooks_(for_own_reference)/size_tag/ibmrd0401F.pdf rename to documentation/sketchbooks_(for_own_reference)/size_tag/ibmrd0401F.pdf diff --git a/other/sketchbooks_(for_own_reference)/size_tag/ijecev5n2_02.pdf b/documentation/sketchbooks_(for_own_reference)/size_tag/ijecev5n2_02.pdf similarity index 100% rename from other/sketchbooks_(for_own_reference)/size_tag/ijecev5n2_02.pdf rename to documentation/sketchbooks_(for_own_reference)/size_tag/ijecev5n2_02.pdf diff --git a/ngham.c b/ngham.c index 22c7eb9..58baf0f 100644 --- a/ngham.c +++ b/ngham.c @@ -5,14 +5,17 @@ #include "ngham.h" -#include "fec-3.0.1/char.h" // Reed Solomon code from Phil Karn -#include "fec-3.0.1/rs-common.h" +#include "fec-3.0.1/fec.h" // RS code from Phil Karn +#include "fec-3.0.1/char.h" // RS code specific to 8-bit symbol size +#include "fec-3.0.1/rs-common.h" // RS control block struct #include // For NULL etc. #include // For memcpy #include "ccsds_scrambler.h" // Pre-generated array from scrambling polynomial #include "ngham_packets.h" // Structs for TX and RX packets #include "crc_ccitt.h" -#include "ngham_platform.h" // CRC-code + +#include "ngham_paths.h" +#include PATH_NGHAM_PLATFORM // There are seven different sizes. // Each size has a correlation tag for size, a total size, a maximum payload size and a parity data size. @@ -141,7 +144,7 @@ void ngham_decode(uint8_t d){ static uint32_t size_tag; switch (decoder_state){ - + case NGH_STATE_SIZE_TAG: size_tag = 0; ngham_action_reception_started(); diff --git a/ngham_packets.c b/ngham_packets.c index 77dc70e..4dc1b87 100644 --- a/ngham_packets.c +++ b/ngham_packets.c @@ -12,4 +12,5 @@ void rx_pkt_init(rx_pkt_t *p){ void tx_pkt_init(tx_pkt_t *p){ p->pl_len = 0; p->ngham_flags = 0; + p->priority = PKT_PRIORITY_NORMAL; } diff --git a/ngham_packets.h b/ngham_packets.h index e7b2e05..ab819c6 100644 --- a/ngham_packets.h +++ b/ngham_packets.h @@ -27,23 +27,33 @@ // If the following flag is set in a packet, NGHam extensions are used and first byte is type #define NGHAM_FLAG_TYPE_EXTENSION 0x01 -typedef struct{ +#define SPP_PL_MAX 512 + +typedef struct __attribute__ ((packed)){ + uint32_t timestamp; // Time stamp of sync word detection uint16_t pl_len; - uint8_t pl[PKT_PL_SIZE]; - uint8_t ngham_flags; - uint8_t rssi; // In dBm + 200 uint8_t noise; // Same as above + uint8_t rssi; // In dBm + 200 uint8_t errors; // Recovered symbols - uint32_t timestamp; // Time stamp of sync word detection + uint8_t ngham_flags; + uint8_t pl[PKT_PL_SIZE]; }rx_pkt_t; -typedef struct{ +typedef struct __attribute__ ((packed)){ uint16_t pl_len; - uint8_t pl[PKT_PL_SIZE]; - uint8_t ngham_flags; uint8_t priority; + uint8_t ngham_flags; + uint8_t pl[PKT_PL_SIZE]; }tx_pkt_t; +// NGHam SPP header +typedef struct __attribute__ ((packed)){ + uint8_t start; + uint16_t crc; + uint8_t pl_type; + uint8_t pl_len; +}ngh_spphdr_t; + void rx_pkt_init(rx_pkt_t *p); void tx_pkt_init(tx_pkt_t *p); diff --git a/ngham_paths.h b/ngham_paths.h new file mode 100644 index 0000000..e9f4992 --- /dev/null +++ b/ngham_paths.h @@ -0,0 +1,7 @@ +// Path to main NGHAM platform specific code +#define PATH_NGHAM_PLATFORM "c:/lagring/prosjekter/owl_vhf/firmware/ngham_owl_platform.h" +// #define PATH_NGHAM_PLATFORM "platform/platform.h" + +// Path to NGHAM serial port protocol platform code +#define PATH_NGHAM_PLATFORM_SPP "c:/lagring/prosjekter/owl_vhf/firmware/ngham_owl_platform_spp.h" +// #define PATH_NGHAM_PLATFORM_SPP "platform/platform_spp.h" diff --git a/ngham_platform.h b/ngham_platform.h deleted file mode 100644 index e441c1f..0000000 --- a/ngham_platform.h +++ /dev/null @@ -1,55 +0,0 @@ -//**************************************************************// -// NGHam protocol - Jon Petter Skagmo, LA3JPA, 2014. // -// Licensed under LGPL. // -//**************************************************************// - -#include "ngham_packets.h" // Packet structs, NA-values etc. - -// Temporary buffer for the decoder, rx packet variable and state variable. -// Define in ngham_platform.c. The only reason these are here and -// not in ngham.c is because they might be defined elsewhere in your application -// and you want to reuse them. -// If this doesn't apply to you, copy this to ngham_platform.c with "extern" removed. -extern uint8_t rx_buf[]; // Should hold the largest packet - ie. 255 B -extern uint16_t rx_buf_len; -extern rx_pkt_t rx_pkt; -extern uint8_t decoder_state; - -// Data to be transmitted (to modulator). Priority can be ignored if NGHam is not used for timing purposes. -void ngham_action_send_data(uint8_t *d, uint16_t d_len, uint8_t priority); - -// Set packet size demodulator, if applicable, to make the demodulator stop outputting data when the packet is finished. -void ngham_action_set_packet_size(uint8_t size); - -// Should return RSSI in dBm + 200 -uint8_t ngham_action_get_rssi(void); - -// Should return noise floor in dBm + 200 -uint8_t ngham_action_get_noise_floor(void); - -// Will always be called after packet reception is finished - whether it was successful or not. -// This function should also handle reinitialization of your decoder/sync word detector. -// Typically start this with: -// switch (condition){ -// case PKT_CONDITION_OK: -// // Do something with data -// break; -// case PKT_CONDITION_FAIL: -// // Count as a fail -// break; -// case PKT_CONDITION_PREFAIL: -// // Count as error and prepare for new sync word immediately -// break; -// } -void ngham_action_handle_packet(uint8_t condition, rx_pkt_t* p); - -// Not required: Code to be executed when reception has just started. -// This could be handling the time stamp of the sync word or starting RSSI readout. -// Tthe time stamp itself should be recorded in an interrupt routine. -void ngham_action_reception_started(void); - -// Not required: If there is more to do a little after reception start, do it here. -// NGHAM_BYTES_TILL_ACTION_HALFWAY is number of payload bytes until ngham_action_reception_halfway is executed. -// Don't care about this if you don't use the mentioned function. -#define NGHAM_BYTES_TILL_ACTION_HALFWAY 10 -void ngham_action_reception_halfway(void); diff --git a/ngham_spp.c b/ngham_spp.c new file mode 100644 index 0000000..aaba9e2 --- /dev/null +++ b/ngham_spp.c @@ -0,0 +1,103 @@ +//**************************************************************// +// NGHam protocol - Jon Petter Skagmo, LA3JPA, 2014. // +// Licensed under LGPL. // +//**************************************************************// + +#include "ngham_packets.h" +#include "crc_ccitt.h" + +#include "ngham_paths.h" +#include PATH_NGHAM_PLATFORM_SPP + +#define SPP_START 0x24 // Packet start byte definition + +#define SPP_STATE_START 0x00 // States +#define SPP_STATE_HEADER 0x01 +#define SPP_STATE_PAYLOAD 0x02 + +#define SPP_TYPE_RF 0x00 // Packet types +#define SPP_TYPE_LOCAL 0x01 +#define SPP_TYPE_CMD 0x02 + +void ngham_pack_byte(port_ctx_t* ctx, uint8_t c){ + switch(ctx->state){ + case SPP_STATE_START: + if (c == SPP_START){ + ctx->state = SPP_STATE_HEADER; // Start found; go to next state + ctx->d_ip = 1; // Starts at next first as SPP_START is already received + } + break; + + case SPP_STATE_HEADER: + ((uint8_t*)&ctx->ngh_spp)[ctx->d_ip++] = c; // Fill header + if (ctx->d_ip >= sizeof(ngh_spphdr_t)){ + ctx->d_ip = 0; + ctx->state = SPP_STATE_PAYLOAD; + } + break; + + case SPP_STATE_PAYLOAD: + if (ctx->d_ip < PORT_BUF_SIZE) ctx->d[ctx->d_ip++] = c; // Fill ctx->d with payload + if (ctx->d_ip >= ctx->ngh_spp.pl_len){ + ctx->state = SPP_STATE_START; + + // Calc CRC of type, length and payload + int j; + uint16_t crc = 0xffff; + for (j=3; j<5; j++) crc = crc_ccitt_byte(((uint8_t*)&ctx->ngh_spp)[j], crc); + for (j=0; jd_ip; j++) crc = crc_ccitt_byte(ctx->d[j], crc); + crc ^= 0xffff; + if (crc == ctx->ngh_spp.crc){ + switch(ctx->ngh_spp.pl_type){ + case SPP_TYPE_RF: + { + // Data to be sent + tx_pkt_t p; + tx_pkt_init(&p); + p.ngham_flags = ctx->d[0]; // First byte in NGH SPP RF type is flags + p.pl_len = ctx->d_ip-1; + for (j=0; jd[j+1]; + PACKER_CALL(&p); + + // TODO: Generate response! + } + break; + case SPP_TYPE_CMD: + { + // Prepare command and response + ngh_spphdr_t hdr; + uint8_t r[sizeof(hdr)+SPP_PL_MAX]; + hdr.start = SPP_START; + hdr.pl_type = SPP_TYPE_CMD; + hdr.pl_len = 0; + cmd(ctx->d, ctx->ngh_spp.pl_len, &r[sizeof(hdr)], &hdr.pl_len); // Run command + for (j=3; j<5; j++) r[j] = ((uint8_t*)&hdr)[j]; // Copy length and type into header + hdr.crc = crc_ccitt(&r[3], hdr.pl_len+2); + for (j=0; j<3; j++) r[j] = ((uint8_t*)&hdr)[j]; // Copy CRC and stat into header + port_output(ctx, r, sizeof(hdr)+hdr.pl_len); // Send to port + } + break; + } + } + } + break; + } +} + +void ngham_unpack(rx_pkt_t* p){ + int j; + ngh_spphdr_t hdr; + hdr.start = SPP_START; + hdr.crc = 0xffff; + hdr.pl_type = SPP_TYPE_RF; + hdr.pl_len = p->pl_len+4; + + // Calc CRC + for (j=3; j<5; j++) hdr.crc = crc_ccitt_byte(((uint8_t*)&hdr)[j], hdr.crc); + for (j=0; jnoise)[j], hdr.crc); // SPP-protocol must match with rx_pkt_t struct + hdr.crc ^= 0xffff; + + // Copy remaining and send to port + UNPACKER_CALL(PACKER_NGHAM, (uint8_t*)&hdr, sizeof(ngh_spphdr_t)); + UNPACKER_CALL(PACKER_NGHAM, (uint8_t*)&p->noise, hdr.pl_len); +} diff --git a/ngham_spp.h b/ngham_spp.h index c78b66f..ad3fa0b 100644 --- a/ngham_spp.h +++ b/ngham_spp.h @@ -3,3 +3,10 @@ // Licensed under LGPL. // //**************************************************************// +#include + +#include "ngham_paths.h" +#include PATH_NGHAM_PLATFORM_SPP + +void ngham_pack_byte(port_ctx_t* ctx, uint8_t c); +void ngham_unpack(rx_pkt_t* p); \ No newline at end of file diff --git a/ngham_spp_test.py b/ngham_spp_test.py new file mode 100644 index 0000000..9b4df90 --- /dev/null +++ b/ngham_spp_test.py @@ -0,0 +1,107 @@ +import struct +import serial +import time, crcmod + +# States +STATE_START = 0 +STATE_HEADER = 1 +STATE_PAYLOAD = 2 + +# Types +TYPES = ["rf-data", "local-data", "command"] + +# Constants +NGHAM_START = '\x24' + +class ngham_spp: + def __init__(self, portname): + self.portname = portname + self.open() + + def __del__(self): + self.close() + + def open(self): + self.state = STATE_START + self.pl = "" + self.ser = serial.Serial(self.portname,38400,timeout=0) + self.crc = 0 + self.type = 0 + self.len = 0 + self.crc_func = crcmod.mkCrcFun(0x11021, rev=True, initCrc=0xffff, xorOut=0x0000) + self.crc_calc = 0 + + def close(self): + if self.ser: + self.ser.close() + self.ser = False + + def cmd(self, pl): + crc = self.crc_func(struct.pack(' + +// Temporary buffer for the decoder, rx packet variable and state variable. +uint8_t rx_buf[]; // Should hold the largest packet - ie. 255 B +uint16_t rx_buf_len; +rx_pkt_t rx_pkt; +uint8_t decoder_state; + +// Should return RSSI in dBm + 200 +uint8_t ngham_action_get_rssi(void){ + return RSSI_NA; +} + +// Should return noise floor in dBm + 200 +uint8_t ngham_action_get_noise_floor(void){ + return RSSI_NA; +} + +// Set packet size demodulator, if applicable, to make the demodulator stop outputting data when the packet is finished. +void ngham_action_set_packet_size(uint8_t size){ +} + +// Data to be transmitted (to modulator). Priority can be ignored if NGHam is not used for timing purposes. +void ngham_action_send_data(uint8_t *d, uint16_t d_len, uint8_t priority){ + switch (priority){ + case PKT_PRIORITY_NORMAL: + // Send d[] + break; + case PKT_PRIORITY_FIRST_IN_SLOT: + // Send d[] + break; + } +} + +// Will always be called after packet reception is finished - whether it was successful or not. +// This function should also handle reinitialization of your decoder/sync word detector. +void ngham_action_handle_packet(uint8_t condition, rx_pkt_t* p){ + switch (condition){ + case PKT_CONDITION_OK: + // Add statistics? + // Handle the received packet in p->pl[] + break; + case PKT_CONDITION_PREFAIL: + // Count as fail + break; + case PKT_CONDITION_FAIL: + // Count as fail and prepare for new sync word immediately + break; + } + + // Reset RX packet content + rx_pkt_init(&rx_pkt); +} + +// Not required: Code to be executed when reception has just started. +// This could be handling the time stamp of the sync word or starting RSSI readout. +void ngham_action_reception_started(void){ + // rx_pkt.timestamp = ; +} + +// Not required: If there is more to do a little after reception start, do it here. +void ngham_action_reception_halfway(void){ +} \ No newline at end of file diff --git a/platform/platform.h b/platform/platform.h new file mode 100644 index 0000000..3b96216 --- /dev/null +++ b/platform/platform.h @@ -0,0 +1,29 @@ +//**************************************************************// +// NGHam protocol - Jon Petter Skagmo, LA3JPA, 2014. // +// Licensed under LGPL. // +//**************************************************************// + +#ifndef PLATFORM_NGHAM_H +#define PLATFORM_NGHAM_H + +#include "ngham_packets.h" // Packet structs, NA-values etc. +#include + +// NGHAM_BYTES_TILL_ACTION_HALFWAY is number of payload bytes until ngham_action_reception_halfway is executed +// Don't care about this if you don't use the mentioned function. +#define NGHAM_BYTES_TILL_ACTION_HALFWAY 10 + +extern uint8_t rx_buf[]; // Should hold the largest packet - ie. 255 B +extern uint16_t rx_buf_len; +extern rx_pkt_t rx_pkt; +extern uint8_t decoder_state; + +void ngham_action_send_data(uint8_t *d, uint16_t d_len, uint8_t priority); +void ngham_action_set_packet_size(uint8_t size); +uint8_t ngham_action_get_rssi(void); +uint8_t ngham_action_get_noise_floor(void); +void ngham_action_handle_packet(uint8_t condition, rx_pkt_t* p); +void ngham_action_reception_started(void); +void ngham_action_reception_halfway(void); + +#endif \ No newline at end of file diff --git a/platform/platform_spp.h b/platform/platform_spp.h new file mode 100644 index 0000000..57fae50 --- /dev/null +++ b/platform/platform_spp.h @@ -0,0 +1,11 @@ +#include +#include "../ngham_packets.h" + +#define PORT_BUF_SIZE 1024 + +typedef struct{ + uint8_t d[PORT_BUF_SIZE]; + uint16_t d_ip; // Input index - counts position in buffer d + uint16_t d_op; // Output index - if d is used as ring buffer + ngh_spphdr_t ngh_spp; // For NGH SPP +}port_ctx_t; diff --git a/unused/ngham_spp_big_endian.c b/unused/ngham_spp_big_endian.c new file mode 100644 index 0000000..1aaf1ac --- /dev/null +++ b/unused/ngham_spp_big_endian.c @@ -0,0 +1,108 @@ +//**************************************************************// +// NGHam protocol - Jon Petter Skagmo, LA3JPA, 2014. // +// Licensed under LGPL. // +//**************************************************************// + +#include "ngham_packets.h" +#include "crc_ccitt.h" +#include "../terminal.h" // TODO: Put definition of port context port_ctx_t elsewhere! +#include "../config.h" // TODO: Packer call from elsewhere + + +#define SPP_START 0x24 // Packet start byte definition +#define SPP_STATE_START 0x00 // States +#define SPP_STATE_HEADER 0x01 +#define SPP_STATE_PAYLOAD 0x02 +#define SPP_TYPE_RF 0x00 // Packet types +#define SPP_TYPE_LOCAL 0x01 +#define SPP_TYPE_CMD 0x02 + +void ngham_pack_byte(port_ctx_t* ctx, uint8_t c){ + switch(ctx->state){ + case SPP_STATE_START: + if (c == SPP_START){ + ctx->state++; // Start found; go to next state + ctx->d_ip = sizeof(ngh_spphdr_rev_t)-2; + // Header is filled in reverse order to correct endianness + // Starts at next last byte (next first) as SPP_START is already received + } + break; + case SPP_STATE_HEADER: + ((uint8_t*)&ctx->ngh_spp)[ctx->d_ip] = c; // Fill header backwards + if (!ctx->d_ip) ctx->state++; // When zero is reached, d_ip is ready to count up + else ctx->d_ip--; + break; + + case SPP_STATE_PAYLOAD: + // Fill ctx->d with payload in correct order + if (ctx->d_ip < PORT_BUF_SIZE) ctx->d[ctx->d_ip++] = c; + if (ctx->d_ip >= ctx->ngh_spp.pl_len){ + ctx->state = SPP_STATE_START; + + // Calc CRC + int j; + uint16_t crc = 0xffff; + for (j=0; j<3; j++) crc = crc_ccitt_byte(((uint8_t*)&ctx->ngh_spp)[2-j], crc); + for (j=0; jd_ip; j++) crc = crc_ccitt_byte(ctx->d[j], crc); + crc ^= 0xffff; + + + if (crc == ctx->ngh_spp.crc){ + switch(ctx->ngh_spp.pl_type){ + // Data to be sent + case SPP_TYPE_RF: + { + tx_pkt_t p; + tx_pkt_init(&p); + p.ngham_flags = ctx->d[0]; // First byte in NGH SPP RF type is flags + p.pl_len = ctx->d_ip-1; + for (j=0; jd[j+1]; + packer_call(&p); + } + break; + // Command + case SPP_TYPE_CMD: + { + // Prepare response + ngh_spphdr_rev_t r_hdr; + uint8_t r[sizeof(r_hdr)+SPP_PL_MAX]; + r_hdr.start = SPP_START; + r_hdr.pl_type = SPP_TYPE_CMD; + r_hdr.pl_len = 0; + cmd(ctx->d, ctx->ngh_spp.pl_len, &r[sizeof(r_hdr)], &r_hdr.pl_len); + for (j=0; j<3; j++) r[5-j] = ((uint8_t*)&r_hdr)[j]; // Copy length and type into header in reverse order + r_hdr.crc = crc_ccitt(&r[3], r_hdr.pl_len+3); + for (j=0; j<3; j++) r[2-j] = ((uint8_t*)&r_hdr)[j+3]; // Copy CRC and stat into header in reverse order + + // Send to port + port_output(ctx, r, sizeof(r_hdr)+r_hdr.pl_len); + } + break; + } + } + else port_output(ctx, "CRC", 3); + } + break; + } +} + +void ngham_unpack(rx_pkt_t* p){ + int j; + ngh_spphdr_rev_t hdr_rev; + uint8_t hdr[sizeof(hdr_rev)]; + hdr_rev.start = SPP_START; + hdr_rev.pl_type = SPP_TYPE_RF; + hdr_rev.pl_len = p->pl_len+4; + uint8_t* p_u8 = (uint8_t*)&p->noise; // SPP-protocol must match with rx_pkt_t struct + + // Calc CRC + hdr_rev.crc = 0xffff; + for (j=0; j<3; j++) hdr_rev.crc = crc_ccitt_byte(((uint8_t*)&hdr_rev.pl_type)[3-j], hdr_rev.crc); + for (j=0; j<(p->pl_len+4); j++) hdr_rev.crc = crc_ccitt_byte(p_u8[j], hdr_rev.crc); + hdr_rev.crc ^= 0xffff; + + // Copy remaining and send to port + for (j=0; jpl_len+4); +}