4141
4242from micropython import const
4343
44+ try :
45+ from typing import Optional , Union , Type , List
46+ from busio import I2C
47+ from microcontroller import Pin
48+ from circuitpython_typing import WriteableBuffer
49+ except ImportError :
50+ pass
51+
4452CTRLI = const (0x50 )
4553_R_BYPASS = const (0x05 )
4654_QS = const (0x44 )
954962
955963
956964class _RegBits :
957- def __init__ (self , bank , reg , shift , mask ) :
965+ def __init__ (self , bank : int , reg : int , shift : int , mask : int ) -> None :
958966 self .bank = bank
959967 self .reg = reg
960968 self .shift = shift
961969 self .mask = mask
962970
963- def __get__ (self , obj , objtype = None ):
971+ def __get__ (self , obj : "_SCCBCameraBase" , objtype : Optional [ Type ] = None ) -> int :
964972 reg_value = obj ._read_bank_register (self .bank , self .reg )
965973 return (reg_value >> self .shift ) & self .mask
966974
967- def __set__ (self , obj , value ) :
975+ def __set__ (self , obj : "_SCCBCameraBase" , value : Union [ bool , int ]) -> None :
968976 if value & ~ self .mask :
969977 raise ValueError (
970978 f"Value 0x{ value :02x} does not fit in mask 0x{ self .mask :02x} "
@@ -976,38 +984,38 @@ def __set__(self, obj, value):
976984
977985
978986class _SCCBCameraBase : # pylint: disable=too-few-public-methods
979- def __init__ (self , i2c_bus , i2c_address ) :
987+ def __init__ (self , i2c_bus : I2C , i2c_address : int ) -> None :
980988 self ._i2c_device = I2CDevice (i2c_bus , i2c_address )
981989 self ._bank = None
982990
983- def _get_reg_bits (self , bank , reg , shift , mask ) :
991+ def _get_reg_bits (self , bank : int , reg : int , shift : int , mask : int ) -> int :
984992 return (self ._read_bank_register (bank , reg ) >> shift ) & mask
985993
986- def _set_reg_bits (
987- self , bank , reg , shift , mask , value
988- ): # pylint: disable=too-many-arguments
994+ def _set_reg_bits ( # pylint: disable=too-many-arguments
995+ self , bank : int , reg : int , shift : int , mask : int , value : int
996+ ) -> None :
989997 reg_value = self ._read_bank_register (bank , reg )
990998 reg_value &= ~ (mask << shift )
991999 reg_value |= value << shift
9921000 self ._write_register (reg , reg_value )
9931001
994- def _write_list (self , reg_list ) :
1002+ def _write_list (self , reg_list : List [ int ]) -> None :
9951003 for i in range (0 , len (reg_list ), 2 ):
9961004 self ._write_register (reg_list [i ], reg_list [i + 1 ])
9971005 time .sleep (0.001 )
9981006
999- def _write_bank_register (self , bank , reg , value ) :
1007+ def _write_bank_register (self , bank : int , reg : int , value : int ) -> None :
10001008 if self ._bank != bank :
10011009 self ._write_register (_BANK_SEL , bank )
10021010 self ._write_register (reg , value )
10031011
1004- def _read_bank_register (self , bank , reg ) :
1012+ def _read_bank_register (self , bank : int , reg : int ) -> int :
10051013 if self ._bank != bank :
10061014 self ._write_register (_BANK_SEL , bank )
10071015 result = self ._read_register (reg )
10081016 return result
10091017
1010- def _write_register (self , reg , value ) :
1018+ def _write_register (self , reg : int , value : int ) -> None :
10111019 if reg == _BANK_SEL :
10121020 if self ._bank == value :
10131021 return
@@ -1019,7 +1027,7 @@ def _write_register(self, reg, value):
10191027 with self ._i2c_device as i2c :
10201028 i2c .write (b )
10211029
1022- def _read_register (self , reg ) :
1030+ def _read_register (self , reg : int ) -> int :
10231031 b = bytearray (1 )
10241032 b [0 ] = reg
10251033 with self ._i2c_device as i2c :
@@ -1039,17 +1047,17 @@ class OV2640(_SCCBCameraBase): # pylint: disable=too-many-instance-attributes
10391047
10401048 def __init__ (
10411049 self ,
1042- i2c_bus ,
1043- data_pins ,
1044- clock ,
1045- vsync ,
1046- href ,
1047- shutdown = None ,
1048- reset = None ,
1049- mclk = None ,
1050- mclk_frequency = 20_000_000 ,
1051- i2c_address = 0x30 ,
1052- size = OV2640_SIZE_QQVGA ,
1050+ i2c_bus : I2C ,
1051+ data_pins : Pin ,
1052+ clock : Pin ,
1053+ vsync : Pin ,
1054+ href : Pin ,
1055+ shutdown : Optional [ Pin ] = None ,
1056+ reset : Optional [ Pin ] = None ,
1057+ mclk : Optional [ Pin ] = None ,
1058+ mclk_frequency : int = 20_000_000 ,
1059+ i2c_address : int = 0x30 ,
1060+ size : int = OV2640_SIZE_QQVGA ,
10531061 ): # pylint: disable=too-many-arguments
10541062 """
10551063 Args:
@@ -1122,11 +1130,11 @@ def __init__(
11221130 data_pins = data_pins , clock = clock , vsync = vsync , href = href
11231131 )
11241132
1125- def capture (self , buf ) :
1133+ def capture (self , buf : WriteableBuffer ) -> Optional [ memoryview ] :
11261134 """Capture an image into the buffer.
11271135
11281136 Args:
1129- buf (Union[bytearray, memoryview] ): A WritableBuffer to contain the \
1137+ buf (WriteableBuffer ): A WritableBuffer to contain the \
11301138 captured image. Note that this can be a ulab array or a displayio Bitmap.
11311139 """
11321140 self ._imagecapture .capture (buf )
@@ -1138,40 +1146,40 @@ def capture(self, buf):
11381146 return None
11391147
11401148 @property
1141- def capture_buffer_size (self ):
1149+ def capture_buffer_size (self ) -> int :
11421150 """Return the size of capture buffer to use with current resolution & colorspace settings"""
11431151 if self .colorspace == OV2640_COLOR_JPEG :
11441152 return self .width * self .height // 5
11451153 return self .width * self .height * 2
11461154
11471155 @property
1148- def mclk_frequency (self ):
1156+ def mclk_frequency (self ) -> Optional [ int ] :
11491157 """Get the actual frequency the generated mclk, or None"""
11501158 return self ._mclk_pwm .frequency if self ._mclk_pwm else None
11511159
11521160 @property
1153- def width (self ):
1161+ def width (self ) -> int :
11541162 """Get the image width in pixels. A buffer of 2*width*height bytes \
11551163 stores a whole image."""
11561164 return self ._w
11571165
11581166 @property
1159- def height (self ):
1167+ def height (self ) -> int :
11601168 """Get the image height in pixels. A buffer of 2*width*height bytes \
11611169 stores a whole image."""
11621170 return self ._h
11631171
11641172 @property
1165- def colorspace (self ):
1173+ def colorspace (self ) -> bytes :
11661174 """Get or set the colorspace, one of the ``OV2640_COLOR_`` constants."""
11671175 return self ._colorspace
11681176
11691177 @colorspace .setter
1170- def colorspace (self , colorspace ) :
1178+ def colorspace (self , colorspace : bytes ) -> None :
11711179 self ._colorspace = colorspace
11721180 self ._set_size_and_colorspace ()
11731181
1174- def _set_colorspace (self ):
1182+ def _set_colorspace (self ) -> None :
11751183 colorspace = self ._colorspace
11761184 settings = _ov2640_color_settings [colorspace ]
11771185
@@ -1180,7 +1188,7 @@ def _set_colorspace(self):
11801188 self ._write_list (settings )
11811189 time .sleep (0.01 )
11821190
1183- def deinit (self ):
1191+ def deinit (self ) -> None :
11841192 """Deinitialize the camera"""
11851193 self ._imagecapture .deinit ()
11861194 if self ._mclk_pwm :
@@ -1191,11 +1199,11 @@ def deinit(self):
11911199 self ._reset .deinit ()
11921200
11931201 @property
1194- def size (self ):
1202+ def size (self ) -> int :
11951203 """Get or set the captured image size, one of the ``OV2640_SIZE_`` constants."""
11961204 return self ._size
11971205
1198- def _set_size_and_colorspace (self ):
1206+ def _set_size_and_colorspace (self ) -> None :
11991207 size = self ._size
12001208 width , height , ratio = _resolution_info [size ]
12011209 offset_x , offset_y , max_x , max_y = _ratio_table [ratio ]
@@ -1218,11 +1226,11 @@ def _set_size_and_colorspace(self):
12181226 self ._set_window (mode , offset_x , offset_y , max_x , max_y , width , height )
12191227
12201228 @size .setter
1221- def size (self , size ) :
1229+ def size (self , size : int ) -> None :
12221230 self ._size = size
12231231 self ._set_size_and_colorspace ()
12241232
1225- def _set_flip (self ):
1233+ def _set_flip (self ) -> None :
12261234 bits = 0
12271235 if self ._flip_x :
12281236 bits |= _REG04_HFLIP_IMG
@@ -1231,38 +1239,45 @@ def _set_flip(self):
12311239 self ._write_bank_register (_BANK_SENSOR , _REG04 , _REG04_SET (bits ))
12321240
12331241 @property
1234- def flip_x (self ):
1242+ def flip_x (self ) -> bool :
12351243 """Get or set the X-flip flag"""
12361244 return self ._flip_x
12371245
12381246 @flip_x .setter
1239- def flip_x (self , value ) :
1247+ def flip_x (self , value : bool ) -> None :
12401248 self ._flip_x = bool (value )
12411249 self ._set_flip ()
12421250
12431251 @property
1244- def flip_y (self ):
1252+ def flip_y (self ) -> bool :
12451253 """Get or set the Y-flip flag"""
12461254 return self ._flip_y
12471255
12481256 @flip_y .setter
1249- def flip_y (self , value ) :
1257+ def flip_y (self , value : bool ) -> None :
12501258 self ._flip_y = bool (value )
12511259 self ._set_flip ()
12521260
12531261 @property
1254- def product_id (self ):
1262+ def product_id (self ) -> int :
12551263 """Get the product id (PID) register. The expected value is 0x26."""
12561264 return self ._read_bank_register (_BANK_SENSOR , _REG_PID )
12571265
12581266 @property
1259- def product_version (self ):
1260- """Get the version (VER) register. The expected value is 0x4x ."""
1267+ def product_version (self ) -> int :
1268+ """Get the version (VER) register. The expected value is 0x41 ."""
12611269 return self ._read_bank_register (_BANK_SENSOR , _REG_VER )
12621270
1263- def _set_window (
1264- self , mode , offset_x , offset_y , max_x , max_y , width , height
1265- ): # pylint: disable=too-many-arguments, too-many-locals
1271+ def _set_window ( # pylint: disable=too-many-arguments, too-many-locals
1272+ self ,
1273+ mode : int ,
1274+ offset_x : int ,
1275+ offset_y : int ,
1276+ max_x : int ,
1277+ max_y : int ,
1278+ width : int ,
1279+ height : int ,
1280+ ) -> None :
12661281 self ._w = width
12671282 self ._h = height
12681283
@@ -1335,7 +1350,7 @@ def _set_window(
13351350 self .test_pattern = self ._test_pattern
13361351
13371352 @property
1338- def exposure (self ):
1353+ def exposure (self ) -> int :
13391354 """The exposure level of the sensor"""
13401355 aec_9_2 = self ._get_reg_bits (_BANK_SENSOR , _AEC , 0 , 0xFF )
13411356 aec_15_10 = self ._get_reg_bits (_BANK_SENSOR , _REG45 , 0 , 0b111111 )
@@ -1344,7 +1359,7 @@ def exposure(self):
13441359 return aec_1_0 | (aec_9_2 << 2 ) | (aec_15_10 << 10 )
13451360
13461361 @exposure .setter
1347- def exposure (self , exposure ) :
1362+ def exposure (self , exposure : int ) -> None :
13481363 aec_1_0 = exposure & 0x11
13491364 aec_9_2 = (exposure >> 2 ) & 0b11111111
13501365 aec_15_10 = exposure >> 10
0 commit comments