Sfoglia il codice sorgente

add infrared transmit function

Oliver Fabel 1 anno fa
parent
commit
37adc1e1f5

+ 2 - 0
examples/flipperzero_infrared_test.py

@@ -40,3 +40,5 @@ for duration in signal:
 f0.canvas_update()
 f0.canvas_update()
 
 
 time.sleep(5)
 time.sleep(5)
+
+f0.infrared_transmit(raw_signal)

+ 1 - 1
lib/micropython

@@ -1 +1 @@
-Subproject commit 7a3539090c46072f59c0323b4efc7dbad933ee4c
+Subproject commit c564e62afd65c1e91ad61087b178a75e1a39d1f5

+ 10 - 0
lib/micropython-port/mp_flipper_context.h

@@ -21,6 +21,15 @@ typedef struct {
     bool running;
     bool running;
 } mp_flipper_infrared_rx_t;
 } mp_flipper_infrared_rx_t;
 
 
+typedef struct {
+    size_t size;
+    void* signal;
+    size_t index;
+    uint32_t repeat;
+    bool level;
+    mp_flipper_infrared_signal_tx_provider provider;
+} mp_flipper_infrared_tx_t;
+
 typedef struct {
 typedef struct {
     Gui* gui;
     Gui* gui;
     ViewPort* view_port;
     ViewPort* view_port;
@@ -34,4 +43,5 @@ typedef struct {
     FuriHalAdcHandle* adc_handle;
     FuriHalAdcHandle* adc_handle;
     mp_flipper_gpio_pin_t* gpio_pins;
     mp_flipper_gpio_pin_t* gpio_pins;
     mp_flipper_infrared_rx_t* infrared_rx;
     mp_flipper_infrared_rx_t* infrared_rx;
+    mp_flipper_infrared_tx_t* infrared_tx;
 } mp_flipper_context_t;
 } mp_flipper_context_t;

+ 63 - 9
lib/micropython-port/mp_flipper_modflipperzero_infrared.c

@@ -6,7 +6,7 @@
 
 
 #include "mp_flipper_context.h"
 #include "mp_flipper_context.h"
 
 
-static void infrared_receive_callback(void* ctx, bool level, uint32_t duration) {
+inline static void on_rx(void* ctx, bool level, uint32_t duration) {
     mp_flipper_infrared_rx_t* session = ctx;
     mp_flipper_infrared_rx_t* session = ctx;
 
 
     if(session->pointer == 0 && !level) {
     if(session->pointer == 0 && !level) {
@@ -22,12 +22,29 @@ static void infrared_receive_callback(void* ctx, bool level, uint32_t duration)
     }
     }
 }
 }
 
 
-static void infrared_timeout_callback(void* ctx) {
+inline static void on_rx_timeout(void* ctx) {
     mp_flipper_infrared_rx_t* session = ctx;
     mp_flipper_infrared_rx_t* session = ctx;
 
 
     session->running = false;
     session->running = false;
+}
+
+inline static FuriHalInfraredTxGetDataState on_tx(void* ctx, uint32_t* duration, bool* level) {
+    mp_flipper_infrared_tx_t* session = ctx;
+
+    *duration = session->provider(session->signal, session->index);
+    *level = session->level;
+
+    session->index++;
+
+    if(session->index >= session->size) {
+        session->index = 0;
+        session->repeat--;
+    }
+
+    session->level = !session->level;
 
 
-    furi_hal_infrared_async_rx_stop();
+    return session->repeat > 0 ? FuriHalInfraredTxGetDataStateOk :
+                                 FuriHalInfraredTxGetDataStateLastDone;
 }
 }
 
 
 inline uint32_t* mp_flipper_infrared_receive(uint32_t timeout, size_t* length) {
 inline uint32_t* mp_flipper_infrared_receive(uint32_t timeout, size_t* length) {
@@ -38,18 +55,55 @@ inline uint32_t* mp_flipper_infrared_receive(uint32_t timeout, size_t* length) {
     session->pointer = 0;
     session->pointer = 0;
     session->running = true;
     session->running = true;
 
 
-    furi_hal_infrared_async_rx_set_capture_isr_callback(infrared_receive_callback, session);
-    furi_hal_infrared_async_rx_set_timeout_isr_callback(infrared_timeout_callback, session);
+    if(!furi_hal_infrared_is_busy()) {
+        furi_hal_infrared_async_rx_set_capture_isr_callback(on_rx, session);
+        furi_hal_infrared_async_rx_set_timeout_isr_callback(on_rx_timeout, session);
+
+        furi_hal_infrared_async_rx_start();
 
 
-    furi_hal_infrared_async_rx_start();
+        furi_hal_infrared_async_rx_set_timeout(timeout);
 
 
-    furi_hal_infrared_async_rx_set_timeout(timeout);
+        while(session->running) {
+            furi_delay_tick(10);
+        }
 
 
-    while(session->running) {
-        furi_delay_tick(10);
+        furi_hal_infrared_async_rx_stop();
     }
     }
 
 
     *length = session->pointer;
     *length = session->pointer;
 
 
     return session->buffer;
     return session->buffer;
 }
 }
+
+inline bool mp_flipper_infrared_transmit(
+    void* signal,
+    size_t length,
+    mp_flipper_infrared_signal_tx_provider callback,
+    uint32_t repeat,
+    uint32_t frequency,
+    float duty) {
+    if(furi_hal_infrared_is_busy()) {
+        return false;
+    }
+
+    const mp_flipper_context_t* ctx = mp_flipper_context;
+
+    mp_flipper_infrared_tx_t* session = ctx->infrared_tx;
+
+    session->index = 0;
+    session->level = true;
+    session->provider = callback;
+    session->signal = signal;
+    session->repeat = repeat;
+    session->size = length;
+
+    furi_hal_infrared_set_tx_output(FuriHalInfraredTxPinInternal);
+
+    furi_hal_infrared_async_tx_set_data_isr_callback(on_tx, session);
+
+    furi_hal_infrared_async_tx_start(frequency, duty);
+
+    furi_hal_infrared_async_tx_wait_termination();
+
+    return true;
+}

+ 11 - 1
lib/micropython-port/mp_flipper_runtime.c

@@ -93,7 +93,7 @@ void* mp_flipper_context_alloc() {
         ctx->gpio_pins[pin] = MP_FLIPPER_GPIO_PIN_OFF;
         ctx->gpio_pins[pin] = MP_FLIPPER_GPIO_PIN_OFF;
     }
     }
 
 
-    // infrared
+    // infrared rx
     ctx->infrared_rx = malloc(sizeof(mp_flipper_infrared_rx_t));
     ctx->infrared_rx = malloc(sizeof(mp_flipper_infrared_rx_t));
 
 
     ctx->infrared_rx->size = MP_FLIPPER_INFRARED_RX_BUFFER_SIZE;
     ctx->infrared_rx->size = MP_FLIPPER_INFRARED_RX_BUFFER_SIZE;
@@ -101,6 +101,15 @@ void* mp_flipper_context_alloc() {
     ctx->infrared_rx->pointer = 0;
     ctx->infrared_rx->pointer = 0;
     ctx->infrared_rx->running = true;
     ctx->infrared_rx->running = true;
 
 
+    // infrared tx
+    ctx->infrared_tx = malloc(sizeof(mp_flipper_infrared_tx_t));
+    ctx->infrared_tx->index = 0;
+    ctx->infrared_tx->provider = NULL;
+    ctx->infrared_tx->repeat = 0;
+    ctx->infrared_tx->signal = NULL;
+    ctx->infrared_tx->size = 0;
+    ctx->infrared_tx->level = false;
+
     return ctx;
     return ctx;
 }
 }
 
 
@@ -139,6 +148,7 @@ void mp_flipper_context_free(void* context) {
     // stop infrared
     // stop infrared
     free(ctx->infrared_rx->buffer);
     free(ctx->infrared_rx->buffer);
     free(ctx->infrared_rx);
     free(ctx->infrared_rx);
+    free(ctx->infrared_tx);
 
 
     free(ctx);
     free(ctx);
 }
 }