 584c0962d8
			
		
	
	
		584c0962d8
		
			
		
	
	
	
	
		
			
			* FURI stdglue: stdout hooks, local and global, ISR safe printf. Uniform newlines for terminal/debug output. Power: prevent sleep while core 2 has not started. * Furi record, stdglue: check mutex allocation * remove unused test * Furi stdglue: buferized output, dynamically allocated state. Furi record: dynamically allocated state. Input dump: proper line ending. Hal VCP: dynamically allocated state. * Interrupt manager: explicitly init list. * Makefile: cleanup rules, fix broken dfu upload. F4: add compiler stack protection options. * BLE: call debug uart callback on transmission complete * FreeRTOS: add configUSE_NEWLIB_REENTRANT * API HAL Timebase: fix issue with idle thread stack corruption caused by systick interrupt. BT: cleanup debug info output. FreeRTOS: disable reentry for newlib. * F4: update stack protection CFLAGS to match used compiller * F4: disable compiller stack protection because of incompatibility with current compiller * Makefile: return openocd logs to gdb * BLE: fixed pin, moar power, ble trace info. * Prevent sleep when connection is active * Makefile: return serial port to upload rule, add workaround for mac os * Furi: prevent usage of stack for cmsis functions. * F4: add missing includes, add debugger breakpoints * Applications: per app stack size. * Furi: honor kernel state in stdglue * FreeRTOS: remove unused hooks * Cleanup and format sources Co-authored-by: DrZlo13 <who.just.the.doctor@gmail.com>
		
			
				
	
	
		
			131 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <input/input.h>
 | |
| #include <stdio.h>
 | |
| #include <furi.h>
 | |
| 
 | |
| #ifdef APP_NFC
 | |
| void nfc_isr(void);
 | |
| #endif
 | |
| 
 | |
| #ifdef BUILD_CC1101
 | |
| void cc1101_isr();
 | |
| #endif
 | |
| 
 | |
| static volatile bool initialized = false;
 | |
| static ValueManager input_state_record;
 | |
| static PubSub input_events_record;
 | |
| static Event event;
 | |
| static InputState input_state = {
 | |
|     false,
 | |
| };
 | |
| 
 | |
| static void exti_input_callback(void* _pin, void* _ctx);
 | |
| 
 | |
| void input_task(void* p) {
 | |
|     uint32_t state_bits = 0;
 | |
|     uint8_t debounce_counters[INPUT_COUNT];
 | |
| 
 | |
|     if(!init_managed(&input_state_record, &input_state, sizeof(input_state))) {
 | |
|         printf("[input_task] cannot initialize ValueManager for input_state\r\n");
 | |
|         furiac_exit(NULL);
 | |
|     }
 | |
|     if(!init_pubsub(&input_events_record)) {
 | |
|         printf("[input_task] cannot initialize PubSub for input_events\r\n");
 | |
|         furiac_exit(NULL);
 | |
|     }
 | |
|     if(!init_event(&event)) {
 | |
|         printf("[input_task] cannot initialize Event\r\n");
 | |
|         furiac_exit(NULL);
 | |
|     }
 | |
| 
 | |
|     furi_record_create("input_state", &input_state_record);
 | |
|     furi_record_create("input_events", &input_events_record);
 | |
| 
 | |
|     api_interrupt_add(exti_input_callback, InterruptTypeExternalInterrupt, NULL);
 | |
| 
 | |
|     // we ready to work
 | |
|     initialized = true;
 | |
| 
 | |
|     // Force state update
 | |
|     for(uint32_t i = 0; i < INPUT_COUNT; i++) {
 | |
|         debounce_counters[i] = DEBOUNCE_TICKS / 2;
 | |
|     }
 | |
| 
 | |
|     for(;;) {
 | |
|         bool changed = false;
 | |
|         for(uint32_t i = 0; i < INPUT_COUNT; i++) {
 | |
|             bool input_state = false;
 | |
| 
 | |
|             // dirty hack, f3 has no CHARGING pin
 | |
|             // TODO rewrite this
 | |
|             if(i < GPIO_INPUT_PINS_COUNT) {
 | |
|                 input_state = gpio_read(&input_gpio[i]) ^ input_invert[i];
 | |
|             }
 | |
| 
 | |
|             if(input_state) {
 | |
|                 if(debounce_counters[i] < DEBOUNCE_TICKS) {
 | |
|                     debounce_counters[i] += 1;
 | |
|                     changed = true;
 | |
|                 }
 | |
|             } else {
 | |
|                 if(debounce_counters[i] > 0) {
 | |
|                     debounce_counters[i] -= 1;
 | |
|                     changed = true;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if(!changed) {
 | |
|             uint32_t new_state_bits = 0;
 | |
|             for(uint32_t i = 0; i < INPUT_COUNT; i++) {
 | |
|                 if(debounce_counters[i] == DEBOUNCE_TICKS) {
 | |
|                     new_state_bits |= (1 << i);
 | |
|                 }
 | |
|             }
 | |
|             uint32_t changed_bits = new_state_bits ^ state_bits;
 | |
| 
 | |
|             if(changed_bits != 0) {
 | |
|                 // printf("[input] %02x -> %02x\n", state_bits, new_state_bits);
 | |
|                 InputState new_state = _BITS2STATE(new_state_bits);
 | |
|                 write_managed(&input_state_record, &new_state, sizeof(new_state), osWaitForever);
 | |
| 
 | |
|                 state_bits = new_state_bits;
 | |
| 
 | |
|                 for(uint32_t i = 0; i < INPUT_COUNT; i++) {
 | |
|                     if((changed_bits & (1 << i)) != 0) {
 | |
|                         bool state = (new_state_bits & (1 << i)) != 0;
 | |
|                         InputEvent event = {i, state};
 | |
|                         notify_pubsub(&input_events_record, &event);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // Sleep: wait for event
 | |
|             wait_event(&event);
 | |
|         } else {
 | |
|             osDelay(1);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void exti_input_callback(void* _pin, void* _ctx) {
 | |
|     // interrupt manager get us pin constant, so...
 | |
|     uint32_t pin = (uint32_t)_pin;
 | |
| 
 | |
| #ifdef APP_NFC
 | |
|     if(pin == NFC_IRQ_Pin) {
 | |
|         nfc_isr();
 | |
|         return;
 | |
|     }
 | |
| #endif
 | |
| 
 | |
| #ifdef BUILD_CC1101
 | |
|     if(pin == CC1101_G0_Pin) {
 | |
|         cc1101_isr();
 | |
|         return;
 | |
|     }
 | |
| #endif
 | |
| 
 | |
|     if(!initialized) return;
 | |
| 
 | |
|     signal_event(&event);
 | |
| } |