diff options
author | Ekaitz Zarraga <ekaitz@elenq.tech> | 2024-12-29 16:30:28 +0100 |
---|---|---|
committer | Ekaitz Zarraga <ekaitz@elenq.tech> | 2024-12-29 16:30:28 +0100 |
commit | 9fdc216f3b4223bbce338a6c806d54288da26c40 (patch) | |
tree | 08f9c198aedcca2a18ef1cae9c444f0865529edc /simulation.scm | |
parent | 7cb6de7a9dbb09144aa210674da5cc8d157522c2 (diff) |
simulation: Enable RX1 and RX2
Diffstat (limited to 'simulation.scm')
-rw-r--r-- | simulation.scm | 109 |
1 files changed, 67 insertions, 42 deletions
diff --git a/simulation.scm b/simulation.scm index 314c15d..061c703 100644 --- a/simulation.scm +++ b/simulation.scm @@ -12,9 +12,9 @@ #:use-module (fibers timers)) (define RX1 1) ; s (has to be between 1-15s) -(define RX2 (1+ RX1)) ; s -(define RECEIVE_DELAY1 1) ; s -(define RECEIVE_DELAY2 (1+ RECEIVE_DELAY1)) ; s +(define RX2 (+ 2 RX1)) ; s +(define RECEIVE_DELAY1 3) ; s +(define RECEIVE_DELAY2 (+ 2 RECEIVE_DELAY1)) ; s (define RETRANSMISSION_DELAY 2) ; s ;; From RP002 (Regional Parameters): ;; MAC commands exist in the LoRaWAN® specification to change the value of @@ -62,6 +62,11 @@ (put-message *id-channel-in* #t) (get-message *id-channel-out*)) + +;; For timer operations +(define (seconds->time-unit s) + (* internal-time-units-per-second s)) + ;; For End-Device <--> Radio <--> Gateway ;; type can be: ;; '[up/down]link-start @@ -113,8 +118,6 @@ (define internal-com (make-channel)) ;; Make all atomic (define channel initial-channel) - (define (listening-to? chn) - (= channel chn)) ;; TODO: Unhardcode me (define time-on-air 0.01) @@ -147,7 +150,56 @@ (sleep time-on-air) (put-message upstream-chn (make-radio-event 'uplink-end event-id channel frame)))) + + (define (receive-window channel time) + (define (listening-to? chn) + (= channel chn)) + + (define (detect-preamble) + (let wait-for-downlink-start () + (let ((msg (perform-operation + (choice-operation + (wrap-operation (sleep-operation time) + (lambda _ 'time-is-out)) + (get-operation downstream-chn))))) + (match msg + ;; We got the preamble in time + (($ <radio-event> 'downlink-start message-id (= listening-to? chn) frame) + (ll "Device ~a got preamble" id) + message-id) + ;; No preamble in time + ('time-is-out #f) + ;; Current message is not a preamble, continue + (_ (wait-for-downlink-start)))))) + + (define (demodulate message-id) + (let wait-for-downlink-end ((interference? #f)) + (let ((part-of-same-message? (lambda (i) (= message-id i))) + (msg (get-message downstream-chn))) + (match msg + (($ <radio-event> 'interference + (= part-of-same-message? id) + (= listening-to? chn) + frame) + (wait-for-downlink-end #t)) ;; Got interference + (($ <radio-event> 'downlink-end + (= part-of-same-message? id) + (= listening-to? chn) + frame) + (and (not interference?) frame)) + (_ (wait-for-downlink-end interference?)))))) + + (put-message internal-com 'wait) + (let* ((preamble-id (detect-preamble)) + (result (and preamble-id (demodulate preamble-id)))) + (put-message internal-com 'continue) + result)) + (define (device-operation) + (define (wait-until t) + (perform-operation + (timer-operation t))) + (define current-frame 0) (forever ;; TODO check to-confirm @@ -156,43 +208,16 @@ (send-uplink-frame current-frame id #t) (set! current-frame (1+ current-frame)) ;; TODO: improve - (sleep RECEIVE_DELAY1) ;; TODO: make sure this is ok - (put-message internal-com 'wait) - (let ((until (+ (get-internal-real-time) - (* RX1 internal-time-units-per-second)))) - ;; TODO: listen to the first, and then hook to its radio-event-id - (let wait-for-downlink-start () - (let ((msg (perform-operation - (choice-operation - (wrap-operation (timer-operation until) - (lambda _ 'time-is-out)) - (get-operation downstream-chn))))) - (ll "~a" msg) - (match msg - ;; We got the preamble in time - (($ <radio-event> 'downlink-start message-id (= listening-to? chn) frame) - (ll "Device ~a got preamble" id) - (let wait-for-downlink-end ((interference? #f)) - (let ((part-of-same-message? (lambda (i) (= message-id i))) - (msg (get-message downstream-chn))) - (match msg - (($ <radio-event> 'interference - (= part-of-same-message? id) - (= listening-to? chn) - frame) - (wait-for-downlink-end #t)) ;; Got interference - (($ <radio-event> 'downlink-end - (= part-of-same-message? id) - (= listening-to? chn) - frame) - (unless interference? - (process-downlink! frame))) ;; TODO try RX2 - (_ (wait-for-downlink-end interference?)))))) - ;; No preamble in time - ('time-is-out #f) - ;; Current message is not a preamble, continue - (_ (wait-for-downlink-start)))))) - (put-message internal-com 'continue))) + (let* ((now (get-internal-real-time)) + (RX1-start (+ now (seconds->time-unit RECEIVE_DELAY1))) + (RX2-start (+ now (seconds->time-unit RECEIVE_DELAY2))) + (downlink (or (begin (wait-until RX1-start) + (receive-window channel RX1)) + (if (< (get-internal-real-time) RX2-start) + (begin (wait-until RX2-start) + (receive-window channel RX2)) + #f)))) + (when downlink (process-downlink! downlink))))) (define (downstream-sink) (forever |