80 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			80 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /**
 | |
|  * Copyright (c) 2021 mjcross
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-3-Clause
 | |
|  */
 | |
| 
 | |
| // SDK types and declarations
 | |
| #include "pico/stdlib.h"
 | |
| #include "hardware/pio.h"
 | |
| #include "hardware/clocks.h"    // for clock_get_hz()
 | |
| 
 | |
| #include "nec_receive.h"
 | |
| 
 | |
| // import the assembled PIO state machine program
 | |
| #include "nec_receive.pio.h"
 | |
| 
 | |
| // Claim an unused state machine on the specified PIO and configure it
 | |
| // to receive NEC IR frames on the given GPIO pin.
 | |
| //
 | |
| // Returns: the state machine number on success, otherwise -1
 | |
| int nec_rx_init(PIO pio, uint pin_num) {
 | |
| 
 | |
|     // disable pull-up and pull-down on gpio pin
 | |
|     gpio_disable_pulls(pin_num);
 | |
| 
 | |
|     // install the program in the PIO shared instruction space
 | |
|     uint offset;
 | |
|     if (pio_can_add_program(pio, &nec_receive_program)) {
 | |
|         offset = pio_add_program(pio, &nec_receive_program);
 | |
|     } else {
 | |
|         return -1;      // the program could not be added
 | |
|     }
 | |
| 
 | |
|     // claim an unused state machine on this PIO
 | |
|     int sm = pio_claim_unused_sm(pio, true);
 | |
|     if (sm == -1) {
 | |
|         return -1;      // we were unable to claim a state machine
 | |
|     }
 | |
| 
 | |
|     // configure and enable the state machine
 | |
|     nec_receive_program_init(pio, sm, offset, pin_num);
 | |
| 
 | |
|     return sm;
 | |
| }
 | |
| 
 | |
| 
 | |
| // Validate a 32-bit frame and store the address and data at the locations
 | |
| // provided.
 | |
| //
 | |
| // Returns: `true` if the frame was valid, otherwise `false`
 | |
| bool nec_decode_frame(uint32_t frame, uint8_t *p_address, uint8_t *p_data) {
 | |
| 
 | |
|     // access the frame data as four 8-bit fields
 | |
|     //
 | |
|     union {
 | |
|         uint32_t raw;
 | |
|         struct {
 | |
|             uint8_t address;
 | |
|             uint8_t inverted_address;
 | |
|             uint8_t data;
 | |
|             uint8_t inverted_data;
 | |
|         };
 | |
|     } f;
 | |
| 
 | |
|     f.raw = frame;
 | |
| 
 | |
|     // a valid (non-extended) 'NEC' frame should contain 8 bit
 | |
|     // address, inverted address, data and inverted data
 | |
|     if (f.address != (f.inverted_address ^ 0xff) ||
 | |
|         f.data != (f.inverted_data ^ 0xff)) {
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     // store the validated address and data
 | |
|     *p_address = f.address;
 | |
|     *p_data = f.data;
 | |
| 
 | |
|     return true;
 | |
| }
 |