From 64c9baa6aa6203e21ff0420ce5a9889f44422334 Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Fri, 7 Aug 2020 15:46:00 -0500 Subject: Added bitmap.insert function for slice copy into a bitmap from another bitmap --- shared-module/displayio/Bitmap.c | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'shared-module') diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index 8bcda6086..ab6e4f5dd 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -105,6 +105,77 @@ uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *self, int16_t return 0; } +void common_hal_displayio_bitmap_insert(displayio_bitmap_t *self, int16_t x, int16_t y, displayio_bitmap_t *source, + int16_t x1, int16_t y1, int16_t x2, int16_t y2) { + // Copy complete "source" bitmap into "self" bitmap at location x,y in the "self" + // Add a boolean to determine if all values are copied, or only if non-zero + // Default is copy all values, but for text glyphs this should copy only non-zero values + + if (self->read_only) { + mp_raise_RuntimeError(translate("Read-only object")); + } + + //// check for zero width, this would be a single pixel + // if (x1_source == x2_source) || (y1_source == y2_source) { + // return 0 + // } + + // Dirty area update is unnecessary with simplest version. + // int16_t x_max=x+(x2_source-x1_source); + // int16_t y_max=y+(y2_source-y1_source); + // + // + // // Update the dirty area. + // if (x < self->dirty_area.x1) { + // self->dirty_area.x1 = x; + // } else if (x_max >= self->dirty_area.x2) { + // self->dirty_area.x2 = x_max); + // } + // if (y < self->dirty_area.y1) { + // self->dirty_area.y1 = y; + // } else if (y_max >= self->dirty_area.y2) { + // self->dirty_area.y2 = y_max; + // } + + // simplest version - use internal functions for get/set pixels + for (uint16_t i=0; i<= (x2-x1) ; i++) { + for (uint16_t j=0; j<= (y2-y1) ; j++){ + uint16_t value = common_hal_displayio_bitmap_get_pixel(source, x1+i, y1+j); + if ( (x+i >= 0) && (y+j >= 0) && (x+i <= self->width-1) && (y+j <= self->height-1) ){ + common_hal_displayio_bitmap_set_pixel(self, x+i, y+j, value); + } + } + } + + // Would be faster if copying a full word at a time. + /// Hard work here!!!! + // index into the original row + // figure out how to shift the bits into the right location + // check the boolean and don't update any zero's + + // // Update our data + // int32_t row_start = y * self->stride; + // uint32_t bytes_per_value = self->bits_per_value / 8; + // if (bytes_per_value < 1) { + // uint32_t bit_position = (sizeof(size_t) * 8 - ((x & self->x_mask) + 1) * self->bits_per_value); + // uint32_t index = row_start + (x >> self->x_shift); + // uint32_t word = self->data[index]; + // word &= ~(self->bitmask << bit_position); + // word |= (value & self->bitmask) << bit_position; + // self->data[index] = word; + // } else { + // size_t* row = self->data + row_start; + // if (bytes_per_value == 1) { + // ((uint8_t*) row)[x] = value; + // } else if (bytes_per_value == 2) { + // ((uint16_t*) row)[x] = value; + // } else if (bytes_per_value == 4) { + // ((uint32_t*) row)[x] = value; + // } + // } +} + + void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x, int16_t y, uint32_t value) { if (self->read_only) { mp_raise_RuntimeError(translate("Read-only object")); -- cgit v1.2.3 From b6008d0032a49e6b5c332576fa2f141d353b9fd3 Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Fri, 7 Aug 2020 15:59:42 -0500 Subject: Adding bitmap.insert to copy a slice of a source bitmap into another bitmap --- shared-module/displayio/Bitmap.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'shared-module') diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index ab6e4f5dd..75f352b30 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -115,6 +115,10 @@ void common_hal_displayio_bitmap_insert(displayio_bitmap_t *self, int16_t x, int mp_raise_RuntimeError(translate("Read-only object")); } + // If this value is encountered in the source bitmap, it will not be copied (for text glyphs) + // This should be added as an optional parameter, and if it is `None`, then all pixels are copied + uint32_t skip_value=0; + //// check for zero width, this would be a single pixel // if (x1_source == x2_source) || (y1_source == y2_source) { // return 0 @@ -140,9 +144,11 @@ void common_hal_displayio_bitmap_insert(displayio_bitmap_t *self, int16_t x, int // simplest version - use internal functions for get/set pixels for (uint16_t i=0; i<= (x2-x1) ; i++) { for (uint16_t j=0; j<= (y2-y1) ; j++){ - uint16_t value = common_hal_displayio_bitmap_get_pixel(source, x1+i, y1+j); - if ( (x+i >= 0) && (y+j >= 0) && (x+i <= self->width-1) && (y+j <= self->height-1) ){ - common_hal_displayio_bitmap_set_pixel(self, x+i, y+j, value); + uint32_t value = common_hal_displayio_bitmap_get_pixel(source, x1+i, y1+j); + if (value != skip_value) { + if ( (x+i >= 0) && (y+j >= 0) && (x+i <= self->width-1) && (y+j <= self->height-1) ){ + common_hal_displayio_bitmap_set_pixel(self, x+i, y+j, value); + } } } } -- cgit v1.2.3 From 14f5d03b6dd947bd82d2daf88ca398d7d3b44930 Mon Sep 17 00:00:00 2001 From: Kevin Matocha Date: Thu, 13 Aug 2020 18:59:00 -0500 Subject: bringing up to date --- extmod/ulab | 2 +- frozen/Adafruit_CircuitPython_BLE | 2 +- ...uit_CircuitPython_BLE_Apple_Notification_Center | 2 +- frozen/Adafruit_CircuitPython_BusDevice | 2 +- frozen/Adafruit_CircuitPython_CircuitPlayground | 2 +- frozen/Adafruit_CircuitPython_Crickit | 2 +- frozen/Adafruit_CircuitPython_DRV2605 | 2 +- frozen/Adafruit_CircuitPython_DS3231 | 2 +- frozen/Adafruit_CircuitPython_ESP32SPI | 2 +- frozen/Adafruit_CircuitPython_FocalTouch | 2 +- frozen/Adafruit_CircuitPython_HID | 2 +- frozen/Adafruit_CircuitPython_IRRemote | 2 +- frozen/Adafruit_CircuitPython_LIS3DH | 2 +- frozen/Adafruit_CircuitPython_LSM6DS | 2 +- frozen/Adafruit_CircuitPython_Motor | 2 +- frozen/Adafruit_CircuitPython_Register | 2 +- frozen/Adafruit_CircuitPython_Requests | 2 +- frozen/Adafruit_CircuitPython_Thermistor | 2 +- frozen/Adafruit_CircuitPython_seesaw | 2 +- frozen/circuitpython-stage | 2 +- lib/mp3 | 2 +- lib/protomatter | 2 +- lib/tinyusb | 2 +- ports/atmel-samd/asf4 | 2 +- ports/atmel-samd/peripherals | 2 +- ports/cxd56/spresense-exported-sdk | 2 +- ports/esp32s2/esp-idf | 2 +- ports/stm/st_driver | 2 +- shared-bindings/_typing/__init__ 2.pyi | 54 +++ shared-bindings/gnss/GNSS 2.c | 205 +++++++++ shared-bindings/gnss/GNSS 2.h | 27 ++ shared-bindings/gnss/PositionFix 2.c | 80 ++++ shared-bindings/gnss/PositionFix 2.h | 28 ++ shared-bindings/gnss/SatelliteSystem 2.c | 113 +++++ shared-bindings/gnss/SatelliteSystem 2.h | 33 ++ shared-bindings/gnss/__init__ 2.c | 31 ++ shared-bindings/i2cperipheral/I2CPeripheral 2.c | 436 +++++++++++++++++++ shared-bindings/i2cperipheral/I2CPeripheral 2.h | 60 +++ shared-bindings/i2cperipheral/__init__ 2.c | 106 +++++ shared-bindings/memorymonitor/AllocationAlarm 2.c | 137 ++++++ shared-bindings/memorymonitor/AllocationAlarm 2.h | 39 ++ shared-bindings/memorymonitor/AllocationSize 2.c | 183 ++++++++ shared-bindings/memorymonitor/AllocationSize 2.h | 42 ++ shared-bindings/memorymonitor/__init__ 2.c | 76 ++++ shared-bindings/memorymonitor/__init__ 2.h | 49 +++ shared-bindings/sdcardio/SDCard 2.c | 183 ++++++++ shared-bindings/sdcardio/SDCard 2.h | 30 ++ shared-bindings/sdcardio/__init__ 2.c | 47 +++ shared-bindings/sdcardio/__init__ 2.h | 0 shared-bindings/sdioio/SDCard 2.c | 296 +++++++++++++ shared-bindings/sdioio/SDCard 2.h | 66 +++ shared-bindings/sdioio/__init__ 2.c | 47 +++ shared-bindings/sdioio/__init__ 2.h | 0 shared-module/memorymonitor/AllocationAlarm 2.c | 94 +++++ shared-module/memorymonitor/AllocationAlarm 2.h | 51 +++ shared-module/memorymonitor/AllocationSize 2.c | 91 ++++ shared-module/memorymonitor/AllocationSize 2.h | 51 +++ shared-module/memorymonitor/__init__ 2.c | 39 ++ shared-module/memorymonitor/__init__ 2.h | 35 ++ shared-module/sdcardio/SDCard 2.c | 466 +++++++++++++++++++++ shared-module/sdcardio/SDCard 2.h | 51 +++ shared-module/sdcardio/__init__ 2.c | 0 shared-module/sdcardio/__init__ 2.h | 0 supervisor/background_callback 2.h | 87 ++++ supervisor/shared/background_callback 2.c | 138 ++++++ 65 files changed, 3499 insertions(+), 28 deletions(-) create mode 100644 shared-bindings/_typing/__init__ 2.pyi create mode 100644 shared-bindings/gnss/GNSS 2.c create mode 100644 shared-bindings/gnss/GNSS 2.h create mode 100644 shared-bindings/gnss/PositionFix 2.c create mode 100644 shared-bindings/gnss/PositionFix 2.h create mode 100644 shared-bindings/gnss/SatelliteSystem 2.c create mode 100644 shared-bindings/gnss/SatelliteSystem 2.h create mode 100644 shared-bindings/gnss/__init__ 2.c create mode 100644 shared-bindings/i2cperipheral/I2CPeripheral 2.c create mode 100644 shared-bindings/i2cperipheral/I2CPeripheral 2.h create mode 100644 shared-bindings/i2cperipheral/__init__ 2.c create mode 100644 shared-bindings/memorymonitor/AllocationAlarm 2.c create mode 100644 shared-bindings/memorymonitor/AllocationAlarm 2.h create mode 100644 shared-bindings/memorymonitor/AllocationSize 2.c create mode 100644 shared-bindings/memorymonitor/AllocationSize 2.h create mode 100644 shared-bindings/memorymonitor/__init__ 2.c create mode 100644 shared-bindings/memorymonitor/__init__ 2.h create mode 100644 shared-bindings/sdcardio/SDCard 2.c create mode 100644 shared-bindings/sdcardio/SDCard 2.h create mode 100644 shared-bindings/sdcardio/__init__ 2.c create mode 100644 shared-bindings/sdcardio/__init__ 2.h create mode 100644 shared-bindings/sdioio/SDCard 2.c create mode 100644 shared-bindings/sdioio/SDCard 2.h create mode 100644 shared-bindings/sdioio/__init__ 2.c create mode 100644 shared-bindings/sdioio/__init__ 2.h create mode 100644 shared-module/memorymonitor/AllocationAlarm 2.c create mode 100644 shared-module/memorymonitor/AllocationAlarm 2.h create mode 100644 shared-module/memorymonitor/AllocationSize 2.c create mode 100644 shared-module/memorymonitor/AllocationSize 2.h create mode 100644 shared-module/memorymonitor/__init__ 2.c create mode 100644 shared-module/memorymonitor/__init__ 2.h create mode 100644 shared-module/sdcardio/SDCard 2.c create mode 100644 shared-module/sdcardio/SDCard 2.h create mode 100644 shared-module/sdcardio/__init__ 2.c create mode 100644 shared-module/sdcardio/__init__ 2.h create mode 100644 supervisor/background_callback 2.h create mode 100644 supervisor/shared/background_callback 2.c (limited to 'shared-module') diff --git a/extmod/ulab b/extmod/ulab index 11a7ecff6..cf61d728e 160000 --- a/extmod/ulab +++ b/extmod/ulab @@ -1 +1 @@ -Subproject commit 11a7ecff6d76a02644ff23a734b792afaa615e44 +Subproject commit cf61d728e70b9ec57e5711b40540793a89296f5d diff --git a/frozen/Adafruit_CircuitPython_BLE b/frozen/Adafruit_CircuitPython_BLE index 41f7a3530..5d584576e 160000 --- a/frozen/Adafruit_CircuitPython_BLE +++ b/frozen/Adafruit_CircuitPython_BLE @@ -1 +1 @@ -Subproject commit 41f7a3530d4cacdbf668399d3a015ea29c7e169b +Subproject commit 5d584576ef79ca36506e6c7470e7ac5204cf0a8d diff --git a/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center b/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center index 6a034887e..3ffb3f02d 160000 --- a/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center +++ b/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center @@ -1 +1 @@ -Subproject commit 6a034887e370caa61fee5f51db8dd393d3e72542 +Subproject commit 3ffb3f02d2046910e09d1f5a74721bd1a4cdf8cf diff --git a/frozen/Adafruit_CircuitPython_BusDevice b/frozen/Adafruit_CircuitPython_BusDevice index eb4b21e21..e9411c424 160000 --- a/frozen/Adafruit_CircuitPython_BusDevice +++ b/frozen/Adafruit_CircuitPython_BusDevice @@ -1 +1 @@ -Subproject commit eb4b21e216efd8ec0c4862a938e81b56be961724 +Subproject commit e9411c4244984b69ec6928370ede40cec014c10b diff --git a/frozen/Adafruit_CircuitPython_CircuitPlayground b/frozen/Adafruit_CircuitPython_CircuitPlayground index 3c540329b..e9f15d615 160000 --- a/frozen/Adafruit_CircuitPython_CircuitPlayground +++ b/frozen/Adafruit_CircuitPython_CircuitPlayground @@ -1 +1 @@ -Subproject commit 3c540329b63163e45f108df4bfebc387d5352c4f +Subproject commit e9f15d61502f34173912ba271aaaf9446dae8da1 diff --git a/frozen/Adafruit_CircuitPython_Crickit b/frozen/Adafruit_CircuitPython_Crickit index 809646ba1..0e1230676 160000 --- a/frozen/Adafruit_CircuitPython_Crickit +++ b/frozen/Adafruit_CircuitPython_Crickit @@ -1 +1 @@ -Subproject commit 809646ba11366b5aedbc8a90be1da1829304bf62 +Subproject commit 0e1230676a54da17a309d1dfffdd7fa90240191c diff --git a/frozen/Adafruit_CircuitPython_DRV2605 b/frozen/Adafruit_CircuitPython_DRV2605 index 209edd164..7914a6390 160000 --- a/frozen/Adafruit_CircuitPython_DRV2605 +++ b/frozen/Adafruit_CircuitPython_DRV2605 @@ -1 +1 @@ -Subproject commit 209edd164eb640a8ced561a54505792fc99a67b9 +Subproject commit 7914a6390318687bb8e2e9c4119aa932fea01531 diff --git a/frozen/Adafruit_CircuitPython_DS3231 b/frozen/Adafruit_CircuitPython_DS3231 index 5d81a9ea8..0d49a1fcd 160000 --- a/frozen/Adafruit_CircuitPython_DS3231 +++ b/frozen/Adafruit_CircuitPython_DS3231 @@ -1 +1 @@ -Subproject commit 5d81a9ea822a85e46be4a512ac44abf21e77d816 +Subproject commit 0d49a1fcd96c13a94e8bdf26f92abe79b8517906 diff --git a/frozen/Adafruit_CircuitPython_ESP32SPI b/frozen/Adafruit_CircuitPython_ESP32SPI index 01f3f6674..94b03517c 160000 --- a/frozen/Adafruit_CircuitPython_ESP32SPI +++ b/frozen/Adafruit_CircuitPython_ESP32SPI @@ -1 +1 @@ -Subproject commit 01f3f6674b4493ba29b857e0f43deb69975736ec +Subproject commit 94b03517c1f4ff68cc2bb09b0963f7e7e3ce3d04 diff --git a/frozen/Adafruit_CircuitPython_FocalTouch b/frozen/Adafruit_CircuitPython_FocalTouch index 1e3312ab1..72968d354 160000 --- a/frozen/Adafruit_CircuitPython_FocalTouch +++ b/frozen/Adafruit_CircuitPython_FocalTouch @@ -1 +1 @@ -Subproject commit 1e3312ab1cba0b1d3bb1f559c52acfdc1a6d57b8 +Subproject commit 72968d3546f9d6c5af138d4c179343007cb9662c diff --git a/frozen/Adafruit_CircuitPython_HID b/frozen/Adafruit_CircuitPython_HID index 829ba0f0a..65fb213b8 160000 --- a/frozen/Adafruit_CircuitPython_HID +++ b/frozen/Adafruit_CircuitPython_HID @@ -1 +1 @@ -Subproject commit 829ba0f0a2d8a63f7d0215c6c9fc821e14e52a93 +Subproject commit 65fb213b8c554181d54b77f75335e16e2f4c0987 diff --git a/frozen/Adafruit_CircuitPython_IRRemote b/frozen/Adafruit_CircuitPython_IRRemote index fc3a7b479..d435fc9a9 160000 --- a/frozen/Adafruit_CircuitPython_IRRemote +++ b/frozen/Adafruit_CircuitPython_IRRemote @@ -1 +1 @@ -Subproject commit fc3a7b479874a1ea315ddb3bf6c5e281e16ef097 +Subproject commit d435fc9a9d90cb063608ae037bf5284b33bc5e84 diff --git a/frozen/Adafruit_CircuitPython_LIS3DH b/frozen/Adafruit_CircuitPython_LIS3DH index 9fe8f314c..457aba6dd 160000 --- a/frozen/Adafruit_CircuitPython_LIS3DH +++ b/frozen/Adafruit_CircuitPython_LIS3DH @@ -1 +1 @@ -Subproject commit 9fe8f314c032cee89b9ad7697d61e9cba76431ff +Subproject commit 457aba6dd59ad00502b80c9031655d3d26ecc82b diff --git a/frozen/Adafruit_CircuitPython_LSM6DS b/frozen/Adafruit_CircuitPython_LSM6DS index f1cc47f02..ee8f2187d 160000 --- a/frozen/Adafruit_CircuitPython_LSM6DS +++ b/frozen/Adafruit_CircuitPython_LSM6DS @@ -1 +1 @@ -Subproject commit f1cc47f024b27e670b9bf2a51c89e32f93c1b957 +Subproject commit ee8f2187d4795b08ae4aa60558f564d26c997be9 diff --git a/frozen/Adafruit_CircuitPython_Motor b/frozen/Adafruit_CircuitPython_Motor index 434e5b534..5fd72fb96 160000 --- a/frozen/Adafruit_CircuitPython_Motor +++ b/frozen/Adafruit_CircuitPython_Motor @@ -1 +1 @@ -Subproject commit 434e5b5346cb0a1a9eb15989b00278be87cb2ff1 +Subproject commit 5fd72fb963c4a0318d29282ca2cc988f19787fda diff --git a/frozen/Adafruit_CircuitPython_Register b/frozen/Adafruit_CircuitPython_Register index 6143ec2a9..56358b449 160000 --- a/frozen/Adafruit_CircuitPython_Register +++ b/frozen/Adafruit_CircuitPython_Register @@ -1 +1 @@ -Subproject commit 6143ec2a96a6d218041e9cab5968de26702d7bbf +Subproject commit 56358b4494da825cd99a56a854119f926abca670 diff --git a/frozen/Adafruit_CircuitPython_Requests b/frozen/Adafruit_CircuitPython_Requests index 43017e30a..41de8b3c0 160000 --- a/frozen/Adafruit_CircuitPython_Requests +++ b/frozen/Adafruit_CircuitPython_Requests @@ -1 +1 @@ -Subproject commit 43017e30a1e772b67ac68293a944e863c031e389 +Subproject commit 41de8b3c05dd78d7be8893a0f6cb47a7e9b421a2 diff --git a/frozen/Adafruit_CircuitPython_Thermistor b/frozen/Adafruit_CircuitPython_Thermistor index fb773e0ed..b5bbdbd56 160000 --- a/frozen/Adafruit_CircuitPython_Thermistor +++ b/frozen/Adafruit_CircuitPython_Thermistor @@ -1 +1 @@ -Subproject commit fb773e0ed1891cda2ace6271fafc5312e167d275 +Subproject commit b5bbdbd56ca205c581ba2c84d927ef99befce88e diff --git a/frozen/Adafruit_CircuitPython_seesaw b/frozen/Adafruit_CircuitPython_seesaw index 88738da27..76c0dd132 160000 --- a/frozen/Adafruit_CircuitPython_seesaw +++ b/frozen/Adafruit_CircuitPython_seesaw @@ -1 +1 @@ -Subproject commit 88738da275a83acabb14b7140d1c79b33cdc7b02 +Subproject commit 76c0dd13294ce8ae0518cb9882dcad5d3668977e diff --git a/frozen/circuitpython-stage b/frozen/circuitpython-stage index 9596a5904..0d2c083a2 160000 --- a/frozen/circuitpython-stage +++ b/frozen/circuitpython-stage @@ -1 +1 @@ -Subproject commit 9596a5904ed757e6fbffcf03e7aa77ae9ecf5223 +Subproject commit 0d2c083a2fb57a1562d4806775f45273abbfbfae diff --git a/lib/mp3 b/lib/mp3 index bc58a6549..c3c664bf4 160000 --- a/lib/mp3 +++ b/lib/mp3 @@ -1 +1 @@ -Subproject commit bc58a654964c799e972719a63ff12694998f3549 +Subproject commit c3c664bf4db6a36d11808dfcbb5dbf7cff1715b8 diff --git a/lib/protomatter b/lib/protomatter index 761d6437e..9f71088d2 160000 --- a/lib/protomatter +++ b/lib/protomatter @@ -1 +1 @@ -Subproject commit 761d6437e8cd6a131d51de96974337121a9c7164 +Subproject commit 9f71088d2c32206c6f0495704ae0c040426d5764 diff --git a/lib/tinyusb b/lib/tinyusb index 22100b252..dc5445e2f 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 22100b252fc2eb8f51ed407949645653c4880fd9 +Subproject commit dc5445e2f45cb348a44fe24fc1be4bc8b5ba5bab diff --git a/ports/atmel-samd/asf4 b/ports/atmel-samd/asf4 index 35a152579..039b5f3bb 160000 --- a/ports/atmel-samd/asf4 +++ b/ports/atmel-samd/asf4 @@ -1 +1 @@ -Subproject commit 35a1525796c7ef8a3893d90befdad2f267fca20e +Subproject commit 039b5f3bbc3f4ba4421e581db290560d59fef625 diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals index 0f5f1522d..6b531fc92 160000 --- a/ports/atmel-samd/peripherals +++ b/ports/atmel-samd/peripherals @@ -1 +1 @@ -Subproject commit 0f5f1522d09c8fa7d858edec484a994c21c59668 +Subproject commit 6b531fc923d9f02b14bd731a5f584ddf716e8773 diff --git a/ports/cxd56/spresense-exported-sdk b/ports/cxd56/spresense-exported-sdk index c991d439f..7f6568c7f 160000 --- a/ports/cxd56/spresense-exported-sdk +++ b/ports/cxd56/spresense-exported-sdk @@ -1 +1 @@ -Subproject commit c991d439fac9c23cfcac0da16fe8055f818d40a4 +Subproject commit 7f6568c7f4898cdb24a2f06040784a836050686e diff --git a/ports/esp32s2/esp-idf b/ports/esp32s2/esp-idf index 160ba4924..0daf6e0e4 160000 --- a/ports/esp32s2/esp-idf +++ b/ports/esp32s2/esp-idf @@ -1 +1 @@ -Subproject commit 160ba4924d8b588e718f76e3a0d0e92c11052fa3 +Subproject commit 0daf6e0e41f95d22d193d08941a00df9525bc405 diff --git a/ports/stm/st_driver b/ports/stm/st_driver index 190083475..3fc2e0f3d 160000 --- a/ports/stm/st_driver +++ b/ports/stm/st_driver @@ -1 +1 @@ -Subproject commit 1900834751fd6754457874b8c971690bab33e0a7 +Subproject commit 3fc2e0f3db155b33177bb0705e0dd65cadb58412 diff --git a/shared-bindings/_typing/__init__ 2.pyi b/shared-bindings/_typing/__init__ 2.pyi new file mode 100644 index 000000000..48e68a8d5 --- /dev/null +++ b/shared-bindings/_typing/__init__ 2.pyi @@ -0,0 +1,54 @@ +"""Types for the C-level protocols""" + +from typing import Union + +import array +import audiocore +import audiomixer +import audiomp3 +import rgbmatrix +import ulab + +ReadableBuffer = Union[ + bytes, bytearray, memoryview, array.array, ulab.array, rgbmatrix.RGBMatrix +] +"""Classes that implement the readable buffer protocol + + - `bytes` + - `bytearray` + - `memoryview` + - `array.array` + - `ulab.array` + - `rgbmatrix.RGBMatrix` +""" + +WriteableBuffer = Union[ + bytearray, memoryview, array.array, ulab.array, rgbmatrix.RGBMatrix +] +"""Classes that implement the writeable buffer protocol + + - `bytearray` + - `memoryview` + - `array.array` + - `ulab.array` + - `rgbmatrix.RGBMatrix` +""" + +AudioSample = Union[ + audiocore.WaveFile, audiocore.RawSample, audiomixer.Mixer, audiomp3.MP3Decoder +] +"""Classes that implement the audiosample protocol + + - `audiocore.WaveFile` + - `audiocore.RawSample` + - `audiomixer.Mixer` + - `audiomp3.MP3Decoder` + + You can play these back with `audioio.AudioOut`, `audiobusio.I2SOut` or `audiopwmio.PWMAudioOut`. +""" + +FrameBuffer = Union[rgbmatrix.RGBMatrix] +"""Classes that implement the framebuffer protocol + + - `rgbmatrix.RGBMatrix` +""" diff --git a/shared-bindings/gnss/GNSS 2.c b/shared-bindings/gnss/GNSS 2.c new file mode 100644 index 000000000..087c35395 --- /dev/null +++ b/shared-bindings/gnss/GNSS 2.c @@ -0,0 +1,205 @@ +// SPDX-FileCopyrightText: Sony Semiconductor Solutions Corporation +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/gnss/GNSS.h" +#include "shared-bindings/time/__init__.h" +#include "shared-bindings/util.h" + +#include "py/objproperty.h" +#include "py/runtime.h" + +//| class GNSS: +//| """Get updated positioning information from Global Navigation Satellite System (GNSS) +//| +//| Usage:: +//| +//| import gnss +//| import time +//| +//| nav = gnss.GNSS([gnss.SatelliteSystem.GPS, gnss.SatelliteSystem.GLONASS]) +//| last_print = time.monotonic() +//| while True: +//| nav.update() +//| current = time.monotonic() +//| if current - last_print >= 1.0: +//| last_print = current +//| if nav.fix is gnss.PositionFix.INVALID: +//| print("Waiting for fix...") +//| continue +//| print("Latitude: {0:.6f} degrees".format(nav.latitude)) +//| print("Longitude: {0:.6f} degrees".format(nav.longitude))""" +//| + +//| def __init__(self, system: Union[SatelliteSystem, List[SatelliteSystem]]) -> None: +//| """Turn on the GNSS. +//| +//| :param system: satellite system to use""" +//| ... +//| +STATIC mp_obj_t gnss_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + gnss_obj_t *self = m_new_obj(gnss_obj_t); + self->base.type = &gnss_type; + enum { ARG_system }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_system, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + unsigned long selection = 0; + if (MP_OBJ_IS_TYPE(args[ARG_system].u_obj, &gnss_satellitesystem_type)) { + selection |= gnss_satellitesystem_obj_to_type(args[ARG_system].u_obj); + } else if (MP_OBJ_IS_TYPE(args[ARG_system].u_obj, &mp_type_list)) { + size_t systems_size = 0; + mp_obj_t *systems; + mp_obj_list_get(args[ARG_system].u_obj, &systems_size, &systems); + for (size_t i = 0; i < systems_size; ++i) { + if (!MP_OBJ_IS_TYPE(systems[i], &gnss_satellitesystem_type)) { + mp_raise_TypeError(translate("System entry must be gnss.SatelliteSystem")); + } + selection |= gnss_satellitesystem_obj_to_type(systems[i]); + } + } else { + mp_raise_TypeError(translate("System entry must be gnss.SatelliteSystem")); + } + + common_hal_gnss_construct(self, selection); + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Turn off the GNSS.""" +//| ... +//| +STATIC mp_obj_t gnss_obj_deinit(mp_obj_t self_in) { + gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_gnss_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(gnss_deinit_obj, gnss_obj_deinit); + +STATIC void check_for_deinit(gnss_obj_t *self) { + if (common_hal_gnss_deinited(self)) { + raise_deinited_error(); + } +} + +//| def update(self) -> None: +//| """Update GNSS positioning information.""" +//| ... +//| +STATIC mp_obj_t gnss_obj_update(mp_obj_t self_in) { + gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + common_hal_gnss_update(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(gnss_update_obj, gnss_obj_update); + +//| latitude: float +//| """Latitude of current position in degrees (float).""" +//| +STATIC mp_obj_t gnss_obj_get_latitude(mp_obj_t self_in) { + gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_float(common_hal_gnss_get_latitude(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(gnss_get_latitude_obj, gnss_obj_get_latitude); + +const mp_obj_property_t gnss_latitude_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&gnss_get_latitude_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| longitude: float +//| """Longitude of current position in degrees (float).""" +//| +STATIC mp_obj_t gnss_obj_get_longitude(mp_obj_t self_in) { + gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_float(common_hal_gnss_get_longitude(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(gnss_get_longitude_obj, gnss_obj_get_longitude); + +const mp_obj_property_t gnss_longitude_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&gnss_get_longitude_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| altitude: float +//| """Altitude of current position in meters (float).""" +//| +STATIC mp_obj_t gnss_obj_get_altitude(mp_obj_t self_in) { + gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_float(common_hal_gnss_get_altitude(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(gnss_get_altitude_obj, gnss_obj_get_altitude); + +const mp_obj_property_t gnss_altitude_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&gnss_get_altitude_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| timestamp: time.struct_time +//| """Time when the position data was updated.""" +//| +STATIC mp_obj_t gnss_obj_get_timestamp(mp_obj_t self_in) { + gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + timeutils_struct_time_t tm; + common_hal_gnss_get_timestamp(self, &tm); + return struct_time_from_tm(&tm); +} +MP_DEFINE_CONST_FUN_OBJ_1(gnss_get_timestamp_obj, gnss_obj_get_timestamp); + +const mp_obj_property_t gnss_timestamp_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&gnss_get_timestamp_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| fix: PositionFix +//| """Fix mode.""" +//| +STATIC mp_obj_t gnss_obj_get_fix(mp_obj_t self_in) { + gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return gnss_positionfix_type_to_obj(common_hal_gnss_get_fix(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(gnss_get_fix_obj, gnss_obj_get_fix); + +const mp_obj_property_t gnss_fix_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&gnss_get_fix_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t gnss_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&gnss_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&gnss_update_obj) }, + + { MP_ROM_QSTR(MP_QSTR_latitude), MP_ROM_PTR(&gnss_latitude_obj) }, + { MP_ROM_QSTR(MP_QSTR_longitude), MP_ROM_PTR(&gnss_longitude_obj) }, + { MP_ROM_QSTR(MP_QSTR_altitude), MP_ROM_PTR(&gnss_altitude_obj) }, + { MP_ROM_QSTR(MP_QSTR_timestamp), MP_ROM_PTR(&gnss_timestamp_obj) }, + { MP_ROM_QSTR(MP_QSTR_fix), MP_ROM_PTR(&gnss_fix_obj) } +}; +STATIC MP_DEFINE_CONST_DICT(gnss_locals_dict, gnss_locals_dict_table); + +const mp_obj_type_t gnss_type = { + { &mp_type_type }, + .name = MP_QSTR_GNSS, + .make_new = gnss_make_new, + .locals_dict = (mp_obj_dict_t*)&gnss_locals_dict, +}; diff --git a/shared-bindings/gnss/GNSS 2.h b/shared-bindings/gnss/GNSS 2.h new file mode 100644 index 000000000..60069a90a --- /dev/null +++ b/shared-bindings/gnss/GNSS 2.h @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: Sony Semiconductor Solutions Corporation +// +// SPDX-License-Identifier: MIT + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_GNSS_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_GNSS_H + +#include "common-hal/gnss/GNSS.h" +#include "shared-bindings/gnss/SatelliteSystem.h" +#include "shared-bindings/gnss/PositionFix.h" + +#include "lib/timeutils/timeutils.h" + +extern const mp_obj_type_t gnss_type; + +void common_hal_gnss_construct(gnss_obj_t *self, unsigned long selection); +void common_hal_gnss_deinit(gnss_obj_t *self); +bool common_hal_gnss_deinited(gnss_obj_t *self); +void common_hal_gnss_update(gnss_obj_t *self); + +mp_float_t common_hal_gnss_get_latitude(gnss_obj_t *self); +mp_float_t common_hal_gnss_get_longitude(gnss_obj_t *self); +mp_float_t common_hal_gnss_get_altitude(gnss_obj_t *self); +void common_hal_gnss_get_timestamp(gnss_obj_t *self, timeutils_struct_time_t *tm); +gnss_positionfix_t common_hal_gnss_get_fix(gnss_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_GNSS_H diff --git a/shared-bindings/gnss/PositionFix 2.c b/shared-bindings/gnss/PositionFix 2.c new file mode 100644 index 000000000..e60611d70 --- /dev/null +++ b/shared-bindings/gnss/PositionFix 2.c @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: Sony Semiconductor Solutions Corporation +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/gnss/PositionFix.h" + +//| class PositionFix: +//| """Position fix mode""" +//| +//| def __init__(self) -> None: +//| """Enum-like class to define the position fix mode.""" +//| +//| INVALID: PositionFix +//| """No measurement.""" +//| +//| FIX_2D: PositionFix +//| """2D fix.""" +//| +//| FIX_3D: PositionFix +//| """3D fix.""" +//| +const mp_obj_type_t gnss_positionfix_type; + +const gnss_positionfix_obj_t gnss_positionfix_invalid_obj = { + { &gnss_positionfix_type }, +}; + +const gnss_positionfix_obj_t gnss_positionfix_fix2d_obj = { + { &gnss_positionfix_type }, +}; + +const gnss_positionfix_obj_t gnss_positionfix_fix3d_obj = { + { &gnss_positionfix_type }, +}; + +gnss_positionfix_t gnss_positionfix_obj_to_type(mp_obj_t obj) { + gnss_positionfix_t posfix = POSITIONFIX_INVALID; + if (obj == MP_ROM_PTR(&gnss_positionfix_fix2d_obj)) { + posfix = POSITIONFIX_2D; + } else if (obj == MP_ROM_PTR(&gnss_positionfix_fix3d_obj)) { + posfix = POSITIONFIX_3D; + } + return posfix; +} + +mp_obj_t gnss_positionfix_type_to_obj(gnss_positionfix_t posfix) { + switch (posfix) { + case POSITIONFIX_2D: + return (mp_obj_t)MP_ROM_PTR(&gnss_positionfix_fix2d_obj); + case POSITIONFIX_3D: + return (mp_obj_t)MP_ROM_PTR(&gnss_positionfix_fix3d_obj); + case POSITIONFIX_INVALID: + default: + return (mp_obj_t)MP_ROM_PTR(&gnss_positionfix_invalid_obj); + } +} + +STATIC const mp_rom_map_elem_t gnss_positionfix_locals_dict_table[] = { + {MP_ROM_QSTR(MP_QSTR_INVALID), MP_ROM_PTR(&gnss_positionfix_invalid_obj)}, + {MP_ROM_QSTR(MP_QSTR_FIX_2D), MP_ROM_PTR(&gnss_positionfix_fix2d_obj)}, + {MP_ROM_QSTR(MP_QSTR_FIX_3D), MP_ROM_PTR(&gnss_positionfix_fix3d_obj)}, +}; +STATIC MP_DEFINE_CONST_DICT(gnss_positionfix_locals_dict, gnss_positionfix_locals_dict_table); + +STATIC void gnss_positionfix_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr posfix = MP_QSTR_INVALID; + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&gnss_positionfix_fix2d_obj)) { + posfix = MP_QSTR_FIX_2D; + } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&gnss_positionfix_fix3d_obj)) { + posfix = MP_QSTR_FIX_3D; + } + mp_printf(print, "%q.%q.%q", MP_QSTR_gnss, MP_QSTR_PositionFix, posfix); +} + +const mp_obj_type_t gnss_positionfix_type = { + { &mp_type_type }, + .name = MP_QSTR_PositionFix, + .print = gnss_positionfix_print, + .locals_dict = (mp_obj_t)&gnss_positionfix_locals_dict, +}; diff --git a/shared-bindings/gnss/PositionFix 2.h b/shared-bindings/gnss/PositionFix 2.h new file mode 100644 index 000000000..34090872c --- /dev/null +++ b/shared-bindings/gnss/PositionFix 2.h @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: Sony Semiconductor Solutions Corporation +// +// SPDX-License-Identifier: MIT + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_POSITIONFIX_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_POSITIONFIX_H + +#include "py/obj.h" + +typedef enum { + POSITIONFIX_INVALID, + POSITIONFIX_2D, + POSITIONFIX_3D, +} gnss_positionfix_t; + +const mp_obj_type_t gnss_positionfix_type; + +gnss_positionfix_t gnss_positionfix_obj_to_type(mp_obj_t obj); +mp_obj_t gnss_positionfix_type_to_obj(gnss_positionfix_t mode); + +typedef struct { + mp_obj_base_t base; +} gnss_positionfix_obj_t; +extern const gnss_positionfix_obj_t gnss_positionfix_invalid_obj; +extern const gnss_positionfix_obj_t gnss_positionfix_fix2d_obj; +extern const gnss_positionfix_obj_t gnss_positionfix_fix3d_obj; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_POSITIONFIX_H diff --git a/shared-bindings/gnss/SatelliteSystem 2.c b/shared-bindings/gnss/SatelliteSystem 2.c new file mode 100644 index 000000000..7d66727b8 --- /dev/null +++ b/shared-bindings/gnss/SatelliteSystem 2.c @@ -0,0 +1,113 @@ +// SPDX-FileCopyrightText: Sony Semiconductor Solutions Corporation +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/gnss/SatelliteSystem.h" + +//| class SatelliteSystem: +//| """Satellite system type""" +//| +//| def __init__(self) -> None: +//| """Enum-like class to define the satellite system type.""" +//| +//| GPS: SatelliteSystem +//| """Global Positioning System.""" +//| +//| GLONASS: SatelliteSystem +//| """GLObal NAvigation Satellite System.""" +//| +//| SBAS: SatelliteSystem +//| """Satellite Based Augmentation System.""" +//| +//| QZSS_L1CA: SatelliteSystem +//| """Quasi-Zenith Satellite System L1C/A.""" +//| +//| QZSS_L1S: SatelliteSystem +//| """Quasi-Zenith Satellite System L1S.""" +//| +const mp_obj_type_t gnss_satellitesystem_type; + +const gnss_satellitesystem_obj_t gnss_satellitesystem_gps_obj = { + { &gnss_satellitesystem_type }, +}; + +const gnss_satellitesystem_obj_t gnss_satellitesystem_glonass_obj = { + { &gnss_satellitesystem_type }, +}; + +const gnss_satellitesystem_obj_t gnss_satellitesystem_sbas_obj = { + { &gnss_satellitesystem_type }, +}; + +const gnss_satellitesystem_obj_t gnss_satellitesystem_qzss_l1ca_obj = { + { &gnss_satellitesystem_type }, +}; + +const gnss_satellitesystem_obj_t gnss_satellitesystem_qzss_l1s_obj = { + { &gnss_satellitesystem_type }, +}; + +gnss_satellitesystem_t gnss_satellitesystem_obj_to_type(mp_obj_t obj) { + if (obj == MP_ROM_PTR(&gnss_satellitesystem_gps_obj)) { + return SATELLITESYSTEM_GPS; + } else if (obj == MP_ROM_PTR(&gnss_satellitesystem_glonass_obj)) { + return SATELLITESYSTEM_GLONASS; + } else if (obj == MP_ROM_PTR(&gnss_satellitesystem_sbas_obj)) { + return SATELLITESYSTEM_SBAS; + } else if (obj == MP_ROM_PTR(&gnss_satellitesystem_qzss_l1ca_obj)) { + return SATELLITESYSTEM_QZSS_L1CA; + } else if (obj == MP_ROM_PTR(&gnss_satellitesystem_qzss_l1s_obj)) { + return SATELLITESYSTEM_QZSS_L1S; + } + return SATELLITESYSTEM_NONE; +} + +mp_obj_t gnss_satellitesystem_type_to_obj(gnss_satellitesystem_t system) { + switch (system) { + case SATELLITESYSTEM_GPS: + return (mp_obj_t)MP_ROM_PTR(&gnss_satellitesystem_gps_obj); + case SATELLITESYSTEM_GLONASS: + return (mp_obj_t)MP_ROM_PTR(&gnss_satellitesystem_glonass_obj); + case SATELLITESYSTEM_SBAS: + return (mp_obj_t)MP_ROM_PTR(&gnss_satellitesystem_sbas_obj); + case SATELLITESYSTEM_QZSS_L1CA: + return (mp_obj_t)MP_ROM_PTR(&gnss_satellitesystem_qzss_l1ca_obj); + case SATELLITESYSTEM_QZSS_L1S: + return (mp_obj_t)MP_ROM_PTR(&gnss_satellitesystem_qzss_l1s_obj); + case SATELLITESYSTEM_NONE: + default: + return (mp_obj_t)MP_ROM_PTR(&mp_const_none_obj); + } +} + +STATIC const mp_rom_map_elem_t gnss_satellitesystem_locals_dict_table[] = { + {MP_ROM_QSTR(MP_QSTR_GPS), MP_ROM_PTR(&gnss_satellitesystem_gps_obj)}, + {MP_ROM_QSTR(MP_QSTR_GLONASS), MP_ROM_PTR(&gnss_satellitesystem_glonass_obj)}, + {MP_ROM_QSTR(MP_QSTR_SBAS), MP_ROM_PTR(&gnss_satellitesystem_sbas_obj)}, + {MP_ROM_QSTR(MP_QSTR_QZSS_L1CA), MP_ROM_PTR(&gnss_satellitesystem_qzss_l1ca_obj)}, + {MP_ROM_QSTR(MP_QSTR_QZSS_L1S), MP_ROM_PTR(&gnss_satellitesystem_qzss_l1s_obj)}, +}; +STATIC MP_DEFINE_CONST_DICT(gnss_satellitesystem_locals_dict, gnss_satellitesystem_locals_dict_table); + +STATIC void gnss_satellitesystem_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr system = MP_QSTR_None; + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&gnss_satellitesystem_gps_obj)) { + system = MP_QSTR_GPS; + } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&gnss_satellitesystem_glonass_obj)) { + system = MP_QSTR_GLONASS; + } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&gnss_satellitesystem_sbas_obj)) { + system = MP_QSTR_SBAS; + } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&gnss_satellitesystem_qzss_l1ca_obj)) { + system = MP_QSTR_QZSS_L1CA; + } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&gnss_satellitesystem_qzss_l1s_obj)) { + system = MP_QSTR_QZSS_L1S; + } + mp_printf(print, "%q.%q.%q", MP_QSTR_gnss, MP_QSTR_SatelliteSystem, system); +} + +const mp_obj_type_t gnss_satellitesystem_type = { + { &mp_type_type }, + .name = MP_QSTR_SatelliteSystem, + .print = gnss_satellitesystem_print, + .locals_dict = (mp_obj_t)&gnss_satellitesystem_locals_dict, +}; diff --git a/shared-bindings/gnss/SatelliteSystem 2.h b/shared-bindings/gnss/SatelliteSystem 2.h new file mode 100644 index 000000000..17f155002 --- /dev/null +++ b/shared-bindings/gnss/SatelliteSystem 2.h @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Sony Semiconductor Solutions Corporation +// +// SPDX-License-Identifier: MIT + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_SATELLITESYSTEM_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_SATELLITESYSTEM_H + +#include "py/obj.h" + +typedef enum { + SATELLITESYSTEM_NONE = 0, + SATELLITESYSTEM_GPS = (1U << 0), + SATELLITESYSTEM_GLONASS = (1U << 1), + SATELLITESYSTEM_SBAS = (1U << 2), + SATELLITESYSTEM_QZSS_L1CA = (1U << 3), + SATELLITESYSTEM_QZSS_L1S = (1U << 4), +} gnss_satellitesystem_t; + +const mp_obj_type_t gnss_satellitesystem_type; + +gnss_satellitesystem_t gnss_satellitesystem_obj_to_type(mp_obj_t obj); +mp_obj_t gnss_satellitesystem_type_to_obj(gnss_satellitesystem_t mode); + +typedef struct { + mp_obj_base_t base; +} gnss_satellitesystem_obj_t; +extern const gnss_satellitesystem_obj_t gnss_satellitesystem_gps_obj; +extern const gnss_satellitesystem_obj_t gnss_satellitesystem_glonass_obj; +extern const gnss_satellitesystem_obj_t gnss_satellitesystem_sbas_obj; +extern const gnss_satellitesystem_obj_t gnss_satellitesystem_qzss_l1ca_obj; +extern const gnss_satellitesystem_obj_t gnss_satellitesystem_qzss_l1s_obj; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_SATELLITESYSTEM_H diff --git a/shared-bindings/gnss/__init__ 2.c b/shared-bindings/gnss/__init__ 2.c new file mode 100644 index 000000000..4b0d312ae --- /dev/null +++ b/shared-bindings/gnss/__init__ 2.c @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Sony Semiconductor Solutions Corporation +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "shared-bindings/gnss/GNSS.h" +#include "shared-bindings/gnss/SatelliteSystem.h" +#include "shared-bindings/gnss/PositionFix.h" +#include "shared-bindings/util.h" + +//| """Global Navigation Satellite System +//| +//| The `gnss` module contains classes to control the GNSS and acquire positioning information.""" +//| +STATIC const mp_rom_map_elem_t gnss_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_gnss) }, + { MP_ROM_QSTR(MP_QSTR_GNSS), MP_ROM_PTR(&gnss_type) }, + + // Enum-like Classes. + { MP_ROM_QSTR(MP_QSTR_SatelliteSystem), MP_ROM_PTR(&gnss_satellitesystem_type) }, + { MP_ROM_QSTR(MP_QSTR_PositionFix), MP_ROM_PTR(&gnss_positionfix_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(gnss_module_globals, gnss_module_globals_table); + +const mp_obj_module_t gnss_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&gnss_module_globals, +}; diff --git a/shared-bindings/i2cperipheral/I2CPeripheral 2.c b/shared-bindings/i2cperipheral/I2CPeripheral 2.c new file mode 100644 index 000000000..b5ac861b4 --- /dev/null +++ b/shared-bindings/i2cperipheral/I2CPeripheral 2.c @@ -0,0 +1,436 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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. + */ + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/i2cperipheral/I2CPeripheral.h" +#include "shared-bindings/time/__init__.h" +#include "shared-bindings/util.h" + +#include "lib/utils/buffer_helper.h" +#include "lib/utils/context_manager_helpers.h" +#include "lib/utils/interrupt_char.h" + +#include "py/mperrno.h" +#include "py/mphal.h" +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +STATIC mp_obj_t mp_obj_new_i2cperipheral_i2c_peripheral_request(i2cperipheral_i2c_peripheral_obj_t *peripheral, uint8_t address, bool is_read, bool is_restart) { + i2cperipheral_i2c_peripheral_request_obj_t *self = m_new_obj(i2cperipheral_i2c_peripheral_request_obj_t); + self->base.type = &i2cperipheral_i2c_peripheral_request_type; + self->peripheral = peripheral; + self->address = address; + self->is_read = is_read; + self->is_restart = is_restart; + return (mp_obj_t)self; +} + +//| class I2CPeripheral: +//| """Two wire serial protocol peripheral""" +//| +//| def __init__(self, scl: microcontroller.Pin, sda: microcontroller.Pin, addresses: Sequence[int], smbus: bool = False) -> None: +//| """I2C is a two-wire protocol for communicating between devices. +//| This implements the peripheral (sensor, secondary) side. +//| +//| :param ~microcontroller.Pin scl: The clock pin +//| :param ~microcontroller.Pin sda: The data pin +//| :param addresses: The I2C addresses to respond to (how many is hw dependent). +//| :type addresses: list[int] +//| :param bool smbus: Use SMBUS timings if the hardware supports it""" +//| ... +//| +STATIC mp_obj_t i2cperipheral_i2c_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + i2cperipheral_i2c_peripheral_obj_t *self = m_new_obj(i2cperipheral_i2c_peripheral_obj_t); + self->base.type = &i2cperipheral_i2c_peripheral_type; + enum { ARG_scl, ARG_sda, ARG_addresses, ARG_smbus }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_addresses, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_smbus, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mcu_pin_obj_t* scl = validate_obj_is_free_pin(args[ARG_scl].u_obj); + const mcu_pin_obj_t* sda = validate_obj_is_free_pin(args[ARG_sda].u_obj); + + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(args[ARG_addresses].u_obj, &iter_buf); + mp_obj_t item; + uint8_t *addresses = NULL; + unsigned int i = 0; + while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + mp_int_t value; + if (!mp_obj_get_int_maybe(item, &value)) { + mp_raise_TypeError_varg(translate("can't convert %q to %q"), MP_QSTR_address, MP_QSTR_int); + } + if (value < 0x00 || value > 0x7f) { + mp_raise_ValueError(translate("address out of bounds")); + } + addresses = m_renew(uint8_t, addresses, i, i + 1); + addresses[i++] = value; + } + if (i == 0) { + mp_raise_ValueError(translate("addresses is empty")); + } + + common_hal_i2cperipheral_i2c_peripheral_construct(self, scl, sda, addresses, i, args[ARG_smbus].u_bool); + return (mp_obj_t)self; +} + +//| def deinit(self) -> None: +//| """Releases control of the underlying hardware so other classes can use it.""" +//| ... +//| +STATIC mp_obj_t i2cperipheral_i2c_peripheral_obj_deinit(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_type)); + i2cperipheral_i2c_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_i2cperipheral_i2c_peripheral_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cperipheral_i2c_peripheral_deinit_obj, i2cperipheral_i2c_peripheral_obj_deinit); + +//| def __enter__(self) -> I2CPeripheral: +//| """No-op used in Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware on context exit. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +STATIC mp_obj_t i2cperipheral_i2c_peripheral_obj___exit__(size_t n_args, const mp_obj_t *args) { + mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cperipheral_i2c_peripheral_type)); + i2cperipheral_i2c_peripheral_obj_t *self = MP_OBJ_TO_PTR(args[0]); + common_hal_i2cperipheral_i2c_peripheral_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cperipheral_i2c_peripheral___exit___obj, 4, 4, i2cperipheral_i2c_peripheral_obj___exit__); + +//| def request(self, timeout: float = -1) -> I2CPeripheralRequest: +//| """Wait for an I2C request. +//| +//| :param float timeout: Timeout in seconds. Zero means wait forever, a negative value means check once +//| :return: I2C Slave Request or None if timeout=-1 and there's no request +//| :rtype: ~i2cperipheral.I2CPeripheralRequest""" +//| +STATIC mp_obj_t i2cperipheral_i2c_peripheral_request(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cperipheral_i2c_peripheral_type)); + i2cperipheral_i2c_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + if(common_hal_i2cperipheral_i2c_peripheral_deinited(self)) { + raise_deinited_error(); + } + enum { ARG_timeout }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + #if MICROPY_PY_BUILTINS_FLOAT + float f = mp_obj_get_float(args[ARG_timeout].u_obj) * 1000; + int timeout_ms = (int)f; + #else + int timeout_ms = mp_obj_get_int(args[ARG_timeout].u_obj) * 1000; + #endif + + bool forever = false; + uint64_t timeout_end = 0; + if (timeout_ms == 0) { + forever = true; + } else if (timeout_ms > 0) { + timeout_end = common_hal_time_monotonic() + timeout_ms; + } + + int last_error = 0; + + do { + uint8_t address; + bool is_read; + bool is_restart; + + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + return mp_const_none; + } + + int status = common_hal_i2cperipheral_i2c_peripheral_is_addressed(self, &address, &is_read, &is_restart); + if (status < 0) { + // On error try one more time before bailing out + if (last_error) { + mp_raise_OSError(last_error); + } + last_error = -status; + mp_hal_delay_ms(10); + continue; + } + + last_error = 0; + + if (status == 0) { + mp_hal_delay_us(10); + continue; + } + + return mp_obj_new_i2cperipheral_i2c_peripheral_request(self, address, is_read, is_restart); + } while (forever || common_hal_time_monotonic() < timeout_end); + + if (timeout_ms > 0) { + mp_raise_OSError(MP_ETIMEDOUT); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(i2cperipheral_i2c_peripheral_request_obj, 1, i2cperipheral_i2c_peripheral_request); + +STATIC const mp_rom_map_elem_t i2cperipheral_i2c_peripheral_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2cperipheral_i2c_peripheral___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_request), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_obj) }, + +}; + +STATIC MP_DEFINE_CONST_DICT(i2cperipheral_i2c_peripheral_locals_dict, i2cperipheral_i2c_peripheral_locals_dict_table); + +const mp_obj_type_t i2cperipheral_i2c_peripheral_type = { + { &mp_type_type }, + .name = MP_QSTR_I2CPeripheral, + .make_new = i2cperipheral_i2c_peripheral_make_new, + .locals_dict = (mp_obj_dict_t*)&i2cperipheral_i2c_peripheral_locals_dict, +}; + +//| class I2CPeripheralRequest: +//| +//| def __init__(self, peripheral: i2cperipheral.I2CPeripheral, address: int, is_read: bool, is_restart: bool) -> None: +//| """Information about an I2C transfer request +//| This cannot be instantiated directly, but is returned by :py:meth:`I2CPeripheral.request`. +//| +//| :param peripheral: The I2CPeripheral object receiving this request +//| :param address: I2C address +//| :param is_read: True if the main peripheral is requesting data +//| :param is_restart: Repeated Start Condition""" +//| +STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 4, 4, false); + return mp_obj_new_i2cperipheral_i2c_peripheral_request(args[0], mp_obj_get_int(args[1]), mp_obj_is_true(args[2]), mp_obj_is_true(args[3])); +} + +//| def __enter__(self) -> I2CPeripheralRequest: +//| """No-op used in Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Close the request.""" +//| ... +//| +STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_obj___exit__(size_t n_args, const mp_obj_t *args) { + mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cperipheral_i2c_peripheral_request_type)); + i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(args[0]); + common_hal_i2cperipheral_i2c_peripheral_close(self->peripheral); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cperipheral_i2c_peripheral_request___exit___obj, 4, 4, i2cperipheral_i2c_peripheral_request_obj___exit__); + +//| address: int +//| """The I2C address of the request.""" +//| +STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_get_address(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); + i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int(self->address); +} +MP_DEFINE_CONST_PROP_GET(i2cperipheral_i2c_peripheral_request_address_obj, i2cperipheral_i2c_peripheral_request_get_address); + +//| is_read: bool +//| """The I2C main controller is reading from this peripheral.""" +//| +STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_get_is_read(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); + i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(self->is_read); +} +MP_DEFINE_CONST_PROP_GET(i2cperipheral_i2c_peripheral_request_is_read_obj, i2cperipheral_i2c_peripheral_request_get_is_read); + +//| is_restart: bool +//| """Is Repeated Start Condition.""" +//| +STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_get_is_restart(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); + i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(self->is_restart); +} +MP_DEFINE_CONST_PROP_GET(i2cperipheral_i2c_peripheral_request_is_restart_obj, i2cperipheral_i2c_peripheral_request_get_is_restart); + +//| def read(self, n: int = -1, ack: bool = True) -> bytearray: +//| """Read data. +//| If ack=False, the caller is responsible for calling :py:meth:`I2CPeripheralRequest.ack`. +//| +//| :param n: Number of bytes to read (negative means all) +//| :param ack: Whether or not to send an ACK after the n'th byte +//| :return: Bytes read""" +//| ... +//| +STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cperipheral_i2c_peripheral_request_type)); + i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + enum { ARG_n, ARG_ack }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_n, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_ack, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + if (self->is_read) { + mp_raise_OSError(MP_EACCES); + } + + int n = args[ARG_n].u_int; + if (n == 0) { + return mp_obj_new_bytearray(0, NULL); + } + bool ack = args[ARG_ack].u_bool; + + int i = 0; + uint8_t *buffer = NULL; + uint64_t timeout_end = common_hal_time_monotonic() + 10 * 1000; + while (common_hal_time_monotonic() < timeout_end) { + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + break; + } + + uint8_t data; + int num = common_hal_i2cperipheral_i2c_peripheral_read_byte(self->peripheral, &data); + if (num == 0) { + break; + } + + buffer = m_renew(uint8_t, buffer, i, i + 1); + buffer[i++] = data; + if (i == n) { + if (ack) { + common_hal_i2cperipheral_i2c_peripheral_ack(self->peripheral, true); + } + break; + } + common_hal_i2cperipheral_i2c_peripheral_ack(self->peripheral, true); + } + + return mp_obj_new_bytearray(i, buffer); +} +MP_DEFINE_CONST_FUN_OBJ_KW(i2cperipheral_i2c_peripheral_request_read_obj, 1, i2cperipheral_i2c_peripheral_request_read); + +//| def write(self, buffer: ReadableBuffer) -> int: +//| """Write the data contained in buffer. +//| +//| :param ~_typing.ReadableBuffer buffer: Write out the data in this buffer +//| :return: Number of bytes written""" +//| ... +//| +STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_write(mp_obj_t self_in, mp_obj_t buf_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); + i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (!self->is_read) { + mp_raise_OSError(MP_EACCES); + } + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); + + for (size_t i = 0; i < bufinfo.len; i++) { + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + break; + } + + int num = common_hal_i2cperipheral_i2c_peripheral_write_byte(self->peripheral, ((uint8_t *)(bufinfo.buf))[i]); + if (num == 0) { + return mp_obj_new_int(i); + } + } + + return mp_obj_new_int(bufinfo.len); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(i2cperipheral_i2c_peripheral_request_write_obj, i2cperipheral_i2c_peripheral_request_write); + +//| def ack(self, ack: bool = True) -> None: +//| """Acknowledge or Not Acknowledge last byte received. +//| Use together with :py:meth:`I2CPeripheralRequest.read` ack=False. +//| +//| :param ack: Whether to send an ACK or NACK""" +//| ... +//| +STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_ack(uint n_args, const mp_obj_t *args) { + mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cperipheral_i2c_peripheral_request_type)); + i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(args[0]); + bool ack = (n_args == 1) ? true : mp_obj_is_true(args[1]); + + if (self->is_read) { + mp_raise_OSError(MP_EACCES); + } + + common_hal_i2cperipheral_i2c_peripheral_ack(self->peripheral, ack); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cperipheral_i2c_peripheral_request_ack_obj, 1, 2, i2cperipheral_i2c_peripheral_request_ack); + +STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_close(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); + i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_i2cperipheral_i2c_peripheral_close(self->peripheral); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(i2cperipheral_i2c_peripheral_request_close_obj, i2cperipheral_i2c_peripheral_request_close); + +STATIC const mp_rom_map_elem_t i2cperipheral_i2c_peripheral_request_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_address_obj) }, + { MP_ROM_QSTR(MP_QSTR_is_read), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_is_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_is_restart), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_is_restart_obj) }, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_ack), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_ack_obj) }, + { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_close_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(i2cperipheral_i2c_peripheral_request_locals_dict, i2cperipheral_i2c_peripheral_request_locals_dict_table); + +const mp_obj_type_t i2cperipheral_i2c_peripheral_request_type = { + { &mp_type_type }, + .name = MP_QSTR_I2CPeripheralRequest, + .make_new = i2cperipheral_i2c_peripheral_request_make_new, + .locals_dict = (mp_obj_dict_t*)&i2cperipheral_i2c_peripheral_request_locals_dict, +}; diff --git a/shared-bindings/i2cperipheral/I2CPeripheral 2.h b/shared-bindings/i2cperipheral/I2CPeripheral 2.h new file mode 100644 index 000000000..3035cfbfe --- /dev/null +++ b/shared-bindings/i2cperipheral/I2CPeripheral 2.h @@ -0,0 +1,60 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H + +#include "py/obj.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/i2cperipheral/I2CPeripheral.h" + +typedef struct { + mp_obj_base_t base; + i2cperipheral_i2c_peripheral_obj_t *peripheral; + uint16_t address; + bool is_read; + bool is_restart; +} i2cperipheral_i2c_peripheral_request_obj_t; + +extern const mp_obj_type_t i2cperipheral_i2c_peripheral_request_type; + +extern const mp_obj_type_t i2cperipheral_i2c_peripheral_type; + +extern void common_hal_i2cperipheral_i2c_peripheral_construct(i2cperipheral_i2c_peripheral_obj_t *self, + const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, + uint8_t *addresses, unsigned int num_addresses, bool smbus); +extern void common_hal_i2cperipheral_i2c_peripheral_deinit(i2cperipheral_i2c_peripheral_obj_t *self); +extern bool common_hal_i2cperipheral_i2c_peripheral_deinited(i2cperipheral_i2c_peripheral_obj_t *self); + +extern int common_hal_i2cperipheral_i2c_peripheral_is_addressed(i2cperipheral_i2c_peripheral_obj_t *self, + uint8_t *address, bool *is_read, bool *is_restart); +extern int common_hal_i2cperipheral_i2c_peripheral_read_byte(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t *data); +extern int common_hal_i2cperipheral_i2c_peripheral_write_byte(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t data); +extern void common_hal_i2cperipheral_i2c_peripheral_ack(i2cperipheral_i2c_peripheral_obj_t *self, bool ack); +extern void common_hal_i2cperipheral_i2c_peripheral_close(i2cperipheral_i2c_peripheral_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H diff --git a/shared-bindings/i2cperipheral/__init__ 2.c b/shared-bindings/i2cperipheral/__init__ 2.c new file mode 100644 index 000000000..e2cb8509d --- /dev/null +++ b/shared-bindings/i2cperipheral/__init__ 2.c @@ -0,0 +1,106 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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. + */ + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +//#include "shared-bindings/i2cperipheral/__init__.h" +#include "shared-bindings/i2cperipheral/I2CPeripheral.h" + +#include "py/runtime.h" + +//| """Two wire serial protocol peripheral +//| +//| The `i2cperipheral` module contains classes to support an I2C peripheral. +//| +//| Example emulating a peripheral with 2 addresses (read and write):: +//| +//| import board +//| from i2cperipheral import I2CPeripheral +//| +//| regs = [0] * 16 +//| index = 0 +//| +//| with I2CPeripheral(board.SCL, board.SDA, (0x40, 0x41)) as device: +//| while True: +//| r = device.request() +//| if not r: +//| # Maybe do some housekeeping +//| continue +//| with r: # Closes the transfer if necessary by sending a NACK or feeding dummy bytes +//| if r.address == 0x40: +//| if not r.is_read: # Main write which is Selected read +//| b = r.read(1) +//| if not b or b[0] > 15: +//| break +//| index = b[0] +//| b = r.read(1) +//| if b: +//| regs[index] = b[0] +//| elif r.is_restart: # Combined transfer: This is the Main read message +//| n = r.write(bytes([regs[index]])) +//| #else: +//| # A read transfer is not supported in this example +//| # If the microcontroller tries, it will get 0xff byte(s) by the ctx manager (r.close()) +//| elif r.address == 0x41: +//| if not r.is_read: +//| b = r.read(1) +//| if b and b[0] == 0xde: +//| # do something +//| pass +//| +//| This example sets up an I2C device that can be accessed from Linux like this:: +//| +//| $ i2cget -y 1 0x40 0x01 +//| 0x00 +//| $ i2cset -y 1 0x40 0x01 0xaa +//| $ i2cget -y 1 0x40 0x01 +//| 0xaa +//| +//| .. warning:: +//| I2CPeripheral makes use of clock stretching in order to slow down +//| the host. +//| Make sure the I2C host supports this. +//| +//| Raspberry Pi in particular does not support this with its I2C hw block. +//| This can be worked around by using the ``i2c-gpio`` bit banging driver. +//| Since the RPi firmware uses the hw i2c, it's not possible to emulate a HAT eeprom.""" +//| + +STATIC const mp_rom_map_elem_t i2cperipheral_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_i2cperipheral) }, + { MP_ROM_QSTR(MP_QSTR_I2CPeripheral), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(i2cperipheral_module_globals, i2cperipheral_module_globals_table); + +const mp_obj_module_t i2cperipheral_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&i2cperipheral_module_globals, +}; diff --git a/shared-bindings/memorymonitor/AllocationAlarm 2.c b/shared-bindings/memorymonitor/AllocationAlarm 2.c new file mode 100644 index 000000000..7de8c1287 --- /dev/null +++ b/shared-bindings/memorymonitor/AllocationAlarm 2.c @@ -0,0 +1,137 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#include + +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" +#include "shared-bindings/memorymonitor/AllocationAlarm.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| class AllocationAlarm: +//| +//| def __init__(self, *, minimum_block_count: int = 1) -> None: +//| """Throw an exception when an allocation of ``minimum_block_count`` or more blocks +//| occurs while active. +//| +//| Track allocations:: +//| +//| import memorymonitor +//| +//| aa = memorymonitor.AllocationAlarm(minimum_block_count=2) +//| x = 2 +//| # Should not allocate any blocks. +//| with aa: +//| x = 5 +//| +//| # Should throw an exception when allocating storage for the 20 bytes. +//| with aa: +//| x = bytearray(20) +//| +//| """ +//| ... +//| +STATIC mp_obj_t memorymonitor_allocationalarm_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_minimum_block_count }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_minimum_block_count, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + mp_int_t minimum_block_count = args[ARG_minimum_block_count].u_int; + if (minimum_block_count < 1) { + mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_minimum_block_count); + } + + memorymonitor_allocationalarm_obj_t *self = m_new_obj(memorymonitor_allocationalarm_obj_t); + self->base.type = &memorymonitor_allocationalarm_type; + + common_hal_memorymonitor_allocationalarm_construct(self, minimum_block_count); + + return MP_OBJ_FROM_PTR(self); +} + +//| def ignore(self, count: int) -> AllocationAlarm: +//| """Sets the number of applicable allocations to ignore before raising the exception. +//| Automatically set back to zero at context exit. +//| +//| Use it within a ``with`` block:: +//| +//| # Will not alarm because the bytearray allocation will be ignored. +//| with aa.ignore(2): +//| x = bytearray(20) +//| """ +//| ... +//| +STATIC mp_obj_t memorymonitor_allocationalarm_obj_ignore(mp_obj_t self_in, mp_obj_t count_obj) { + mp_int_t count = mp_obj_get_int(count_obj); + if (count < 0) { + mp_raise_ValueError_varg(translate("%q must be >= 0"), MP_QSTR_count); + } + common_hal_memorymonitor_allocationalarm_set_ignore(self_in, count); + return self_in; +} +MP_DEFINE_CONST_FUN_OBJ_2(memorymonitor_allocationalarm_ignore_obj, memorymonitor_allocationalarm_obj_ignore); + +//| def __enter__(self) -> AllocationAlarm: +//| """Enables the alarm.""" +//| ... +//| +STATIC mp_obj_t memorymonitor_allocationalarm_obj___enter__(mp_obj_t self_in) { + common_hal_memorymonitor_allocationalarm_resume(self_in); + return self_in; +} +MP_DEFINE_CONST_FUN_OBJ_1(memorymonitor_allocationalarm___enter___obj, memorymonitor_allocationalarm_obj___enter__); + +//| def __exit__(self) -> None: +//| """Automatically disables the allocation alarm when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +STATIC mp_obj_t memorymonitor_allocationalarm_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_memorymonitor_allocationalarm_set_ignore(args[0], 0); + common_hal_memorymonitor_allocationalarm_pause(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(memorymonitor_allocationalarm___exit___obj, 4, 4, memorymonitor_allocationalarm_obj___exit__); + +STATIC const mp_rom_map_elem_t memorymonitor_allocationalarm_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_ignore), MP_ROM_PTR(&memorymonitor_allocationalarm_ignore_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&memorymonitor_allocationalarm___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&memorymonitor_allocationalarm___exit___obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(memorymonitor_allocationalarm_locals_dict, memorymonitor_allocationalarm_locals_dict_table); + +const mp_obj_type_t memorymonitor_allocationalarm_type = { + { &mp_type_type }, + .name = MP_QSTR_AllocationAlarm, + .make_new = memorymonitor_allocationalarm_make_new, + .locals_dict = (mp_obj_dict_t*)&memorymonitor_allocationalarm_locals_dict, +}; diff --git a/shared-bindings/memorymonitor/AllocationAlarm 2.h b/shared-bindings/memorymonitor/AllocationAlarm 2.h new file mode 100644 index 000000000..304b9c5a7 --- /dev/null +++ b/shared-bindings/memorymonitor/AllocationAlarm 2.h @@ -0,0 +1,39 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONALARM_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONALARM_H + +#include "shared-module/memorymonitor/AllocationAlarm.h" + +extern const mp_obj_type_t memorymonitor_allocationalarm_type; + +void common_hal_memorymonitor_allocationalarm_construct(memorymonitor_allocationalarm_obj_t* self, size_t minimum_block_count); +void common_hal_memorymonitor_allocationalarm_pause(memorymonitor_allocationalarm_obj_t* self); +void common_hal_memorymonitor_allocationalarm_resume(memorymonitor_allocationalarm_obj_t* self); +void common_hal_memorymonitor_allocationalarm_set_ignore(memorymonitor_allocationalarm_obj_t* self, mp_int_t count); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONALARM_H diff --git a/shared-bindings/memorymonitor/AllocationSize 2.c b/shared-bindings/memorymonitor/AllocationSize 2.c new file mode 100644 index 000000000..b35bae360 --- /dev/null +++ b/shared-bindings/memorymonitor/AllocationSize 2.c @@ -0,0 +1,183 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#include + +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" +#include "shared-bindings/memorymonitor/AllocationSize.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| class AllocationSize: +//| +//| def __init__(self) -> None: +//| """Tracks the number of allocations in power of two buckets. +//| +//| It will have 16 16-bit buckets to track allocation counts. It is total allocations +//| meaning frees are ignored. Reallocated memory is counted twice, at allocation and when +//| reallocated with the larger size. +//| +//| The buckets are measured in terms of blocks which is the finest granularity of the heap. +//| This means bucket 0 will count all allocations less than or equal to the number of bytes +//| per block, typically 16. Bucket 2 will be less than or equal to 4 blocks. See +//| `bytes_per_block` to convert blocks to bytes. +//| +//| Multiple AllocationSizes can be used to track different code boundaries. +//| +//| Track allocations:: +//| +//| import memorymonitor +//| +//| mm = memorymonitor.AllocationSize() +//| with mm: +//| print("hello world" * 3) +//| +//| for bucket, count in enumerate(mm): +//| print("<", 2 ** bucket, count) +//| +//| """ +//| ... +//| +STATIC mp_obj_t memorymonitor_allocationsize_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + memorymonitor_allocationsize_obj_t *self = m_new_obj(memorymonitor_allocationsize_obj_t); + self->base.type = &memorymonitor_allocationsize_type; + + common_hal_memorymonitor_allocationsize_construct(self); + + return MP_OBJ_FROM_PTR(self); +} + +//| def __enter__(self) -> AllocationSize: +//| """Clears counts and resumes tracking.""" +//| ... +//| +STATIC mp_obj_t memorymonitor_allocationsize_obj___enter__(mp_obj_t self_in) { + common_hal_memorymonitor_allocationsize_clear(self_in); + common_hal_memorymonitor_allocationsize_resume(self_in); + return self_in; +} +MP_DEFINE_CONST_FUN_OBJ_1(memorymonitor_allocationsize___enter___obj, memorymonitor_allocationsize_obj___enter__); + +//| def __exit__(self) -> None: +//| """Automatically pauses allocation tracking when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +STATIC mp_obj_t memorymonitor_allocationsize_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_memorymonitor_allocationsize_pause(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(memorymonitor_allocationsize___exit___obj, 4, 4, memorymonitor_allocationsize_obj___exit__); + +//| bytes_per_block: int +//| """Number of bytes per block""" +//| +STATIC mp_obj_t memorymonitor_allocationsize_obj_get_bytes_per_block(mp_obj_t self_in) { + memorymonitor_allocationsize_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_NEW_SMALL_INT(common_hal_memorymonitor_allocationsize_get_bytes_per_block(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(memorymonitor_allocationsize_get_bytes_per_block_obj, memorymonitor_allocationsize_obj_get_bytes_per_block); + +const mp_obj_property_t memorymonitor_allocationsize_bytes_per_block_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&memorymonitor_allocationsize_get_bytes_per_block_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| def __len__(self) -> int: +//| """Returns the number of allocation buckets. +//| +//| This allows you to:: +//| +//| mm = memorymonitor.AllocationSize() +//| print(len(mm))""" +//| ... +//| +STATIC mp_obj_t memorymonitor_allocationsize_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + memorymonitor_allocationsize_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint16_t len = common_hal_memorymonitor_allocationsize_get_len(self); + switch (op) { + case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); + case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len); + default: return MP_OBJ_NULL; // op not supported + } +} + +//| def __getitem__(self, index: int) -> Optional[int]: +//| """Returns the allocation count for the given bucket. +//| +//| This allows you to:: +//| +//| mm = memorymonitor.AllocationSize() +//| print(mm[0])""" +//| ... +//| +STATIC mp_obj_t memorymonitor_allocationsize_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { + if (value == mp_const_none) { + // delete item + mp_raise_AttributeError(translate("Cannot delete values")); + } else { + memorymonitor_allocationsize_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { + mp_raise_NotImplementedError(translate("Slices not supported")); + } else { + size_t index = mp_get_index(&memorymonitor_allocationsize_type, common_hal_memorymonitor_allocationsize_get_len(self), index_obj, false); + if (value == MP_OBJ_SENTINEL) { + // load + return MP_OBJ_NEW_SMALL_INT(common_hal_memorymonitor_allocationsize_get_item(self, index)); + } else { + mp_raise_AttributeError(translate("Read-only")); + } + } + } + return mp_const_none; +} + +STATIC const mp_rom_map_elem_t memorymonitor_allocationsize_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&memorymonitor_allocationsize___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&memorymonitor_allocationsize___exit___obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_bytes_per_block), MP_ROM_PTR(&memorymonitor_allocationsize_bytes_per_block_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(memorymonitor_allocationsize_locals_dict, memorymonitor_allocationsize_locals_dict_table); + +const mp_obj_type_t memorymonitor_allocationsize_type = { + { &mp_type_type }, + .name = MP_QSTR_AllocationSize, + .make_new = memorymonitor_allocationsize_make_new, + .subscr = memorymonitor_allocationsize_subscr, + .unary_op = memorymonitor_allocationsize_unary_op, + .getiter = mp_obj_new_generic_iterator, + .locals_dict = (mp_obj_dict_t*)&memorymonitor_allocationsize_locals_dict, +}; diff --git a/shared-bindings/memorymonitor/AllocationSize 2.h b/shared-bindings/memorymonitor/AllocationSize 2.h new file mode 100644 index 000000000..bcd9514bf --- /dev/null +++ b/shared-bindings/memorymonitor/AllocationSize 2.h @@ -0,0 +1,42 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONSIZE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONSIZE_H + +#include "shared-module/memorymonitor/AllocationSize.h" + +extern const mp_obj_type_t memorymonitor_allocationsize_type; + +extern void common_hal_memorymonitor_allocationsize_construct(memorymonitor_allocationsize_obj_t* self); +extern void common_hal_memorymonitor_allocationsize_pause(memorymonitor_allocationsize_obj_t* self); +extern void common_hal_memorymonitor_allocationsize_resume(memorymonitor_allocationsize_obj_t* self); +extern void common_hal_memorymonitor_allocationsize_clear(memorymonitor_allocationsize_obj_t* self); +extern size_t common_hal_memorymonitor_allocationsize_get_bytes_per_block(memorymonitor_allocationsize_obj_t* self); +extern uint16_t common_hal_memorymonitor_allocationsize_get_len(memorymonitor_allocationsize_obj_t* self); +extern uint16_t common_hal_memorymonitor_allocationsize_get_item(memorymonitor_allocationsize_obj_t* self, int16_t index); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONSIZE_H diff --git a/shared-bindings/memorymonitor/__init__ 2.c b/shared-bindings/memorymonitor/__init__ 2.c new file mode 100644 index 000000000..c101ba5e0 --- /dev/null +++ b/shared-bindings/memorymonitor/__init__ 2.c @@ -0,0 +1,76 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft + * + * 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. + */ + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/memorymonitor/__init__.h" +#include "shared-bindings/memorymonitor/AllocationAlarm.h" +#include "shared-bindings/memorymonitor/AllocationSize.h" + +//| """Memory monitoring helpers""" +//| + +//| class AllocationError(Exception): +//| """Catchall exception for allocation related errors.""" +//| ... +MP_DEFINE_MEMORYMONITOR_EXCEPTION(AllocationError, Exception) + +NORETURN void mp_raise_memorymonitor_AllocationError(const compressed_string_t* fmt, ...) { + va_list argptr; + va_start(argptr,fmt); + mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_memorymonitor_AllocationError, fmt, argptr); + va_end(argptr); + nlr_raise(exception); +} + +STATIC const mp_rom_map_elem_t memorymonitor_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_memorymonitor) }, + { MP_ROM_QSTR(MP_QSTR_AllocationAlarm), MP_ROM_PTR(&memorymonitor_allocationalarm_type) }, + { MP_ROM_QSTR(MP_QSTR_AllocationSize), MP_ROM_PTR(&memorymonitor_allocationsize_type) }, + + // Errors + { MP_ROM_QSTR(MP_QSTR_AllocationError), MP_ROM_PTR(&mp_type_memorymonitor_AllocationError) }, +}; + +STATIC MP_DEFINE_CONST_DICT(memorymonitor_module_globals, memorymonitor_module_globals_table); + +void memorymonitor_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { + mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS; + bool is_subclass = kind & PRINT_EXC_SUBCLASS; + if (!is_subclass && (k == PRINT_EXC)) { + mp_print_str(print, qstr_str(MP_OBJ_QSTR_VALUE(memorymonitor_module_globals_table[0].value))); + mp_print_str(print, "."); + } + mp_obj_exception_print(print, o_in, kind); +} + +const mp_obj_module_t memorymonitor_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&memorymonitor_module_globals, +}; diff --git a/shared-bindings/memorymonitor/__init__ 2.h b/shared-bindings/memorymonitor/__init__ 2.h new file mode 100644 index 000000000..60fcdc3f6 --- /dev/null +++ b/shared-bindings/memorymonitor/__init__ 2.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR___INIT___H + +#include "py/obj.h" + + +void memorymonitor_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); + +#define MP_DEFINE_MEMORYMONITOR_EXCEPTION(exc_name, base_name) \ +const mp_obj_type_t mp_type_memorymonitor_ ## exc_name = { \ + { &mp_type_type }, \ + .name = MP_QSTR_ ## exc_name, \ + .print = memorymonitor_exception_print, \ + .make_new = mp_obj_exception_make_new, \ + .attr = mp_obj_exception_attr, \ + .parent = &mp_type_ ## base_name, \ +}; + +extern const mp_obj_type_t mp_type_memorymonitor_AllocationError; + +NORETURN void mp_raise_memorymonitor_AllocationError(const compressed_string_t* msg, ...); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR___INIT___H diff --git a/shared-bindings/sdcardio/SDCard 2.c b/shared-bindings/sdcardio/SDCard 2.c new file mode 100644 index 000000000..975f8b095 --- /dev/null +++ b/shared-bindings/sdcardio/SDCard 2.c @@ -0,0 +1,183 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/objarray.h" + +#include "shared-bindings/sdcardio/SDCard.h" +#include "shared-module/sdcardio/SDCard.h" +#include "common-hal/busio/SPI.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/flash.h" + +//| class SDCard: +//| """SD Card Block Interface +//| +//| Controls an SD card over SPI. This built-in module has higher read +//| performance than the library adafruit_sdcard, but it is only compatible with +//| `busio.SPI`, not `bitbangio.SPI`. Usually an SDCard object is used +//| with ``storage.VfsFat`` to allow file I/O to an SD card.""" +//| +//| def __init__(self, bus: busio.SPI, cs: microcontroller.Pin, baudrate: int = 8000000) -> None: +//| """Construct an SPI SD Card object with the given properties +//| +//| :param busio.SPI spi: The SPI bus +//| :param microcontroller.Pin cs: The chip select connected to the card +//| :param int baudrate: The SPI data rate to use after card setup +//| +//| Note that during detection and configuration, a hard-coded low baudrate is used. +//| Data transfers use the specified baurate (rounded down to one that is supported by +//| the microcontroller) +//| +//| Example usage: +//| +//| .. code-block:: python +//| +//| import os +//| +//| import board +//| import sdcardio +//| import storage +//| +//| sd = sdcardio.SDCard(board.SPI(), board.SD_CS) +//| vfs = storage.VfsFat(sd) +//| storage.mount(vfs, '/sd') +//| os.listdir('/sd')""" + +STATIC mp_obj_t sdcardio_sdcard_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_spi, ARG_cs, ARG_baudrate, ARG_sdio, NUM_ARGS }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_spi, MP_ARG_OBJ, {.u_obj = mp_const_none } }, + { MP_QSTR_cs, MP_ARG_OBJ, {.u_obj = mp_const_none } }, + { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 8000000} }, + { MP_QSTR_sdio, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_int = 8000000} }, + }; + MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + busio_spi_obj_t *spi = validate_obj_is_spi_bus(args[ARG_spi].u_obj); + mcu_pin_obj_t *cs = validate_obj_is_free_pin(args[ARG_cs].u_obj); + + sdcardio_sdcard_obj_t *self = m_new_obj(sdcardio_sdcard_obj_t); + self->base.type = &sdcardio_SDCard_type; + + common_hal_sdcardio_sdcard_construct(self, spi, cs, args[ARG_baudrate].u_int); + + return self; +} + + +//| def count(self) -> int: +//| """Returns the total number of sectors +//| +//| Due to technical limitations, this is a function and not a property. +//| +//| :return: The number of 512-byte blocks, as a number""" +//| +mp_obj_t sdcardio_sdcard_count(mp_obj_t self_in) { + sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t*)self_in; + return mp_obj_new_int_from_ull(common_hal_sdcardio_sdcard_get_blockcount(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_count_obj, sdcardio_sdcard_count); + +//| def deinit(self) -> None: +//| """Disable permanently. +//| +//| :return: None""" +//| +mp_obj_t sdcardio_sdcard_deinit(mp_obj_t self_in) { + sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t*)self_in; + common_hal_sdcardio_sdcard_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_deinit_obj, sdcardio_sdcard_deinit); + + +//| def readblocks(self, start_block: int, buf: WriteableBuffer) -> None: +//| +//| """Read one or more blocks from the card +//| +//| :param int start_block: The block to start reading from +//| :param ~_typing.WriteableBuffer buf: The buffer to write into. Length must be multiple of 512. +//| +//| :return: None""" +//| + +mp_obj_t sdcardio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { + uint32_t start_block = mp_obj_get_int(start_block_in); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE); + sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t*)self_in; + int result = common_hal_sdcardio_sdcard_readblocks(self, start_block, &bufinfo); + if (result < 0) { + mp_raise_OSError(-result); + } + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_readblocks_obj, sdcardio_sdcard_readblocks); + +//| def writeblocks(self, start_block: int, buf: ReadableBuffer) -> None: +//| +//| """Write one or more blocks to the card +//| +//| :param int start_block: The block to start writing from +//| :param ~_typing.ReadableBuffer buf: The buffer to read from. Length must be multiple of 512. +//| +//| :return: None""" +//| + +mp_obj_t sdcardio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { + uint32_t start_block = mp_obj_get_int(start_block_in); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); + sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t*)self_in; + int result = common_hal_sdcardio_sdcard_writeblocks(self, start_block, &bufinfo); + if (result < 0) { + mp_raise_OSError(-result); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_writeblocks_obj, sdcardio_sdcard_writeblocks); + +STATIC const mp_rom_map_elem_t sdcardio_sdcard_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_count), MP_ROM_PTR(&sdcardio_sdcard_count_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&sdcardio_sdcard_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&sdcardio_sdcard_readblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&sdcardio_sdcard_writeblocks_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(sdcardio_sdcard_locals_dict, sdcardio_sdcard_locals_dict_table); + +const mp_obj_type_t sdcardio_SDCard_type = { + { &mp_type_type }, + .name = MP_QSTR_SDCard, + .make_new = sdcardio_sdcard_make_new, + .locals_dict = (mp_obj_dict_t*)&sdcardio_sdcard_locals_dict, +}; diff --git a/shared-bindings/sdcardio/SDCard 2.h b/shared-bindings/sdcardio/SDCard 2.h new file mode 100644 index 000000000..5986d5b81 --- /dev/null +++ b/shared-bindings/sdcardio/SDCard 2.h @@ -0,0 +1,30 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#pragma once + +extern const mp_obj_type_t sdcardio_SDCard_type; diff --git a/shared-bindings/sdcardio/__init__ 2.c b/shared-bindings/sdcardio/__init__ 2.c new file mode 100644 index 000000000..746aa5588 --- /dev/null +++ b/shared-bindings/sdcardio/__init__ 2.c @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/sdcardio/SDCard.h" + +//| """Interface to an SD card via the SPI bus""" + +STATIC const mp_rom_map_elem_t sdcardio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sdcardio) }, + { MP_ROM_QSTR(MP_QSTR_SDCard), MP_ROM_PTR(&sdcardio_SDCard_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(sdcardio_module_globals, sdcardio_module_globals_table); + +const mp_obj_module_t sdcardio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&sdcardio_module_globals, +}; diff --git a/shared-bindings/sdcardio/__init__ 2.h b/shared-bindings/sdcardio/__init__ 2.h new file mode 100644 index 000000000..e69de29bb diff --git a/shared-bindings/sdioio/SDCard 2.c b/shared-bindings/sdioio/SDCard 2.c new file mode 100644 index 000000000..aba414cd6 --- /dev/null +++ b/shared-bindings/sdioio/SDCard 2.c @@ -0,0 +1,296 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +// This file contains all of the Python API definitions for the +// sdioio.SDCard class. + +#include + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/sdioio/SDCard.h" +#include "shared-bindings/util.h" + +#include "lib/utils/buffer_helper.h" +#include "lib/utils/context_manager_helpers.h" +#include "py/mperrno.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +//| class SDCard: +//| """SD Card Block Interface with SDIO +//| +//| Controls an SD card over SDIO. SDIO is a parallel protocol designed +//| for SD cards. It uses a clock pin, a command pin, and 1 or 4 +//| data pins. It can be operated at a high frequency such as +//| 25MHz. Usually an SDCard object is used with ``storage.VfsFat`` +//| to allow file I/O to an SD card.""" +//| +//| def __init__(self, clock: microcontroller.Pin, command: microcontroller.Pin, data: Sequence[microcontroller.Pin], frequency: int) -> None: +//| """Construct an SDIO SD Card object with the given properties +//| +//| :param ~microcontroller.Pin clock: the pin to use for the clock. +//| :param ~microcontroller.Pin command: the pin to use for the command. +//| :param data: A sequence of pins to use for data. +//| :param frequency: The frequency of the bus in Hz +//| +//| Example usage: +//| +//| .. code-block:: python +//| +//| import os +//| +//| import board +//| import sdioio +//| import storage +//| +//| sd = sdioio.SDCard( +//| clock=board.SDIO_CLOCK, +//| command=board.SDIO_COMMAND, +//| data=board.SDIO_DATA, +//| frequency=25000000) +//| vfs = storage.VfsFat(sd) +//| storage.mount(vfs, '/sd') +//| os.listdir('/sd')""" +//| ... +//| + +STATIC mp_obj_t sdioio_sdcard_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + sdioio_sdcard_obj_t *self = m_new_obj(sdioio_sdcard_obj_t); + self->base.type = &sdioio_SDCard_type; + enum { ARG_clock, ARG_command, ARG_data, ARG_frequency, NUM_ARGS }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ }, + { MP_QSTR_command, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ }, + { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ }, + { MP_QSTR_frequency, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT }, + }; + MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mcu_pin_obj_t* clock = validate_obj_is_free_pin(args[ARG_clock].u_obj); + const mcu_pin_obj_t* command = validate_obj_is_free_pin(args[ARG_command].u_obj); + mcu_pin_obj_t *data_pins[4]; + uint8_t num_data; + validate_list_is_free_pins(MP_QSTR_data, data_pins, MP_ARRAY_SIZE(data_pins), args[ARG_data].u_obj, &num_data); + + common_hal_sdioio_sdcard_construct(self, clock, command, num_data, data_pins, args[ARG_frequency].u_int); + return MP_OBJ_FROM_PTR(self); +} + +STATIC void check_for_deinit(sdioio_sdcard_obj_t *self) { + if (common_hal_sdioio_sdcard_deinited(self)) { + raise_deinited_error(); + } +} + +//| def configure(self, frequency: int = 0, width: int = 0) -> None: +//| """Configures the SDIO bus. +//| +//| :param int frequency: the desired clock rate in Hertz. The actual clock rate may be higher or lower due to the granularity of available clock settings. Check the `frequency` attribute for the actual clock rate. +//| :param int width: the number of data lines to use. Must be 1 or 4 and must also not exceed the number of data lines at construction +//| +//| .. note:: Leaving a value unspecified or 0 means the current setting is kept""" +//| +STATIC mp_obj_t sdioio_sdcard_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_frequency, ARG_width, NUM_ARGS }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_width, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + }; + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t frequency = args[ARG_frequency].u_int; + if (frequency < 0) { + mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_baudrate); + } + + uint8_t width = args[ARG_width].u_int; + if (width != 0 && width != 1 && width != 4) { + mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_width); + } + + if (!common_hal_sdioio_sdcard_configure(self, frequency, width)) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(sdioio_sdcard_configure_obj, 1, sdioio_sdcard_configure); + +//| def count(self) -> int: +//| """Returns the total number of sectors +//| +//| Due to technical limitations, this is a function and not a property. +//| +//| :return: The number of 512-byte blocks, as a number""" +//| +STATIC mp_obj_t sdioio_sdcard_count(mp_obj_t self_in) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_sdioio_sdcard_get_count(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_count_obj, sdioio_sdcard_count); + +//| def readblocks(self, start_block: int, buf: WriteableBuffer) -> None: +//| +//| """Read one or more blocks from the card +//| +//| :param int start_block: The block to start reading from +//| :param ~_typing.WriteableBuffer buf: The buffer to write into. Length must be multiple of 512. +//| +//| :return: None""" +mp_obj_t sdioio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { + uint32_t start_block = mp_obj_get_int(start_block_in); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE); + sdioio_sdcard_obj_t *self = (sdioio_sdcard_obj_t*)self_in; + int result = common_hal_sdioio_sdcard_readblocks(self, start_block, &bufinfo); + if (result < 0) { + mp_raise_OSError(-result); + } + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_readblocks_obj, sdioio_sdcard_readblocks); + +//| def writeblocks(self, start_block: int, buf: ReadableBuffer) -> None: +//| +//| """Write one or more blocks to the card +//| +//| :param int start_block: The block to start writing from +//| :param ~_typing.ReadableBuffer buf: The buffer to read from. Length must be multiple of 512. +//| +//| :return: None""" +//| +mp_obj_t sdioio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { + uint32_t start_block = mp_obj_get_int(start_block_in); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); + sdioio_sdcard_obj_t *self = (sdioio_sdcard_obj_t*)self_in; + int result = common_hal_sdioio_sdcard_writeblocks(self, start_block, &bufinfo); + if (result < 0) { + mp_raise_OSError(-result); + } + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_writeblocks_obj, sdioio_sdcard_writeblocks); + +//| @property +//| def frequency(self) -> int: +//| """The actual SDIO bus frequency. This may not match the frequency +//| requested due to internal limitations.""" +//| ... +//| +STATIC mp_obj_t sdioio_sdcard_obj_get_frequency(mp_obj_t self_in) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_sdioio_sdcard_get_frequency(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_get_frequency_obj, sdioio_sdcard_obj_get_frequency); + +const mp_obj_property_t sdioio_sdcard_frequency_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&sdioio_sdcard_get_frequency_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| @property +//| def width(self) -> int: +//| """The actual SDIO bus width, in bits""" +//| ... +//| +STATIC mp_obj_t sdioio_sdcard_obj_get_width(mp_obj_t self_in) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_sdioio_sdcard_get_width(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_get_width_obj, sdioio_sdcard_obj_get_width); + +const mp_obj_property_t sdioio_sdcard_width_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&sdioio_sdcard_get_width_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| def deinit(self) -> None: +//| """Disable permanently. +//| +//| :return: None""" +STATIC mp_obj_t sdioio_sdcard_obj_deinit(mp_obj_t self_in) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_sdioio_sdcard_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_deinit_obj, sdioio_sdcard_obj_deinit); + +//| def __enter__(self) -> SDCard: +//| """No-op used by Context Managers. +//| Provided by context manager helper.""" +//| ... +//| + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +STATIC mp_obj_t sdioio_sdcard_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_sdioio_sdcard_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(sdioio_sdcard_obj___exit___obj, 4, 4, sdioio_sdcard_obj___exit__); + +STATIC const mp_rom_map_elem_t sdioio_sdcard_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&sdioio_sdcard_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&sdioio_sdcard_obj___exit___obj) }, + + { MP_ROM_QSTR(MP_QSTR_configure), MP_ROM_PTR(&sdioio_sdcard_configure_obj) }, + { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&sdioio_sdcard_frequency_obj) }, + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&sdioio_sdcard_width_obj) }, + + { MP_ROM_QSTR(MP_QSTR_count), MP_ROM_PTR(&sdioio_sdcard_count_obj) }, + { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&sdioio_sdcard_readblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&sdioio_sdcard_writeblocks_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(sdioio_sdcard_locals_dict, sdioio_sdcard_locals_dict_table); + +const mp_obj_type_t sdioio_SDCard_type = { + { &mp_type_type }, + .name = MP_QSTR_SDCard, + .make_new = sdioio_sdcard_make_new, + .locals_dict = (mp_obj_dict_t*)&sdioio_sdcard_locals_dict, +}; diff --git a/shared-bindings/sdioio/SDCard 2.h b/shared-bindings/sdioio/SDCard 2.h new file mode 100644 index 000000000..7f62ee7a6 --- /dev/null +++ b/shared-bindings/sdioio/SDCard 2.h @@ -0,0 +1,66 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SDIO_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SDIO_H + +#include "py/obj.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/sdioio/SDCard.h" + +// Type object used in Python. Should be shared between ports. +extern const mp_obj_type_t sdioio_SDCard_type; + +// Construct an underlying SDIO object. +extern void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self, + const mcu_pin_obj_t * clock, const mcu_pin_obj_t * command, + uint8_t num_data, mcu_pin_obj_t ** data, uint32_t frequency); + +extern void common_hal_sdioio_sdcard_deinit(sdioio_sdcard_obj_t *self); +extern bool common_hal_sdioio_sdcard_deinited(sdioio_sdcard_obj_t *self); + +extern bool common_hal_sdioio_sdcard_configure(sdioio_sdcard_obj_t *self, uint32_t baudrate, uint8_t width); + +extern void common_hal_sdioio_sdcard_unlock(sdioio_sdcard_obj_t *self); + +// Return actual SDIO bus frequency. +uint32_t common_hal_sdioio_sdcard_get_frequency(sdioio_sdcard_obj_t* self); + +// Return SDIO bus width. +uint8_t common_hal_sdioio_sdcard_get_width(sdioio_sdcard_obj_t* self); + +// Return number of device blocks +uint32_t common_hal_sdioio_sdcard_get_count(sdioio_sdcard_obj_t* self); + +// Read or write blocks +int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t* self, uint32_t start_block, mp_buffer_info_t *bufinfo); +int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t* self, uint32_t start_block, mp_buffer_info_t *bufinfo); + +// This is used by the supervisor to claim SDIO devices indefinitely. +extern void common_hal_sdioio_sdcard_never_reset(sdioio_sdcard_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SDIO_H diff --git a/shared-bindings/sdioio/__init__ 2.c b/shared-bindings/sdioio/__init__ 2.c new file mode 100644 index 000000000..b88e5c3a9 --- /dev/null +++ b/shared-bindings/sdioio/__init__ 2.c @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/sdioio/SDCard.h" + +//| """Interface to an SD card via the SDIO bus""" + +STATIC const mp_rom_map_elem_t sdioio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sdio) }, + { MP_ROM_QSTR(MP_QSTR_SDCard), MP_ROM_PTR(&sdioio_SDCard_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(sdioio_module_globals, sdioio_module_globals_table); + +const mp_obj_module_t sdioio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&sdioio_module_globals, +}; diff --git a/shared-bindings/sdioio/__init__ 2.h b/shared-bindings/sdioio/__init__ 2.h new file mode 100644 index 000000000..e69de29bb diff --git a/shared-module/memorymonitor/AllocationAlarm 2.c b/shared-module/memorymonitor/AllocationAlarm 2.c new file mode 100644 index 000000000..35f4e4c63 --- /dev/null +++ b/shared-module/memorymonitor/AllocationAlarm 2.c @@ -0,0 +1,94 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#include "shared-bindings/memorymonitor/__init__.h" +#include "shared-bindings/memorymonitor/AllocationAlarm.h" + +#include "py/gc.h" +#include "py/mpstate.h" +#include "py/runtime.h" + +void common_hal_memorymonitor_allocationalarm_construct(memorymonitor_allocationalarm_obj_t* self, size_t minimum_block_count) { + self->minimum_block_count = minimum_block_count; + self->next = NULL; + self->previous = NULL; +} + +void common_hal_memorymonitor_allocationalarm_set_ignore(memorymonitor_allocationalarm_obj_t* self, mp_int_t count) { + self->count = count; +} + +void common_hal_memorymonitor_allocationalarm_pause(memorymonitor_allocationalarm_obj_t* self) { + // Check to make sure we aren't already paused. We can be if we're exiting from an exception we + // caused. + if (self->previous == NULL) { + return; + } + *self->previous = self->next; + self->next = NULL; + self->previous = NULL; +} + +void common_hal_memorymonitor_allocationalarm_resume(memorymonitor_allocationalarm_obj_t* self) { + if (self->previous != NULL) { + mp_raise_RuntimeError(translate("Already running")); + } + self->next = MP_STATE_VM(active_allocationalarms); + self->previous = (memorymonitor_allocationalarm_obj_t**) &MP_STATE_VM(active_allocationalarms); + if (self->next != NULL) { + self->next->previous = &self->next; + } + MP_STATE_VM(active_allocationalarms) = self; +} + +void memorymonitor_allocationalarms_allocation(size_t block_count) { + memorymonitor_allocationalarm_obj_t* alarm = MP_OBJ_TO_PTR(MP_STATE_VM(active_allocationalarms)); + size_t alert_count = 0; + while (alarm != NULL) { + // Hold onto next in case we remove the alarm from the list. + memorymonitor_allocationalarm_obj_t* next = alarm->next; + if (block_count >= alarm->minimum_block_count) { + if (alarm->count > 0) { + alarm->count--; + } else { + // Uncomment the breakpoint below if you want to use a C debugger to figure out the C + // call stack for an allocation. + // asm("bkpt"); + // Pause now because we may alert when throwing the exception too. + common_hal_memorymonitor_allocationalarm_pause(alarm); + alert_count++; + } + } + alarm = next; + } + if (alert_count > 0) { + mp_raise_memorymonitor_AllocationError(translate("Attempt to allocate %d blocks"), block_count); + } +} + +void memorymonitor_allocationalarms_reset(void) { + MP_STATE_VM(active_allocationalarms) = NULL; +} diff --git a/shared-module/memorymonitor/AllocationAlarm 2.h b/shared-module/memorymonitor/AllocationAlarm 2.h new file mode 100644 index 000000000..172c24f6c --- /dev/null +++ b/shared-module/memorymonitor/AllocationAlarm 2.h @@ -0,0 +1,51 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONALARM_H +#define MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONALARM_H + +#include +#include + +#include "py/obj.h" + +typedef struct _memorymonitor_allocationalarm_obj_t memorymonitor_allocationalarm_obj_t; + +#define ALLOCATION_SIZE_BUCKETS 16 + +typedef struct _memorymonitor_allocationalarm_obj_t { + mp_obj_base_t base; + size_t minimum_block_count; + mp_int_t count; + // Store the location that points to us so we can remove ourselves. + memorymonitor_allocationalarm_obj_t** previous; + memorymonitor_allocationalarm_obj_t* next; +} memorymonitor_allocationalarm_obj_t; + +void memorymonitor_allocationalarms_allocation(size_t block_count); +void memorymonitor_allocationalarms_reset(void); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONALARM_H diff --git a/shared-module/memorymonitor/AllocationSize 2.c b/shared-module/memorymonitor/AllocationSize 2.c new file mode 100644 index 000000000..c28e65592 --- /dev/null +++ b/shared-module/memorymonitor/AllocationSize 2.c @@ -0,0 +1,91 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#include "shared-bindings/memorymonitor/AllocationSize.h" + +#include "py/gc.h" +#include "py/mpstate.h" +#include "py/runtime.h" + +void common_hal_memorymonitor_allocationsize_construct(memorymonitor_allocationsize_obj_t* self) { + common_hal_memorymonitor_allocationsize_clear(self); + self->next = NULL; + self->previous = NULL; +} + +void common_hal_memorymonitor_allocationsize_pause(memorymonitor_allocationsize_obj_t* self) { + *self->previous = self->next; + self->next = NULL; + self->previous = NULL; +} + +void common_hal_memorymonitor_allocationsize_resume(memorymonitor_allocationsize_obj_t* self) { + if (self->previous != NULL) { + mp_raise_RuntimeError(translate("Already running")); + } + self->next = MP_STATE_VM(active_allocationsizes); + self->previous = (memorymonitor_allocationsize_obj_t**) &MP_STATE_VM(active_allocationsizes); + if (self->next != NULL) { + self->next->previous = &self->next; + } + MP_STATE_VM(active_allocationsizes) = self; +} + +void common_hal_memorymonitor_allocationsize_clear(memorymonitor_allocationsize_obj_t* self) { + for (size_t i = 0; i < ALLOCATION_SIZE_BUCKETS; i++) { + self->buckets[i] = 0; + } +} + +uint16_t common_hal_memorymonitor_allocationsize_get_len(memorymonitor_allocationsize_obj_t* self) { + return ALLOCATION_SIZE_BUCKETS; +} + +size_t common_hal_memorymonitor_allocationsize_get_bytes_per_block(memorymonitor_allocationsize_obj_t* self) { + return BYTES_PER_BLOCK; +} + +uint16_t common_hal_memorymonitor_allocationsize_get_item(memorymonitor_allocationsize_obj_t* self, int16_t index) { + return self->buckets[index]; +} + +void memorymonitor_allocationsizes_track_allocation(size_t block_count) { + memorymonitor_allocationsize_obj_t* as = MP_OBJ_TO_PTR(MP_STATE_VM(active_allocationsizes)); + size_t power_of_two = 0; + block_count >>= 1; + while (block_count != 0) { + power_of_two++; + block_count >>= 1; + } + while (as != NULL) { + as->buckets[power_of_two]++; + as = as->next; + } +} + +void memorymonitor_allocationsizes_reset(void) { + MP_STATE_VM(active_allocationsizes) = NULL; +} diff --git a/shared-module/memorymonitor/AllocationSize 2.h b/shared-module/memorymonitor/AllocationSize 2.h new file mode 100644 index 000000000..3baab2213 --- /dev/null +++ b/shared-module/memorymonitor/AllocationSize 2.h @@ -0,0 +1,51 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONSIZE_H +#define MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONSIZE_H + +#include +#include + +#include "py/obj.h" + +typedef struct _memorymonitor_allocationsize_obj_t memorymonitor_allocationsize_obj_t; + +#define ALLOCATION_SIZE_BUCKETS 16 + +typedef struct _memorymonitor_allocationsize_obj_t { + mp_obj_base_t base; + uint16_t buckets[ALLOCATION_SIZE_BUCKETS]; + // Store the location that points to us so we can remove ourselves. + memorymonitor_allocationsize_obj_t** previous; + memorymonitor_allocationsize_obj_t* next; + bool paused; +} memorymonitor_allocationsize_obj_t; + +void memorymonitor_allocationsizes_track_allocation(size_t block_count); +void memorymonitor_allocationsizes_reset(void); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONSIZE_H diff --git a/shared-module/memorymonitor/__init__ 2.c b/shared-module/memorymonitor/__init__ 2.c new file mode 100644 index 000000000..6cb424153 --- /dev/null +++ b/shared-module/memorymonitor/__init__ 2.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft + * + * 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. + */ + +#include "shared-module/memorymonitor/__init__.h" +#include "shared-module/memorymonitor/AllocationAlarm.h" +#include "shared-module/memorymonitor/AllocationSize.h" + +void memorymonitor_track_allocation(size_t block_count) { + memorymonitor_allocationalarms_allocation(block_count); + memorymonitor_allocationsizes_track_allocation(block_count); +} + +void memorymonitor_reset(void) { + memorymonitor_allocationalarms_reset(); + memorymonitor_allocationsizes_reset(); +} diff --git a/shared-module/memorymonitor/__init__ 2.h b/shared-module/memorymonitor/__init__ 2.h new file mode 100644 index 000000000..f47f6434b --- /dev/null +++ b/shared-module/memorymonitor/__init__ 2.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_MEMORYMONITOR___INIT___H +#define MICROPY_INCLUDED_MEMORYMONITOR___INIT___H + +#include + +void memorymonitor_track_allocation(size_t block_count); +void memorymonitor_reset(void); + +#endif // MICROPY_INCLUDED_MEMORYMONITOR___INIT___H diff --git a/shared-module/sdcardio/SDCard 2.c b/shared-module/sdcardio/SDCard 2.c new file mode 100644 index 000000000..9e861279d --- /dev/null +++ b/shared-module/sdcardio/SDCard 2.c @@ -0,0 +1,466 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +// This implementation largely follows the structure of adafruit_sdcard.py + +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/time/__init__.h" +#include "shared-bindings/util.h" +#include "shared-module/sdcardio/SDCard.h" + +#include "py/mperrno.h" + +#if 0 +#define DEBUG_PRINT(...) ((void)mp_printf(&mp_plat_print, ## __VA_ARGS__)) +#else +#define DEBUG_PRINT(...) ((void)0) +#endif + +#define CMD_TIMEOUT (200) + +#define R1_IDLE_STATE (1<<0) +#define R1_ILLEGAL_COMMAND (1<<2) + +#define TOKEN_CMD25 (0xFC) +#define TOKEN_STOP_TRAN (0xFD) +#define TOKEN_DATA (0xFE) + +STATIC bool lock_and_configure_bus(sdcardio_sdcard_obj_t *self) { + if (!common_hal_busio_spi_try_lock(self->bus)) { + return false; + } + common_hal_busio_spi_configure(self->bus, self->baudrate, 0, 0, 8); + common_hal_digitalio_digitalinout_set_value(&self->cs, false); + return true; +} + +STATIC void lock_bus_or_throw(sdcardio_sdcard_obj_t *self) { + if (!lock_and_configure_bus(self)) { + mp_raise_OSError(EAGAIN); + } +} + +STATIC void clock_card(sdcardio_sdcard_obj_t *self, int bytes) { + uint8_t buf[] = {0xff}; + common_hal_digitalio_digitalinout_set_value(&self->cs, true); + for (int i=0; ibus, buf, 1); + } +} + +STATIC void extraclock_and_unlock_bus(sdcardio_sdcard_obj_t *self) { + clock_card(self, 1); + common_hal_busio_spi_unlock(self->bus); +} + +static uint8_t CRC7(const uint8_t* data, uint8_t n) { + uint8_t crc = 0; + for (uint8_t i = 0; i < n; i++) { + uint8_t d = data[i]; + for (uint8_t j = 0; j < 8; j++) { + crc <<= 1; + if ((d & 0x80) ^ (crc & 0x80)) { + crc ^= 0x09; + } + d <<= 1; + } + } + return (crc << 1) | 1; +} + +#define READY_TIMEOUT_NS (300 * 1000 * 1000) // 300ms +STATIC void wait_for_ready(sdcardio_sdcard_obj_t *self) { + uint64_t deadline = common_hal_time_monotonic_ns() + READY_TIMEOUT_NS; + while (common_hal_time_monotonic_ns() < deadline) { + uint8_t b; + common_hal_busio_spi_read(self->bus, &b, 1, 0xff); + if (b == 0xff) { + break; + } + } +} + +// In Python API, defaults are response=None, data_block=True, wait=True +STATIC int cmd(sdcardio_sdcard_obj_t *self, int cmd, int arg, void *response_buf, size_t response_len, bool data_block, bool wait) { + DEBUG_PRINT("cmd % 3d [%02x] arg=% 11d [%08x] len=%d%s%s\n", cmd, cmd, arg, arg, response_len, data_block ? " data" : "", wait ? " wait" : ""); + uint8_t cmdbuf[6]; + cmdbuf[0] = cmd | 0x40; + cmdbuf[1] = (arg >> 24) & 0xff; + cmdbuf[2] = (arg >> 16) & 0xff; + cmdbuf[3] = (arg >> 8) & 0xff; + cmdbuf[4] = arg & 0xff; + cmdbuf[5] = CRC7(cmdbuf, 5); + + if (wait) { + wait_for_ready(self); + } + + common_hal_busio_spi_write(self->bus, cmdbuf, sizeof(cmdbuf)); + + // Wait for the response (response[7] == 0) + bool response_received = false; + for (int i=0; ibus, cmdbuf, 1, 0xff); + if ((cmdbuf[0] & 0x80) == 0) { + response_received = true; + break; + } + } + + if (!response_received) { + return -EIO; + } + + if (response_buf) { + + if (data_block) { + cmdbuf[1] = 0xff; + do { + // Wait for the start block byte + common_hal_busio_spi_read(self->bus, cmdbuf+1, 1, 0xff); + } while (cmdbuf[1] != 0xfe); + } + + common_hal_busio_spi_read(self->bus, response_buf, response_len, 0xff); + + if (data_block) { + // Read and discard the CRC-CCITT checksum + common_hal_busio_spi_read(self->bus, cmdbuf+1, 2, 0xff); + } + + } + + return cmdbuf[0]; +} + +STATIC int block_cmd(sdcardio_sdcard_obj_t *self, int cmd_, int block, void *response_buf, size_t response_len, bool data_block, bool wait) { + return cmd(self, cmd_, block * self->cdv, response_buf, response_len, true, true); +} + +STATIC bool cmd_nodata(sdcardio_sdcard_obj_t* self, int cmd, int response) { + uint8_t cmdbuf[2] = {cmd, 0xff}; + + common_hal_busio_spi_write(self->bus, cmdbuf, sizeof(cmdbuf)); + + // Wait for the response (response[7] == response) + for (int i=0; ibus, cmdbuf, 1, 0xff); + if (cmdbuf[0] == response) { + return 0; + } + } + return -EIO; +} + +STATIC const compressed_string_t *init_card_v1(sdcardio_sdcard_obj_t *self) { + for (int i=0; icdv = 1; + } + return NULL; + } + } + return translate("timeout waiting for v2 card"); +} + +STATIC const compressed_string_t *init_card(sdcardio_sdcard_obj_t *self) { + clock_card(self, 10); + + common_hal_digitalio_digitalinout_set_value(&self->cs, false); + + // CMD0: init card: should return _R1_IDLE_STATE (allow 5 attempts) + { + bool reached_idle_state = false; + for (int i=0; i<5; i++) { + if (cmd(self, 0, 0, NULL, 0, true, true) == R1_IDLE_STATE) { + reached_idle_state = true; + break; + } + } + if (!reached_idle_state) { + return translate("no SD card"); + } + } + + // CMD8: determine card version + { + uint8_t rb7[4]; + int response = cmd(self, 8, 0x1AA, rb7, sizeof(rb7), false, true); + if (response == R1_IDLE_STATE) { + const compressed_string_t *result =init_card_v2(self); + if (result != NULL) { + return result; + } + } else if (response == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { + const compressed_string_t *result =init_card_v1(self); + if (result != NULL) { + return result; + } + } else { + return translate("couldn't determine SD card version"); + } + } + + // CMD9: get number of sectors + { + uint8_t csd[16]; + int response = cmd(self, 9, 0, csd, sizeof(csd), true, true); + if (response != 0) { + return translate("no response from SD card"); + } + int csd_version = (csd[0] & 0xC0) >> 6; + if (csd_version >= 2) { + return translate("SD card CSD format not supported"); + } + + if (csd_version == 1) { + self->sectors = ((csd[8] << 8 | csd[9]) + 1) * 1024; + } else { + uint32_t block_length = 1 << (csd[5] & 0xF); + uint32_t c_size = ((csd[6] & 0x3) << 10) | (csd[7] << 2) | ((csd[8] & 0xC) >> 6); + uint32_t mult = 1 << (((csd[9] & 0x3) << 1 | (csd[10] & 0x80) >> 7) + 2); + self->sectors = block_length / 512 * mult * (c_size + 1); + } + } + + // CMD16: set block length to 512 bytes + { + int response = cmd(self, 16, 512, NULL, 0, true, true); + if (response != 0) { + return translate("can't set 512 block size"); + } + } + + return NULL; +} + +void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, mcu_pin_obj_t *cs, int baudrate) { + self->bus = bus; + common_hal_digitalio_digitalinout_construct(&self->cs, cs); + common_hal_digitalio_digitalinout_switch_to_output(&self->cs, true, DRIVE_MODE_PUSH_PULL); + + self->cdv = 512; + self->sectors = 0; + self->baudrate = 250000; + + lock_bus_or_throw(self); + const compressed_string_t *result = init_card(self); + extraclock_and_unlock_bus(self); + + if (result != NULL) { + common_hal_digitalio_digitalinout_deinit(&self->cs); + mp_raise_OSError_msg(result); + } + + self->baudrate = baudrate; +} + +void common_hal_sdcardio_sdcard_deinit(sdcardio_sdcard_obj_t *self) { + if (!self->bus) { + return; + } + self->bus = 0; + common_hal_digitalio_digitalinout_deinit(&self->cs); +} + +void common_hal_sdcardio_check_for_deinit(sdcardio_sdcard_obj_t *self) { + if (!self->bus) { + raise_deinited_error(); + } +} + +int common_hal_sdcardio_sdcard_get_blockcount(sdcardio_sdcard_obj_t *self) { + common_hal_sdcardio_check_for_deinit(self); + return self->sectors; +} + +int readinto(sdcardio_sdcard_obj_t *self, void *buf, size_t size) { + uint8_t aux[2] = {0, 0}; + while (aux[0] != 0xfe) { + common_hal_busio_spi_read(self->bus, aux, 1, 0xff); + } + + common_hal_busio_spi_read(self->bus, buf, size, 0xff); + + // Read checksum and throw it away + common_hal_busio_spi_read(self->bus, aux, sizeof(aux), 0xff); + return 0; +} + +int readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) { + uint32_t nblocks = buf->len / 512; + if (nblocks == 1) { + // Use CMD17 to read a single block + return block_cmd(self, 17, start_block, buf->buf, buf->len, true, true); + } else { + // Use CMD18 to read multiple blocks + int r = block_cmd(self, 18, start_block, NULL, 0, true, true); + if (r < 0) { + return r; + } + + uint8_t *ptr = buf->buf; + while (nblocks--) { + r = readinto(self, ptr, 512); + if (r < 0) { + return r; + } + ptr += 512; + } + + // End the multi-block read + r = cmd(self, 12, 0, NULL, 0, true, false); + + // Return first status 0 or last before card ready (0xff) + while (r != 0) { + uint8_t single_byte; + common_hal_busio_spi_read(self->bus, &single_byte, 1, 0xff); + if (single_byte & 0x80) { + return r; + } + r = single_byte; + } + } + return 0; +} + +int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) { + common_hal_sdcardio_check_for_deinit(self); + if (buf->len % 512 != 0) { + mp_raise_ValueError(translate("Buffer length must be a multiple of 512")); + } + + lock_and_configure_bus(self); + int r = readblocks(self, start_block, buf); + extraclock_and_unlock_bus(self); + return r; +} + +int _write(sdcardio_sdcard_obj_t *self, uint8_t token, void *buf, size_t size) { + wait_for_ready(self); + + uint8_t cmd[2]; + cmd[0] = token; + + common_hal_busio_spi_write(self->bus, cmd, 1); + common_hal_busio_spi_write(self->bus, buf, size); + + cmd[0] = cmd[1] = 0xff; + common_hal_busio_spi_write(self->bus, cmd, 2); + + // Check the response + // This differs from the traditional adafruit_sdcard handling, + // but adafruit_sdcard also ignored the return value of SDCard._write(!) + // so nobody noticed + // + // + // Response is as follows: + // x x x 0 STAT 1 + // 7 6 5 4 3..1 0 + // with STATUS 010 indicating "data accepted", and other status bit + // combinations indicating failure. + // In practice, I was seeing cmd[0] as 0xe5, indicating success + for (int i=0; ibus, cmd, 1, 0xff); + DEBUG_PRINT("i=%02d cmd[0] = 0x%02x\n", i, cmd[0]); + if ((cmd[0] & 0b00010001) == 0b00000001) { + if ((cmd[0] & 0x1f) != 0x5) { + return -EIO; + } else { + break; + } + } + } + + // Wait for the write to finish + do { + common_hal_busio_spi_read(self->bus, cmd, 1, 0xff); + } while (cmd[0] == 0); + + // Success + return 0; +} + +int writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) { + common_hal_sdcardio_check_for_deinit(self); + uint32_t nblocks = buf->len / 512; + if (nblocks == 1) { + // Use CMD24 to write a single block + int r = block_cmd(self, 24, start_block, NULL, 0, true, true); + if (r < 0) { + return r; + } + r = _write(self, TOKEN_DATA, buf->buf, buf->len); + if (r < 0) { + return r; + } + } else { + // Use CMD25 to write multiple block + int r = block_cmd(self, 25, start_block, NULL, 0, true, true); + if (r < 0) { + return r; + } + + uint8_t *ptr = buf->buf; + while (nblocks--) { + r = _write(self, TOKEN_CMD25, ptr, 512); + if (r < 0) { + return r; + } + ptr += 512; + } + + cmd_nodata(self, TOKEN_STOP_TRAN, 0); + } + return 0; +} + +int common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) { + common_hal_sdcardio_check_for_deinit(self); + if (buf->len % 512 != 0) { + mp_raise_ValueError(translate("Buffer length must be a multiple of 512")); + } + lock_and_configure_bus(self); + int r = writeblocks(self, start_block, buf); + extraclock_and_unlock_bus(self); + return r; +} diff --git a/shared-module/sdcardio/SDCard 2.h b/shared-module/sdcardio/SDCard 2.h new file mode 100644 index 000000000..76c906029 --- /dev/null +++ b/shared-module/sdcardio/SDCard 2.h @@ -0,0 +1,51 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#pragma once + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/objarray.h" + +#include "common-hal/busio/SPI.h" +#include "common-hal/digitalio/DigitalInOut.h" + +typedef struct { + mp_obj_base_t base; + busio_spi_obj_t *bus; + digitalio_digitalinout_obj_t cs; + int cdv; + int baudrate; + uint32_t sectors; +} sdcardio_sdcard_obj_t; + +void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *spi, mcu_pin_obj_t *cs, int baudrate); +void common_hal_sdcardio_sdcard_deinit(sdcardio_sdcard_obj_t *self); +void common_hal_sdcardio_sdcard_check_for_deinit(sdcardio_sdcard_obj_t *self); +int common_hal_sdcardio_sdcard_get_blockcount(sdcardio_sdcard_obj_t *self); +int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf); +int common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf); diff --git a/shared-module/sdcardio/__init__ 2.c b/shared-module/sdcardio/__init__ 2.c new file mode 100644 index 000000000..e69de29bb diff --git a/shared-module/sdcardio/__init__ 2.h b/shared-module/sdcardio/__init__ 2.h new file mode 100644 index 000000000..e69de29bb diff --git a/supervisor/background_callback 2.h b/supervisor/background_callback 2.h new file mode 100644 index 000000000..535dd656b --- /dev/null +++ b/supervisor/background_callback 2.h @@ -0,0 +1,87 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#ifndef CIRCUITPY_INCLUDED_SUPERVISOR_BACKGROUND_CALLBACK_H +#define CIRCUITPY_INCLUDED_SUPERVISOR_BACKGROUND_CALLBACK_H + +/** Background callbacks are a linked list of tasks to call in the background. + * + * Include a member of type `background_callback_t` inside an object + * which needs to queue up background work, and zero-initialize it. + * + * To schedule the work, use background_callback_add, with fun as the + * function to call and data pointing to the object itself. + * + * Next time run_background_tasks_if_tick is called, the callback will + * be run and removed from the linked list. + * + * Queueing a task that is already queued does nothing. Unconditionally + * re-queueing it from its own background task will cause it to run during the + * very next background-tasks invocation, leading to a CircuitPython freeze, so + * don't do that. + * + * background_callback_add can be called from interrupt context. + */ +typedef void (*background_callback_fun)(void *data); +typedef struct background_callback { + background_callback_fun fun; + void *data; + struct background_callback *next; + struct background_callback *prev; +} background_callback_t; + +/* Add a background callback for which 'fun' and 'data' were previously set */ +void background_callback_add_core(background_callback_t *cb); + +/* Add a background callback to the given function with the given data. When + * the callback involves an object on the GC heap, the 'data' must be a pointer + * to that object itself, not an internal pointer. Otherwise, it can be the + * case that no other references to the object itself survive, and the object + * becomes garbage collected while an outstanding background callback still + * exists. + */ +void background_callback_add(background_callback_t *cb, background_callback_fun fun, void *data); + +/* Run all background callbacks. Normally, this is done by the supervisor + * whenever the list is non-empty */ +void background_callback_run_all(void); + +/* During soft reset, remove all pending callbacks and clear the critical section flag */ +void background_callback_reset(void); + +/* Sometimes background callbacks must be blocked. Use these functions to + * bracket the section of code where this is the case. These calls nest, and + * begins must be balanced with ends. + */ +void background_callback_begin_critical_section(void); +void background_callback_end_critical_section(void); + +/* + * Background callbacks may stop objects from being collected + */ +void background_callback_gc_collect(void); + +#endif diff --git a/supervisor/shared/background_callback 2.c b/supervisor/shared/background_callback 2.c new file mode 100644 index 000000000..8e12dd362 --- /dev/null +++ b/supervisor/shared/background_callback 2.c @@ -0,0 +1,138 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#include + +#include "py/gc.h" +#include "py/mpconfig.h" +#include "supervisor/background_callback.h" +#include "supervisor/shared/tick.h" +#include "shared-bindings/microcontroller/__init__.h" + +STATIC volatile background_callback_t *callback_head, *callback_tail; + +#define CALLBACK_CRITICAL_BEGIN (common_hal_mcu_disable_interrupts()) +#define CALLBACK_CRITICAL_END (common_hal_mcu_enable_interrupts()) + +void background_callback_add_core(background_callback_t *cb) { + CALLBACK_CRITICAL_BEGIN; + if (cb->prev || callback_head == cb) { + CALLBACK_CRITICAL_END; + return; + } + cb->next = 0; + cb->prev = (background_callback_t*)callback_tail; + if (callback_tail) { + callback_tail->next = cb; + cb->prev = (background_callback_t*)callback_tail; + } + if (!callback_head) { + callback_head = cb; + } + callback_tail = cb; + CALLBACK_CRITICAL_END; +} + +void background_callback_add(background_callback_t *cb, background_callback_fun fun, void *data) { + cb->fun = fun; + cb->data = data; + background_callback_add_core(cb); +} + +static bool in_background_callback; +void background_callback_run_all() { + if (!callback_head) { + return; + } + CALLBACK_CRITICAL_BEGIN; + if (in_background_callback) { + CALLBACK_CRITICAL_END; + return; + } + in_background_callback = true; + background_callback_t *cb = (background_callback_t*)callback_head; + callback_head = NULL; + callback_tail = NULL; + while (cb) { + background_callback_t *next = cb->next; + cb->next = cb->prev = NULL; + background_callback_fun fun = cb->fun; + void *data = cb->data; + CALLBACK_CRITICAL_END; + // Leave the critical section in order to run the callback function + if (fun) { + fun(data); + } + CALLBACK_CRITICAL_BEGIN; + cb = next; + } + in_background_callback = false; + CALLBACK_CRITICAL_END; +} + +void background_callback_begin_critical_section() { + CALLBACK_CRITICAL_BEGIN; +} + +void background_callback_end_critical_section() { + CALLBACK_CRITICAL_END; +} + +void background_callback_reset() { + CALLBACK_CRITICAL_BEGIN; + background_callback_t *cb = (background_callback_t*)callback_head; + while(cb) { + background_callback_t *next = cb->next; + memset(cb, 0, sizeof(*cb)); + cb = next; + } + callback_head = NULL; + callback_tail = NULL; + in_background_callback = false; + CALLBACK_CRITICAL_END; +} + +void background_callback_gc_collect(void) { + // We don't enter the callback critical section here. We rely on + // gc_collect_ptr _NOT_ entering background callbacks, so it is not + // possible for the list to be cleared. + // + // However, it is possible for the list to be extended. We make the + // minor assumption that no newly added callback is for a + // collectable object. That is, we only plug the hole where an + // object becomes collectable AFTER it is added but before the + // callback is run, not the hole where an object was ALREADY + // collectable but adds a background task for itself. + // + // It's necessary to traverse the whole list here, as the callbacks + // themselves can be in non-gc memory, and some of the cb->data + // objects themselves might be in non-gc memory. + background_callback_t *cb = (background_callback_t*)callback_head; + while(cb) { + gc_collect_ptr(cb->data); + cb = cb->next; + } +} -- cgit v1.2.3 From 4ba9ff892c2176d4aeefe1a8287cdb899acf5da1 Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Mon, 10 Aug 2020 11:04:56 -0500 Subject: Added bitmap.blit function for copying slices of bitmaps --- shared-bindings/displayio/Bitmap.c | 62 +++++++++++++++++++++++++++++++++++++- shared-bindings/displayio/Bitmap.h | 2 ++ shared-module/displayio/Bitmap.c | 31 +++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) (limited to 'shared-module') diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index 0a45bbdfd..56c6007f0 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -172,7 +172,66 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val return mp_const_none; } -//| def fill(self, value: int) -> None: +//| def blit(self, x: int, y: int, source_bitmap: bitmap, x1: int, y1: int, x2: int, y2:int) -> Any: +//| """Inserts the source_bitmap region defined by rectangular boundaries +//| (x1,y1) and (x2,y2) into the bitmap at the specified (x,y) location. +//| :param int x: Horizontal pixel location in bitmap where source_bitmap upper-left +//| corner will be placed +//| :param int y: Vertical pixel location in bitmap where source_bitmap upper-left +//| corner will be placed +//| :param bitmap source_bitmap: Source bitmap that contains the graphical region to be copied +//| : param x1: Minimum x-value for rectangular bounding box to be copied from the source bitmap +//| : param y1: Minimum y-value for rectangular bounding box to be copied from the source bitmap +//| : param x2: Maximum x-value for rectangular bounding box to be copied from the source bitmap +//| : param y2: Maximum y-value for rectangular bounding box to be copied from the source bitmap +//| +//| ... +//| + +STATIC mp_obj_t displayio_bitmap_obj_blit(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args){ + + // Consider improving the input checking. + + displayio_bitmap_t *self = MP_OBJ_TO_PTR(pos_args[0]); + int16_t x = mp_obj_get_int(pos_args[1]); + int16_t y = mp_obj_get_int(pos_args[2]); + displayio_bitmap_t *source = MP_OBJ_TO_PTR(pos_args[3]); + int16_t x1 = mp_obj_get_int(pos_args[4]); + int16_t y1 = mp_obj_get_int(pos_args[5]); + int16_t x2 = mp_obj_get_int(pos_args[6]); + int16_t y2 = mp_obj_get_int(pos_args[7]); + + if ( (x<0) || (y<0) || (x > self-> width) || (y > self->height) ) { + mp_raise_ValueError(translate("(x,y): out of range of target bitmap")); + } + if ( (x1 < 0) || (x1 > source->width) || + (y1 < 0) || (y1 > source->height) || + (x2 < 0) || (x2 > source->width) || + (y2 < 0) || (y2 > source->height) ) { + mp_raise_ValueError(translate("(x1,y1) or (x2,y2): out of range of source bitmap")); + } + + // Ensure x1 < x2 and y1 < y2 + if (x1 > x2) { + int16_t temp=x2; + x2=x1; + x1=temp; + } + if (y1 > y2) { + int16_t temp=y2; + y2=y1; + y1=temp; + } + + common_hal_displayio_bitmap_blit(self, x, y, source, x1, y1, x2, y2); + + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_KW(displayio_bitmap_blit_obj, 8, displayio_bitmap_obj_blit); +// requires 8 parameters + +//| def fill(self, value: Any) -> Any: //| """Fills the bitmap with the supplied palette index value.""" //| ... //| @@ -192,6 +251,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_bitmap_fill_obj, displayio_bitmap_obj_fill); STATIC const mp_rom_map_elem_t displayio_bitmap_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_bitmap_height_obj) }, { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_bitmap_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_blit), MP_ROM_PTR(&displayio_bitmap_blit_obj) }, { MP_ROM_QSTR(MP_QSTR_fill), MP_ROM_PTR(&displayio_bitmap_fill_obj) }, }; diff --git a/shared-bindings/displayio/Bitmap.h b/shared-bindings/displayio/Bitmap.h index 46c337329..8225af6c6 100644 --- a/shared-bindings/displayio/Bitmap.h +++ b/shared-bindings/displayio/Bitmap.h @@ -40,6 +40,8 @@ uint16_t common_hal_displayio_bitmap_get_height(displayio_bitmap_t *self); uint16_t common_hal_displayio_bitmap_get_width(displayio_bitmap_t *self); uint32_t common_hal_displayio_bitmap_get_bits_per_value(displayio_bitmap_t *self); void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *bitmap, int16_t x, int16_t y, uint32_t value); +void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16_t y, displayio_bitmap_t *source, + int16_t x1, int16_t y1, int16_t x2, int16_t y2); uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *bitmap, int16_t x, int16_t y); void common_hal_displayio_bitmap_fill(displayio_bitmap_t *bitmap, uint32_t value); diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index 8bcda6086..dde346ad3 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -105,6 +105,37 @@ uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *self, int16_t return 0; } +void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16_t y, displayio_bitmap_t *source, + int16_t x1, int16_t y1, int16_t x2, int16_t y2) { + // Copy complete "source" bitmap into "self" bitmap at location x,y in the "self" + // Add a boolean to determine if all values are copied, or only if non-zero + // Default is copy all values, but for text glyphs this should copy only non-zero values + + if (self->read_only) { + mp_raise_RuntimeError(translate("Read-only object")); + } + + // If this value is encountered in the source bitmap, it will not be copied (for text glyphs) + // This should be added as an optional parameter, and if it is `None`, then all pixels are copied + uint32_t skip_value=0; + + // simplest version - use internal functions for get/set pixels + for (uint16_t i=0; i<= (x2-x1) ; i++) { + if ( (x+i >= 0) && (x+i < self->width) ) { + for (uint16_t j=0; j<= (y2-y1) ; j++){ + if ((y+j >= 0) && (y+j < self->height) ) { + uint32_t value = common_hal_displayio_bitmap_get_pixel(source, x1+i, y1+j); + if ( (value != skip_value) ) { + common_hal_displayio_bitmap_set_pixel(self, x+i, y+j, value); + } + } + } + } + } + +} + + void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x, int16_t y, uint32_t value) { if (self->read_only) { mp_raise_RuntimeError(translate("Read-only object")); -- cgit v1.2.3 From 824f47d6e99d85b2b604db524c9e9178e0a99ceb Mon Sep 17 00:00:00 2001 From: Margaret Matocha Date: Wed, 12 Aug 2020 21:50:17 -0500 Subject: Added bitmap.blit function for bitmap slice copy --- shared-bindings/displayio/Bitmap.c | 100 +++++++++++++++++++++++++++---------- shared-bindings/displayio/Bitmap.h | 3 +- shared-module/displayio/Bitmap.c | 16 +++--- 3 files changed, 84 insertions(+), 35 deletions(-) (limited to 'shared-module') diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index 56c6007f0..af9f6c3c8 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -172,7 +172,7 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val return mp_const_none; } -//| def blit(self, x: int, y: int, source_bitmap: bitmap, x1: int, y1: int, x2: int, y2:int) -> Any: +//| def blit(self, x: int, y: int, source_bitmap: bitmap, x1: int, y1: int, x2: int, y2: int, skip_index: int) -> Any: //| """Inserts the source_bitmap region defined by rectangular boundaries //| (x1,y1) and (x2,y2) into the bitmap at the specified (x,y) location. //| :param int x: Horizontal pixel location in bitmap where source_bitmap upper-left @@ -180,34 +180,74 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val //| :param int y: Vertical pixel location in bitmap where source_bitmap upper-left //| corner will be placed //| :param bitmap source_bitmap: Source bitmap that contains the graphical region to be copied -//| : param x1: Minimum x-value for rectangular bounding box to be copied from the source bitmap -//| : param y1: Minimum y-value for rectangular bounding box to be copied from the source bitmap -//| : param x2: Maximum x-value for rectangular bounding box to be copied from the source bitmap -//| : param y2: Maximum y-value for rectangular bounding box to be copied from the source bitmap -//| +//| : param int x1: Minimum x-value for rectangular bounding box to be copied from the source bitmap +//| : param int y1: Minimum y-value for rectangular bounding box to be copied from the source bitmap +//| : param int x2: Maximum x-value for rectangular bounding box to be copied from the source bitmap +//| : param int y2: Maximum y-value for rectangular bounding box to be copied from the source bitmap +//| : param int skip_index: bitmap palette index in the source that will not be copied, set `None` to copy all pixels //| ... //| STATIC mp_obj_t displayio_bitmap_obj_blit(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args){ + enum {ARG_x, ARG_y, ARG_source, ARG_x1, ARG_y1, ARG_x2, ARG_y2, ARG_skip_index}; + static const mp_arg_t allowed_args[] = { + {MP_QSTR_x, MP_ARG_REQUIRED | MP_ARG_INT}, + {MP_QSTR_y, MP_ARG_REQUIRED | MP_ARG_INT}, + {MP_QSTR_source, MP_ARG_REQUIRED | MP_ARG_OBJ}, + {MP_QSTR_x1, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + {MP_QSTR_y1, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + {MP_QSTR_x2, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, // None convert to source->width + {MP_QSTR_y2, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, // None convert to source->height + {MP_QSTR_skip_index, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj=mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + displayio_bitmap_t *self = MP_OBJ_TO_PTR(pos_args[0]); //******* + + int16_t x = args[ARG_x].u_int; + int16_t y = args[ARG_y].u_int; + + displayio_bitmap_t *source = MP_OBJ_TO_PTR(args[ARG_source].u_obj); + + int16_t x1, y1; + // if x1 or y1 is None, then set as the zero-point of the bitmap + if ( args[ARG_x1].u_obj == mp_const_none ) { + x1 = 0; + } else { + x1 = mp_obj_get_int(args[ARG_x1].u_obj); + } + //int16_t y1; + if ( args[ARG_y1].u_obj == mp_const_none ) { + y1 = 0; + } else { + y1 = mp_obj_get_int(args[ARG_y1].u_obj); + } + + int16_t x2, y2; + // if x2 or y2 is None, then set as the maximum size of the source bitmap + if ( args[ARG_x2].u_obj == mp_const_none ) { + x2 = source->width-1; + } else { + x2 = mp_obj_get_int(args[ARG_x2].u_obj); + } + //int16_t y2; + if ( args[ARG_y2].u_obj == mp_const_none ) { + y2 = source->height-1; + } else { + y2 = mp_obj_get_int(args[ARG_y2].u_obj); + } - // Consider improving the input checking. - - displayio_bitmap_t *self = MP_OBJ_TO_PTR(pos_args[0]); - int16_t x = mp_obj_get_int(pos_args[1]); - int16_t y = mp_obj_get_int(pos_args[2]); - displayio_bitmap_t *source = MP_OBJ_TO_PTR(pos_args[3]); - int16_t x1 = mp_obj_get_int(pos_args[4]); - int16_t y1 = mp_obj_get_int(pos_args[5]); - int16_t x2 = mp_obj_get_int(pos_args[6]); - int16_t y2 = mp_obj_get_int(pos_args[7]); - if ( (x<0) || (y<0) || (x > self-> width) || (y > self->height) ) { + // Check x,y are within self (target) bitmap boundary + if ( (x < 0) || (y < 0) || (x >= self->width) || (y >= self->height) ) { mp_raise_ValueError(translate("(x,y): out of range of target bitmap")); } - if ( (x1 < 0) || (x1 > source->width) || - (y1 < 0) || (y1 > source->height) || - (x2 < 0) || (x2 > source->width) || - (y2 < 0) || (y2 > source->height) ) { + // Check x1,y1,x2,y2 are within source bitmap boundary + if ( (x1 < 0) || (x1 >= source->width) || + (y1 < 0) || (y1 >= source->height) || + (x2 < 0) || (x2 >= source->width) || + (y2 < 0) || (y2 >= source->height) ) { mp_raise_ValueError(translate("(x1,y1) or (x2,y2): out of range of source bitmap")); } @@ -223,13 +263,23 @@ STATIC mp_obj_t displayio_bitmap_obj_blit(size_t n_args, const mp_obj_t *pos_arg y1=temp; } - common_hal_displayio_bitmap_blit(self, x, y, source, x1, y1, x2, y2); + uint32_t skip_index; + bool skip_index_none; // flag whether skip_value was None + + if (args[ARG_skip_index].u_obj == mp_const_none ) { + skip_index = 0; + skip_index_none = true; + } else { + skip_index = mp_obj_get_int(args[ARG_skip_index].u_obj); + skip_index_none = false; + } + + common_hal_displayio_bitmap_blit(self, x, y, source, x1, y1, x2, y2, skip_index, skip_index_none); return mp_const_none; } - -MP_DEFINE_CONST_FUN_OBJ_KW(displayio_bitmap_blit_obj, 8, displayio_bitmap_obj_blit); -// requires 8 parameters +MP_DEFINE_CONST_FUN_OBJ_KW(displayio_bitmap_blit_obj, 4, displayio_bitmap_obj_blit); +// `displayio_bitmap_obj_blit` requires at least 4 arguments //| def fill(self, value: Any) -> Any: //| """Fills the bitmap with the supplied palette index value.""" diff --git a/shared-bindings/displayio/Bitmap.h b/shared-bindings/displayio/Bitmap.h index 8225af6c6..cf75f3d76 100644 --- a/shared-bindings/displayio/Bitmap.h +++ b/shared-bindings/displayio/Bitmap.h @@ -41,7 +41,8 @@ uint16_t common_hal_displayio_bitmap_get_width(displayio_bitmap_t *self); uint32_t common_hal_displayio_bitmap_get_bits_per_value(displayio_bitmap_t *self); void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *bitmap, int16_t x, int16_t y, uint32_t value); void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16_t y, displayio_bitmap_t *source, - int16_t x1, int16_t y1, int16_t x2, int16_t y2); + int16_t x1, int16_t y1, int16_t x2, int16_t y2, + uint32_t skip_index, bool skip_index_none); uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *bitmap, int16_t x, int16_t y); void common_hal_displayio_bitmap_fill(displayio_bitmap_t *bitmap, uint32_t value); diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index dde346ad3..dbcba6b58 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -106,26 +106,24 @@ uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *self, int16_t } void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16_t y, displayio_bitmap_t *source, - int16_t x1, int16_t y1, int16_t x2, int16_t y2) { + int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint32_t skip_index, bool skip_index_none) { // Copy complete "source" bitmap into "self" bitmap at location x,y in the "self" // Add a boolean to determine if all values are copied, or only if non-zero - // Default is copy all values, but for text glyphs this should copy only non-zero values + // + // If skip_value is encountered in the source bitmap, it will not be copied. + // If skip_value is `None`, then all pixels are copied. if (self->read_only) { mp_raise_RuntimeError(translate("Read-only object")); } - // If this value is encountered in the source bitmap, it will not be copied (for text glyphs) - // This should be added as an optional parameter, and if it is `None`, then all pixels are copied - uint32_t skip_value=0; - // simplest version - use internal functions for get/set pixels - for (uint16_t i=0; i<= (x2-x1) ; i++) { + for (int16_t i=0; i<= (x2-x1) ; i++) { if ( (x+i >= 0) && (x+i < self->width) ) { - for (uint16_t j=0; j<= (y2-y1) ; j++){ + for (int16_t j=0; j<= (y2-y1) ; j++){ if ((y+j >= 0) && (y+j < self->height) ) { uint32_t value = common_hal_displayio_bitmap_get_pixel(source, x1+i, y1+j); - if ( (value != skip_value) ) { + if ( (skip_index_none) || (value != skip_index) ) { // write if skip_value_none is True common_hal_displayio_bitmap_set_pixel(self, x+i, y+j, value); } } -- cgit v1.2.3 From a66ef32da2fee0077f7917071294fa54b689e2e9 Mon Sep 17 00:00:00 2001 From: Kevin Matocha Date: Thu, 13 Aug 2020 17:03:06 -0500 Subject: Added inclusive indexing for x2,y2, fixed default value handling for x1,y1, added bitmap palette comparison --- locale/circuitpython.pot | 40 +++++++++++++++++++++++++++++++-- shared-bindings/displayio/Bitmap.c | 45 +++++++++++++++----------------------- shared-module/displayio/Bitmap.c | 4 ++-- 3 files changed, 58 insertions(+), 31 deletions(-) (limited to 'shared-module') diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index a1b286e2e..3eb5b1ced 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-14 09:36-0400\n" +"POT-Creation-Date: 2020-08-14 13:10-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -82,6 +82,8 @@ msgstr "" msgid "%q list must be a list" msgstr "" +#: shared-bindings/memorymonitor/AllocationAlarm 3.c +#: shared-bindings/memorymonitor/AllocationAlarm 4.c #: shared-bindings/memorymonitor/AllocationAlarm.c msgid "%q must be >= 0" msgstr "" @@ -89,6 +91,8 @@ msgstr "" #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c #: shared-bindings/displayio/Shape.c +#: shared-bindings/memorymonitor/AllocationAlarm 3.c +#: shared-bindings/memorymonitor/AllocationAlarm 4.c #: shared-bindings/memorymonitor/AllocationAlarm.c #: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c msgid "%q must be >= 1" @@ -252,6 +256,14 @@ msgstr "" msgid "'yield' outside function" msgstr "" +#: shared-bindings/displayio/Bitmap.c +msgid "(x,y): out of range of target bitmap" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "(x1,y1) or (x2,y2): out of range of source bitmap" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "" @@ -306,6 +318,7 @@ msgstr "" msgid "All timers for this pin are in use" msgstr "" +#: ports/atmel-samd/common-hal/_pew/PewPew 2.c #: ports/atmel-samd/common-hal/_pew/PewPew.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c @@ -322,7 +335,11 @@ msgstr "" msgid "Already advertising." msgstr "" +#: shared-module/memorymonitor/AllocationAlarm 3.c +#: shared-module/memorymonitor/AllocationAlarm 4.c #: shared-module/memorymonitor/AllocationAlarm.c +#: shared-module/memorymonitor/AllocationSize 3.c +#: shared-module/memorymonitor/AllocationSize 4.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "" @@ -362,6 +379,8 @@ msgstr "" msgid "At most %d %q may be specified (not %d)" msgstr "" +#: shared-module/memorymonitor/AllocationAlarm 3.c +#: shared-module/memorymonitor/AllocationAlarm 4.c #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" @@ -491,6 +510,12 @@ msgid "Can't set CCCD on local Characteristic" msgstr "" #: shared-bindings/displayio/Bitmap.c +msgid "Cannot blit: source palette too large." +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +#: shared-bindings/memorymonitor/AllocationSize 3.c +#: shared-bindings/memorymonitor/AllocationSize 4.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c msgid "Cannot delete values" @@ -1014,6 +1039,7 @@ msgstr "" #: ports/atmel-samd/common-hal/busio/I2C.c #: ports/atmel-samd/common-hal/busio/SPI.c #: ports/atmel-samd/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/i2cperipheral/I2CPeripheral 2.c #: ports/atmel-samd/common-hal/i2cperipheral/I2CPeripheral.c #: ports/cxd56/common-hal/busio/I2C.c ports/cxd56/common-hal/busio/SPI.c #: ports/cxd56/common-hal/busio/UART.c ports/cxd56/common-hal/sdioio/SDCard.c @@ -1370,6 +1396,8 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/memorymonitor/AllocationSize 3.c +#: shared-bindings/memorymonitor/AllocationSize 4.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c msgid "Read-only" @@ -1462,6 +1490,8 @@ msgstr "" #: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c #: shared-bindings/displayio/TileGrid.c +#: shared-bindings/memorymonitor/AllocationSize 3.c +#: shared-bindings/memorymonitor/AllocationSize 4.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c msgid "Slices not supported" @@ -1791,10 +1821,14 @@ msgstr "" msgid "address %08x is not aligned to %d bytes" msgstr "" +#: shared-bindings/i2cperipheral/I2CPeripheral 3.c +#: shared-bindings/i2cperipheral/I2CPeripheral 4.c #: shared-bindings/i2cperipheral/I2CPeripheral.c msgid "address out of bounds" msgstr "" +#: shared-bindings/i2cperipheral/I2CPeripheral 3.c +#: shared-bindings/i2cperipheral/I2CPeripheral 4.c #: shared-bindings/i2cperipheral/I2CPeripheral.c msgid "addresses is empty" msgstr "" @@ -1957,7 +1991,9 @@ msgstr "" msgid "can't assign to expression" msgstr "" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c +#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral 3.c +#: shared-bindings/i2cperipheral/I2CPeripheral 4.c +#: shared-bindings/i2cperipheral/I2CPeripheral.c msgid "can't convert %q to %q" msgstr "" diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index af9f6c3c8..5852f1a70 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -172,7 +172,7 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val return mp_const_none; } -//| def blit(self, x: int, y: int, source_bitmap: bitmap, x1: int, y1: int, x2: int, y2: int, skip_index: int) -> Any: +//| def blit(self, x: int, y: int, source_bitmap: bitmap, *, x1: int, y1: int, x2: int, y2: int, skip_index: int) -> Any: //| """Inserts the source_bitmap region defined by rectangular boundaries //| (x1,y1) and (x2,y2) into the bitmap at the specified (x,y) location. //| :param int x: Horizontal pixel location in bitmap where source_bitmap upper-left @@ -193,9 +193,9 @@ STATIC mp_obj_t displayio_bitmap_obj_blit(size_t n_args, const mp_obj_t *pos_arg static const mp_arg_t allowed_args[] = { {MP_QSTR_x, MP_ARG_REQUIRED | MP_ARG_INT}, {MP_QSTR_y, MP_ARG_REQUIRED | MP_ARG_INT}, - {MP_QSTR_source, MP_ARG_REQUIRED | MP_ARG_OBJ}, - {MP_QSTR_x1, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - {MP_QSTR_y1, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + {MP_QSTR_source_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ}, + {MP_QSTR_x1, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = 0} }, + {MP_QSTR_y1, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = 0} }, {MP_QSTR_x2, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, // None convert to source->width {MP_QSTR_y2, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, // None convert to source->height {MP_QSTR_skip_index, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj=mp_const_none} }, @@ -203,51 +203,42 @@ STATIC mp_obj_t displayio_bitmap_obj_blit(size_t n_args, const mp_obj_t *pos_arg mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - displayio_bitmap_t *self = MP_OBJ_TO_PTR(pos_args[0]); //******* + displayio_bitmap_t *self = MP_OBJ_TO_PTR(pos_args[0]); int16_t x = args[ARG_x].u_int; int16_t y = args[ARG_y].u_int; displayio_bitmap_t *source = MP_OBJ_TO_PTR(args[ARG_source].u_obj); - int16_t x1, y1; - // if x1 or y1 is None, then set as the zero-point of the bitmap - if ( args[ARG_x1].u_obj == mp_const_none ) { - x1 = 0; - } else { - x1 = mp_obj_get_int(args[ARG_x1].u_obj); - } - //int16_t y1; - if ( args[ARG_y1].u_obj == mp_const_none ) { - y1 = 0; - } else { - y1 = mp_obj_get_int(args[ARG_y1].u_obj); + // ensure that the target bitmap (self) has at least as many `bits_per_value` as the source + if (self->bits_per_value < source->bits_per_value) { + mp_raise_ValueError(translate("Cannot blit: source palette too large.")); } - - int16_t x2, y2; + + int16_t x1, y1, x2, y2; // if x2 or y2 is None, then set as the maximum size of the source bitmap if ( args[ARG_x2].u_obj == mp_const_none ) { - x2 = source->width-1; + x2 = source->width; } else { x2 = mp_obj_get_int(args[ARG_x2].u_obj); } //int16_t y2; if ( args[ARG_y2].u_obj == mp_const_none ) { - y2 = source->height-1; + y2 = source->height; } else { y2 = mp_obj_get_int(args[ARG_y2].u_obj); } // Check x,y are within self (target) bitmap boundary - if ( (x < 0) || (y < 0) || (x >= self->width) || (y >= self->height) ) { + if ( (x < 0) || (y < 0) || (x > self->width) || (y > self->height) ) { mp_raise_ValueError(translate("(x,y): out of range of target bitmap")); } // Check x1,y1,x2,y2 are within source bitmap boundary - if ( (x1 < 0) || (x1 >= source->width) || - (y1 < 0) || (y1 >= source->height) || - (x2 < 0) || (x2 >= source->width) || - (y2 < 0) || (y2 >= source->height) ) { + if ( (x1 < 0) || (x1 > source->width) || + (y1 < 0) || (y1 > source->height) || + (x2 < 0) || (x2 > source->width) || + (y2 < 0) || (y2 > source->height) ) { mp_raise_ValueError(translate("(x1,y1) or (x2,y2): out of range of source bitmap")); } @@ -272,7 +263,7 @@ STATIC mp_obj_t displayio_bitmap_obj_blit(size_t n_args, const mp_obj_t *pos_arg } else { skip_index = mp_obj_get_int(args[ARG_skip_index].u_obj); skip_index_none = false; - } + } common_hal_displayio_bitmap_blit(self, x, y, source, x1, y1, x2, y2, skip_index, skip_index_none); diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index dbcba6b58..7de9e9755 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -118,9 +118,9 @@ void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16 } // simplest version - use internal functions for get/set pixels - for (int16_t i=0; i<= (x2-x1) ; i++) { + for (int16_t i=0; i < (x2-x1) ; i++) { if ( (x+i >= 0) && (x+i < self->width) ) { - for (int16_t j=0; j<= (y2-y1) ; j++){ + for (int16_t j=0; j < (y2-y1) ; j++){ if ((y+j >= 0) && (y+j < self->height) ) { uint32_t value = common_hal_displayio_bitmap_get_pixel(source, x1+i, y1+j); if ( (skip_index_none) || (value != skip_index) ) { // write if skip_value_none is True -- cgit v1.2.3 From b1fce9e933275cd9d945ec46c3ea8eaa350e6a67 Mon Sep 17 00:00:00 2001 From: Kevin Matocha Date: Thu, 13 Aug 2020 19:56:45 -0500 Subject: Deleted trailing whitespace --- shared-bindings/displayio/Bitmap.c | 13 ++++++------- shared-bindings/displayio/Bitmap.h | 4 ++-- shared-module/displayio/Bitmap.c | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) (limited to 'shared-module') diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index 5852f1a70..9479dc1a5 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -184,7 +184,8 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val //| : param int y1: Minimum y-value for rectangular bounding box to be copied from the source bitmap //| : param int x2: Maximum x-value for rectangular bounding box to be copied from the source bitmap //| : param int y2: Maximum y-value for rectangular bounding box to be copied from the source bitmap -//| : param int skip_index: bitmap palette index in the source that will not be copied, set `None` to copy all pixels +//| : param int skip_index: bitmap palette index in the source that will not be copied, +//| set `None` to copy all pixels""" //| ... //| @@ -229,19 +230,17 @@ STATIC mp_obj_t displayio_bitmap_obj_blit(size_t n_args, const mp_obj_t *pos_arg y2 = mp_obj_get_int(args[ARG_y2].u_obj); } - // Check x,y are within self (target) bitmap boundary if ( (x < 0) || (y < 0) || (x > self->width) || (y > self->height) ) { mp_raise_ValueError(translate("(x,y): out of range of target bitmap")); } // Check x1,y1,x2,y2 are within source bitmap boundary - if ( (x1 < 0) || (x1 > source->width) || - (y1 < 0) || (y1 > source->height) || + if ( (x1 < 0) || (x1 > source->width) || + (y1 < 0) || (y1 > source->height) || (x2 < 0) || (x2 > source->width) || (y2 < 0) || (y2 > source->height) ) { mp_raise_ValueError(translate("(x1,y1) or (x2,y2): out of range of source bitmap")); } - // Ensure x1 < x2 and y1 < y2 if (x1 > x2) { int16_t temp=x2; @@ -254,7 +253,7 @@ STATIC mp_obj_t displayio_bitmap_obj_blit(size_t n_args, const mp_obj_t *pos_arg y1=temp; } - uint32_t skip_index; + uint32_t skip_index; bool skip_index_none; // flag whether skip_value was None if (args[ARG_skip_index].u_obj == mp_const_none ) { @@ -263,7 +262,7 @@ STATIC mp_obj_t displayio_bitmap_obj_blit(size_t n_args, const mp_obj_t *pos_arg } else { skip_index = mp_obj_get_int(args[ARG_skip_index].u_obj); skip_index_none = false; - } + } common_hal_displayio_bitmap_blit(self, x, y, source, x1, y1, x2, y2, skip_index, skip_index_none); diff --git a/shared-bindings/displayio/Bitmap.h b/shared-bindings/displayio/Bitmap.h index cf75f3d76..00cd98b0a 100644 --- a/shared-bindings/displayio/Bitmap.h +++ b/shared-bindings/displayio/Bitmap.h @@ -40,8 +40,8 @@ uint16_t common_hal_displayio_bitmap_get_height(displayio_bitmap_t *self); uint16_t common_hal_displayio_bitmap_get_width(displayio_bitmap_t *self); uint32_t common_hal_displayio_bitmap_get_bits_per_value(displayio_bitmap_t *self); void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *bitmap, int16_t x, int16_t y, uint32_t value); -void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16_t y, displayio_bitmap_t *source, - int16_t x1, int16_t y1, int16_t x2, int16_t y2, +void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16_t y, displayio_bitmap_t *source, + int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint32_t skip_index, bool skip_index_none); uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *bitmap, int16_t x, int16_t y); void common_hal_displayio_bitmap_fill(displayio_bitmap_t *bitmap, uint32_t value); diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index 7de9e9755..e581d849d 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -110,7 +110,7 @@ void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16 // Copy complete "source" bitmap into "self" bitmap at location x,y in the "self" // Add a boolean to determine if all values are copied, or only if non-zero // - // If skip_value is encountered in the source bitmap, it will not be copied. + // If skip_value is encountered in the source bitmap, it will not be copied. // If skip_value is `None`, then all pixels are copied. if (self->read_only) { -- cgit v1.2.3 From ba5dedc1df768bfac05db844f6220c4756c24223 Mon Sep 17 00:00:00 2001 From: Kevin Matocha Date: Thu, 13 Aug 2020 20:57:17 -0500 Subject: deleted whitespace --- shared-module/displayio/Bitmap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'shared-module') diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index e581d849d..b470cecc3 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -105,11 +105,10 @@ uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *self, int16_t return 0; } -void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16_t y, displayio_bitmap_t *source, - int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint32_t skip_index, bool skip_index_none) { +void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16_t y, displayio_bitmap_t *source, + int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint32_t skip_index, bool skip_index_none) { // Copy complete "source" bitmap into "self" bitmap at location x,y in the "self" // Add a boolean to determine if all values are copied, or only if non-zero - // // If skip_value is encountered in the source bitmap, it will not be copied. // If skip_value is `None`, then all pixels are copied. -- cgit v1.2.3 From fc1347ac2a0b467c1cbd9ac4a8ecf117bcdbb96a Mon Sep 17 00:00:00 2001 From: Kevin Matocha Date: Thu, 13 Aug 2020 20:58:29 -0500 Subject: deleted whitespace --- shared-module/displayio/Bitmap.c | 1 - 1 file changed, 1 deletion(-) (limited to 'shared-module') diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index b470cecc3..2f87a8944 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -129,7 +129,6 @@ void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16 } } } - } -- cgit v1.2.3 From 1ccd2e234f336872b646ba978ac139dcdc7dc84f Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 17 Aug 2020 10:48:23 -0500 Subject: allocate_display_bus: fix bug where in-use bus would be returned --- shared-module/displayio/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-module') diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 5afcba35e..8049be5b4 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -398,7 +398,7 @@ primary_display_t *allocate_display_or_raise(void) { } primary_display_t *allocate_display_bus(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - mp_const_obj_t display_type = displays[i].display.base.type; + mp_const_obj_t display_type = displays[i].bus_base.type; if (display_type == NULL || display_type == &mp_type_NoneType) { return &displays[i]; } -- cgit v1.2.3 From 6425a411ca7e53b8cdc6c8399c6cd717f39e25fe Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 17 Aug 2020 21:07:24 -0500 Subject: Update shared-module/displayio/__init__.c Co-authored-by: Scott Shawcroft --- shared-module/displayio/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-module') diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 8049be5b4..73626ce15 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -398,7 +398,7 @@ primary_display_t *allocate_display_or_raise(void) { } primary_display_t *allocate_display_bus(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - mp_const_obj_t display_type = displays[i].bus_base.type; + mp_const_obj_t display_bus_type = displays[i].bus_base.type; if (display_type == NULL || display_type == &mp_type_NoneType) { return &displays[i]; } -- cgit v1.2.3 From 6d2d36db3d161fefadd52cc1f2d5a9da99bb2dc9 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 17 Aug 2020 21:09:21 -0500 Subject: Finish implementing scott's suggestion --- shared-module/displayio/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-module') diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 73626ce15..295af3e7c 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -399,7 +399,7 @@ primary_display_t *allocate_display_or_raise(void) { primary_display_t *allocate_display_bus(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { mp_const_obj_t display_bus_type = displays[i].bus_base.type; - if (display_type == NULL || display_type == &mp_type_NoneType) { + if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) { return &displays[i]; } } -- cgit v1.2.3 From dc502a5f26fdf5514eb835fae5f523c1b15c23b5 Mon Sep 17 00:00:00 2001 From: Kevin Matocha Date: Fri, 21 Aug 2020 19:08:25 -0500 Subject: remove extraneous files --- shared-bindings/_typing/__init__ 2.pyi | 54 --- shared-bindings/gnss/GNSS 2.c | 205 ---------- shared-bindings/gnss/GNSS 2.h | 27 -- shared-bindings/gnss/PositionFix 2.c | 80 ---- shared-bindings/gnss/PositionFix 2.h | 28 -- shared-bindings/gnss/SatelliteSystem 2.c | 113 ------ shared-bindings/gnss/SatelliteSystem 2.h | 33 -- shared-bindings/gnss/__init__ 2.c | 31 -- shared-bindings/i2cperipheral/I2CPeripheral 2.c | 436 -------------------- shared-bindings/i2cperipheral/I2CPeripheral 2.h | 60 --- shared-bindings/i2cperipheral/__init__ 2.c | 106 ----- shared-bindings/memorymonitor/AllocationAlarm 2.c | 137 ------- shared-bindings/memorymonitor/AllocationAlarm 2.h | 39 -- shared-bindings/memorymonitor/AllocationSize 2.c | 183 --------- shared-bindings/memorymonitor/AllocationSize 2.h | 42 -- shared-bindings/memorymonitor/__init__ 2.c | 76 ---- shared-bindings/memorymonitor/__init__ 2.h | 49 --- shared-bindings/sdcardio/SDCard 2.c | 183 --------- shared-bindings/sdcardio/SDCard 2.h | 30 -- shared-bindings/sdcardio/__init__ 2.c | 47 --- shared-bindings/sdcardio/__init__ 2.h | 0 shared-module/sdcardio/SDCard 2.c | 466 ---------------------- shared-module/sdcardio/SDCard 2.h | 51 --- shared-module/sdcardio/__init__ 2.c | 0 shared-module/sdcardio/__init__ 2.h | 0 supervisor/background_callback 2.h | 87 ---- supervisor/shared/background_callback 2.c | 138 ------- 27 files changed, 2701 deletions(-) delete mode 100644 shared-bindings/_typing/__init__ 2.pyi delete mode 100644 shared-bindings/gnss/GNSS 2.c delete mode 100644 shared-bindings/gnss/GNSS 2.h delete mode 100644 shared-bindings/gnss/PositionFix 2.c delete mode 100644 shared-bindings/gnss/PositionFix 2.h delete mode 100644 shared-bindings/gnss/SatelliteSystem 2.c delete mode 100644 shared-bindings/gnss/SatelliteSystem 2.h delete mode 100644 shared-bindings/gnss/__init__ 2.c delete mode 100644 shared-bindings/i2cperipheral/I2CPeripheral 2.c delete mode 100644 shared-bindings/i2cperipheral/I2CPeripheral 2.h delete mode 100644 shared-bindings/i2cperipheral/__init__ 2.c delete mode 100644 shared-bindings/memorymonitor/AllocationAlarm 2.c delete mode 100644 shared-bindings/memorymonitor/AllocationAlarm 2.h delete mode 100644 shared-bindings/memorymonitor/AllocationSize 2.c delete mode 100644 shared-bindings/memorymonitor/AllocationSize 2.h delete mode 100644 shared-bindings/memorymonitor/__init__ 2.c delete mode 100644 shared-bindings/memorymonitor/__init__ 2.h delete mode 100644 shared-bindings/sdcardio/SDCard 2.c delete mode 100644 shared-bindings/sdcardio/SDCard 2.h delete mode 100644 shared-bindings/sdcardio/__init__ 2.c delete mode 100644 shared-bindings/sdcardio/__init__ 2.h delete mode 100644 shared-module/sdcardio/SDCard 2.c delete mode 100644 shared-module/sdcardio/SDCard 2.h delete mode 100644 shared-module/sdcardio/__init__ 2.c delete mode 100644 shared-module/sdcardio/__init__ 2.h delete mode 100644 supervisor/background_callback 2.h delete mode 100644 supervisor/shared/background_callback 2.c (limited to 'shared-module') diff --git a/shared-bindings/_typing/__init__ 2.pyi b/shared-bindings/_typing/__init__ 2.pyi deleted file mode 100644 index 48e68a8d5..000000000 --- a/shared-bindings/_typing/__init__ 2.pyi +++ /dev/null @@ -1,54 +0,0 @@ -"""Types for the C-level protocols""" - -from typing import Union - -import array -import audiocore -import audiomixer -import audiomp3 -import rgbmatrix -import ulab - -ReadableBuffer = Union[ - bytes, bytearray, memoryview, array.array, ulab.array, rgbmatrix.RGBMatrix -] -"""Classes that implement the readable buffer protocol - - - `bytes` - - `bytearray` - - `memoryview` - - `array.array` - - `ulab.array` - - `rgbmatrix.RGBMatrix` -""" - -WriteableBuffer = Union[ - bytearray, memoryview, array.array, ulab.array, rgbmatrix.RGBMatrix -] -"""Classes that implement the writeable buffer protocol - - - `bytearray` - - `memoryview` - - `array.array` - - `ulab.array` - - `rgbmatrix.RGBMatrix` -""" - -AudioSample = Union[ - audiocore.WaveFile, audiocore.RawSample, audiomixer.Mixer, audiomp3.MP3Decoder -] -"""Classes that implement the audiosample protocol - - - `audiocore.WaveFile` - - `audiocore.RawSample` - - `audiomixer.Mixer` - - `audiomp3.MP3Decoder` - - You can play these back with `audioio.AudioOut`, `audiobusio.I2SOut` or `audiopwmio.PWMAudioOut`. -""" - -FrameBuffer = Union[rgbmatrix.RGBMatrix] -"""Classes that implement the framebuffer protocol - - - `rgbmatrix.RGBMatrix` -""" diff --git a/shared-bindings/gnss/GNSS 2.c b/shared-bindings/gnss/GNSS 2.c deleted file mode 100644 index 087c35395..000000000 --- a/shared-bindings/gnss/GNSS 2.c +++ /dev/null @@ -1,205 +0,0 @@ -// SPDX-FileCopyrightText: Sony Semiconductor Solutions Corporation -// -// SPDX-License-Identifier: MIT - -#include "shared-bindings/gnss/GNSS.h" -#include "shared-bindings/time/__init__.h" -#include "shared-bindings/util.h" - -#include "py/objproperty.h" -#include "py/runtime.h" - -//| class GNSS: -//| """Get updated positioning information from Global Navigation Satellite System (GNSS) -//| -//| Usage:: -//| -//| import gnss -//| import time -//| -//| nav = gnss.GNSS([gnss.SatelliteSystem.GPS, gnss.SatelliteSystem.GLONASS]) -//| last_print = time.monotonic() -//| while True: -//| nav.update() -//| current = time.monotonic() -//| if current - last_print >= 1.0: -//| last_print = current -//| if nav.fix is gnss.PositionFix.INVALID: -//| print("Waiting for fix...") -//| continue -//| print("Latitude: {0:.6f} degrees".format(nav.latitude)) -//| print("Longitude: {0:.6f} degrees".format(nav.longitude))""" -//| - -//| def __init__(self, system: Union[SatelliteSystem, List[SatelliteSystem]]) -> None: -//| """Turn on the GNSS. -//| -//| :param system: satellite system to use""" -//| ... -//| -STATIC mp_obj_t gnss_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - gnss_obj_t *self = m_new_obj(gnss_obj_t); - self->base.type = &gnss_type; - enum { ARG_system }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_system, MP_ARG_REQUIRED | MP_ARG_OBJ }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - unsigned long selection = 0; - if (MP_OBJ_IS_TYPE(args[ARG_system].u_obj, &gnss_satellitesystem_type)) { - selection |= gnss_satellitesystem_obj_to_type(args[ARG_system].u_obj); - } else if (MP_OBJ_IS_TYPE(args[ARG_system].u_obj, &mp_type_list)) { - size_t systems_size = 0; - mp_obj_t *systems; - mp_obj_list_get(args[ARG_system].u_obj, &systems_size, &systems); - for (size_t i = 0; i < systems_size; ++i) { - if (!MP_OBJ_IS_TYPE(systems[i], &gnss_satellitesystem_type)) { - mp_raise_TypeError(translate("System entry must be gnss.SatelliteSystem")); - } - selection |= gnss_satellitesystem_obj_to_type(systems[i]); - } - } else { - mp_raise_TypeError(translate("System entry must be gnss.SatelliteSystem")); - } - - common_hal_gnss_construct(self, selection); - return MP_OBJ_FROM_PTR(self); -} - -//| def deinit(self) -> None: -//| """Turn off the GNSS.""" -//| ... -//| -STATIC mp_obj_t gnss_obj_deinit(mp_obj_t self_in) { - gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_gnss_deinit(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(gnss_deinit_obj, gnss_obj_deinit); - -STATIC void check_for_deinit(gnss_obj_t *self) { - if (common_hal_gnss_deinited(self)) { - raise_deinited_error(); - } -} - -//| def update(self) -> None: -//| """Update GNSS positioning information.""" -//| ... -//| -STATIC mp_obj_t gnss_obj_update(mp_obj_t self_in) { - gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - - common_hal_gnss_update(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(gnss_update_obj, gnss_obj_update); - -//| latitude: float -//| """Latitude of current position in degrees (float).""" -//| -STATIC mp_obj_t gnss_obj_get_latitude(mp_obj_t self_in) { - gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_float(common_hal_gnss_get_latitude(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(gnss_get_latitude_obj, gnss_obj_get_latitude); - -const mp_obj_property_t gnss_latitude_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&gnss_get_latitude_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| longitude: float -//| """Longitude of current position in degrees (float).""" -//| -STATIC mp_obj_t gnss_obj_get_longitude(mp_obj_t self_in) { - gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_float(common_hal_gnss_get_longitude(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(gnss_get_longitude_obj, gnss_obj_get_longitude); - -const mp_obj_property_t gnss_longitude_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&gnss_get_longitude_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| altitude: float -//| """Altitude of current position in meters (float).""" -//| -STATIC mp_obj_t gnss_obj_get_altitude(mp_obj_t self_in) { - gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_float(common_hal_gnss_get_altitude(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(gnss_get_altitude_obj, gnss_obj_get_altitude); - -const mp_obj_property_t gnss_altitude_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&gnss_get_altitude_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| timestamp: time.struct_time -//| """Time when the position data was updated.""" -//| -STATIC mp_obj_t gnss_obj_get_timestamp(mp_obj_t self_in) { - gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - timeutils_struct_time_t tm; - common_hal_gnss_get_timestamp(self, &tm); - return struct_time_from_tm(&tm); -} -MP_DEFINE_CONST_FUN_OBJ_1(gnss_get_timestamp_obj, gnss_obj_get_timestamp); - -const mp_obj_property_t gnss_timestamp_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&gnss_get_timestamp_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| fix: PositionFix -//| """Fix mode.""" -//| -STATIC mp_obj_t gnss_obj_get_fix(mp_obj_t self_in) { - gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return gnss_positionfix_type_to_obj(common_hal_gnss_get_fix(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(gnss_get_fix_obj, gnss_obj_get_fix); - -const mp_obj_property_t gnss_fix_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&gnss_get_fix_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -STATIC const mp_rom_map_elem_t gnss_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&gnss_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&gnss_update_obj) }, - - { MP_ROM_QSTR(MP_QSTR_latitude), MP_ROM_PTR(&gnss_latitude_obj) }, - { MP_ROM_QSTR(MP_QSTR_longitude), MP_ROM_PTR(&gnss_longitude_obj) }, - { MP_ROM_QSTR(MP_QSTR_altitude), MP_ROM_PTR(&gnss_altitude_obj) }, - { MP_ROM_QSTR(MP_QSTR_timestamp), MP_ROM_PTR(&gnss_timestamp_obj) }, - { MP_ROM_QSTR(MP_QSTR_fix), MP_ROM_PTR(&gnss_fix_obj) } -}; -STATIC MP_DEFINE_CONST_DICT(gnss_locals_dict, gnss_locals_dict_table); - -const mp_obj_type_t gnss_type = { - { &mp_type_type }, - .name = MP_QSTR_GNSS, - .make_new = gnss_make_new, - .locals_dict = (mp_obj_dict_t*)&gnss_locals_dict, -}; diff --git a/shared-bindings/gnss/GNSS 2.h b/shared-bindings/gnss/GNSS 2.h deleted file mode 100644 index 60069a90a..000000000 --- a/shared-bindings/gnss/GNSS 2.h +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: Sony Semiconductor Solutions Corporation -// -// SPDX-License-Identifier: MIT - -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_GNSS_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_GNSS_H - -#include "common-hal/gnss/GNSS.h" -#include "shared-bindings/gnss/SatelliteSystem.h" -#include "shared-bindings/gnss/PositionFix.h" - -#include "lib/timeutils/timeutils.h" - -extern const mp_obj_type_t gnss_type; - -void common_hal_gnss_construct(gnss_obj_t *self, unsigned long selection); -void common_hal_gnss_deinit(gnss_obj_t *self); -bool common_hal_gnss_deinited(gnss_obj_t *self); -void common_hal_gnss_update(gnss_obj_t *self); - -mp_float_t common_hal_gnss_get_latitude(gnss_obj_t *self); -mp_float_t common_hal_gnss_get_longitude(gnss_obj_t *self); -mp_float_t common_hal_gnss_get_altitude(gnss_obj_t *self); -void common_hal_gnss_get_timestamp(gnss_obj_t *self, timeutils_struct_time_t *tm); -gnss_positionfix_t common_hal_gnss_get_fix(gnss_obj_t *self); - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_GNSS_H diff --git a/shared-bindings/gnss/PositionFix 2.c b/shared-bindings/gnss/PositionFix 2.c deleted file mode 100644 index e60611d70..000000000 --- a/shared-bindings/gnss/PositionFix 2.c +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-FileCopyrightText: Sony Semiconductor Solutions Corporation -// -// SPDX-License-Identifier: MIT - -#include "shared-bindings/gnss/PositionFix.h" - -//| class PositionFix: -//| """Position fix mode""" -//| -//| def __init__(self) -> None: -//| """Enum-like class to define the position fix mode.""" -//| -//| INVALID: PositionFix -//| """No measurement.""" -//| -//| FIX_2D: PositionFix -//| """2D fix.""" -//| -//| FIX_3D: PositionFix -//| """3D fix.""" -//| -const mp_obj_type_t gnss_positionfix_type; - -const gnss_positionfix_obj_t gnss_positionfix_invalid_obj = { - { &gnss_positionfix_type }, -}; - -const gnss_positionfix_obj_t gnss_positionfix_fix2d_obj = { - { &gnss_positionfix_type }, -}; - -const gnss_positionfix_obj_t gnss_positionfix_fix3d_obj = { - { &gnss_positionfix_type }, -}; - -gnss_positionfix_t gnss_positionfix_obj_to_type(mp_obj_t obj) { - gnss_positionfix_t posfix = POSITIONFIX_INVALID; - if (obj == MP_ROM_PTR(&gnss_positionfix_fix2d_obj)) { - posfix = POSITIONFIX_2D; - } else if (obj == MP_ROM_PTR(&gnss_positionfix_fix3d_obj)) { - posfix = POSITIONFIX_3D; - } - return posfix; -} - -mp_obj_t gnss_positionfix_type_to_obj(gnss_positionfix_t posfix) { - switch (posfix) { - case POSITIONFIX_2D: - return (mp_obj_t)MP_ROM_PTR(&gnss_positionfix_fix2d_obj); - case POSITIONFIX_3D: - return (mp_obj_t)MP_ROM_PTR(&gnss_positionfix_fix3d_obj); - case POSITIONFIX_INVALID: - default: - return (mp_obj_t)MP_ROM_PTR(&gnss_positionfix_invalid_obj); - } -} - -STATIC const mp_rom_map_elem_t gnss_positionfix_locals_dict_table[] = { - {MP_ROM_QSTR(MP_QSTR_INVALID), MP_ROM_PTR(&gnss_positionfix_invalid_obj)}, - {MP_ROM_QSTR(MP_QSTR_FIX_2D), MP_ROM_PTR(&gnss_positionfix_fix2d_obj)}, - {MP_ROM_QSTR(MP_QSTR_FIX_3D), MP_ROM_PTR(&gnss_positionfix_fix3d_obj)}, -}; -STATIC MP_DEFINE_CONST_DICT(gnss_positionfix_locals_dict, gnss_positionfix_locals_dict_table); - -STATIC void gnss_positionfix_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - qstr posfix = MP_QSTR_INVALID; - if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&gnss_positionfix_fix2d_obj)) { - posfix = MP_QSTR_FIX_2D; - } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&gnss_positionfix_fix3d_obj)) { - posfix = MP_QSTR_FIX_3D; - } - mp_printf(print, "%q.%q.%q", MP_QSTR_gnss, MP_QSTR_PositionFix, posfix); -} - -const mp_obj_type_t gnss_positionfix_type = { - { &mp_type_type }, - .name = MP_QSTR_PositionFix, - .print = gnss_positionfix_print, - .locals_dict = (mp_obj_t)&gnss_positionfix_locals_dict, -}; diff --git a/shared-bindings/gnss/PositionFix 2.h b/shared-bindings/gnss/PositionFix 2.h deleted file mode 100644 index 34090872c..000000000 --- a/shared-bindings/gnss/PositionFix 2.h +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: Sony Semiconductor Solutions Corporation -// -// SPDX-License-Identifier: MIT - -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_POSITIONFIX_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_POSITIONFIX_H - -#include "py/obj.h" - -typedef enum { - POSITIONFIX_INVALID, - POSITIONFIX_2D, - POSITIONFIX_3D, -} gnss_positionfix_t; - -const mp_obj_type_t gnss_positionfix_type; - -gnss_positionfix_t gnss_positionfix_obj_to_type(mp_obj_t obj); -mp_obj_t gnss_positionfix_type_to_obj(gnss_positionfix_t mode); - -typedef struct { - mp_obj_base_t base; -} gnss_positionfix_obj_t; -extern const gnss_positionfix_obj_t gnss_positionfix_invalid_obj; -extern const gnss_positionfix_obj_t gnss_positionfix_fix2d_obj; -extern const gnss_positionfix_obj_t gnss_positionfix_fix3d_obj; - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_POSITIONFIX_H diff --git a/shared-bindings/gnss/SatelliteSystem 2.c b/shared-bindings/gnss/SatelliteSystem 2.c deleted file mode 100644 index 7d66727b8..000000000 --- a/shared-bindings/gnss/SatelliteSystem 2.c +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-FileCopyrightText: Sony Semiconductor Solutions Corporation -// -// SPDX-License-Identifier: MIT - -#include "shared-bindings/gnss/SatelliteSystem.h" - -//| class SatelliteSystem: -//| """Satellite system type""" -//| -//| def __init__(self) -> None: -//| """Enum-like class to define the satellite system type.""" -//| -//| GPS: SatelliteSystem -//| """Global Positioning System.""" -//| -//| GLONASS: SatelliteSystem -//| """GLObal NAvigation Satellite System.""" -//| -//| SBAS: SatelliteSystem -//| """Satellite Based Augmentation System.""" -//| -//| QZSS_L1CA: SatelliteSystem -//| """Quasi-Zenith Satellite System L1C/A.""" -//| -//| QZSS_L1S: SatelliteSystem -//| """Quasi-Zenith Satellite System L1S.""" -//| -const mp_obj_type_t gnss_satellitesystem_type; - -const gnss_satellitesystem_obj_t gnss_satellitesystem_gps_obj = { - { &gnss_satellitesystem_type }, -}; - -const gnss_satellitesystem_obj_t gnss_satellitesystem_glonass_obj = { - { &gnss_satellitesystem_type }, -}; - -const gnss_satellitesystem_obj_t gnss_satellitesystem_sbas_obj = { - { &gnss_satellitesystem_type }, -}; - -const gnss_satellitesystem_obj_t gnss_satellitesystem_qzss_l1ca_obj = { - { &gnss_satellitesystem_type }, -}; - -const gnss_satellitesystem_obj_t gnss_satellitesystem_qzss_l1s_obj = { - { &gnss_satellitesystem_type }, -}; - -gnss_satellitesystem_t gnss_satellitesystem_obj_to_type(mp_obj_t obj) { - if (obj == MP_ROM_PTR(&gnss_satellitesystem_gps_obj)) { - return SATELLITESYSTEM_GPS; - } else if (obj == MP_ROM_PTR(&gnss_satellitesystem_glonass_obj)) { - return SATELLITESYSTEM_GLONASS; - } else if (obj == MP_ROM_PTR(&gnss_satellitesystem_sbas_obj)) { - return SATELLITESYSTEM_SBAS; - } else if (obj == MP_ROM_PTR(&gnss_satellitesystem_qzss_l1ca_obj)) { - return SATELLITESYSTEM_QZSS_L1CA; - } else if (obj == MP_ROM_PTR(&gnss_satellitesystem_qzss_l1s_obj)) { - return SATELLITESYSTEM_QZSS_L1S; - } - return SATELLITESYSTEM_NONE; -} - -mp_obj_t gnss_satellitesystem_type_to_obj(gnss_satellitesystem_t system) { - switch (system) { - case SATELLITESYSTEM_GPS: - return (mp_obj_t)MP_ROM_PTR(&gnss_satellitesystem_gps_obj); - case SATELLITESYSTEM_GLONASS: - return (mp_obj_t)MP_ROM_PTR(&gnss_satellitesystem_glonass_obj); - case SATELLITESYSTEM_SBAS: - return (mp_obj_t)MP_ROM_PTR(&gnss_satellitesystem_sbas_obj); - case SATELLITESYSTEM_QZSS_L1CA: - return (mp_obj_t)MP_ROM_PTR(&gnss_satellitesystem_qzss_l1ca_obj); - case SATELLITESYSTEM_QZSS_L1S: - return (mp_obj_t)MP_ROM_PTR(&gnss_satellitesystem_qzss_l1s_obj); - case SATELLITESYSTEM_NONE: - default: - return (mp_obj_t)MP_ROM_PTR(&mp_const_none_obj); - } -} - -STATIC const mp_rom_map_elem_t gnss_satellitesystem_locals_dict_table[] = { - {MP_ROM_QSTR(MP_QSTR_GPS), MP_ROM_PTR(&gnss_satellitesystem_gps_obj)}, - {MP_ROM_QSTR(MP_QSTR_GLONASS), MP_ROM_PTR(&gnss_satellitesystem_glonass_obj)}, - {MP_ROM_QSTR(MP_QSTR_SBAS), MP_ROM_PTR(&gnss_satellitesystem_sbas_obj)}, - {MP_ROM_QSTR(MP_QSTR_QZSS_L1CA), MP_ROM_PTR(&gnss_satellitesystem_qzss_l1ca_obj)}, - {MP_ROM_QSTR(MP_QSTR_QZSS_L1S), MP_ROM_PTR(&gnss_satellitesystem_qzss_l1s_obj)}, -}; -STATIC MP_DEFINE_CONST_DICT(gnss_satellitesystem_locals_dict, gnss_satellitesystem_locals_dict_table); - -STATIC void gnss_satellitesystem_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - qstr system = MP_QSTR_None; - if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&gnss_satellitesystem_gps_obj)) { - system = MP_QSTR_GPS; - } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&gnss_satellitesystem_glonass_obj)) { - system = MP_QSTR_GLONASS; - } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&gnss_satellitesystem_sbas_obj)) { - system = MP_QSTR_SBAS; - } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&gnss_satellitesystem_qzss_l1ca_obj)) { - system = MP_QSTR_QZSS_L1CA; - } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&gnss_satellitesystem_qzss_l1s_obj)) { - system = MP_QSTR_QZSS_L1S; - } - mp_printf(print, "%q.%q.%q", MP_QSTR_gnss, MP_QSTR_SatelliteSystem, system); -} - -const mp_obj_type_t gnss_satellitesystem_type = { - { &mp_type_type }, - .name = MP_QSTR_SatelliteSystem, - .print = gnss_satellitesystem_print, - .locals_dict = (mp_obj_t)&gnss_satellitesystem_locals_dict, -}; diff --git a/shared-bindings/gnss/SatelliteSystem 2.h b/shared-bindings/gnss/SatelliteSystem 2.h deleted file mode 100644 index 17f155002..000000000 --- a/shared-bindings/gnss/SatelliteSystem 2.h +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-FileCopyrightText: Sony Semiconductor Solutions Corporation -// -// SPDX-License-Identifier: MIT - -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_SATELLITESYSTEM_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_SATELLITESYSTEM_H - -#include "py/obj.h" - -typedef enum { - SATELLITESYSTEM_NONE = 0, - SATELLITESYSTEM_GPS = (1U << 0), - SATELLITESYSTEM_GLONASS = (1U << 1), - SATELLITESYSTEM_SBAS = (1U << 2), - SATELLITESYSTEM_QZSS_L1CA = (1U << 3), - SATELLITESYSTEM_QZSS_L1S = (1U << 4), -} gnss_satellitesystem_t; - -const mp_obj_type_t gnss_satellitesystem_type; - -gnss_satellitesystem_t gnss_satellitesystem_obj_to_type(mp_obj_t obj); -mp_obj_t gnss_satellitesystem_type_to_obj(gnss_satellitesystem_t mode); - -typedef struct { - mp_obj_base_t base; -} gnss_satellitesystem_obj_t; -extern const gnss_satellitesystem_obj_t gnss_satellitesystem_gps_obj; -extern const gnss_satellitesystem_obj_t gnss_satellitesystem_glonass_obj; -extern const gnss_satellitesystem_obj_t gnss_satellitesystem_sbas_obj; -extern const gnss_satellitesystem_obj_t gnss_satellitesystem_qzss_l1ca_obj; -extern const gnss_satellitesystem_obj_t gnss_satellitesystem_qzss_l1s_obj; - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GNSS_SATELLITESYSTEM_H diff --git a/shared-bindings/gnss/__init__ 2.c b/shared-bindings/gnss/__init__ 2.c deleted file mode 100644 index 4b0d312ae..000000000 --- a/shared-bindings/gnss/__init__ 2.c +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: Sony Semiconductor Solutions Corporation -// -// SPDX-License-Identifier: MIT - -#include "py/obj.h" -#include "py/runtime.h" -#include "py/mphal.h" -#include "shared-bindings/gnss/GNSS.h" -#include "shared-bindings/gnss/SatelliteSystem.h" -#include "shared-bindings/gnss/PositionFix.h" -#include "shared-bindings/util.h" - -//| """Global Navigation Satellite System -//| -//| The `gnss` module contains classes to control the GNSS and acquire positioning information.""" -//| -STATIC const mp_rom_map_elem_t gnss_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_gnss) }, - { MP_ROM_QSTR(MP_QSTR_GNSS), MP_ROM_PTR(&gnss_type) }, - - // Enum-like Classes. - { MP_ROM_QSTR(MP_QSTR_SatelliteSystem), MP_ROM_PTR(&gnss_satellitesystem_type) }, - { MP_ROM_QSTR(MP_QSTR_PositionFix), MP_ROM_PTR(&gnss_positionfix_type) }, -}; - -STATIC MP_DEFINE_CONST_DICT(gnss_module_globals, gnss_module_globals_table); - -const mp_obj_module_t gnss_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&gnss_module_globals, -}; diff --git a/shared-bindings/i2cperipheral/I2CPeripheral 2.c b/shared-bindings/i2cperipheral/I2CPeripheral 2.c deleted file mode 100644 index b5ac861b4..000000000 --- a/shared-bindings/i2cperipheral/I2CPeripheral 2.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Noralf Trønnes - * - * 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. - */ - -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/i2cperipheral/I2CPeripheral.h" -#include "shared-bindings/time/__init__.h" -#include "shared-bindings/util.h" - -#include "lib/utils/buffer_helper.h" -#include "lib/utils/context_manager_helpers.h" -#include "lib/utils/interrupt_char.h" - -#include "py/mperrno.h" -#include "py/mphal.h" -#include "py/obj.h" -#include "py/objproperty.h" -#include "py/runtime.h" - -STATIC mp_obj_t mp_obj_new_i2cperipheral_i2c_peripheral_request(i2cperipheral_i2c_peripheral_obj_t *peripheral, uint8_t address, bool is_read, bool is_restart) { - i2cperipheral_i2c_peripheral_request_obj_t *self = m_new_obj(i2cperipheral_i2c_peripheral_request_obj_t); - self->base.type = &i2cperipheral_i2c_peripheral_request_type; - self->peripheral = peripheral; - self->address = address; - self->is_read = is_read; - self->is_restart = is_restart; - return (mp_obj_t)self; -} - -//| class I2CPeripheral: -//| """Two wire serial protocol peripheral""" -//| -//| def __init__(self, scl: microcontroller.Pin, sda: microcontroller.Pin, addresses: Sequence[int], smbus: bool = False) -> None: -//| """I2C is a two-wire protocol for communicating between devices. -//| This implements the peripheral (sensor, secondary) side. -//| -//| :param ~microcontroller.Pin scl: The clock pin -//| :param ~microcontroller.Pin sda: The data pin -//| :param addresses: The I2C addresses to respond to (how many is hw dependent). -//| :type addresses: list[int] -//| :param bool smbus: Use SMBUS timings if the hardware supports it""" -//| ... -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - i2cperipheral_i2c_peripheral_obj_t *self = m_new_obj(i2cperipheral_i2c_peripheral_obj_t); - self->base.type = &i2cperipheral_i2c_peripheral_type; - enum { ARG_scl, ARG_sda, ARG_addresses, ARG_smbus }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_addresses, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_smbus, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - const mcu_pin_obj_t* scl = validate_obj_is_free_pin(args[ARG_scl].u_obj); - const mcu_pin_obj_t* sda = validate_obj_is_free_pin(args[ARG_sda].u_obj); - - mp_obj_iter_buf_t iter_buf; - mp_obj_t iterable = mp_getiter(args[ARG_addresses].u_obj, &iter_buf); - mp_obj_t item; - uint8_t *addresses = NULL; - unsigned int i = 0; - while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - mp_int_t value; - if (!mp_obj_get_int_maybe(item, &value)) { - mp_raise_TypeError_varg(translate("can't convert %q to %q"), MP_QSTR_address, MP_QSTR_int); - } - if (value < 0x00 || value > 0x7f) { - mp_raise_ValueError(translate("address out of bounds")); - } - addresses = m_renew(uint8_t, addresses, i, i + 1); - addresses[i++] = value; - } - if (i == 0) { - mp_raise_ValueError(translate("addresses is empty")); - } - - common_hal_i2cperipheral_i2c_peripheral_construct(self, scl, sda, addresses, i, args[ARG_smbus].u_bool); - return (mp_obj_t)self; -} - -//| def deinit(self) -> None: -//| """Releases control of the underlying hardware so other classes can use it.""" -//| ... -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_obj_deinit(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_type)); - i2cperipheral_i2c_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_i2cperipheral_i2c_peripheral_deinit(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(i2cperipheral_i2c_peripheral_deinit_obj, i2cperipheral_i2c_peripheral_obj_deinit); - -//| def __enter__(self) -> I2CPeripheral: -//| """No-op used in Context Managers.""" -//| ... -//| -// Provided by context manager helper. - -//| def __exit__(self) -> None: -//| """Automatically deinitializes the hardware on context exit. See -//| :ref:`lifetime-and-contextmanagers` for more info.""" -//| ... -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_obj___exit__(size_t n_args, const mp_obj_t *args) { - mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cperipheral_i2c_peripheral_type)); - i2cperipheral_i2c_peripheral_obj_t *self = MP_OBJ_TO_PTR(args[0]); - common_hal_i2cperipheral_i2c_peripheral_deinit(self); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cperipheral_i2c_peripheral___exit___obj, 4, 4, i2cperipheral_i2c_peripheral_obj___exit__); - -//| def request(self, timeout: float = -1) -> I2CPeripheralRequest: -//| """Wait for an I2C request. -//| -//| :param float timeout: Timeout in seconds. Zero means wait forever, a negative value means check once -//| :return: I2C Slave Request or None if timeout=-1 and there's no request -//| :rtype: ~i2cperipheral.I2CPeripheralRequest""" -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cperipheral_i2c_peripheral_type)); - i2cperipheral_i2c_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - if(common_hal_i2cperipheral_i2c_peripheral_deinited(self)) { - raise_deinited_error(); - } - enum { ARG_timeout }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - #if MICROPY_PY_BUILTINS_FLOAT - float f = mp_obj_get_float(args[ARG_timeout].u_obj) * 1000; - int timeout_ms = (int)f; - #else - int timeout_ms = mp_obj_get_int(args[ARG_timeout].u_obj) * 1000; - #endif - - bool forever = false; - uint64_t timeout_end = 0; - if (timeout_ms == 0) { - forever = true; - } else if (timeout_ms > 0) { - timeout_end = common_hal_time_monotonic() + timeout_ms; - } - - int last_error = 0; - - do { - uint8_t address; - bool is_read; - bool is_restart; - - RUN_BACKGROUND_TASKS; - if (mp_hal_is_interrupted()) { - return mp_const_none; - } - - int status = common_hal_i2cperipheral_i2c_peripheral_is_addressed(self, &address, &is_read, &is_restart); - if (status < 0) { - // On error try one more time before bailing out - if (last_error) { - mp_raise_OSError(last_error); - } - last_error = -status; - mp_hal_delay_ms(10); - continue; - } - - last_error = 0; - - if (status == 0) { - mp_hal_delay_us(10); - continue; - } - - return mp_obj_new_i2cperipheral_i2c_peripheral_request(self, address, is_read, is_restart); - } while (forever || common_hal_time_monotonic() < timeout_end); - - if (timeout_ms > 0) { - mp_raise_OSError(MP_ETIMEDOUT); - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(i2cperipheral_i2c_peripheral_request_obj, 1, i2cperipheral_i2c_peripheral_request); - -STATIC const mp_rom_map_elem_t i2cperipheral_i2c_peripheral_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2cperipheral_i2c_peripheral___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_request), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_obj) }, - -}; - -STATIC MP_DEFINE_CONST_DICT(i2cperipheral_i2c_peripheral_locals_dict, i2cperipheral_i2c_peripheral_locals_dict_table); - -const mp_obj_type_t i2cperipheral_i2c_peripheral_type = { - { &mp_type_type }, - .name = MP_QSTR_I2CPeripheral, - .make_new = i2cperipheral_i2c_peripheral_make_new, - .locals_dict = (mp_obj_dict_t*)&i2cperipheral_i2c_peripheral_locals_dict, -}; - -//| class I2CPeripheralRequest: -//| -//| def __init__(self, peripheral: i2cperipheral.I2CPeripheral, address: int, is_read: bool, is_restart: bool) -> None: -//| """Information about an I2C transfer request -//| This cannot be instantiated directly, but is returned by :py:meth:`I2CPeripheral.request`. -//| -//| :param peripheral: The I2CPeripheral object receiving this request -//| :param address: I2C address -//| :param is_read: True if the main peripheral is requesting data -//| :param is_restart: Repeated Start Condition""" -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - mp_arg_check_num(n_args, kw_args, 4, 4, false); - return mp_obj_new_i2cperipheral_i2c_peripheral_request(args[0], mp_obj_get_int(args[1]), mp_obj_is_true(args[2]), mp_obj_is_true(args[3])); -} - -//| def __enter__(self) -> I2CPeripheralRequest: -//| """No-op used in Context Managers.""" -//| ... -//| -// Provided by context manager helper. - -//| def __exit__(self) -> None: -//| """Close the request.""" -//| ... -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_obj___exit__(size_t n_args, const mp_obj_t *args) { - mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(args[0]); - common_hal_i2cperipheral_i2c_peripheral_close(self->peripheral); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cperipheral_i2c_peripheral_request___exit___obj, 4, 4, i2cperipheral_i2c_peripheral_request_obj___exit__); - -//| address: int -//| """The I2C address of the request.""" -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_get_address(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_int(self->address); -} -MP_DEFINE_CONST_PROP_GET(i2cperipheral_i2c_peripheral_request_address_obj, i2cperipheral_i2c_peripheral_request_get_address); - -//| is_read: bool -//| """The I2C main controller is reading from this peripheral.""" -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_get_is_read(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_bool(self->is_read); -} -MP_DEFINE_CONST_PROP_GET(i2cperipheral_i2c_peripheral_request_is_read_obj, i2cperipheral_i2c_peripheral_request_get_is_read); - -//| is_restart: bool -//| """Is Repeated Start Condition.""" -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_get_is_restart(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_bool(self->is_restart); -} -MP_DEFINE_CONST_PROP_GET(i2cperipheral_i2c_peripheral_request_is_restart_obj, i2cperipheral_i2c_peripheral_request_get_is_restart); - -//| def read(self, n: int = -1, ack: bool = True) -> bytearray: -//| """Read data. -//| If ack=False, the caller is responsible for calling :py:meth:`I2CPeripheralRequest.ack`. -//| -//| :param n: Number of bytes to read (negative means all) -//| :param ack: Whether or not to send an ACK after the n'th byte -//| :return: Bytes read""" -//| ... -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - enum { ARG_n, ARG_ack }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_n, MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_ack, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - if (self->is_read) { - mp_raise_OSError(MP_EACCES); - } - - int n = args[ARG_n].u_int; - if (n == 0) { - return mp_obj_new_bytearray(0, NULL); - } - bool ack = args[ARG_ack].u_bool; - - int i = 0; - uint8_t *buffer = NULL; - uint64_t timeout_end = common_hal_time_monotonic() + 10 * 1000; - while (common_hal_time_monotonic() < timeout_end) { - RUN_BACKGROUND_TASKS; - if (mp_hal_is_interrupted()) { - break; - } - - uint8_t data; - int num = common_hal_i2cperipheral_i2c_peripheral_read_byte(self->peripheral, &data); - if (num == 0) { - break; - } - - buffer = m_renew(uint8_t, buffer, i, i + 1); - buffer[i++] = data; - if (i == n) { - if (ack) { - common_hal_i2cperipheral_i2c_peripheral_ack(self->peripheral, true); - } - break; - } - common_hal_i2cperipheral_i2c_peripheral_ack(self->peripheral, true); - } - - return mp_obj_new_bytearray(i, buffer); -} -MP_DEFINE_CONST_FUN_OBJ_KW(i2cperipheral_i2c_peripheral_request_read_obj, 1, i2cperipheral_i2c_peripheral_request_read); - -//| def write(self, buffer: ReadableBuffer) -> int: -//| """Write the data contained in buffer. -//| -//| :param ~_typing.ReadableBuffer buffer: Write out the data in this buffer -//| :return: Number of bytes written""" -//| ... -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_write(mp_obj_t self_in, mp_obj_t buf_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); - - if (!self->is_read) { - mp_raise_OSError(MP_EACCES); - } - - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); - - for (size_t i = 0; i < bufinfo.len; i++) { - RUN_BACKGROUND_TASKS; - if (mp_hal_is_interrupted()) { - break; - } - - int num = common_hal_i2cperipheral_i2c_peripheral_write_byte(self->peripheral, ((uint8_t *)(bufinfo.buf))[i]); - if (num == 0) { - return mp_obj_new_int(i); - } - } - - return mp_obj_new_int(bufinfo.len); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(i2cperipheral_i2c_peripheral_request_write_obj, i2cperipheral_i2c_peripheral_request_write); - -//| def ack(self, ack: bool = True) -> None: -//| """Acknowledge or Not Acknowledge last byte received. -//| Use together with :py:meth:`I2CPeripheralRequest.read` ack=False. -//| -//| :param ack: Whether to send an ACK or NACK""" -//| ... -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_ack(uint n_args, const mp_obj_t *args) { - mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(args[0]); - bool ack = (n_args == 1) ? true : mp_obj_is_true(args[1]); - - if (self->is_read) { - mp_raise_OSError(MP_EACCES); - } - - common_hal_i2cperipheral_i2c_peripheral_ack(self->peripheral, ack); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cperipheral_i2c_peripheral_request_ack_obj, 1, 2, i2cperipheral_i2c_peripheral_request_ack); - -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_close(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); - - common_hal_i2cperipheral_i2c_peripheral_close(self->peripheral); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(i2cperipheral_i2c_peripheral_request_close_obj, i2cperipheral_i2c_peripheral_request_close); - -STATIC const mp_rom_map_elem_t i2cperipheral_i2c_peripheral_request_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_address_obj) }, - { MP_ROM_QSTR(MP_QSTR_is_read), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_is_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_is_restart), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_is_restart_obj) }, - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_write_obj) }, - { MP_ROM_QSTR(MP_QSTR_ack), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_ack_obj) }, - { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_close_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(i2cperipheral_i2c_peripheral_request_locals_dict, i2cperipheral_i2c_peripheral_request_locals_dict_table); - -const mp_obj_type_t i2cperipheral_i2c_peripheral_request_type = { - { &mp_type_type }, - .name = MP_QSTR_I2CPeripheralRequest, - .make_new = i2cperipheral_i2c_peripheral_request_make_new, - .locals_dict = (mp_obj_dict_t*)&i2cperipheral_i2c_peripheral_request_locals_dict, -}; diff --git a/shared-bindings/i2cperipheral/I2CPeripheral 2.h b/shared-bindings/i2cperipheral/I2CPeripheral 2.h deleted file mode 100644 index 3035cfbfe..000000000 --- a/shared-bindings/i2cperipheral/I2CPeripheral 2.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Noralf Trønnes - * - * 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. - */ - -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H - -#include "py/obj.h" - -#include "common-hal/microcontroller/Pin.h" -#include "common-hal/i2cperipheral/I2CPeripheral.h" - -typedef struct { - mp_obj_base_t base; - i2cperipheral_i2c_peripheral_obj_t *peripheral; - uint16_t address; - bool is_read; - bool is_restart; -} i2cperipheral_i2c_peripheral_request_obj_t; - -extern const mp_obj_type_t i2cperipheral_i2c_peripheral_request_type; - -extern const mp_obj_type_t i2cperipheral_i2c_peripheral_type; - -extern void common_hal_i2cperipheral_i2c_peripheral_construct(i2cperipheral_i2c_peripheral_obj_t *self, - const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, - uint8_t *addresses, unsigned int num_addresses, bool smbus); -extern void common_hal_i2cperipheral_i2c_peripheral_deinit(i2cperipheral_i2c_peripheral_obj_t *self); -extern bool common_hal_i2cperipheral_i2c_peripheral_deinited(i2cperipheral_i2c_peripheral_obj_t *self); - -extern int common_hal_i2cperipheral_i2c_peripheral_is_addressed(i2cperipheral_i2c_peripheral_obj_t *self, - uint8_t *address, bool *is_read, bool *is_restart); -extern int common_hal_i2cperipheral_i2c_peripheral_read_byte(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t *data); -extern int common_hal_i2cperipheral_i2c_peripheral_write_byte(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t data); -extern void common_hal_i2cperipheral_i2c_peripheral_ack(i2cperipheral_i2c_peripheral_obj_t *self, bool ack); -extern void common_hal_i2cperipheral_i2c_peripheral_close(i2cperipheral_i2c_peripheral_obj_t *self); - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H diff --git a/shared-bindings/i2cperipheral/__init__ 2.c b/shared-bindings/i2cperipheral/__init__ 2.c deleted file mode 100644 index e2cb8509d..000000000 --- a/shared-bindings/i2cperipheral/__init__ 2.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Noralf Trønnes - * - * 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. - */ - -#include - -#include "py/obj.h" -#include "py/runtime.h" - -#include "shared-bindings/microcontroller/Pin.h" -//#include "shared-bindings/i2cperipheral/__init__.h" -#include "shared-bindings/i2cperipheral/I2CPeripheral.h" - -#include "py/runtime.h" - -//| """Two wire serial protocol peripheral -//| -//| The `i2cperipheral` module contains classes to support an I2C peripheral. -//| -//| Example emulating a peripheral with 2 addresses (read and write):: -//| -//| import board -//| from i2cperipheral import I2CPeripheral -//| -//| regs = [0] * 16 -//| index = 0 -//| -//| with I2CPeripheral(board.SCL, board.SDA, (0x40, 0x41)) as device: -//| while True: -//| r = device.request() -//| if not r: -//| # Maybe do some housekeeping -//| continue -//| with r: # Closes the transfer if necessary by sending a NACK or feeding dummy bytes -//| if r.address == 0x40: -//| if not r.is_read: # Main write which is Selected read -//| b = r.read(1) -//| if not b or b[0] > 15: -//| break -//| index = b[0] -//| b = r.read(1) -//| if b: -//| regs[index] = b[0] -//| elif r.is_restart: # Combined transfer: This is the Main read message -//| n = r.write(bytes([regs[index]])) -//| #else: -//| # A read transfer is not supported in this example -//| # If the microcontroller tries, it will get 0xff byte(s) by the ctx manager (r.close()) -//| elif r.address == 0x41: -//| if not r.is_read: -//| b = r.read(1) -//| if b and b[0] == 0xde: -//| # do something -//| pass -//| -//| This example sets up an I2C device that can be accessed from Linux like this:: -//| -//| $ i2cget -y 1 0x40 0x01 -//| 0x00 -//| $ i2cset -y 1 0x40 0x01 0xaa -//| $ i2cget -y 1 0x40 0x01 -//| 0xaa -//| -//| .. warning:: -//| I2CPeripheral makes use of clock stretching in order to slow down -//| the host. -//| Make sure the I2C host supports this. -//| -//| Raspberry Pi in particular does not support this with its I2C hw block. -//| This can be worked around by using the ``i2c-gpio`` bit banging driver. -//| Since the RPi firmware uses the hw i2c, it's not possible to emulate a HAT eeprom.""" -//| - -STATIC const mp_rom_map_elem_t i2cperipheral_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_i2cperipheral) }, - { MP_ROM_QSTR(MP_QSTR_I2CPeripheral), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_type) }, -}; - -STATIC MP_DEFINE_CONST_DICT(i2cperipheral_module_globals, i2cperipheral_module_globals_table); - -const mp_obj_module_t i2cperipheral_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&i2cperipheral_module_globals, -}; diff --git a/shared-bindings/memorymonitor/AllocationAlarm 2.c b/shared-bindings/memorymonitor/AllocationAlarm 2.c deleted file mode 100644 index 7de8c1287..000000000 --- a/shared-bindings/memorymonitor/AllocationAlarm 2.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries - * - * 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. - */ - -#include - -#include "py/objproperty.h" -#include "py/runtime.h" -#include "py/runtime0.h" -#include "shared-bindings/memorymonitor/AllocationAlarm.h" -#include "shared-bindings/util.h" -#include "supervisor/shared/translate.h" - -//| class AllocationAlarm: -//| -//| def __init__(self, *, minimum_block_count: int = 1) -> None: -//| """Throw an exception when an allocation of ``minimum_block_count`` or more blocks -//| occurs while active. -//| -//| Track allocations:: -//| -//| import memorymonitor -//| -//| aa = memorymonitor.AllocationAlarm(minimum_block_count=2) -//| x = 2 -//| # Should not allocate any blocks. -//| with aa: -//| x = 5 -//| -//| # Should throw an exception when allocating storage for the 20 bytes. -//| with aa: -//| x = bytearray(20) -//| -//| """ -//| ... -//| -STATIC mp_obj_t memorymonitor_allocationalarm_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_minimum_block_count }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_minimum_block_count, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - mp_int_t minimum_block_count = args[ARG_minimum_block_count].u_int; - if (minimum_block_count < 1) { - mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_minimum_block_count); - } - - memorymonitor_allocationalarm_obj_t *self = m_new_obj(memorymonitor_allocationalarm_obj_t); - self->base.type = &memorymonitor_allocationalarm_type; - - common_hal_memorymonitor_allocationalarm_construct(self, minimum_block_count); - - return MP_OBJ_FROM_PTR(self); -} - -//| def ignore(self, count: int) -> AllocationAlarm: -//| """Sets the number of applicable allocations to ignore before raising the exception. -//| Automatically set back to zero at context exit. -//| -//| Use it within a ``with`` block:: -//| -//| # Will not alarm because the bytearray allocation will be ignored. -//| with aa.ignore(2): -//| x = bytearray(20) -//| """ -//| ... -//| -STATIC mp_obj_t memorymonitor_allocationalarm_obj_ignore(mp_obj_t self_in, mp_obj_t count_obj) { - mp_int_t count = mp_obj_get_int(count_obj); - if (count < 0) { - mp_raise_ValueError_varg(translate("%q must be >= 0"), MP_QSTR_count); - } - common_hal_memorymonitor_allocationalarm_set_ignore(self_in, count); - return self_in; -} -MP_DEFINE_CONST_FUN_OBJ_2(memorymonitor_allocationalarm_ignore_obj, memorymonitor_allocationalarm_obj_ignore); - -//| def __enter__(self) -> AllocationAlarm: -//| """Enables the alarm.""" -//| ... -//| -STATIC mp_obj_t memorymonitor_allocationalarm_obj___enter__(mp_obj_t self_in) { - common_hal_memorymonitor_allocationalarm_resume(self_in); - return self_in; -} -MP_DEFINE_CONST_FUN_OBJ_1(memorymonitor_allocationalarm___enter___obj, memorymonitor_allocationalarm_obj___enter__); - -//| def __exit__(self) -> None: -//| """Automatically disables the allocation alarm when exiting a context. See -//| :ref:`lifetime-and-contextmanagers` for more info.""" -//| ... -//| -STATIC mp_obj_t memorymonitor_allocationalarm_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_memorymonitor_allocationalarm_set_ignore(args[0], 0); - common_hal_memorymonitor_allocationalarm_pause(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(memorymonitor_allocationalarm___exit___obj, 4, 4, memorymonitor_allocationalarm_obj___exit__); - -STATIC const mp_rom_map_elem_t memorymonitor_allocationalarm_locals_dict_table[] = { - // Methods - { MP_ROM_QSTR(MP_QSTR_ignore), MP_ROM_PTR(&memorymonitor_allocationalarm_ignore_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&memorymonitor_allocationalarm___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&memorymonitor_allocationalarm___exit___obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(memorymonitor_allocationalarm_locals_dict, memorymonitor_allocationalarm_locals_dict_table); - -const mp_obj_type_t memorymonitor_allocationalarm_type = { - { &mp_type_type }, - .name = MP_QSTR_AllocationAlarm, - .make_new = memorymonitor_allocationalarm_make_new, - .locals_dict = (mp_obj_dict_t*)&memorymonitor_allocationalarm_locals_dict, -}; diff --git a/shared-bindings/memorymonitor/AllocationAlarm 2.h b/shared-bindings/memorymonitor/AllocationAlarm 2.h deleted file mode 100644 index 304b9c5a7..000000000 --- a/shared-bindings/memorymonitor/AllocationAlarm 2.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries - * - * 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. - */ - -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONALARM_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONALARM_H - -#include "shared-module/memorymonitor/AllocationAlarm.h" - -extern const mp_obj_type_t memorymonitor_allocationalarm_type; - -void common_hal_memorymonitor_allocationalarm_construct(memorymonitor_allocationalarm_obj_t* self, size_t minimum_block_count); -void common_hal_memorymonitor_allocationalarm_pause(memorymonitor_allocationalarm_obj_t* self); -void common_hal_memorymonitor_allocationalarm_resume(memorymonitor_allocationalarm_obj_t* self); -void common_hal_memorymonitor_allocationalarm_set_ignore(memorymonitor_allocationalarm_obj_t* self, mp_int_t count); - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONALARM_H diff --git a/shared-bindings/memorymonitor/AllocationSize 2.c b/shared-bindings/memorymonitor/AllocationSize 2.c deleted file mode 100644 index b35bae360..000000000 --- a/shared-bindings/memorymonitor/AllocationSize 2.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries - * - * 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. - */ - -#include - -#include "py/objproperty.h" -#include "py/runtime.h" -#include "py/runtime0.h" -#include "shared-bindings/memorymonitor/AllocationSize.h" -#include "shared-bindings/util.h" -#include "supervisor/shared/translate.h" - -//| class AllocationSize: -//| -//| def __init__(self) -> None: -//| """Tracks the number of allocations in power of two buckets. -//| -//| It will have 16 16-bit buckets to track allocation counts. It is total allocations -//| meaning frees are ignored. Reallocated memory is counted twice, at allocation and when -//| reallocated with the larger size. -//| -//| The buckets are measured in terms of blocks which is the finest granularity of the heap. -//| This means bucket 0 will count all allocations less than or equal to the number of bytes -//| per block, typically 16. Bucket 2 will be less than or equal to 4 blocks. See -//| `bytes_per_block` to convert blocks to bytes. -//| -//| Multiple AllocationSizes can be used to track different code boundaries. -//| -//| Track allocations:: -//| -//| import memorymonitor -//| -//| mm = memorymonitor.AllocationSize() -//| with mm: -//| print("hello world" * 3) -//| -//| for bucket, count in enumerate(mm): -//| print("<", 2 ** bucket, count) -//| -//| """ -//| ... -//| -STATIC mp_obj_t memorymonitor_allocationsize_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - memorymonitor_allocationsize_obj_t *self = m_new_obj(memorymonitor_allocationsize_obj_t); - self->base.type = &memorymonitor_allocationsize_type; - - common_hal_memorymonitor_allocationsize_construct(self); - - return MP_OBJ_FROM_PTR(self); -} - -//| def __enter__(self) -> AllocationSize: -//| """Clears counts and resumes tracking.""" -//| ... -//| -STATIC mp_obj_t memorymonitor_allocationsize_obj___enter__(mp_obj_t self_in) { - common_hal_memorymonitor_allocationsize_clear(self_in); - common_hal_memorymonitor_allocationsize_resume(self_in); - return self_in; -} -MP_DEFINE_CONST_FUN_OBJ_1(memorymonitor_allocationsize___enter___obj, memorymonitor_allocationsize_obj___enter__); - -//| def __exit__(self) -> None: -//| """Automatically pauses allocation tracking when exiting a context. See -//| :ref:`lifetime-and-contextmanagers` for more info.""" -//| ... -//| -STATIC mp_obj_t memorymonitor_allocationsize_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_memorymonitor_allocationsize_pause(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(memorymonitor_allocationsize___exit___obj, 4, 4, memorymonitor_allocationsize_obj___exit__); - -//| bytes_per_block: int -//| """Number of bytes per block""" -//| -STATIC mp_obj_t memorymonitor_allocationsize_obj_get_bytes_per_block(mp_obj_t self_in) { - memorymonitor_allocationsize_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return MP_OBJ_NEW_SMALL_INT(common_hal_memorymonitor_allocationsize_get_bytes_per_block(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(memorymonitor_allocationsize_get_bytes_per_block_obj, memorymonitor_allocationsize_obj_get_bytes_per_block); - -const mp_obj_property_t memorymonitor_allocationsize_bytes_per_block_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&memorymonitor_allocationsize_get_bytes_per_block_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| def __len__(self) -> int: -//| """Returns the number of allocation buckets. -//| -//| This allows you to:: -//| -//| mm = memorymonitor.AllocationSize() -//| print(len(mm))""" -//| ... -//| -STATIC mp_obj_t memorymonitor_allocationsize_unary_op(mp_unary_op_t op, mp_obj_t self_in) { - memorymonitor_allocationsize_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint16_t len = common_hal_memorymonitor_allocationsize_get_len(self); - switch (op) { - case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); - case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len); - default: return MP_OBJ_NULL; // op not supported - } -} - -//| def __getitem__(self, index: int) -> Optional[int]: -//| """Returns the allocation count for the given bucket. -//| -//| This allows you to:: -//| -//| mm = memorymonitor.AllocationSize() -//| print(mm[0])""" -//| ... -//| -STATIC mp_obj_t memorymonitor_allocationsize_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { - if (value == mp_const_none) { - // delete item - mp_raise_AttributeError(translate("Cannot delete values")); - } else { - memorymonitor_allocationsize_obj_t *self = MP_OBJ_TO_PTR(self_in); - - if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { - mp_raise_NotImplementedError(translate("Slices not supported")); - } else { - size_t index = mp_get_index(&memorymonitor_allocationsize_type, common_hal_memorymonitor_allocationsize_get_len(self), index_obj, false); - if (value == MP_OBJ_SENTINEL) { - // load - return MP_OBJ_NEW_SMALL_INT(common_hal_memorymonitor_allocationsize_get_item(self, index)); - } else { - mp_raise_AttributeError(translate("Read-only")); - } - } - } - return mp_const_none; -} - -STATIC const mp_rom_map_elem_t memorymonitor_allocationsize_locals_dict_table[] = { - // Methods - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&memorymonitor_allocationsize___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&memorymonitor_allocationsize___exit___obj) }, - - // Properties - { MP_ROM_QSTR(MP_QSTR_bytes_per_block), MP_ROM_PTR(&memorymonitor_allocationsize_bytes_per_block_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(memorymonitor_allocationsize_locals_dict, memorymonitor_allocationsize_locals_dict_table); - -const mp_obj_type_t memorymonitor_allocationsize_type = { - { &mp_type_type }, - .name = MP_QSTR_AllocationSize, - .make_new = memorymonitor_allocationsize_make_new, - .subscr = memorymonitor_allocationsize_subscr, - .unary_op = memorymonitor_allocationsize_unary_op, - .getiter = mp_obj_new_generic_iterator, - .locals_dict = (mp_obj_dict_t*)&memorymonitor_allocationsize_locals_dict, -}; diff --git a/shared-bindings/memorymonitor/AllocationSize 2.h b/shared-bindings/memorymonitor/AllocationSize 2.h deleted file mode 100644 index bcd9514bf..000000000 --- a/shared-bindings/memorymonitor/AllocationSize 2.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries - * - * 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. - */ - -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONSIZE_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONSIZE_H - -#include "shared-module/memorymonitor/AllocationSize.h" - -extern const mp_obj_type_t memorymonitor_allocationsize_type; - -extern void common_hal_memorymonitor_allocationsize_construct(memorymonitor_allocationsize_obj_t* self); -extern void common_hal_memorymonitor_allocationsize_pause(memorymonitor_allocationsize_obj_t* self); -extern void common_hal_memorymonitor_allocationsize_resume(memorymonitor_allocationsize_obj_t* self); -extern void common_hal_memorymonitor_allocationsize_clear(memorymonitor_allocationsize_obj_t* self); -extern size_t common_hal_memorymonitor_allocationsize_get_bytes_per_block(memorymonitor_allocationsize_obj_t* self); -extern uint16_t common_hal_memorymonitor_allocationsize_get_len(memorymonitor_allocationsize_obj_t* self); -extern uint16_t common_hal_memorymonitor_allocationsize_get_item(memorymonitor_allocationsize_obj_t* self, int16_t index); - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONSIZE_H diff --git a/shared-bindings/memorymonitor/__init__ 2.c b/shared-bindings/memorymonitor/__init__ 2.c deleted file mode 100644 index c101ba5e0..000000000 --- a/shared-bindings/memorymonitor/__init__ 2.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Scott Shawcroft - * - * 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. - */ - -#include - -#include "py/obj.h" -#include "py/runtime.h" - -#include "shared-bindings/memorymonitor/__init__.h" -#include "shared-bindings/memorymonitor/AllocationAlarm.h" -#include "shared-bindings/memorymonitor/AllocationSize.h" - -//| """Memory monitoring helpers""" -//| - -//| class AllocationError(Exception): -//| """Catchall exception for allocation related errors.""" -//| ... -MP_DEFINE_MEMORYMONITOR_EXCEPTION(AllocationError, Exception) - -NORETURN void mp_raise_memorymonitor_AllocationError(const compressed_string_t* fmt, ...) { - va_list argptr; - va_start(argptr,fmt); - mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_memorymonitor_AllocationError, fmt, argptr); - va_end(argptr); - nlr_raise(exception); -} - -STATIC const mp_rom_map_elem_t memorymonitor_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_memorymonitor) }, - { MP_ROM_QSTR(MP_QSTR_AllocationAlarm), MP_ROM_PTR(&memorymonitor_allocationalarm_type) }, - { MP_ROM_QSTR(MP_QSTR_AllocationSize), MP_ROM_PTR(&memorymonitor_allocationsize_type) }, - - // Errors - { MP_ROM_QSTR(MP_QSTR_AllocationError), MP_ROM_PTR(&mp_type_memorymonitor_AllocationError) }, -}; - -STATIC MP_DEFINE_CONST_DICT(memorymonitor_module_globals, memorymonitor_module_globals_table); - -void memorymonitor_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { - mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS; - bool is_subclass = kind & PRINT_EXC_SUBCLASS; - if (!is_subclass && (k == PRINT_EXC)) { - mp_print_str(print, qstr_str(MP_OBJ_QSTR_VALUE(memorymonitor_module_globals_table[0].value))); - mp_print_str(print, "."); - } - mp_obj_exception_print(print, o_in, kind); -} - -const mp_obj_module_t memorymonitor_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&memorymonitor_module_globals, -}; diff --git a/shared-bindings/memorymonitor/__init__ 2.h b/shared-bindings/memorymonitor/__init__ 2.h deleted file mode 100644 index 60fcdc3f6..000000000 --- a/shared-bindings/memorymonitor/__init__ 2.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft - * - * 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. - */ - -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR___INIT___H - -#include "py/obj.h" - - -void memorymonitor_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); - -#define MP_DEFINE_MEMORYMONITOR_EXCEPTION(exc_name, base_name) \ -const mp_obj_type_t mp_type_memorymonitor_ ## exc_name = { \ - { &mp_type_type }, \ - .name = MP_QSTR_ ## exc_name, \ - .print = memorymonitor_exception_print, \ - .make_new = mp_obj_exception_make_new, \ - .attr = mp_obj_exception_attr, \ - .parent = &mp_type_ ## base_name, \ -}; - -extern const mp_obj_type_t mp_type_memorymonitor_AllocationError; - -NORETURN void mp_raise_memorymonitor_AllocationError(const compressed_string_t* msg, ...); - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR___INIT___H diff --git a/shared-bindings/sdcardio/SDCard 2.c b/shared-bindings/sdcardio/SDCard 2.c deleted file mode 100644 index 975f8b095..000000000 --- a/shared-bindings/sdcardio/SDCard 2.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries - * - * 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. - */ - -#include "py/obj.h" -#include "py/objproperty.h" -#include "py/runtime.h" -#include "py/objarray.h" - -#include "shared-bindings/sdcardio/SDCard.h" -#include "shared-module/sdcardio/SDCard.h" -#include "common-hal/busio/SPI.h" -#include "shared-bindings/busio/SPI.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "supervisor/flash.h" - -//| class SDCard: -//| """SD Card Block Interface -//| -//| Controls an SD card over SPI. This built-in module has higher read -//| performance than the library adafruit_sdcard, but it is only compatible with -//| `busio.SPI`, not `bitbangio.SPI`. Usually an SDCard object is used -//| with ``storage.VfsFat`` to allow file I/O to an SD card.""" -//| -//| def __init__(self, bus: busio.SPI, cs: microcontroller.Pin, baudrate: int = 8000000) -> None: -//| """Construct an SPI SD Card object with the given properties -//| -//| :param busio.SPI spi: The SPI bus -//| :param microcontroller.Pin cs: The chip select connected to the card -//| :param int baudrate: The SPI data rate to use after card setup -//| -//| Note that during detection and configuration, a hard-coded low baudrate is used. -//| Data transfers use the specified baurate (rounded down to one that is supported by -//| the microcontroller) -//| -//| Example usage: -//| -//| .. code-block:: python -//| -//| import os -//| -//| import board -//| import sdcardio -//| import storage -//| -//| sd = sdcardio.SDCard(board.SPI(), board.SD_CS) -//| vfs = storage.VfsFat(sd) -//| storage.mount(vfs, '/sd') -//| os.listdir('/sd')""" - -STATIC mp_obj_t sdcardio_sdcard_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_spi, ARG_cs, ARG_baudrate, ARG_sdio, NUM_ARGS }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_spi, MP_ARG_OBJ, {.u_obj = mp_const_none } }, - { MP_QSTR_cs, MP_ARG_OBJ, {.u_obj = mp_const_none } }, - { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 8000000} }, - { MP_QSTR_sdio, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_int = 8000000} }, - }; - MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - busio_spi_obj_t *spi = validate_obj_is_spi_bus(args[ARG_spi].u_obj); - mcu_pin_obj_t *cs = validate_obj_is_free_pin(args[ARG_cs].u_obj); - - sdcardio_sdcard_obj_t *self = m_new_obj(sdcardio_sdcard_obj_t); - self->base.type = &sdcardio_SDCard_type; - - common_hal_sdcardio_sdcard_construct(self, spi, cs, args[ARG_baudrate].u_int); - - return self; -} - - -//| def count(self) -> int: -//| """Returns the total number of sectors -//| -//| Due to technical limitations, this is a function and not a property. -//| -//| :return: The number of 512-byte blocks, as a number""" -//| -mp_obj_t sdcardio_sdcard_count(mp_obj_t self_in) { - sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t*)self_in; - return mp_obj_new_int_from_ull(common_hal_sdcardio_sdcard_get_blockcount(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_count_obj, sdcardio_sdcard_count); - -//| def deinit(self) -> None: -//| """Disable permanently. -//| -//| :return: None""" -//| -mp_obj_t sdcardio_sdcard_deinit(mp_obj_t self_in) { - sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t*)self_in; - common_hal_sdcardio_sdcard_deinit(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_deinit_obj, sdcardio_sdcard_deinit); - - -//| def readblocks(self, start_block: int, buf: WriteableBuffer) -> None: -//| -//| """Read one or more blocks from the card -//| -//| :param int start_block: The block to start reading from -//| :param ~_typing.WriteableBuffer buf: The buffer to write into. Length must be multiple of 512. -//| -//| :return: None""" -//| - -mp_obj_t sdcardio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { - uint32_t start_block = mp_obj_get_int(start_block_in); - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE); - sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t*)self_in; - int result = common_hal_sdcardio_sdcard_readblocks(self, start_block, &bufinfo); - if (result < 0) { - mp_raise_OSError(-result); - } - return mp_const_none; -} - -MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_readblocks_obj, sdcardio_sdcard_readblocks); - -//| def writeblocks(self, start_block: int, buf: ReadableBuffer) -> None: -//| -//| """Write one or more blocks to the card -//| -//| :param int start_block: The block to start writing from -//| :param ~_typing.ReadableBuffer buf: The buffer to read from. Length must be multiple of 512. -//| -//| :return: None""" -//| - -mp_obj_t sdcardio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { - uint32_t start_block = mp_obj_get_int(start_block_in); - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); - sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t*)self_in; - int result = common_hal_sdcardio_sdcard_writeblocks(self, start_block, &bufinfo); - if (result < 0) { - mp_raise_OSError(-result); - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_writeblocks_obj, sdcardio_sdcard_writeblocks); - -STATIC const mp_rom_map_elem_t sdcardio_sdcard_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_count), MP_ROM_PTR(&sdcardio_sdcard_count_obj) }, - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&sdcardio_sdcard_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&sdcardio_sdcard_readblocks_obj) }, - { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&sdcardio_sdcard_writeblocks_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(sdcardio_sdcard_locals_dict, sdcardio_sdcard_locals_dict_table); - -const mp_obj_type_t sdcardio_SDCard_type = { - { &mp_type_type }, - .name = MP_QSTR_SDCard, - .make_new = sdcardio_sdcard_make_new, - .locals_dict = (mp_obj_dict_t*)&sdcardio_sdcard_locals_dict, -}; diff --git a/shared-bindings/sdcardio/SDCard 2.h b/shared-bindings/sdcardio/SDCard 2.h deleted file mode 100644 index 5986d5b81..000000000 --- a/shared-bindings/sdcardio/SDCard 2.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries - * Copyright (c) 2020 Jeff Epler for Adafruit Industries - * - * 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. - */ - -#pragma once - -extern const mp_obj_type_t sdcardio_SDCard_type; diff --git a/shared-bindings/sdcardio/__init__ 2.c b/shared-bindings/sdcardio/__init__ 2.c deleted file mode 100644 index 746aa5588..000000000 --- a/shared-bindings/sdcardio/__init__ 2.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries - * - * 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. - */ - - -#include - -#include "py/obj.h" -#include "py/runtime.h" - -#include "shared-bindings/sdcardio/SDCard.h" - -//| """Interface to an SD card via the SPI bus""" - -STATIC const mp_rom_map_elem_t sdcardio_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sdcardio) }, - { MP_ROM_QSTR(MP_QSTR_SDCard), MP_ROM_PTR(&sdcardio_SDCard_type) }, -}; - -STATIC MP_DEFINE_CONST_DICT(sdcardio_module_globals, sdcardio_module_globals_table); - -const mp_obj_module_t sdcardio_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&sdcardio_module_globals, -}; diff --git a/shared-bindings/sdcardio/__init__ 2.h b/shared-bindings/sdcardio/__init__ 2.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/shared-module/sdcardio/SDCard 2.c b/shared-module/sdcardio/SDCard 2.c deleted file mode 100644 index 9e861279d..000000000 --- a/shared-module/sdcardio/SDCard 2.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries - * - * 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. - */ - -// This implementation largely follows the structure of adafruit_sdcard.py - -#include "shared-bindings/busio/SPI.h" -#include "shared-bindings/digitalio/DigitalInOut.h" -#include "shared-bindings/time/__init__.h" -#include "shared-bindings/util.h" -#include "shared-module/sdcardio/SDCard.h" - -#include "py/mperrno.h" - -#if 0 -#define DEBUG_PRINT(...) ((void)mp_printf(&mp_plat_print, ## __VA_ARGS__)) -#else -#define DEBUG_PRINT(...) ((void)0) -#endif - -#define CMD_TIMEOUT (200) - -#define R1_IDLE_STATE (1<<0) -#define R1_ILLEGAL_COMMAND (1<<2) - -#define TOKEN_CMD25 (0xFC) -#define TOKEN_STOP_TRAN (0xFD) -#define TOKEN_DATA (0xFE) - -STATIC bool lock_and_configure_bus(sdcardio_sdcard_obj_t *self) { - if (!common_hal_busio_spi_try_lock(self->bus)) { - return false; - } - common_hal_busio_spi_configure(self->bus, self->baudrate, 0, 0, 8); - common_hal_digitalio_digitalinout_set_value(&self->cs, false); - return true; -} - -STATIC void lock_bus_or_throw(sdcardio_sdcard_obj_t *self) { - if (!lock_and_configure_bus(self)) { - mp_raise_OSError(EAGAIN); - } -} - -STATIC void clock_card(sdcardio_sdcard_obj_t *self, int bytes) { - uint8_t buf[] = {0xff}; - common_hal_digitalio_digitalinout_set_value(&self->cs, true); - for (int i=0; ibus, buf, 1); - } -} - -STATIC void extraclock_and_unlock_bus(sdcardio_sdcard_obj_t *self) { - clock_card(self, 1); - common_hal_busio_spi_unlock(self->bus); -} - -static uint8_t CRC7(const uint8_t* data, uint8_t n) { - uint8_t crc = 0; - for (uint8_t i = 0; i < n; i++) { - uint8_t d = data[i]; - for (uint8_t j = 0; j < 8; j++) { - crc <<= 1; - if ((d & 0x80) ^ (crc & 0x80)) { - crc ^= 0x09; - } - d <<= 1; - } - } - return (crc << 1) | 1; -} - -#define READY_TIMEOUT_NS (300 * 1000 * 1000) // 300ms -STATIC void wait_for_ready(sdcardio_sdcard_obj_t *self) { - uint64_t deadline = common_hal_time_monotonic_ns() + READY_TIMEOUT_NS; - while (common_hal_time_monotonic_ns() < deadline) { - uint8_t b; - common_hal_busio_spi_read(self->bus, &b, 1, 0xff); - if (b == 0xff) { - break; - } - } -} - -// In Python API, defaults are response=None, data_block=True, wait=True -STATIC int cmd(sdcardio_sdcard_obj_t *self, int cmd, int arg, void *response_buf, size_t response_len, bool data_block, bool wait) { - DEBUG_PRINT("cmd % 3d [%02x] arg=% 11d [%08x] len=%d%s%s\n", cmd, cmd, arg, arg, response_len, data_block ? " data" : "", wait ? " wait" : ""); - uint8_t cmdbuf[6]; - cmdbuf[0] = cmd | 0x40; - cmdbuf[1] = (arg >> 24) & 0xff; - cmdbuf[2] = (arg >> 16) & 0xff; - cmdbuf[3] = (arg >> 8) & 0xff; - cmdbuf[4] = arg & 0xff; - cmdbuf[5] = CRC7(cmdbuf, 5); - - if (wait) { - wait_for_ready(self); - } - - common_hal_busio_spi_write(self->bus, cmdbuf, sizeof(cmdbuf)); - - // Wait for the response (response[7] == 0) - bool response_received = false; - for (int i=0; ibus, cmdbuf, 1, 0xff); - if ((cmdbuf[0] & 0x80) == 0) { - response_received = true; - break; - } - } - - if (!response_received) { - return -EIO; - } - - if (response_buf) { - - if (data_block) { - cmdbuf[1] = 0xff; - do { - // Wait for the start block byte - common_hal_busio_spi_read(self->bus, cmdbuf+1, 1, 0xff); - } while (cmdbuf[1] != 0xfe); - } - - common_hal_busio_spi_read(self->bus, response_buf, response_len, 0xff); - - if (data_block) { - // Read and discard the CRC-CCITT checksum - common_hal_busio_spi_read(self->bus, cmdbuf+1, 2, 0xff); - } - - } - - return cmdbuf[0]; -} - -STATIC int block_cmd(sdcardio_sdcard_obj_t *self, int cmd_, int block, void *response_buf, size_t response_len, bool data_block, bool wait) { - return cmd(self, cmd_, block * self->cdv, response_buf, response_len, true, true); -} - -STATIC bool cmd_nodata(sdcardio_sdcard_obj_t* self, int cmd, int response) { - uint8_t cmdbuf[2] = {cmd, 0xff}; - - common_hal_busio_spi_write(self->bus, cmdbuf, sizeof(cmdbuf)); - - // Wait for the response (response[7] == response) - for (int i=0; ibus, cmdbuf, 1, 0xff); - if (cmdbuf[0] == response) { - return 0; - } - } - return -EIO; -} - -STATIC const compressed_string_t *init_card_v1(sdcardio_sdcard_obj_t *self) { - for (int i=0; icdv = 1; - } - return NULL; - } - } - return translate("timeout waiting for v2 card"); -} - -STATIC const compressed_string_t *init_card(sdcardio_sdcard_obj_t *self) { - clock_card(self, 10); - - common_hal_digitalio_digitalinout_set_value(&self->cs, false); - - // CMD0: init card: should return _R1_IDLE_STATE (allow 5 attempts) - { - bool reached_idle_state = false; - for (int i=0; i<5; i++) { - if (cmd(self, 0, 0, NULL, 0, true, true) == R1_IDLE_STATE) { - reached_idle_state = true; - break; - } - } - if (!reached_idle_state) { - return translate("no SD card"); - } - } - - // CMD8: determine card version - { - uint8_t rb7[4]; - int response = cmd(self, 8, 0x1AA, rb7, sizeof(rb7), false, true); - if (response == R1_IDLE_STATE) { - const compressed_string_t *result =init_card_v2(self); - if (result != NULL) { - return result; - } - } else if (response == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { - const compressed_string_t *result =init_card_v1(self); - if (result != NULL) { - return result; - } - } else { - return translate("couldn't determine SD card version"); - } - } - - // CMD9: get number of sectors - { - uint8_t csd[16]; - int response = cmd(self, 9, 0, csd, sizeof(csd), true, true); - if (response != 0) { - return translate("no response from SD card"); - } - int csd_version = (csd[0] & 0xC0) >> 6; - if (csd_version >= 2) { - return translate("SD card CSD format not supported"); - } - - if (csd_version == 1) { - self->sectors = ((csd[8] << 8 | csd[9]) + 1) * 1024; - } else { - uint32_t block_length = 1 << (csd[5] & 0xF); - uint32_t c_size = ((csd[6] & 0x3) << 10) | (csd[7] << 2) | ((csd[8] & 0xC) >> 6); - uint32_t mult = 1 << (((csd[9] & 0x3) << 1 | (csd[10] & 0x80) >> 7) + 2); - self->sectors = block_length / 512 * mult * (c_size + 1); - } - } - - // CMD16: set block length to 512 bytes - { - int response = cmd(self, 16, 512, NULL, 0, true, true); - if (response != 0) { - return translate("can't set 512 block size"); - } - } - - return NULL; -} - -void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, mcu_pin_obj_t *cs, int baudrate) { - self->bus = bus; - common_hal_digitalio_digitalinout_construct(&self->cs, cs); - common_hal_digitalio_digitalinout_switch_to_output(&self->cs, true, DRIVE_MODE_PUSH_PULL); - - self->cdv = 512; - self->sectors = 0; - self->baudrate = 250000; - - lock_bus_or_throw(self); - const compressed_string_t *result = init_card(self); - extraclock_and_unlock_bus(self); - - if (result != NULL) { - common_hal_digitalio_digitalinout_deinit(&self->cs); - mp_raise_OSError_msg(result); - } - - self->baudrate = baudrate; -} - -void common_hal_sdcardio_sdcard_deinit(sdcardio_sdcard_obj_t *self) { - if (!self->bus) { - return; - } - self->bus = 0; - common_hal_digitalio_digitalinout_deinit(&self->cs); -} - -void common_hal_sdcardio_check_for_deinit(sdcardio_sdcard_obj_t *self) { - if (!self->bus) { - raise_deinited_error(); - } -} - -int common_hal_sdcardio_sdcard_get_blockcount(sdcardio_sdcard_obj_t *self) { - common_hal_sdcardio_check_for_deinit(self); - return self->sectors; -} - -int readinto(sdcardio_sdcard_obj_t *self, void *buf, size_t size) { - uint8_t aux[2] = {0, 0}; - while (aux[0] != 0xfe) { - common_hal_busio_spi_read(self->bus, aux, 1, 0xff); - } - - common_hal_busio_spi_read(self->bus, buf, size, 0xff); - - // Read checksum and throw it away - common_hal_busio_spi_read(self->bus, aux, sizeof(aux), 0xff); - return 0; -} - -int readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) { - uint32_t nblocks = buf->len / 512; - if (nblocks == 1) { - // Use CMD17 to read a single block - return block_cmd(self, 17, start_block, buf->buf, buf->len, true, true); - } else { - // Use CMD18 to read multiple blocks - int r = block_cmd(self, 18, start_block, NULL, 0, true, true); - if (r < 0) { - return r; - } - - uint8_t *ptr = buf->buf; - while (nblocks--) { - r = readinto(self, ptr, 512); - if (r < 0) { - return r; - } - ptr += 512; - } - - // End the multi-block read - r = cmd(self, 12, 0, NULL, 0, true, false); - - // Return first status 0 or last before card ready (0xff) - while (r != 0) { - uint8_t single_byte; - common_hal_busio_spi_read(self->bus, &single_byte, 1, 0xff); - if (single_byte & 0x80) { - return r; - } - r = single_byte; - } - } - return 0; -} - -int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) { - common_hal_sdcardio_check_for_deinit(self); - if (buf->len % 512 != 0) { - mp_raise_ValueError(translate("Buffer length must be a multiple of 512")); - } - - lock_and_configure_bus(self); - int r = readblocks(self, start_block, buf); - extraclock_and_unlock_bus(self); - return r; -} - -int _write(sdcardio_sdcard_obj_t *self, uint8_t token, void *buf, size_t size) { - wait_for_ready(self); - - uint8_t cmd[2]; - cmd[0] = token; - - common_hal_busio_spi_write(self->bus, cmd, 1); - common_hal_busio_spi_write(self->bus, buf, size); - - cmd[0] = cmd[1] = 0xff; - common_hal_busio_spi_write(self->bus, cmd, 2); - - // Check the response - // This differs from the traditional adafruit_sdcard handling, - // but adafruit_sdcard also ignored the return value of SDCard._write(!) - // so nobody noticed - // - // - // Response is as follows: - // x x x 0 STAT 1 - // 7 6 5 4 3..1 0 - // with STATUS 010 indicating "data accepted", and other status bit - // combinations indicating failure. - // In practice, I was seeing cmd[0] as 0xe5, indicating success - for (int i=0; ibus, cmd, 1, 0xff); - DEBUG_PRINT("i=%02d cmd[0] = 0x%02x\n", i, cmd[0]); - if ((cmd[0] & 0b00010001) == 0b00000001) { - if ((cmd[0] & 0x1f) != 0x5) { - return -EIO; - } else { - break; - } - } - } - - // Wait for the write to finish - do { - common_hal_busio_spi_read(self->bus, cmd, 1, 0xff); - } while (cmd[0] == 0); - - // Success - return 0; -} - -int writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) { - common_hal_sdcardio_check_for_deinit(self); - uint32_t nblocks = buf->len / 512; - if (nblocks == 1) { - // Use CMD24 to write a single block - int r = block_cmd(self, 24, start_block, NULL, 0, true, true); - if (r < 0) { - return r; - } - r = _write(self, TOKEN_DATA, buf->buf, buf->len); - if (r < 0) { - return r; - } - } else { - // Use CMD25 to write multiple block - int r = block_cmd(self, 25, start_block, NULL, 0, true, true); - if (r < 0) { - return r; - } - - uint8_t *ptr = buf->buf; - while (nblocks--) { - r = _write(self, TOKEN_CMD25, ptr, 512); - if (r < 0) { - return r; - } - ptr += 512; - } - - cmd_nodata(self, TOKEN_STOP_TRAN, 0); - } - return 0; -} - -int common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) { - common_hal_sdcardio_check_for_deinit(self); - if (buf->len % 512 != 0) { - mp_raise_ValueError(translate("Buffer length must be a multiple of 512")); - } - lock_and_configure_bus(self); - int r = writeblocks(self, start_block, buf); - extraclock_and_unlock_bus(self); - return r; -} diff --git a/shared-module/sdcardio/SDCard 2.h b/shared-module/sdcardio/SDCard 2.h deleted file mode 100644 index 76c906029..000000000 --- a/shared-module/sdcardio/SDCard 2.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries - * - * 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. - */ - -#pragma once - -#include "py/obj.h" -#include "py/objproperty.h" -#include "py/runtime.h" -#include "py/objarray.h" - -#include "common-hal/busio/SPI.h" -#include "common-hal/digitalio/DigitalInOut.h" - -typedef struct { - mp_obj_base_t base; - busio_spi_obj_t *bus; - digitalio_digitalinout_obj_t cs; - int cdv; - int baudrate; - uint32_t sectors; -} sdcardio_sdcard_obj_t; - -void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *spi, mcu_pin_obj_t *cs, int baudrate); -void common_hal_sdcardio_sdcard_deinit(sdcardio_sdcard_obj_t *self); -void common_hal_sdcardio_sdcard_check_for_deinit(sdcardio_sdcard_obj_t *self); -int common_hal_sdcardio_sdcard_get_blockcount(sdcardio_sdcard_obj_t *self); -int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf); -int common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf); diff --git a/shared-module/sdcardio/__init__ 2.c b/shared-module/sdcardio/__init__ 2.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/shared-module/sdcardio/__init__ 2.h b/shared-module/sdcardio/__init__ 2.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/supervisor/background_callback 2.h b/supervisor/background_callback 2.h deleted file mode 100644 index 535dd656b..000000000 --- a/supervisor/background_callback 2.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries - * - * 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. - */ - -#ifndef CIRCUITPY_INCLUDED_SUPERVISOR_BACKGROUND_CALLBACK_H -#define CIRCUITPY_INCLUDED_SUPERVISOR_BACKGROUND_CALLBACK_H - -/** Background callbacks are a linked list of tasks to call in the background. - * - * Include a member of type `background_callback_t` inside an object - * which needs to queue up background work, and zero-initialize it. - * - * To schedule the work, use background_callback_add, with fun as the - * function to call and data pointing to the object itself. - * - * Next time run_background_tasks_if_tick is called, the callback will - * be run and removed from the linked list. - * - * Queueing a task that is already queued does nothing. Unconditionally - * re-queueing it from its own background task will cause it to run during the - * very next background-tasks invocation, leading to a CircuitPython freeze, so - * don't do that. - * - * background_callback_add can be called from interrupt context. - */ -typedef void (*background_callback_fun)(void *data); -typedef struct background_callback { - background_callback_fun fun; - void *data; - struct background_callback *next; - struct background_callback *prev; -} background_callback_t; - -/* Add a background callback for which 'fun' and 'data' were previously set */ -void background_callback_add_core(background_callback_t *cb); - -/* Add a background callback to the given function with the given data. When - * the callback involves an object on the GC heap, the 'data' must be a pointer - * to that object itself, not an internal pointer. Otherwise, it can be the - * case that no other references to the object itself survive, and the object - * becomes garbage collected while an outstanding background callback still - * exists. - */ -void background_callback_add(background_callback_t *cb, background_callback_fun fun, void *data); - -/* Run all background callbacks. Normally, this is done by the supervisor - * whenever the list is non-empty */ -void background_callback_run_all(void); - -/* During soft reset, remove all pending callbacks and clear the critical section flag */ -void background_callback_reset(void); - -/* Sometimes background callbacks must be blocked. Use these functions to - * bracket the section of code where this is the case. These calls nest, and - * begins must be balanced with ends. - */ -void background_callback_begin_critical_section(void); -void background_callback_end_critical_section(void); - -/* - * Background callbacks may stop objects from being collected - */ -void background_callback_gc_collect(void); - -#endif diff --git a/supervisor/shared/background_callback 2.c b/supervisor/shared/background_callback 2.c deleted file mode 100644 index 8e12dd362..000000000 --- a/supervisor/shared/background_callback 2.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries - * - * 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. - */ - -#include - -#include "py/gc.h" -#include "py/mpconfig.h" -#include "supervisor/background_callback.h" -#include "supervisor/shared/tick.h" -#include "shared-bindings/microcontroller/__init__.h" - -STATIC volatile background_callback_t *callback_head, *callback_tail; - -#define CALLBACK_CRITICAL_BEGIN (common_hal_mcu_disable_interrupts()) -#define CALLBACK_CRITICAL_END (common_hal_mcu_enable_interrupts()) - -void background_callback_add_core(background_callback_t *cb) { - CALLBACK_CRITICAL_BEGIN; - if (cb->prev || callback_head == cb) { - CALLBACK_CRITICAL_END; - return; - } - cb->next = 0; - cb->prev = (background_callback_t*)callback_tail; - if (callback_tail) { - callback_tail->next = cb; - cb->prev = (background_callback_t*)callback_tail; - } - if (!callback_head) { - callback_head = cb; - } - callback_tail = cb; - CALLBACK_CRITICAL_END; -} - -void background_callback_add(background_callback_t *cb, background_callback_fun fun, void *data) { - cb->fun = fun; - cb->data = data; - background_callback_add_core(cb); -} - -static bool in_background_callback; -void background_callback_run_all() { - if (!callback_head) { - return; - } - CALLBACK_CRITICAL_BEGIN; - if (in_background_callback) { - CALLBACK_CRITICAL_END; - return; - } - in_background_callback = true; - background_callback_t *cb = (background_callback_t*)callback_head; - callback_head = NULL; - callback_tail = NULL; - while (cb) { - background_callback_t *next = cb->next; - cb->next = cb->prev = NULL; - background_callback_fun fun = cb->fun; - void *data = cb->data; - CALLBACK_CRITICAL_END; - // Leave the critical section in order to run the callback function - if (fun) { - fun(data); - } - CALLBACK_CRITICAL_BEGIN; - cb = next; - } - in_background_callback = false; - CALLBACK_CRITICAL_END; -} - -void background_callback_begin_critical_section() { - CALLBACK_CRITICAL_BEGIN; -} - -void background_callback_end_critical_section() { - CALLBACK_CRITICAL_END; -} - -void background_callback_reset() { - CALLBACK_CRITICAL_BEGIN; - background_callback_t *cb = (background_callback_t*)callback_head; - while(cb) { - background_callback_t *next = cb->next; - memset(cb, 0, sizeof(*cb)); - cb = next; - } - callback_head = NULL; - callback_tail = NULL; - in_background_callback = false; - CALLBACK_CRITICAL_END; -} - -void background_callback_gc_collect(void) { - // We don't enter the callback critical section here. We rely on - // gc_collect_ptr _NOT_ entering background callbacks, so it is not - // possible for the list to be cleared. - // - // However, it is possible for the list to be extended. We make the - // minor assumption that no newly added callback is for a - // collectable object. That is, we only plug the hole where an - // object becomes collectable AFTER it is added but before the - // callback is run, not the hole where an object was ALREADY - // collectable but adds a background task for itself. - // - // It's necessary to traverse the whole list here, as the callbacks - // themselves can be in non-gc memory, and some of the cb->data - // objects themselves might be in non-gc memory. - background_callback_t *cb = (background_callback_t*)callback_head; - while(cb) { - gc_collect_ptr(cb->data); - cb = cb->next; - } -} -- cgit v1.2.3 From 983e1af33d0440329aa4f34109994f8597f0737a Mon Sep 17 00:00:00 2001 From: Kevin Matocha Date: Fri, 21 Aug 2020 19:10:13 -0500 Subject: remove other extraneous files --- shared-bindings/sdioio/SDCard 2.c | 296 ------------------------ shared-bindings/sdioio/SDCard 2.h | 66 ------ shared-bindings/sdioio/__init__ 2.c | 47 ---- shared-bindings/sdioio/__init__ 2.h | 0 shared-module/memorymonitor/AllocationAlarm 2.c | 94 -------- shared-module/memorymonitor/AllocationAlarm 2.h | 51 ---- shared-module/memorymonitor/AllocationSize 2.c | 91 -------- shared-module/memorymonitor/AllocationSize 2.h | 51 ---- shared-module/memorymonitor/__init__ 2.c | 39 ---- shared-module/memorymonitor/__init__ 2.h | 35 --- 10 files changed, 770 deletions(-) delete mode 100644 shared-bindings/sdioio/SDCard 2.c delete mode 100644 shared-bindings/sdioio/SDCard 2.h delete mode 100644 shared-bindings/sdioio/__init__ 2.c delete mode 100644 shared-bindings/sdioio/__init__ 2.h delete mode 100644 shared-module/memorymonitor/AllocationAlarm 2.c delete mode 100644 shared-module/memorymonitor/AllocationAlarm 2.h delete mode 100644 shared-module/memorymonitor/AllocationSize 2.c delete mode 100644 shared-module/memorymonitor/AllocationSize 2.h delete mode 100644 shared-module/memorymonitor/__init__ 2.c delete mode 100644 shared-module/memorymonitor/__init__ 2.h (limited to 'shared-module') diff --git a/shared-bindings/sdioio/SDCard 2.c b/shared-bindings/sdioio/SDCard 2.c deleted file mode 100644 index aba414cd6..000000000 --- a/shared-bindings/sdioio/SDCard 2.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft - * - * 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. - */ - -// This file contains all of the Python API definitions for the -// sdioio.SDCard class. - -#include - -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/sdioio/SDCard.h" -#include "shared-bindings/util.h" - -#include "lib/utils/buffer_helper.h" -#include "lib/utils/context_manager_helpers.h" -#include "py/mperrno.h" -#include "py/objproperty.h" -#include "py/runtime.h" -#include "supervisor/shared/translate.h" - -//| class SDCard: -//| """SD Card Block Interface with SDIO -//| -//| Controls an SD card over SDIO. SDIO is a parallel protocol designed -//| for SD cards. It uses a clock pin, a command pin, and 1 or 4 -//| data pins. It can be operated at a high frequency such as -//| 25MHz. Usually an SDCard object is used with ``storage.VfsFat`` -//| to allow file I/O to an SD card.""" -//| -//| def __init__(self, clock: microcontroller.Pin, command: microcontroller.Pin, data: Sequence[microcontroller.Pin], frequency: int) -> None: -//| """Construct an SDIO SD Card object with the given properties -//| -//| :param ~microcontroller.Pin clock: the pin to use for the clock. -//| :param ~microcontroller.Pin command: the pin to use for the command. -//| :param data: A sequence of pins to use for data. -//| :param frequency: The frequency of the bus in Hz -//| -//| Example usage: -//| -//| .. code-block:: python -//| -//| import os -//| -//| import board -//| import sdioio -//| import storage -//| -//| sd = sdioio.SDCard( -//| clock=board.SDIO_CLOCK, -//| command=board.SDIO_COMMAND, -//| data=board.SDIO_DATA, -//| frequency=25000000) -//| vfs = storage.VfsFat(sd) -//| storage.mount(vfs, '/sd') -//| os.listdir('/sd')""" -//| ... -//| - -STATIC mp_obj_t sdioio_sdcard_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - sdioio_sdcard_obj_t *self = m_new_obj(sdioio_sdcard_obj_t); - self->base.type = &sdioio_SDCard_type; - enum { ARG_clock, ARG_command, ARG_data, ARG_frequency, NUM_ARGS }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ }, - { MP_QSTR_command, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ }, - { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ }, - { MP_QSTR_frequency, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT }, - }; - MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - const mcu_pin_obj_t* clock = validate_obj_is_free_pin(args[ARG_clock].u_obj); - const mcu_pin_obj_t* command = validate_obj_is_free_pin(args[ARG_command].u_obj); - mcu_pin_obj_t *data_pins[4]; - uint8_t num_data; - validate_list_is_free_pins(MP_QSTR_data, data_pins, MP_ARRAY_SIZE(data_pins), args[ARG_data].u_obj, &num_data); - - common_hal_sdioio_sdcard_construct(self, clock, command, num_data, data_pins, args[ARG_frequency].u_int); - return MP_OBJ_FROM_PTR(self); -} - -STATIC void check_for_deinit(sdioio_sdcard_obj_t *self) { - if (common_hal_sdioio_sdcard_deinited(self)) { - raise_deinited_error(); - } -} - -//| def configure(self, frequency: int = 0, width: int = 0) -> None: -//| """Configures the SDIO bus. -//| -//| :param int frequency: the desired clock rate in Hertz. The actual clock rate may be higher or lower due to the granularity of available clock settings. Check the `frequency` attribute for the actual clock rate. -//| :param int width: the number of data lines to use. Must be 1 or 4 and must also not exceed the number of data lines at construction -//| -//| .. note:: Leaving a value unspecified or 0 means the current setting is kept""" -//| -STATIC mp_obj_t sdioio_sdcard_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_frequency, ARG_width, NUM_ARGS }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_width, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - }; - sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - check_for_deinit(self); - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - mp_int_t frequency = args[ARG_frequency].u_int; - if (frequency < 0) { - mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_baudrate); - } - - uint8_t width = args[ARG_width].u_int; - if (width != 0 && width != 1 && width != 4) { - mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_width); - } - - if (!common_hal_sdioio_sdcard_configure(self, frequency, width)) { - mp_raise_OSError(MP_EIO); - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(sdioio_sdcard_configure_obj, 1, sdioio_sdcard_configure); - -//| def count(self) -> int: -//| """Returns the total number of sectors -//| -//| Due to technical limitations, this is a function and not a property. -//| -//| :return: The number of 512-byte blocks, as a number""" -//| -STATIC mp_obj_t sdioio_sdcard_count(mp_obj_t self_in) { - sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_sdioio_sdcard_get_count(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_count_obj, sdioio_sdcard_count); - -//| def readblocks(self, start_block: int, buf: WriteableBuffer) -> None: -//| -//| """Read one or more blocks from the card -//| -//| :param int start_block: The block to start reading from -//| :param ~_typing.WriteableBuffer buf: The buffer to write into. Length must be multiple of 512. -//| -//| :return: None""" -mp_obj_t sdioio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { - uint32_t start_block = mp_obj_get_int(start_block_in); - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE); - sdioio_sdcard_obj_t *self = (sdioio_sdcard_obj_t*)self_in; - int result = common_hal_sdioio_sdcard_readblocks(self, start_block, &bufinfo); - if (result < 0) { - mp_raise_OSError(-result); - } - return mp_const_none; -} - -MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_readblocks_obj, sdioio_sdcard_readblocks); - -//| def writeblocks(self, start_block: int, buf: ReadableBuffer) -> None: -//| -//| """Write one or more blocks to the card -//| -//| :param int start_block: The block to start writing from -//| :param ~_typing.ReadableBuffer buf: The buffer to read from. Length must be multiple of 512. -//| -//| :return: None""" -//| -mp_obj_t sdioio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { - uint32_t start_block = mp_obj_get_int(start_block_in); - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); - sdioio_sdcard_obj_t *self = (sdioio_sdcard_obj_t*)self_in; - int result = common_hal_sdioio_sdcard_writeblocks(self, start_block, &bufinfo); - if (result < 0) { - mp_raise_OSError(-result); - } - return mp_const_none; -} - -MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_writeblocks_obj, sdioio_sdcard_writeblocks); - -//| @property -//| def frequency(self) -> int: -//| """The actual SDIO bus frequency. This may not match the frequency -//| requested due to internal limitations.""" -//| ... -//| -STATIC mp_obj_t sdioio_sdcard_obj_get_frequency(mp_obj_t self_in) { - sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_sdioio_sdcard_get_frequency(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_get_frequency_obj, sdioio_sdcard_obj_get_frequency); - -const mp_obj_property_t sdioio_sdcard_frequency_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&sdioio_sdcard_get_frequency_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| @property -//| def width(self) -> int: -//| """The actual SDIO bus width, in bits""" -//| ... -//| -STATIC mp_obj_t sdioio_sdcard_obj_get_width(mp_obj_t self_in) { - sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_sdioio_sdcard_get_width(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_get_width_obj, sdioio_sdcard_obj_get_width); - -const mp_obj_property_t sdioio_sdcard_width_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&sdioio_sdcard_get_width_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| def deinit(self) -> None: -//| """Disable permanently. -//| -//| :return: None""" -STATIC mp_obj_t sdioio_sdcard_obj_deinit(mp_obj_t self_in) { - sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_sdioio_sdcard_deinit(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_deinit_obj, sdioio_sdcard_obj_deinit); - -//| def __enter__(self) -> SDCard: -//| """No-op used by Context Managers. -//| Provided by context manager helper.""" -//| ... -//| - -//| def __exit__(self) -> None: -//| """Automatically deinitializes the hardware when exiting a context. See -//| :ref:`lifetime-and-contextmanagers` for more info.""" -//| ... -//| -STATIC mp_obj_t sdioio_sdcard_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_sdioio_sdcard_deinit(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(sdioio_sdcard_obj___exit___obj, 4, 4, sdioio_sdcard_obj___exit__); - -STATIC const mp_rom_map_elem_t sdioio_sdcard_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&sdioio_sdcard_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&sdioio_sdcard_obj___exit___obj) }, - - { MP_ROM_QSTR(MP_QSTR_configure), MP_ROM_PTR(&sdioio_sdcard_configure_obj) }, - { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&sdioio_sdcard_frequency_obj) }, - { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&sdioio_sdcard_width_obj) }, - - { MP_ROM_QSTR(MP_QSTR_count), MP_ROM_PTR(&sdioio_sdcard_count_obj) }, - { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&sdioio_sdcard_readblocks_obj) }, - { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&sdioio_sdcard_writeblocks_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(sdioio_sdcard_locals_dict, sdioio_sdcard_locals_dict_table); - -const mp_obj_type_t sdioio_SDCard_type = { - { &mp_type_type }, - .name = MP_QSTR_SDCard, - .make_new = sdioio_sdcard_make_new, - .locals_dict = (mp_obj_dict_t*)&sdioio_sdcard_locals_dict, -}; diff --git a/shared-bindings/sdioio/SDCard 2.h b/shared-bindings/sdioio/SDCard 2.h deleted file mode 100644 index 7f62ee7a6..000000000 --- a/shared-bindings/sdioio/SDCard 2.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft - * - * 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. - */ - -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SDIO_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SDIO_H - -#include "py/obj.h" - -#include "common-hal/microcontroller/Pin.h" -#include "common-hal/sdioio/SDCard.h" - -// Type object used in Python. Should be shared between ports. -extern const mp_obj_type_t sdioio_SDCard_type; - -// Construct an underlying SDIO object. -extern void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self, - const mcu_pin_obj_t * clock, const mcu_pin_obj_t * command, - uint8_t num_data, mcu_pin_obj_t ** data, uint32_t frequency); - -extern void common_hal_sdioio_sdcard_deinit(sdioio_sdcard_obj_t *self); -extern bool common_hal_sdioio_sdcard_deinited(sdioio_sdcard_obj_t *self); - -extern bool common_hal_sdioio_sdcard_configure(sdioio_sdcard_obj_t *self, uint32_t baudrate, uint8_t width); - -extern void common_hal_sdioio_sdcard_unlock(sdioio_sdcard_obj_t *self); - -// Return actual SDIO bus frequency. -uint32_t common_hal_sdioio_sdcard_get_frequency(sdioio_sdcard_obj_t* self); - -// Return SDIO bus width. -uint8_t common_hal_sdioio_sdcard_get_width(sdioio_sdcard_obj_t* self); - -// Return number of device blocks -uint32_t common_hal_sdioio_sdcard_get_count(sdioio_sdcard_obj_t* self); - -// Read or write blocks -int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t* self, uint32_t start_block, mp_buffer_info_t *bufinfo); -int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t* self, uint32_t start_block, mp_buffer_info_t *bufinfo); - -// This is used by the supervisor to claim SDIO devices indefinitely. -extern void common_hal_sdioio_sdcard_never_reset(sdioio_sdcard_obj_t *self); - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SDIO_H diff --git a/shared-bindings/sdioio/__init__ 2.c b/shared-bindings/sdioio/__init__ 2.c deleted file mode 100644 index b88e5c3a9..000000000 --- a/shared-bindings/sdioio/__init__ 2.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries - * - * 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. - */ - - -#include - -#include "py/obj.h" -#include "py/runtime.h" - -#include "shared-bindings/sdioio/SDCard.h" - -//| """Interface to an SD card via the SDIO bus""" - -STATIC const mp_rom_map_elem_t sdioio_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sdio) }, - { MP_ROM_QSTR(MP_QSTR_SDCard), MP_ROM_PTR(&sdioio_SDCard_type) }, -}; - -STATIC MP_DEFINE_CONST_DICT(sdioio_module_globals, sdioio_module_globals_table); - -const mp_obj_module_t sdioio_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&sdioio_module_globals, -}; diff --git a/shared-bindings/sdioio/__init__ 2.h b/shared-bindings/sdioio/__init__ 2.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/shared-module/memorymonitor/AllocationAlarm 2.c b/shared-module/memorymonitor/AllocationAlarm 2.c deleted file mode 100644 index 35f4e4c63..000000000 --- a/shared-module/memorymonitor/AllocationAlarm 2.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries - * - * 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. - */ - -#include "shared-bindings/memorymonitor/__init__.h" -#include "shared-bindings/memorymonitor/AllocationAlarm.h" - -#include "py/gc.h" -#include "py/mpstate.h" -#include "py/runtime.h" - -void common_hal_memorymonitor_allocationalarm_construct(memorymonitor_allocationalarm_obj_t* self, size_t minimum_block_count) { - self->minimum_block_count = minimum_block_count; - self->next = NULL; - self->previous = NULL; -} - -void common_hal_memorymonitor_allocationalarm_set_ignore(memorymonitor_allocationalarm_obj_t* self, mp_int_t count) { - self->count = count; -} - -void common_hal_memorymonitor_allocationalarm_pause(memorymonitor_allocationalarm_obj_t* self) { - // Check to make sure we aren't already paused. We can be if we're exiting from an exception we - // caused. - if (self->previous == NULL) { - return; - } - *self->previous = self->next; - self->next = NULL; - self->previous = NULL; -} - -void common_hal_memorymonitor_allocationalarm_resume(memorymonitor_allocationalarm_obj_t* self) { - if (self->previous != NULL) { - mp_raise_RuntimeError(translate("Already running")); - } - self->next = MP_STATE_VM(active_allocationalarms); - self->previous = (memorymonitor_allocationalarm_obj_t**) &MP_STATE_VM(active_allocationalarms); - if (self->next != NULL) { - self->next->previous = &self->next; - } - MP_STATE_VM(active_allocationalarms) = self; -} - -void memorymonitor_allocationalarms_allocation(size_t block_count) { - memorymonitor_allocationalarm_obj_t* alarm = MP_OBJ_TO_PTR(MP_STATE_VM(active_allocationalarms)); - size_t alert_count = 0; - while (alarm != NULL) { - // Hold onto next in case we remove the alarm from the list. - memorymonitor_allocationalarm_obj_t* next = alarm->next; - if (block_count >= alarm->minimum_block_count) { - if (alarm->count > 0) { - alarm->count--; - } else { - // Uncomment the breakpoint below if you want to use a C debugger to figure out the C - // call stack for an allocation. - // asm("bkpt"); - // Pause now because we may alert when throwing the exception too. - common_hal_memorymonitor_allocationalarm_pause(alarm); - alert_count++; - } - } - alarm = next; - } - if (alert_count > 0) { - mp_raise_memorymonitor_AllocationError(translate("Attempt to allocate %d blocks"), block_count); - } -} - -void memorymonitor_allocationalarms_reset(void) { - MP_STATE_VM(active_allocationalarms) = NULL; -} diff --git a/shared-module/memorymonitor/AllocationAlarm 2.h b/shared-module/memorymonitor/AllocationAlarm 2.h deleted file mode 100644 index 172c24f6c..000000000 --- a/shared-module/memorymonitor/AllocationAlarm 2.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries - * - * 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. - */ - -#ifndef MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONALARM_H -#define MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONALARM_H - -#include -#include - -#include "py/obj.h" - -typedef struct _memorymonitor_allocationalarm_obj_t memorymonitor_allocationalarm_obj_t; - -#define ALLOCATION_SIZE_BUCKETS 16 - -typedef struct _memorymonitor_allocationalarm_obj_t { - mp_obj_base_t base; - size_t minimum_block_count; - mp_int_t count; - // Store the location that points to us so we can remove ourselves. - memorymonitor_allocationalarm_obj_t** previous; - memorymonitor_allocationalarm_obj_t* next; -} memorymonitor_allocationalarm_obj_t; - -void memorymonitor_allocationalarms_allocation(size_t block_count); -void memorymonitor_allocationalarms_reset(void); - -#endif // MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONALARM_H diff --git a/shared-module/memorymonitor/AllocationSize 2.c b/shared-module/memorymonitor/AllocationSize 2.c deleted file mode 100644 index c28e65592..000000000 --- a/shared-module/memorymonitor/AllocationSize 2.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries - * - * 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. - */ - -#include "shared-bindings/memorymonitor/AllocationSize.h" - -#include "py/gc.h" -#include "py/mpstate.h" -#include "py/runtime.h" - -void common_hal_memorymonitor_allocationsize_construct(memorymonitor_allocationsize_obj_t* self) { - common_hal_memorymonitor_allocationsize_clear(self); - self->next = NULL; - self->previous = NULL; -} - -void common_hal_memorymonitor_allocationsize_pause(memorymonitor_allocationsize_obj_t* self) { - *self->previous = self->next; - self->next = NULL; - self->previous = NULL; -} - -void common_hal_memorymonitor_allocationsize_resume(memorymonitor_allocationsize_obj_t* self) { - if (self->previous != NULL) { - mp_raise_RuntimeError(translate("Already running")); - } - self->next = MP_STATE_VM(active_allocationsizes); - self->previous = (memorymonitor_allocationsize_obj_t**) &MP_STATE_VM(active_allocationsizes); - if (self->next != NULL) { - self->next->previous = &self->next; - } - MP_STATE_VM(active_allocationsizes) = self; -} - -void common_hal_memorymonitor_allocationsize_clear(memorymonitor_allocationsize_obj_t* self) { - for (size_t i = 0; i < ALLOCATION_SIZE_BUCKETS; i++) { - self->buckets[i] = 0; - } -} - -uint16_t common_hal_memorymonitor_allocationsize_get_len(memorymonitor_allocationsize_obj_t* self) { - return ALLOCATION_SIZE_BUCKETS; -} - -size_t common_hal_memorymonitor_allocationsize_get_bytes_per_block(memorymonitor_allocationsize_obj_t* self) { - return BYTES_PER_BLOCK; -} - -uint16_t common_hal_memorymonitor_allocationsize_get_item(memorymonitor_allocationsize_obj_t* self, int16_t index) { - return self->buckets[index]; -} - -void memorymonitor_allocationsizes_track_allocation(size_t block_count) { - memorymonitor_allocationsize_obj_t* as = MP_OBJ_TO_PTR(MP_STATE_VM(active_allocationsizes)); - size_t power_of_two = 0; - block_count >>= 1; - while (block_count != 0) { - power_of_two++; - block_count >>= 1; - } - while (as != NULL) { - as->buckets[power_of_two]++; - as = as->next; - } -} - -void memorymonitor_allocationsizes_reset(void) { - MP_STATE_VM(active_allocationsizes) = NULL; -} diff --git a/shared-module/memorymonitor/AllocationSize 2.h b/shared-module/memorymonitor/AllocationSize 2.h deleted file mode 100644 index 3baab2213..000000000 --- a/shared-module/memorymonitor/AllocationSize 2.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries - * - * 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. - */ - -#ifndef MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONSIZE_H -#define MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONSIZE_H - -#include -#include - -#include "py/obj.h" - -typedef struct _memorymonitor_allocationsize_obj_t memorymonitor_allocationsize_obj_t; - -#define ALLOCATION_SIZE_BUCKETS 16 - -typedef struct _memorymonitor_allocationsize_obj_t { - mp_obj_base_t base; - uint16_t buckets[ALLOCATION_SIZE_BUCKETS]; - // Store the location that points to us so we can remove ourselves. - memorymonitor_allocationsize_obj_t** previous; - memorymonitor_allocationsize_obj_t* next; - bool paused; -} memorymonitor_allocationsize_obj_t; - -void memorymonitor_allocationsizes_track_allocation(size_t block_count); -void memorymonitor_allocationsizes_reset(void); - -#endif // MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONSIZE_H diff --git a/shared-module/memorymonitor/__init__ 2.c b/shared-module/memorymonitor/__init__ 2.c deleted file mode 100644 index 6cb424153..000000000 --- a/shared-module/memorymonitor/__init__ 2.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Scott Shawcroft - * - * 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. - */ - -#include "shared-module/memorymonitor/__init__.h" -#include "shared-module/memorymonitor/AllocationAlarm.h" -#include "shared-module/memorymonitor/AllocationSize.h" - -void memorymonitor_track_allocation(size_t block_count) { - memorymonitor_allocationalarms_allocation(block_count); - memorymonitor_allocationsizes_track_allocation(block_count); -} - -void memorymonitor_reset(void) { - memorymonitor_allocationalarms_reset(); - memorymonitor_allocationsizes_reset(); -} diff --git a/shared-module/memorymonitor/__init__ 2.h b/shared-module/memorymonitor/__init__ 2.h deleted file mode 100644 index f47f6434b..000000000 --- a/shared-module/memorymonitor/__init__ 2.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries - * - * 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. - */ - -#ifndef MICROPY_INCLUDED_MEMORYMONITOR___INIT___H -#define MICROPY_INCLUDED_MEMORYMONITOR___INIT___H - -#include - -void memorymonitor_track_allocation(size_t block_count); -void memorymonitor_reset(void); - -#endif // MICROPY_INCLUDED_MEMORYMONITOR___INIT___H -- cgit v1.2.3