Merge remote-tracking branch 'origin/main' into main
This commit is contained in:
commit
63fd57a5bc
@ -1185,6 +1185,7 @@ msgstr ""
|
||||
|
||||
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
|
||||
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
|
||||
#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c
|
||||
#: ports/mimxrt10xx/common-hal/busio/UART.c
|
||||
msgid "Invalid %q pin"
|
||||
msgstr ""
|
||||
@ -1255,6 +1256,11 @@ msgstr ""
|
||||
msgid "Invalid channel count"
|
||||
msgstr ""
|
||||
|
||||
#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c
|
||||
#, c-format
|
||||
msgid "Invalid data_count %d"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/digitalio/DigitalInOut.c
|
||||
msgid "Invalid direction."
|
||||
msgstr ""
|
||||
@ -2114,6 +2120,14 @@ msgstr ""
|
||||
msgid "Timeout is too long: Maximum timeout length is %d seconds"
|
||||
msgstr ""
|
||||
|
||||
#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c
|
||||
msgid "Timeout waiting for DRDY"
|
||||
msgstr ""
|
||||
|
||||
#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c
|
||||
msgid "Timeout waiting for VSYNC"
|
||||
msgstr ""
|
||||
|
||||
#: supervisor/shared/safe_mode.c
|
||||
msgid "To exit, please reset the board without "
|
||||
msgstr ""
|
||||
@ -2791,6 +2805,11 @@ msgstr ""
|
||||
msgid "data must be of equal length"
|
||||
msgstr ""
|
||||
|
||||
#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c
|
||||
#, c-format
|
||||
msgid "data pin #%d in use"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/ndarray.c
|
||||
msgid "data type not understood"
|
||||
msgstr ""
|
||||
|
@ -45,7 +45,15 @@ static volatile bool audio_dma_pending[AUDIO_DMA_CHANNEL_COUNT];
|
||||
|
||||
static bool audio_dma_allocated[AUDIO_DMA_CHANNEL_COUNT];
|
||||
|
||||
uint8_t audio_dma_allocate_channel(void) {
|
||||
uint8_t find_sync_event_channel_raise() {
|
||||
uint8_t event_channel = find_sync_event_channel();
|
||||
if (event_channel >= EVSYS_SYNCH_NUM) {
|
||||
mp_raise_RuntimeError(translate("All sync event channels in use"));
|
||||
}
|
||||
return event_channel;
|
||||
}
|
||||
|
||||
uint8_t dma_allocate_channel(void) {
|
||||
uint8_t channel;
|
||||
for (channel = 0; channel < AUDIO_DMA_CHANNEL_COUNT; channel++) {
|
||||
if (!audio_dma_allocated[channel]) {
|
||||
@ -56,7 +64,7 @@ uint8_t audio_dma_allocate_channel(void) {
|
||||
return channel; // i.e., return failure
|
||||
}
|
||||
|
||||
void audio_dma_free_channel(uint8_t channel) {
|
||||
void dma_free_channel(uint8_t channel) {
|
||||
assert(channel < AUDIO_DMA_CHANNEL_COUNT);
|
||||
assert(audio_dma_allocated[channel]);
|
||||
audio_dma_disable_channel(channel);
|
||||
@ -180,7 +188,7 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma,
|
||||
bool output_signed,
|
||||
uint32_t output_register_address,
|
||||
uint8_t dma_trigger_source) {
|
||||
uint8_t dma_channel = audio_dma_allocate_channel();
|
||||
uint8_t dma_channel = dma_allocate_channel();
|
||||
if (dma_channel >= AUDIO_DMA_CHANNEL_COUNT) {
|
||||
return AUDIO_DMA_DMA_BUSY;
|
||||
}
|
||||
@ -230,11 +238,7 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma,
|
||||
|
||||
// We're likely double buffering so set up the block interrupts.
|
||||
turn_on_event_system();
|
||||
dma->event_channel = find_sync_event_channel();
|
||||
|
||||
if (dma->event_channel >= EVSYS_SYNCH_NUM) {
|
||||
mp_raise_RuntimeError(translate("All sync event channels in use"));
|
||||
}
|
||||
dma->event_channel = find_sync_event_channel_raise();
|
||||
init_event_channel_interrupt(dma->event_channel, CORE_GCLK, EVSYS_ID_GEN_DMAC_CH_0 + dma_channel);
|
||||
|
||||
// We keep the audio_dma_t for internal use and the sample as a root pointer because it
|
||||
@ -302,7 +306,7 @@ void audio_dma_stop(audio_dma_t *dma) {
|
||||
disable_event_channel(dma->event_channel);
|
||||
MP_STATE_PORT(playing_audio)[channel] = NULL;
|
||||
audio_dma_state[channel] = NULL;
|
||||
audio_dma_free_channel(dma->dma_channel);
|
||||
dma_free_channel(dma->dma_channel);
|
||||
}
|
||||
dma->dma_channel = AUDIO_DMA_CHANNEL_COUNT;
|
||||
}
|
||||
|
@ -66,8 +66,8 @@ uint8_t audiosample_channel_count(mp_obj_t sample_obj);
|
||||
void audio_dma_init(audio_dma_t *dma);
|
||||
void audio_dma_reset(void);
|
||||
|
||||
uint8_t audio_dma_allocate_channel(void);
|
||||
void audio_dma_free_channel(uint8_t channel);
|
||||
uint8_t dma_allocate_channel(void);
|
||||
void dma_free_channel(uint8_t channel);
|
||||
|
||||
// This sets everything up but doesn't start the timer.
|
||||
// Sample is the python object for the sample to play.
|
||||
@ -97,4 +97,6 @@ bool audio_dma_get_paused(audio_dma_t *dma);
|
||||
|
||||
void audio_dma_background(void);
|
||||
|
||||
uint8_t find_sync_event_channel_raise(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_AUDIO_DMA_H
|
||||
|
@ -11,3 +11,4 @@ EXTERNAL_FLASH_DEVICES = "W25Q64JVxQ, GD25Q64C"
|
||||
LONGINT_IMPL = MPZ
|
||||
|
||||
CIRCUITPY_SDIOIO = 1
|
||||
CIRCUITPY_IMAGECAPTURE = 1
|
||||
|
@ -367,11 +367,8 @@ static uint16_t filter_sample(uint32_t pdm_samples[4]) {
|
||||
// output_buffer_length is the number of slots, not the number of bytes.
|
||||
uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* self,
|
||||
uint16_t* output_buffer, uint32_t output_buffer_length) {
|
||||
uint8_t dma_channel = audio_dma_allocate_channel();
|
||||
uint8_t event_channel = find_sync_event_channel();
|
||||
if (event_channel >= EVSYS_SYNCH_NUM) {
|
||||
mp_raise_RuntimeError(translate("All sync event channels in use"));
|
||||
}
|
||||
uint8_t dma_channel = dma_allocate_channel();
|
||||
uint8_t event_channel = find_sync_event_channel_raise();
|
||||
|
||||
// We allocate two buffers on the stack to use for double buffering.
|
||||
const uint8_t samples_per_buffer = SAMPLES_PER_BUFFER;
|
||||
@ -476,7 +473,7 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se
|
||||
}
|
||||
|
||||
disable_event_channel(event_channel);
|
||||
audio_dma_free_channel(dma_channel);
|
||||
dma_free_channel(dma_channel);
|
||||
// Turn off serializer, but leave clock on, to avoid mic startup delay.
|
||||
i2s_set_serializer_enable(self->serializer, false);
|
||||
|
||||
|
198
ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c
Normal file
198
ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 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/runtime.h"
|
||||
|
||||
#include "lib/utils/context_manager_helpers.h"
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
|
||||
#include "shared-bindings/imagecapture/ParallelImageCapture.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
#include "common-hal/imagecapture/ParallelImageCapture.h"
|
||||
|
||||
#include "hal/include/hal_gpio.h"
|
||||
#include "atmel_start_pins.h"
|
||||
|
||||
#include "audio_dma.h"
|
||||
#include "samd/clocks.h"
|
||||
#include "samd/events.h"
|
||||
|
||||
#define GPIO_PIN_FUNCTION_PCC (GPIO_PIN_FUNCTION_K)
|
||||
|
||||
#define PIN_PCC_D0 (PIN_PA16)
|
||||
#define PIN_PCC_DEN1 (PIN_PA12)
|
||||
#define PIN_PCC_DEN2 (PIN_PA13)
|
||||
#define PIN_PCC_CLK (PIN_PA14)
|
||||
|
||||
void common_hal_imagecapture_parallelimagecapture_construct(imagecapture_parallelimagecapture_obj_t *self,
|
||||
const mcu_pin_obj_t *data0,
|
||||
const mcu_pin_obj_t *data_clock,
|
||||
const mcu_pin_obj_t *vertical_sync,
|
||||
const mcu_pin_obj_t *horizontal_reference,
|
||||
int data_count)
|
||||
{
|
||||
if (data0->number != PIN_PCC_D0) {
|
||||
mp_raise_ValueError_varg(translate("Invalid %q pin"), MP_QSTR_data0);
|
||||
}
|
||||
// The peripheral supports 8, 10, 12, or 14 data bits, but the code only supports 8 at present
|
||||
if (data_count != 8)
|
||||
{
|
||||
mp_raise_ValueError_varg(translate("Invalid data_count %d"), data_count);
|
||||
}
|
||||
if (vertical_sync && vertical_sync->number != PIN_PCC_DEN1) {
|
||||
mp_raise_ValueError_varg(translate("Invalid %q pin"), MP_QSTR_vsync);
|
||||
}
|
||||
if (horizontal_reference && horizontal_reference->number != PIN_PCC_DEN2) {
|
||||
mp_raise_ValueError_varg(translate("Invalid %q pin"), MP_QSTR_href);
|
||||
}
|
||||
if (data_clock->number != PIN_PCC_CLK) {
|
||||
mp_raise_ValueError_varg(translate("Invalid %q pin"), MP_QSTR_data_clock);
|
||||
}
|
||||
// technically, 0 was validated as free already but check again
|
||||
for (int i=0; i<data_count; i++) {
|
||||
if (!pin_number_is_free(data0->number + i)) {
|
||||
mp_raise_ValueError_varg(translate("data pin #%d in use"), i);
|
||||
}
|
||||
}
|
||||
|
||||
PCC->MR.bit.PCEN = 0; // Make sure PCC is disabled before setting MR reg
|
||||
|
||||
PCC->IDR.reg = 0b1111; // Disable all PCC interrupts
|
||||
MCLK->APBDMASK.bit.PCC_ = 1; // Enable PCC clock
|
||||
|
||||
// Accumulate 4 bytes into RHR register (two 16-bit pixels)
|
||||
PCC->MR.reg = PCC_MR_CID(0x1) | // Clear on falling DEN1 (VSYNC)
|
||||
PCC_MR_ISIZE(0x0) | // Input data bus is 8 bits
|
||||
PCC_MR_DSIZE(0x2); // "4 data" at a time (accumulate in RHR)
|
||||
|
||||
PCC->MR.bit.PCEN = 1; // Enable PCC
|
||||
|
||||
|
||||
// Now we know we can allocate all pins
|
||||
self->data_count = data_count;
|
||||
self->vertical_sync = vertical_sync ? vertical_sync->number : NO_PIN;
|
||||
self->horizontal_reference = horizontal_reference ? horizontal_reference->number : NO_PIN;
|
||||
gpio_set_pin_direction(PIN_PCC_CLK, GPIO_DIRECTION_IN);
|
||||
gpio_set_pin_pull_mode(PIN_PCC_CLK, GPIO_PULL_OFF);
|
||||
gpio_set_pin_function(PIN_PCC_CLK, GPIO_PIN_FUNCTION_PCC);
|
||||
//claim_pin_number(PIN_PCC_CLK);
|
||||
if (vertical_sync) {
|
||||
gpio_set_pin_direction(PIN_PCC_DEN1, GPIO_DIRECTION_IN);
|
||||
gpio_set_pin_pull_mode(PIN_PCC_DEN1, GPIO_PULL_OFF);
|
||||
gpio_set_pin_function(PIN_PCC_DEN1, GPIO_PIN_FUNCTION_PCC); // VSYNC
|
||||
//claim_pin_number(PIN_PCC_DEN1);
|
||||
}
|
||||
if (horizontal_reference) {
|
||||
gpio_set_pin_direction(PIN_PCC_DEN2, GPIO_DIRECTION_IN);
|
||||
gpio_set_pin_pull_mode(PIN_PCC_DEN2, GPIO_PULL_OFF);
|
||||
gpio_set_pin_function(PIN_PCC_DEN2, GPIO_PIN_FUNCTION_PCC); // HSYNC
|
||||
//claim_pin_number(PIN_PCC_DEN2);
|
||||
}
|
||||
for (int i=0; i<data_count; i++) {
|
||||
gpio_set_pin_direction(PIN_PCC_D0+i, GPIO_DIRECTION_IN);
|
||||
gpio_set_pin_pull_mode(PIN_PCC_D0+i, GPIO_PULL_OFF);
|
||||
gpio_set_pin_function(PIN_PCC_D0+i, GPIO_PIN_FUNCTION_PCC);
|
||||
//claim_pin_number(PIN_PCC_D0+i);
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_imagecapture_parallelimagecapture_deinit(imagecapture_parallelimagecapture_obj_t *self)
|
||||
{
|
||||
if (common_hal_imagecapture_parallelimagecapture_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
reset_pin_number(self->vertical_sync);
|
||||
reset_pin_number(self->horizontal_reference);
|
||||
reset_pin_number(PIN_PCC_CLK);
|
||||
for (int i=0; i<self->data_count; i++) {
|
||||
reset_pin_number(PIN_PCC_D0 + i);
|
||||
}
|
||||
self->data_count = 0;
|
||||
}
|
||||
|
||||
bool common_hal_imagecapture_parallelimagecapture_deinited(imagecapture_parallelimagecapture_obj_t *self)
|
||||
{
|
||||
return self->data_count == 0;
|
||||
}
|
||||
|
||||
static void setup_dma(DmacDescriptor* descriptor, size_t count, uint32_t *buffer) {
|
||||
descriptor->BTCTRL.reg = DMAC_BTCTRL_VALID |
|
||||
DMAC_BTCTRL_BLOCKACT_NOACT |
|
||||
DMAC_BTCTRL_EVOSEL_BLOCK |
|
||||
DMAC_BTCTRL_DSTINC |
|
||||
DMAC_BTCTRL_BEATSIZE_WORD;
|
||||
descriptor->BTCNT.reg = count;
|
||||
descriptor->DSTADDR.reg = (uint32_t)buffer + 4*count;
|
||||
descriptor->SRCADDR.reg = (uint32_t)&PCC->RHR.reg;
|
||||
descriptor->DESCADDR.reg = 0;
|
||||
}
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void common_hal_imagecapture_parallelimagecapture_capture(imagecapture_parallelimagecapture_obj_t *self, void *buffer, size_t bufsize)
|
||||
{
|
||||
|
||||
uint8_t dma_channel = dma_allocate_channel();
|
||||
|
||||
uint32_t *dest = buffer;
|
||||
size_t count = bufsize / 4; // PCC receives 4 bytes (2 pixels) at a time
|
||||
|
||||
turn_on_event_system();
|
||||
|
||||
setup_dma(dma_descriptor(dma_channel), count, dest);
|
||||
dma_configure(dma_channel, PCC_DMAC_ID_RX, true);
|
||||
|
||||
if (self->vertical_sync) {
|
||||
const volatile uint32_t *vsync_reg = &PORT->Group[(self->vertical_sync / 32)].IN.reg;
|
||||
uint32_t vsync_bit = 1 << (self->vertical_sync % 32);
|
||||
|
||||
while (*vsync_reg & vsync_bit)
|
||||
{
|
||||
// Wait for VSYNC low (frame end)
|
||||
|
||||
RUN_BACKGROUND_TASKS;
|
||||
// Allow user to break out of a timeout with a KeyboardInterrupt.
|
||||
if (mp_hal_is_interrupted()) {
|
||||
dma_free_channel(dma_channel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dma_enable_channel(dma_channel);
|
||||
|
||||
while (DMAC->Channel[dma_channel].CHCTRLA.bit.ENABLE) {
|
||||
RUN_BACKGROUND_TASKS;
|
||||
if (mp_hal_is_interrupted()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dma_disable_channel(dma_channel);
|
||||
dma_free_channel(dma_channel);
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 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 "shared-bindings/imagecapture/ParallelImageCapture.h"
|
||||
|
||||
struct imagecapture_parallelimagecapture_obj {
|
||||
mp_obj_base_t base;
|
||||
uint8_t data_pin, data_clock, vertical_sync, horizontal_reference, data_count;
|
||||
};
|
0
ports/atmel-samd/common-hal/imagecapture/__init__.c
Normal file
0
ports/atmel-samd/common-hal/imagecapture/__init__.c
Normal file
0
ports/atmel-samd/common-hal/imagecapture/__init__.h
Normal file
0
ports/atmel-samd/common-hal/imagecapture/__init__.h
Normal file
@ -156,7 +156,8 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t* self,
|
||||
return PWMOUT_INVALID_PIN;
|
||||
}
|
||||
|
||||
if (frequency == 0 || frequency > 6000000) {
|
||||
uint32_t system_clock = common_hal_mcu_processor_get_frequency();
|
||||
if (frequency == 0 || frequency > system_clock/2) {
|
||||
return PWMOUT_INVALID_FREQUENCY;
|
||||
}
|
||||
|
||||
@ -237,7 +238,6 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t* self,
|
||||
resolution = tcc_sizes[timer->index];
|
||||
}
|
||||
// First determine the divisor that gets us the highest resolution.
|
||||
uint32_t system_clock = common_hal_mcu_processor_get_frequency();
|
||||
uint32_t top;
|
||||
uint8_t divisor;
|
||||
for (divisor = 0; divisor < 8; divisor++) {
|
||||
@ -413,7 +413,8 @@ uint16_t common_hal_pwmio_pwmout_get_duty_cycle(pwmio_pwmout_obj_t* self) {
|
||||
|
||||
void common_hal_pwmio_pwmout_set_frequency(pwmio_pwmout_obj_t* self,
|
||||
uint32_t frequency) {
|
||||
if (frequency == 0 || frequency > 6000000) {
|
||||
uint32_t system_clock = common_hal_mcu_processor_get_frequency();
|
||||
if (frequency == 0 || frequency > system_clock/2) {
|
||||
mp_raise_ValueError(translate("Invalid PWM frequency"));
|
||||
}
|
||||
const pin_timer_t* t = self->timer;
|
||||
@ -424,7 +425,6 @@ void common_hal_pwmio_pwmout_set_frequency(pwmio_pwmout_obj_t* self,
|
||||
// TCC resolution varies so look it up.
|
||||
resolution = tcc_sizes[t->index];
|
||||
}
|
||||
uint32_t system_clock = common_hal_mcu_processor_get_frequency();
|
||||
uint32_t new_top;
|
||||
uint8_t new_divisor;
|
||||
for (new_divisor = 0; new_divisor < 8; new_divisor++) {
|
||||
|
@ -241,6 +241,7 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
|
||||
first_in_pin, args[ARG_in_pin_count].u_int, args[ARG_pull_in_pin_up].u_int, args[ARG_pull_in_pin_down].u_int,
|
||||
first_set_pin, args[ARG_set_pin_count].u_int, args[ARG_initial_set_pin_state].u_int, args[ARG_initial_set_pin_direction].u_int,
|
||||
first_sideset_pin, args[ARG_sideset_pin_count].u_int, args[ARG_initial_sideset_pin_state].u_int, args[ARG_initial_sideset_pin_direction].u_int,
|
||||
0,
|
||||
args[ARG_exclusive_pin_use].u_bool,
|
||||
args[ARG_auto_pull].u_bool, pull_threshold, args[ARG_out_shift_right].u_bool,
|
||||
args[ARG_wait_for_txstall].u_bool,
|
||||
|
@ -44,6 +44,7 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
|
||||
const mcu_pin_obj_t *first_in_pin, uint8_t in_pin_count, uint32_t pull_pin_up, uint32_t pull_pin_down,
|
||||
const mcu_pin_obj_t *first_set_pin, uint8_t set_pin_count, uint32_t initial_set_pin_state, uint32_t initial_set_pin_direction,
|
||||
const mcu_pin_obj_t *first_sideset_pin, uint8_t sideset_pin_count, uint32_t initial_sideset_pin_state, uint32_t initial_sideset_pin_direction,
|
||||
uint32_t wait_gpio_mask,
|
||||
bool exclusive_pin_use,
|
||||
bool auto_pull, uint8_t pull_threshold, bool out_shift_right,
|
||||
bool wait_for_txstall,
|
||||
|
@ -126,6 +126,7 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self,
|
||||
0, 0, // in pulls
|
||||
NULL, 0, 0, 0x1f, // set pins
|
||||
bit_clock, 2, 0, 0x1f, // sideset pins
|
||||
0, // wait gpio pins
|
||||
true, // exclusive pin use
|
||||
false, 32, false, // shift out left to start with MSB
|
||||
false, // Wait for txstall
|
||||
|
@ -71,6 +71,7 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t *self,
|
||||
0, 0, // in pulls
|
||||
NULL, 0, 0, 0x1f, // set pins
|
||||
clock_pin, 1, 0, 0x1f, // sideset pins
|
||||
0, // wait gpio pins
|
||||
true, // exclusive pin use
|
||||
false, 32, false, // out settings
|
||||
false, // Wait for txstall
|
||||
|
@ -99,6 +99,7 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t *sel
|
||||
NULL, 0, 0, 0, // first in pin, # in pins
|
||||
NULL, 0, 0, 0, // first set pin
|
||||
write, 1, 0, 1, // first sideset pin
|
||||
0, // wait gpio pins
|
||||
true, // exclusive pin usage
|
||||
true, 8, true, // TX, auto pull every 8 bits. shift left to output msb first
|
||||
false, // wait for TX stall
|
||||
|
135
ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c
Normal file
135
ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 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/runtime.h"
|
||||
|
||||
#include "lib/utils/context_manager_helpers.h"
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
|
||||
#include "bindings/rp2pio/StateMachine.h"
|
||||
#include "bindings/rp2pio/__init__.h"
|
||||
#include "common-hal/imagecapture/ParallelImageCapture.h"
|
||||
#include "shared-bindings/imagecapture/ParallelImageCapture.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
#include "shared-bindings/microcontroller/Processor.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
|
||||
#include "src/rp2_common/hardware_pio/include/hardware/pio.h"
|
||||
#include "src/rp2_common/hardware_pio/include/hardware/pio_instructions.h"
|
||||
|
||||
// Define this to (1), and you can scope the instruction-pointer of the state machine on D26..28 (note the weird encoding though!)
|
||||
#define DEBUG_STATE_MACHINE (0)
|
||||
#if DEBUG_STATE_MACHINE
|
||||
#define SIDE(x) ((x)<<8)
|
||||
#else
|
||||
#define SIDE(x) (0)
|
||||
#endif
|
||||
|
||||
#define _0 SIDE(0b11100)
|
||||
#define _1 SIDE(0b00000)
|
||||
#define _2 SIDE(0b10000)
|
||||
#define _3 SIDE(0b10100)
|
||||
#define _4 SIDE(0b11000)
|
||||
#define _5 SIDE(0b10100)
|
||||
|
||||
#define IMAGECAPTURE_CODE(width, pclk, vsync, href) \
|
||||
{ \
|
||||
/* 0 */ pio_encode_wait_gpio(0, vsync) | _0, \
|
||||
/* 1 */ pio_encode_wait_gpio(1, vsync) | _1, \
|
||||
/* .wrap_target */ \
|
||||
/* 2 */ pio_encode_wait_gpio(1, href) | _2, \
|
||||
/* 3 */ pio_encode_wait_gpio(1, pclk) | _3, \
|
||||
/* 4 */ pio_encode_in(pio_pins, width) | _4, \
|
||||
/* 5 */ pio_encode_wait_gpio(0, pclk) | _5, \
|
||||
/* .wrap */ \
|
||||
}
|
||||
|
||||
void common_hal_imagecapture_parallelimagecapture_construct(imagecapture_parallelimagecapture_obj_t *self,
|
||||
const mcu_pin_obj_t *data0,
|
||||
const mcu_pin_obj_t *data_clock,
|
||||
const mcu_pin_obj_t *vertical_sync,
|
||||
const mcu_pin_obj_t *horizontal_reference,
|
||||
int data_count)
|
||||
{
|
||||
|
||||
uint16_t imagecapture_code[] = IMAGECAPTURE_CODE(data_count, data_clock->number, vertical_sync->number, horizontal_reference->number);
|
||||
|
||||
common_hal_rp2pio_statemachine_construct(&self->state_machine,
|
||||
imagecapture_code, MP_ARRAY_SIZE(imagecapture_code),
|
||||
common_hal_mcu_processor_get_frequency(), // full speed (4 instructions per loop -> max pclk 30MHz @ 120MHz)
|
||||
0, 0, // init
|
||||
NULL, 0, 0, 0, // out pins
|
||||
data0, data_count, // in pins
|
||||
0, 0, // in pulls
|
||||
NULL, 0, 0, 0, // set pins
|
||||
#if DEBUG_STATE_MACHINE
|
||||
&pin_GPIO26, 3, 7, 7, // sideset pins
|
||||
#else
|
||||
NULL, 0, 0, 0, // sideset pins
|
||||
#endif
|
||||
(1<<vertical_sync->number) | (1<<horizontal_reference->number) | (1<<data_clock->number), // wait gpio pins
|
||||
true, // exclusive pin use
|
||||
false, 32, false, // out settings
|
||||
false, // wait for txstall
|
||||
true, 32, true); // in settings
|
||||
|
||||
PIO pio = self->state_machine.pio;
|
||||
uint8_t pio_index = pio_get_index(pio);
|
||||
uint sm = self->state_machine.state_machine;
|
||||
rp2pio_statemachine_set_wrap(&self->state_machine, 2, 5);
|
||||
}
|
||||
|
||||
void common_hal_imagecapture_parallelimagecapture_deinit(imagecapture_parallelimagecapture_obj_t *self)
|
||||
{
|
||||
if (common_hal_imagecapture_parallelimagecapture_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
return common_hal_rp2pio_statemachine_deinit(&self->state_machine);
|
||||
}
|
||||
|
||||
bool common_hal_imagecapture_parallelimagecapture_deinited(imagecapture_parallelimagecapture_obj_t *self)
|
||||
{
|
||||
return common_hal_rp2pio_statemachine_deinited(&self->state_machine);
|
||||
}
|
||||
|
||||
void common_hal_imagecapture_parallelimagecapture_capture(imagecapture_parallelimagecapture_obj_t *self, void *buffer, size_t bufsize)
|
||||
{
|
||||
PIO pio = self->state_machine.pio;
|
||||
uint sm = self->state_machine.state_machine;
|
||||
uint8_t offset = rp2pio_statemachine_program_offset(&self->state_machine);
|
||||
|
||||
pio_sm_set_enabled(pio, sm, false);
|
||||
pio_sm_clear_fifos(pio, sm);
|
||||
|
||||
pio_sm_restart(pio, sm);
|
||||
pio_sm_exec(pio, sm, pio_encode_jmp(offset));
|
||||
pio_sm_set_enabled(pio, sm, true);
|
||||
|
||||
common_hal_rp2pio_statemachine_readinto(&self->state_machine, buffer, bufsize, 4);
|
||||
|
||||
pio_sm_set_enabled(pio, sm, false);
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 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 "common-hal/rp2pio/StateMachine.h"
|
||||
#include "shared-bindings/imagecapture/ParallelImageCapture.h"
|
||||
|
||||
struct imagecapture_parallelimagecapture_obj {
|
||||
mp_obj_base_t base;
|
||||
rp2pio_statemachine_obj_t state_machine;
|
||||
};
|
@ -84,6 +84,7 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode
|
||||
3, 0, // in pulls
|
||||
NULL, 0, 0, 0x1f, // set pins
|
||||
NULL, 0, 0, 0x1f, // sideset pins
|
||||
0, // wait gpio pins
|
||||
true, // exclusive pin use
|
||||
false, 32, false, // out settings
|
||||
false, // Wait for txstall
|
||||
|
@ -329,13 +329,14 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
|
||||
uint32_t pull_pin_up, uint32_t pull_pin_down,
|
||||
const mcu_pin_obj_t *first_set_pin, uint8_t set_pin_count, uint32_t initial_set_pin_state, uint32_t initial_set_pin_direction,
|
||||
const mcu_pin_obj_t *first_sideset_pin, uint8_t sideset_pin_count, uint32_t initial_sideset_pin_state, uint32_t initial_sideset_pin_direction,
|
||||
uint32_t wait_gpio_mask,
|
||||
bool exclusive_pin_use,
|
||||
bool auto_pull, uint8_t pull_threshold, bool out_shift_right,
|
||||
bool wait_for_txstall,
|
||||
bool auto_push, uint8_t push_threshold, bool in_shift_right) {
|
||||
|
||||
// First, check that all pins are free OR already in use by any PIO if exclusive_pin_use is false.
|
||||
uint32_t pins_we_use = 0;
|
||||
uint32_t pins_we_use = wait_gpio_mask;
|
||||
pins_we_use |= _check_pins_free(first_out_pin, out_pin_count, exclusive_pin_use);
|
||||
pins_we_use |= _check_pins_free(first_in_pin, in_pin_count, exclusive_pin_use);
|
||||
pins_we_use |= _check_pins_free(first_set_pin, set_pin_count, exclusive_pin_use);
|
||||
@ -801,3 +802,16 @@ STATIC void rp2pio_statemachine_interrupt_handler(void) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self) {
|
||||
uint8_t pio_index = pio_get_index(self->pio);
|
||||
uint8_t sm = self->state_machine;
|
||||
return _current_program_offset[pio_index][sm];
|
||||
}
|
||||
|
||||
void rp2pio_statemachine_set_wrap(rp2pio_statemachine_obj_t *self, uint wrap_target, uint wrap) {
|
||||
uint8_t sm = self->state_machine;
|
||||
uint8_t offset = rp2pio_statemachine_program_offset(self);
|
||||
|
||||
pio_sm_set_wrap(self->pio, sm, offset+wrap_target, offset+wrap);
|
||||
}
|
||||
|
@ -74,6 +74,9 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
|
||||
bool auto_push, uint8_t push_threshold, bool in_shift_right,
|
||||
bool claim_pins);
|
||||
|
||||
uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self);
|
||||
void rp2pio_statemachine_set_wrap(rp2pio_statemachine_obj_t *self, uint wrap_target, uint wrap);
|
||||
|
||||
void rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self, bool leave_pins);
|
||||
|
||||
extern const mp_obj_type_t rp2pio_statemachine_type;
|
||||
|
@ -23,6 +23,7 @@ CIRCUITPY_FRAMEBUFFERIO ?= 1
|
||||
CIRCUITPY_FULL_BUILD ?= 1
|
||||
CIRCUITPY_AUDIOMP3 ?= 1
|
||||
CIRCUITPY_BITOPS ?= 1
|
||||
CIRCUITPY_IMAGECAPTURE ?= 1
|
||||
CIRCUITPY_PWMIO ?= 1
|
||||
CIRCUITPY_RGBMATRIX ?= 1
|
||||
CIRCUITPY_ROTARYIO ?= 1
|
||||
|
@ -319,6 +319,9 @@ endif
|
||||
ifeq ($(CIRCUITPY_PEW),1)
|
||||
SRC_PATTERNS += _pew/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_IMAGECAPTURE),1)
|
||||
SRC_PATTERNS += imagecapture/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_MSGPACK),1)
|
||||
SRC_PATTERNS += msgpack/%
|
||||
endif
|
||||
@ -367,8 +370,11 @@ SRC_COMMON_HAL_ALL = \
|
||||
digitalio/DigitalInOut.c \
|
||||
digitalio/__init__.c \
|
||||
displayio/ParallelBus.c \
|
||||
dualbank/__init__.c \
|
||||
frequencyio/FrequencyIn.c \
|
||||
frequencyio/__init__.c \
|
||||
imagecapture/ParallelImageCapture.c \
|
||||
imagecapture/__init__.c \
|
||||
gnss/__init__.c \
|
||||
gnss/GNSS.c \
|
||||
gnss/PositionFix.c \
|
||||
@ -382,7 +388,6 @@ SRC_COMMON_HAL_ALL = \
|
||||
nvm/ByteArray.c \
|
||||
nvm/__init__.c \
|
||||
os/__init__.c \
|
||||
dualbank/__init__.c \
|
||||
ps2io/Ps2.c \
|
||||
ps2io/__init__.c \
|
||||
pulseio/PulseIn.c \
|
||||
|
@ -412,6 +412,13 @@ extern const struct _mp_obj_module_t terminalio_module;
|
||||
#define TERMINALIO_MODULE
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_DUALBANK
|
||||
extern const struct _mp_obj_module_t dualbank_module;
|
||||
#define DUALBANK_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_dualbank), (mp_obj_t)&dualbank_module },
|
||||
#else
|
||||
#define DUALBANK_MODULE
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_ERRNO
|
||||
#define MICROPY_PY_UERRNO (1)
|
||||
// Uses about 80 bytes.
|
||||
@ -486,6 +493,13 @@ extern const struct _mp_obj_module_t i2cperipheral_module;
|
||||
#define I2CPERIPHERAL_MODULE
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_IMAGECAPTURE
|
||||
extern const struct _mp_obj_module_t imagecapture_module;
|
||||
#define IMAGECAPTURE_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_imagecapture), (mp_obj_t)&imagecapture_module },
|
||||
#else
|
||||
#define IMAGECAPTURE_MODULE
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_IPADDRESS
|
||||
extern const struct _mp_obj_module_t ipaddress_module;
|
||||
#define IPADDRESS_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_ipaddress), (mp_obj_t)&ipaddress_module },
|
||||
@ -574,13 +588,6 @@ extern const struct _mp_obj_module_t os_module;
|
||||
#define OS_MODULE_ALT_NAME
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_DUALBANK
|
||||
extern const struct _mp_obj_module_t dualbank_module;
|
||||
#define DUALBANK_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_dualbank), (mp_obj_t)&dualbank_module },
|
||||
#else
|
||||
#define DUALBANK_MODULE
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_PEW
|
||||
extern const struct _mp_obj_module_t pew_module;
|
||||
#define PEW_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__pew),(mp_obj_t)&pew_module },
|
||||
@ -860,6 +867,7 @@ extern const struct _mp_obj_module_t msgpack_module;
|
||||
COUNTIO_MODULE \
|
||||
DIGITALIO_MODULE \
|
||||
DISPLAYIO_MODULE \
|
||||
DUALBANK_MODULE \
|
||||
FONTIO_MODULE \
|
||||
TERMINALIO_MODULE \
|
||||
VECTORIO_MODULE \
|
||||
@ -872,6 +880,7 @@ extern const struct _mp_obj_module_t msgpack_module;
|
||||
GNSS_MODULE \
|
||||
I2CPERIPHERAL_MODULE \
|
||||
IPADDRESS_MODULE \
|
||||
IMAGECAPTURE_MODULE \
|
||||
JSON_MODULE \
|
||||
MATH_MODULE \
|
||||
_EVE_MODULE \
|
||||
@ -882,7 +891,6 @@ extern const struct _mp_obj_module_t msgpack_module;
|
||||
NETWORK_MODULE \
|
||||
SOCKET_MODULE \
|
||||
WIZNET_MODULE \
|
||||
DUALBANK_MODULE \
|
||||
PEW_MODULE \
|
||||
PIXELBUF_MODULE \
|
||||
PS2IO_MODULE \
|
||||
|
@ -218,6 +218,9 @@ CFLAGS += -DCIRCUITPY_NVM=$(CIRCUITPY_NVM)
|
||||
CIRCUITPY_OS ?= 1
|
||||
CFLAGS += -DCIRCUITPY_OS=$(CIRCUITPY_OS)
|
||||
|
||||
CIRCUITPY_IMAGECAPTURE ?= 0
|
||||
CFLAGS += -DCIRCUITPY_IMAGECAPTURE=$(CIRCUITPY_IMAGECAPTURE)
|
||||
|
||||
CIRCUITPY_PEW ?= 0
|
||||
CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW)
|
||||
|
||||
|
@ -55,6 +55,13 @@ typedef unsigned int uint;
|
||||
// Static assertion macro
|
||||
#define MP_STATIC_ASSERT(cond) ((void)sizeof(char[1 - 2 * !(cond)]))
|
||||
|
||||
// Explicit fallthrough delcarations for case statements
|
||||
#ifdef __GNUC__
|
||||
#define FALLTHROUGH __attribute__((fallthrough))
|
||||
#else
|
||||
#define FALLTHROUGH ((void)0) /* FALLTHROUGH */
|
||||
#endif
|
||||
|
||||
/** memory allocation ******************************************/
|
||||
|
||||
// TODO make a lazy m_renew that can increase by a smaller amount than requested (but by at least 1 more element)
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "lib/utils/context_manager_helpers.h"
|
||||
#include "py/binary.h"
|
||||
#include "py/enum.h"
|
||||
#include "py/objproperty.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
@ -39,20 +40,20 @@
|
||||
//| class ColorConverter:
|
||||
//| """Converts one color format to another."""
|
||||
//|
|
||||
//| def __init__(self, *, dither: bool = False) -> None:
|
||||
//| """Create a ColorConverter object to convert color formats. Only supports RGB888 to RGB565
|
||||
//| currently.
|
||||
//| def __init__(self, *, colorspace: Colorspace=Colorspace.RGB888, dither: bool = False) -> None:
|
||||
//| """Create a ColorConverter object to convert color formats.
|
||||
//|
|
||||
//| :param Colorspace colorspace: The source colorspace, one of the Colorspace constants
|
||||
//| :param bool dither: Adds random noise to dither the output image"""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
// TODO(tannewt): Add support for other color formats.
|
||||
//|
|
||||
STATIC mp_obj_t displayio_colorconverter_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_dither};
|
||||
enum { ARG_dither, ARG_input_colorspace };
|
||||
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_dither, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }
|
||||
{ MP_QSTR_dither, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
{ MP_QSTR_input_colorspace, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = (void *)&displayio_colorspace_RGB888_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);
|
||||
@ -60,13 +61,13 @@ STATIC mp_obj_t displayio_colorconverter_make_new(const mp_obj_type_t *type, siz
|
||||
displayio_colorconverter_t *self = m_new_obj(displayio_colorconverter_t);
|
||||
self->base.type = &displayio_colorconverter_type;
|
||||
|
||||
common_hal_displayio_colorconverter_construct(self, args[ARG_dither].u_bool);
|
||||
common_hal_displayio_colorconverter_construct(self, args[ARG_dither].u_bool, (displayio_colorspace_t)cp_enum_value(&displayio_colorspace_type, args[ARG_input_colorspace].u_obj));
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
//| def convert(self, color: int) -> int:
|
||||
//| """Converts the given RGB888 color to RGB565"""
|
||||
//| """Converts the given color to RGB565 according to the Colorspace"""
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t displayio_colorconverter_obj_convert(mp_obj_t self_in, mp_obj_t color_obj) {
|
||||
|
@ -27,13 +27,14 @@
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_COLORCONVERTER_H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_COLORCONVERTER_H
|
||||
|
||||
#include "shared-bindings/displayio/__init__.h"
|
||||
#include "shared-module/displayio/ColorConverter.h"
|
||||
|
||||
#include "shared-module/displayio/Palette.h"
|
||||
|
||||
extern const mp_obj_type_t displayio_colorconverter_type;
|
||||
|
||||
void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t *self, bool dither);
|
||||
void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t *self, bool dither, displayio_colorspace_t input_colorspace);
|
||||
void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *colorconverter, const _displayio_colorspace_t *colorspace, uint32_t input_color, uint32_t *output_color);
|
||||
|
||||
void common_hal_displayio_colorconverter_set_dither(displayio_colorconverter_t *self, bool dither);
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "py/enum.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
@ -49,7 +50,6 @@
|
||||
//| including synchronizing with refresh rates and partial updating."""
|
||||
//|
|
||||
|
||||
|
||||
//| def release_displays() -> None:
|
||||
//| """Releases any actively used displays so their busses and pins can be used again. This will also
|
||||
//| release the builtin display on boards that have one. You will need to reinitialize it yourself
|
||||
@ -65,10 +65,48 @@ STATIC mp_obj_t displayio_release_displays(void) {
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(displayio_release_displays_obj, displayio_release_displays);
|
||||
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB888, DISPLAYIO_COLORSPACE_RGB888);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB565, DISPLAYIO_COLORSPACE_RGB565);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB565_SWAPPED, DISPLAYIO_COLORSPACE_RGB565_SWAPPED);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB555, DISPLAYIO_COLORSPACE_RGB555);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB555_SWAPPED, DISPLAYIO_COLORSPACE_RGB555_SWAPPED);
|
||||
|
||||
//| class Colorspace:
|
||||
//| """The colorspace for a `ColorConverter` to operate in"""
|
||||
//|
|
||||
//| RGB888: Colorspace
|
||||
//| """The standard 24-bit colorspace. Bits 0-7 are blue, 8-15 are green, and 16-24 are red. (0xRRGGBB)"""
|
||||
//|
|
||||
//| RGB565: Colorspace
|
||||
//| """The standard 16-bit colorspace. Bits 0-4 are blue, bits 5-10 are green, and 11-15 are red (0bRRRRRGGGGGGBBBBB)"""
|
||||
//|
|
||||
//| RGB565_SWAPPED: Colorspace
|
||||
//| """The swapped 16-bit colorspace. First, the high and low 8 bits of the number are swapped, then they are interpreted as for RGB565"""
|
||||
//|
|
||||
//| RGB555: Colorspace
|
||||
//| """The standard 15-bit colorspace. Bits 0-4 are blue, bits 5-9 are green, and 11-14 are red. The top bit is ignored. (0bxRRRRRGGGGGBBBBB)"""
|
||||
//|
|
||||
//| RGB555_SWAPPED: Colorspace
|
||||
//| """The swapped 15-bit colorspace. First, the high and low 8 bits of the number are swapped, then they are interpreted as for RGB555"""
|
||||
//|
|
||||
MAKE_ENUM_MAP(displayio_colorspace) {
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB888),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB565),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB565_SWAPPED),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB555),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB555_SWAPPED),
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(displayio_colorspace_locals_dict, displayio_colorspace_locals_table);
|
||||
|
||||
MAKE_PRINTER(displayio, displayio_colorspace);
|
||||
MAKE_ENUM_TYPE(displayio, ColorSpace, displayio_colorspace);
|
||||
|
||||
|
||||
STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_displayio) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Bitmap), MP_ROM_PTR(&displayio_bitmap_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ColorConverter), MP_ROM_PTR(&displayio_colorconverter_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Colorspace), MP_ROM_PTR(&displayio_colorspace_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&displayio_display_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_EPaperDisplay), MP_ROM_PTR(&displayio_epaperdisplay_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Group), MP_ROM_PTR(&displayio_group_type) },
|
||||
|
@ -27,6 +27,7 @@
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H
|
||||
|
||||
#include "py/enum.h"
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef enum {
|
||||
@ -39,6 +40,14 @@ typedef enum {
|
||||
CHIP_SELECT_TOGGLE_EVERY_BYTE
|
||||
} display_chip_select_behavior_t;
|
||||
|
||||
typedef enum {
|
||||
DISPLAYIO_COLORSPACE_RGB888,
|
||||
DISPLAYIO_COLORSPACE_RGB565,
|
||||
DISPLAYIO_COLORSPACE_RGB555,
|
||||
DISPLAYIO_COLORSPACE_RGB565_SWAPPED,
|
||||
DISPLAYIO_COLORSPACE_RGB555_SWAPPED,
|
||||
} displayio_colorspace_t;
|
||||
|
||||
typedef bool (*display_bus_bus_reset)(mp_obj_t bus);
|
||||
typedef bool (*display_bus_bus_free)(mp_obj_t bus);
|
||||
typedef bool (*display_bus_begin_transaction)(mp_obj_t bus);
|
||||
@ -48,4 +57,7 @@ typedef void (*display_bus_end_transaction)(mp_obj_t bus);
|
||||
|
||||
void common_hal_displayio_release_displays(void);
|
||||
|
||||
extern const mp_obj_type_t displayio_colorspace_type;
|
||||
extern const cp_enum_obj_t displayio_colorspace_RGB888_obj;
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H
|
||||
|
145
shared-bindings/imagecapture/ParallelImageCapture.c
Normal file
145
shared-bindings/imagecapture/ParallelImageCapture.c
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 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/runtime.h"
|
||||
|
||||
#include "lib/utils/context_manager_helpers.h"
|
||||
|
||||
#include "shared-bindings/imagecapture/ParallelImageCapture.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
#include "common-hal/imagecapture/ParallelImageCapture.h"
|
||||
|
||||
//| class ParallelImageCapture:
|
||||
//| """Capture image frames from a camera with parallel data interface"""
|
||||
//|
|
||||
//| def __init__(
|
||||
//| self,
|
||||
//| *,
|
||||
//| data0: microcontroller.Pin,
|
||||
//| data_count: int=8,
|
||||
//| clock: microcontroller.Pin,
|
||||
//| vsync: Optional[microcontroller.Pin],
|
||||
//| href: Optional[microcontroller.Pin],
|
||||
//| ):
|
||||
//| """Create a parallel image capture object
|
||||
//| :param microcontroller.Pin data0: The first data pin. Additional data pins are assumed to follow this pin directly in the microcontroller's standard pin ordering.
|
||||
//| :param int data_count: The number of data pins.
|
||||
//| :param microcontroller.Pin clock: The pixel clock input.
|
||||
//| :param microcontroller.Pin vsync: The vertical sync input, which has a negative-going pulse at the beginning of each frame.
|
||||
//| :param microcontroller.Pin href: The horizontal reference input, which is high whenever the camera is transmitting valid pixel information.
|
||||
//| """
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t imagecapture_parallelimagecapture_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_data0, ARG_data_count, ARG_clock, ARG_vsync, ARG_href,
|
||||
NUM_ARGS };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_data0, MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
|
||||
{ MP_QSTR_data_count, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 8 } },
|
||||
{ MP_QSTR_clock, MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
|
||||
{ MP_QSTR_vsync, MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
|
||||
{ MP_QSTR_href, MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
|
||||
};
|
||||
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, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
mcu_pin_obj_t *data0 = validate_obj_is_free_pin(args[ARG_data0].u_obj);
|
||||
mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj);
|
||||
mcu_pin_obj_t *vsync = validate_obj_is_free_pin_or_none(args[ARG_vsync].u_obj);
|
||||
mcu_pin_obj_t *href = validate_obj_is_free_pin_or_none(args[ARG_href].u_obj);
|
||||
|
||||
imagecapture_parallelimagecapture_obj_t *self = m_new_obj(imagecapture_parallelimagecapture_obj_t);
|
||||
self->base.type = &imagecapture_parallelimagecapture_type;
|
||||
|
||||
common_hal_imagecapture_parallelimagecapture_construct(self, data0, clock, vsync, href, args[ARG_data_count].u_int);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
//| def capture(self, buffer: WriteableBuffer, width: int, height: int, bpp: int=16) -> None:
|
||||
//| """Capture a single frame into the given buffer"""
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t imagecapture_parallelimagecapture_capture(mp_obj_t self_in, mp_obj_t buffer) {
|
||||
imagecapture_parallelimagecapture_obj_t *self = (imagecapture_parallelimagecapture_obj_t *)self_in;
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_RW);
|
||||
common_hal_imagecapture_parallelimagecapture_capture(self, bufinfo.buf, bufinfo.len);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(imagecapture_parallelimagecapture_capture_obj, imagecapture_parallelimagecapture_capture);
|
||||
|
||||
//| def deinit(self) -> None:
|
||||
//| """Deinitialize this instance"""
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t imagecapture_parallelimagecapture_deinit(mp_obj_t self_in) {
|
||||
imagecapture_parallelimagecapture_obj_t *self = (imagecapture_parallelimagecapture_obj_t *)self_in;
|
||||
common_hal_imagecapture_parallelimagecapture_deinit(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(imagecapture_parallelimagecapture_deinit_obj, imagecapture_parallelimagecapture_deinit);
|
||||
|
||||
//| def __enter__(self) -> ParallelImageCapture:
|
||||
//| """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 imagecapture_parallelimagecapture___exit__(size_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
common_hal_imagecapture_parallelimagecapture_deinit(args[0]);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(imagecapture_parallelimagecapture___exit___obj, 4, 4, imagecapture_parallelimagecapture___exit__);
|
||||
|
||||
|
||||
STATIC const mp_rom_map_elem_t imagecapture_parallelimagecapture_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&imagecapture_parallelimagecapture_deinit_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&imagecapture_parallelimagecapture___exit___obj) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_capture), MP_ROM_PTR(&imagecapture_parallelimagecapture_capture_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(imagecapture_parallelimagecapture_locals_dict, imagecapture_parallelimagecapture_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t imagecapture_parallelimagecapture_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_ParallelImageCapture,
|
||||
.make_new = imagecapture_parallelimagecapture_make_new,
|
||||
.locals_dict = (mp_obj_dict_t *)&imagecapture_parallelimagecapture_locals_dict,
|
||||
};
|
42
shared-bindings/imagecapture/ParallelImageCapture.h
Normal file
42
shared-bindings/imagecapture/ParallelImageCapture.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 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 "common-hal/microcontroller/Pin.h"
|
||||
|
||||
typedef struct imagecapture_parallelimagecapture_obj imagecapture_parallelimagecapture_obj_t;
|
||||
extern const mp_obj_type_t imagecapture_parallelimagecapture_type;
|
||||
|
||||
void common_hal_imagecapture_parallelimagecapture_construct(imagecapture_parallelimagecapture_obj_t *self,
|
||||
const mcu_pin_obj_t *data0,
|
||||
const mcu_pin_obj_t *data_clock,
|
||||
const mcu_pin_obj_t *vertical_sync,
|
||||
const mcu_pin_obj_t *horizontal_sync,
|
||||
int data_count);
|
||||
void common_hal_imagecapture_parallelimagecapture_deinit(imagecapture_parallelimagecapture_obj_t *self);
|
||||
bool common_hal_imagecapture_parallelimagecapture_deinited(imagecapture_parallelimagecapture_obj_t *self);
|
||||
void common_hal_imagecapture_parallelimagecapture_capture(imagecapture_parallelimagecapture_obj_t *self, void *buffer, size_t bufsize);
|
47
shared-bindings/imagecapture/__init__.c
Normal file
47
shared-bindings/imagecapture/__init__.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 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 <stdint.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "shared-bindings/imagecapture/ParallelImageCapture.h"
|
||||
|
||||
//| """Support for "Parallel capture" interfaces"""
|
||||
//|
|
||||
|
||||
STATIC const mp_rom_map_elem_t imagecapture_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_imagecapture) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ParallelImageCapture), MP_ROM_PTR(&imagecapture_parallelimagecapture_type) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(imagecapture_module_globals, imagecapture_module_globals_table);
|
||||
|
||||
const mp_obj_module_t imagecapture_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&imagecapture_module_globals,
|
||||
};
|
27
shared-bindings/imagecapture/__init__.h
Normal file
27
shared-bindings/imagecapture/__init__.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 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
|
@ -41,9 +41,10 @@ uint32_t displayio_colorconverter_dither_noise_2(uint32_t x, uint32_t y) {
|
||||
return displayio_colorconverter_dither_noise_1(x + y * 0xFFFF);
|
||||
}
|
||||
|
||||
void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t *self, bool dither) {
|
||||
void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t *self, bool dither, displayio_colorspace_t input_colorspace) {
|
||||
self->dither = dither;
|
||||
self->transparent_color = NO_TRANSPARENT_COLOR;
|
||||
self->input_colorspace = input_colorspace;
|
||||
}
|
||||
|
||||
uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888) {
|
||||
@ -152,6 +153,33 @@ void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _d
|
||||
return;
|
||||
}
|
||||
|
||||
switch (self->input_colorspace) {
|
||||
case DISPLAYIO_COLORSPACE_RGB565_SWAPPED:
|
||||
pixel = __builtin_bswap16(pixel);
|
||||
FALLTHROUGH;
|
||||
case DISPLAYIO_COLORSPACE_RGB565: {
|
||||
uint32_t r8 = (pixel >> 11) << 3;
|
||||
uint32_t g8 = ((pixel >> 5) << 2) & 0xff;
|
||||
uint32_t b8 = (pixel << 3) & 0xff;
|
||||
pixel = (r8 << 16) | (g8 << 8) | b8;
|
||||
}
|
||||
break;
|
||||
|
||||
case DISPLAYIO_COLORSPACE_RGB555_SWAPPED:
|
||||
pixel = __builtin_bswap16(pixel);
|
||||
FALLTHROUGH;
|
||||
case DISPLAYIO_COLORSPACE_RGB555: {
|
||||
uint32_t r8 = (pixel >> 10) << 3;
|
||||
uint32_t g8 = ((pixel >> 5) << 3) & 0xff;
|
||||
uint32_t b8 = (pixel << 3) & 0xff;
|
||||
pixel = (r8 << 16) | (g8 << 8) | b8;
|
||||
}
|
||||
break;
|
||||
|
||||
case DISPLAYIO_COLORSPACE_RGB888:
|
||||
break;
|
||||
}
|
||||
|
||||
if (self->dither) {
|
||||
uint8_t randr = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x,input_pixel->tile_y));
|
||||
uint8_t randg = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x + 33,input_pixel->tile_y));
|
||||
|
@ -36,6 +36,7 @@
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
bool dither;
|
||||
uint8_t input_colorspace;
|
||||
uint32_t transparent_color;
|
||||
} displayio_colorconverter_t;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user