1+ from  ov2640_constants  import  * 
2+ from  ov2640_lores_constants  import  * 
3+ from  ov2640_hires_constants  import  * 
4+ import  machine 
5+ import  time 
6+ import  ubinascii 
7+ import  uos 
8+ import  gc 
9+ 
10+ class  ov2640 (object ):
11+ 	def  __init__ (self , sclpin = 22 , sdapin = 21 , cspin = 15 , resolution = OV2640_320x240_JPEG ):
12+ 		gc .enable ()
13+ 		self .sclpin = sclpin 
14+ 		self .sdapin = sdapin 
15+ 		self .cspin = cspin 
16+ 		self .standby = False 
17+ 
18+ 		self .hspi  =  machine .SPI (1 , baudrate = 80000000 , polarity = 0 , phase = 0 , sck = machine .Pin (14 ), mosi = machine .Pin (13 ), miso = machine .Pin (12 ))
19+ 		self .i2c  =  machine .I2C (scl = machine .Pin (22 ), sda = machine .Pin (21 ), freq = 1000000 )
20+ 		self .hspi .init (baudrate = 2000000 )
21+ 
22+ 		self .cspin  =  machine .Pin (self .cspin , machine .Pin .OUT )
23+ 		self .cspin .value (1 )
24+ 
25+ 		addrs  =  self .i2c .scan ()
26+ 		print ('ov2640_init: devices detected on on i2c:' )
27+ 		for  a  in  addrs :
28+ 		    print ('0x%x'  %  a )
29+ 		time .sleep (1 )
30+ 
31+ 
32+ 		self .i2c .writeto_mem (SENSORADDR , 0xff , b'\x01 ' )
33+ 		# initiate system reset 
34+ 		self .i2c .writeto_mem (SENSORADDR , 0x12 , b'\x80 ' )
35+ 
36+ 		# let it come up 
37+ 		time .sleep_ms (100 )
38+ 
39+ 		# jpg init registers 
40+ 		cam_write_register_set (self .i2c , SENSORADDR , OV2640_JPEG_INIT )
41+ 		cam_write_register_set (self .i2c , SENSORADDR , OV2640_YUV422 )
42+ 		cam_write_register_set (self .i2c , SENSORADDR , OV2640_JPEG )
43+ 
44+ 		self .i2c .writeto_mem (SENSORADDR , 0xff , b'\x01 ' )
45+ 		self .i2c .writeto_mem (SENSORADDR , 0x15 , b'\x00 ' )
46+ 		   
47+ 		cam_write_register_set (i2c , SENSORADDR , OV2640_1600x1200_JPEG )
48+ 
49+ 		cam_spi_write (b'\x00 ' , b'\x55 ' , self .hspi , self .cspin )
50+ 		res  =  cam_spi_read (b'\x00 ' , self .hspi , self .cspin )
51+ 		print (res )
52+ 		print ("ov2640 init:  register test return bytes %s"  %  ubinascii .hexlify (res ))
53+ 		if  (res  ==  b'\x55 ' ):
54+ 		    print ("ov2640_init: register test successful" )
55+ 		else :
56+ 		    print ("ov2640_init: register test failed!" )
57+ 		time .sleep_us (10 )
58+ 
59+ 		self .i2c .writeto_mem (SENSORADDR , 0xff , b'\x01 ' )
60+ 		# check the camera type 
61+ 		time .sleep_us (50 )
62+ 		parta  =  self .i2c .readfrom_mem (SENSORADDR , 0x0a , 1 )
63+ 		time .sleep_us (50 )
64+ 		partb  =  self .i2c .readfrom_mem (SENSORADDR , 0x0b , 1 )
65+ 		if  ((parta  !=  b'\x26 ' ) or  (partb  !=  b'\x42 ' )):
66+ 		    print ("ov2640_init: device type does not appear to be ov2640, bytes: %s/%s"  %  \
67+ 		            (ubinascii .hexlify (parta ), ubinascii .hexlify (partb )))
68+ 		else :
69+ 		    print ("ov2640_init: device type looks correct, bytes: %s/%s"  %  \
70+ 		            (ubinascii .hexlify (parta ), ubinascii .hexlify (partb )))
71+ 		time .sleep_us (50 )
72+ 
73+ def  cam_write_register_set (i , addr , set ):
74+     for  el  in  set :
75+         raddr  =  el [0 ]
76+         val  =  el [1 ]
77+         if  (raddr  ==  0xff  and  val  ==  b'\xff ' ):
78+             return 
79+         i .writeto_mem (SENSORADDR , raddr , val )
80+ 
81+ def  cam_spi_write (address , value , hspi , cspin ):
82+     cspin .value (0 )
83+     modebit  =  b'\x80 ' 
84+     d  =  bytes ([address [0 ] |  modebit [0 ], value [0 ]])
85+     hspi .write (d )
86+     cspin .value (1 )
87+ 
88+ def  appendbuf (fn , picbuf , howmany ):
89+     try :
90+         f  =  open (fn , 'ab' )
91+         c  =  1 
92+         for  by  in  picbuf :
93+             if  (c  >  howmany ):
94+                 break 
95+             c  +=  1 
96+             f .write (bytes ([by [0 ]]))
97+         f .close ()
98+     except  OSError :
99+         print ("error writing file" )
100+     print ("write %d bytes from buffer"  %  howmany )
101+ 
102+ def  capture_to_file (fn , overwrite ):
103+     # bit 0 - clear FIFO write done flag 
104+     cam_spi_write (b'\x04 ' , b'\x01 ' , hspi , cspin )
105+ 
106+     # bit 1 - start capture then read status 
107+     cam_spi_write (b'\x04 ' , b'\x02 ' , hspi , cspin )
108+     time .sleep_ms (10 )
109+ 
110+     # read status 
111+     res  =  cam_spi_read (b'\x41 ' , hspi , cspin )
112+     cnt  =  0 
113+     #if (res == b'\x00'): 
114+     #    print("initiate capture may have failed, return byte: %s" % ubinascii.hexlify(res)) 
115+ 
116+     # read the image from the camera fifo 
117+     while  True :
118+         res  =  cam_spi_read (b'\x41 ' , hspi , cspin )
119+         mask  =  b'\x08 ' 
120+         if  (res [0 ] &  mask [0 ]):
121+             break 
122+         #print("continuing, res register %s" % ubinascii.hexlify(res)) 
123+         time .sleep_ms (10 )
124+         cnt  +=  1 
125+     #print("slept in loop %d times" % cnt) 
126+ 
127+     # read the fifo size 
128+     b1  =  cam_spi_read (b'\x44 ' , hspi , cspin )
129+     b2  =  cam_spi_read (b'\x43 ' , hspi , cspin )
130+     b3  =  cam_spi_read (b'\x42 ' , hspi , cspin )
131+     val  =  b1 [0 ] <<  16  |  b2 [0 ] <<  8  |  b3 [0 ] 
132+     print ("ov2640_capture: %d bytes in fifo"  %  val )
133+     gc .collect ()
134+ 
135+     bytebuf  =  [ 0 , 0  ]
136+     picbuf  =  [ b'\x00 '  ] *  PICBUFSIZE 
137+     l  =  0 
138+     bp  =  0 
139+     if  (overwrite  ==  True ):
140+         #print("deleting old file %s" % fn) 
141+         try :
142+             uos .remove (fn )
143+         except  OSError :
144+             pass 
145+     while  ((bytebuf [0 ] !=  b'\xd9 ' ) or  (bytebuf [1 ] !=  b'\xff ' )):
146+         bytebuf [1 ] =  bytebuf [0 ]
147+         if  (bp  >  (len (picbuf ) -  1 )):
148+             #print("appending buffer to %s" % fn) 
149+             appendbuf (fn , picbuf , bp )
150+             bp  =  0 
151+ 
152+         bytebuf [0 ] =  cam_spi_read (b'\x3d ' , hspi , cspin )
153+         l  +=  1 
154+         #print("read so far: %d, next byte: %s" % (l, ubinascii.hexlify(bytebuf[0]))) 
155+         picbuf [bp ] =  bytebuf [0 ]
156+         bp  +=  1 
157+     if  (bp  >  0 ):
158+         #print("appending final buffer to %s" % fn) 
159+         appendbuf (fn , picbuf , bp )
160+     print ("read %d bytes from fifo, camera said %d were available"  %  (l , val ))
161+     return  (l )
162+ 
163+ def  cam_spi_read (address , hspi , cspin ):
164+     cspin .value (0 )
165+     maskbits  =  b'\x7f ' 
166+     wbuf  =  bytes ([address [0 ] &  maskbits [0 ]])
167+     hspi .write (wbuf )
168+     buf  =  hspi .read (1 )
169+     cspin .value (1 )
170+     return  (buf )
0 commit comments