-
Notifications
You must be signed in to change notification settings - Fork 5
/
videoinput.pio
114 lines (90 loc) · 3.73 KB
/
videoinput.pio
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
*
* The MIT License (MIT)
*
* Copyright (c) 2022 guruthree
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
// we just want to read digital in at a fixed frequency
// wait for vsync, then wait for the vertical back porch
// wait for hsync, then wait for the horizontal back porch
// then read in the pixels
// useful resources:
// https://gregchadwick.co.uk/blog/playing-with-the-pico-pt4/
// https://datasheets.raspberrypi.com/pico/raspberry-pi-pico-c-sdk.pdf
.program videoinput
// pin 0 is data in
// pin 1 is hsync
// pin 2 is vsync
// x counts lines
// y counts pixels across
.wrap_target
wait 0 pin 2 [0] // wait for vsync
set x, 26 // skip the first LINE_OFFSET lines of data, nothing there anyway
vblankloop:
wait 0 pin 1 [0] // fall then
wait 1 pin 1 [0] // rise makes a complete hsync
jmp x-- vblankloop
set x, 0
set y, 0
pull noblock // move a 32-bit word from the TX FIFO into the OSR
out x, 16 // right-hand 16 bits is the number of lines (345)
out y, 16 // left-hand 16 bits is the number of pixels across (22*4*8=704)
mov osr, y // copy y back to OSR so we can re-use it
wait 0 pin 1 // wait for hsync
wait 1 pin 1
hsyncloop:
wait 0 pin 1 // wait for hsync
// skip the horizontal porch (194 pixels?)
set y, 31
nop [4+24] // skip 5 pixels (when also accounting for set)
pixelskiploop:
nop [29] // skip 5 pixels (it's -1 for the jmp)
jmp y-- pixelskiploop
nop [1] // finishing up from the loop
nop [23] // skip 4 pixels
nop [17] // skip 3 pixels
// total 168 or 173 skipped?
mov y, osr // load y back with the number of pixels to read
pixelloop:
nop [1] // off set a bit the read so the timings match
in pins, 1 [2] // read pixel data in every 2 cycles?
jmp y-- pixelloop
jmp x-- hsyncloop
.wrap
% c-sdk {
#define PIN_COUNT 3
static inline void videoinput_program_init(PIO pio, uint sm, uint offset, uint pin_base, float divider) {
for(uint8_t i=pin_base; i<pin_base+PIN_COUNT; i++) {
pio_gpio_init(pio, i);
gpio_set_dir(i, GPIO_IN);
}
pio_sm_set_consecutive_pindirs(pio, sm, pin_base, PIN_COUNT, false);
pio_sm_config c = videoinput_program_get_default_config(offset); // get a default config, this function call is auto-generated
// change # of bits here if we want to write a 32-bit word and then go through it
sm_config_set_in_shift(&c, true, true, 32); // true - shift right, auto pull, # of bits
sm_config_set_in_pins(&c, pin_base); // why doesn't this have a PIN_COUNT like out_pins?
sm_config_set_clkdiv(&c, divider);
pio_sm_init(pio, sm, offset, &c);
pio_sm_clear_fifos(pio, sm);
pio_sm_set_enabled(pio, sm, true); // if false, don't run by ourself
}
%}