kopia lustrzana https://github.com/pimoroni/pimoroni-pico
				
				
				
			Merge pull request #142 from pimoroni/driver/as7262
C++ and MP support and example for AS7262 breakoutpull/148/head
						commit
						15b85d1ee2
					
				|  | @ -11,3 +11,4 @@ add_subdirectory(vl53l1x) | |||
| add_subdirectory(is31fl3731) | ||||
| add_subdirectory(fatfs) | ||||
| add_subdirectory(sdcard) | ||||
| add_subdirectory(as7262) | ||||
|  |  | |||
|  | @ -0,0 +1 @@ | |||
| include(as7262.cmake) | ||||
|  | @ -0,0 +1,10 @@ | |||
| set(DRIVER_NAME as7262) | ||||
| add_library(${DRIVER_NAME} INTERFACE) | ||||
| 
 | ||||
| target_sources(${DRIVER_NAME} INTERFACE | ||||
|   ${CMAKE_CURRENT_LIST_DIR}/${DRIVER_NAME}.cpp) | ||||
| 
 | ||||
| target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) | ||||
| 
 | ||||
| # Pull in pico libraries that we need | ||||
| target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c) | ||||
|  | @ -0,0 +1,228 @@ | |||
| #include <cstdlib> | ||||
| #include <math.h> | ||||
| #include <map> | ||||
| #include <vector> | ||||
| #include <cstring> | ||||
| 
 | ||||
| #include "as7262.hpp" | ||||
| 
 | ||||
| namespace pimoroni { | ||||
| 
 | ||||
|   /***** Device registers and masks here *****/ | ||||
| 
 | ||||
|   enum reg { | ||||
|     DEVICE      = 0x00, | ||||
|     HW_VERSION  = 0x01, | ||||
|     FW_VERSION  = 0x02, // + 0x03
 | ||||
|     CONTROL     = 0x04, | ||||
|     INT_T       = 0x05, | ||||
|     TEMP        = 0x06, | ||||
|     LED_CONTROL = 0x07, | ||||
|     V_HIGH      = 0x08, // Violet
 | ||||
|     V_LOW       = 0x09, | ||||
|     B_HIGH      = 0x0A, // Blue
 | ||||
|     B_LOW       = 0x0B, | ||||
|     G_HIGH      = 0x0C, // Green
 | ||||
|     G_LOW       = 0x0D, | ||||
|     Y_HIGH      = 0x0E, // Yellow
 | ||||
|     Y_LOW       = 0x0F, | ||||
|     O_HIGH      = 0x10, // Orange
 | ||||
|     O_LOW       = 0x11, | ||||
|     R_HIGH      = 0x12, // Red
 | ||||
|     R_LOW       = 0x13, | ||||
|     V_CAL_F     = 0x14, // -> 0x17 Float (Violet)
 | ||||
|     B_CAL_F     = 0x18, // -> 0x1B Float (Blue)
 | ||||
|     G_CAL_F     = 0x1C, // -> 0x1F Float (Green)
 | ||||
|     Y_CAL_F     = 0x20, // -> 0x23 Float (Yellow)
 | ||||
|     O_CAL_F     = 0x24, // -> 0x27 Float (Orange)
 | ||||
|     R_CAL_F     = 0x28, // -> 0x27 Float (Red)
 | ||||
|   }; | ||||
| 
 | ||||
| 
 | ||||
|   bool AS7262::init() { | ||||
|     bool succeeded = false; | ||||
| 
 | ||||
|     i2c_init(i2c, 400000); | ||||
| 
 | ||||
|     gpio_set_function(sda, GPIO_FUNC_I2C); | ||||
|     gpio_pull_up(sda); | ||||
|     gpio_set_function(scl, GPIO_FUNC_I2C); | ||||
|     gpio_pull_up(scl); | ||||
| 
 | ||||
|     if(interrupt != PIN_UNUSED) { | ||||
|       gpio_set_function(interrupt, GPIO_FUNC_SIO); | ||||
|       gpio_set_dir(interrupt, GPIO_IN); | ||||
|       gpio_pull_up(interrupt); | ||||
|     } | ||||
| 
 | ||||
|     reset(); | ||||
| 
 | ||||
|     /***** Replace if(true) with any operations needed to initialise the device *****/ | ||||
|     if(true) { | ||||
|       succeeded = true; | ||||
|     } | ||||
| 
 | ||||
|     return succeeded; | ||||
|   } | ||||
| 
 | ||||
|   void AS7262::reset() { | ||||
|     i2c_reg_write_uint8(reg::CONTROL, 0b10000000); | ||||
|     sleep_ms(1000); | ||||
|   } | ||||
| 
 | ||||
|   i2c_inst_t* AS7262::get_i2c() const { | ||||
|     return i2c; | ||||
|   } | ||||
| 
 | ||||
|   int AS7262::get_sda() const { | ||||
|     return sda; | ||||
|   } | ||||
| 
 | ||||
|   int AS7262::get_scl() const { | ||||
|     return scl; | ||||
|   } | ||||
| 
 | ||||
|   int AS7262::get_int() const { | ||||
|     return interrupt; | ||||
|   } | ||||
| 
 | ||||
|   uint8_t AS7262::device_type() { | ||||
|     return i2c_reg_read_uint8(reg::DEVICE); | ||||
|   } | ||||
| 
 | ||||
|   uint8_t AS7262::hardware_version() { | ||||
|     return i2c_reg_read_uint8(reg::HW_VERSION); | ||||
|   } | ||||
| 
 | ||||
|   void AS7262::firmware_version(uint8_t &major_out, uint8_t &minor_out, uint8_t &sub_out) { | ||||
|     uint16_t fw_version = i2c_reg_read_uint16(reg::FW_VERSION); | ||||
|     major_out = (fw_version & 0x00F0) >> 4; | ||||
|     minor_out = ((fw_version & 0x000F) << 2) | ((fw_version & 0xC000) >> 14); | ||||
|     sub_out = (fw_version & 0x3F00) >> 8; | ||||
|   } | ||||
| 
 | ||||
|   AS7262::reading AS7262::read() { | ||||
|     while(!data_ready()) {} | ||||
|     return AS7262::reading { | ||||
|       i2c_reg_read_float(reg::R_CAL_F), | ||||
|       i2c_reg_read_float(reg::O_CAL_F), | ||||
|       i2c_reg_read_float(reg::Y_CAL_F), | ||||
|       i2c_reg_read_float(reg::G_CAL_F), | ||||
|       i2c_reg_read_float(reg::B_CAL_F), | ||||
|       i2c_reg_read_float(reg::V_CAL_F) | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   uint8_t AS7262::temperature() { | ||||
|     return i2c_reg_read_uint8(reg::TEMP); | ||||
|   } | ||||
| 
 | ||||
|   void AS7262::set_gain(gain gain) { | ||||
|     uint8_t temp = i2c_reg_read_uint8(reg::CONTROL) & ~0b00110000; | ||||
|     temp |= (uint8_t)gain << 4; | ||||
|     i2c_reg_write_uint8(reg::CONTROL, temp); | ||||
|   } | ||||
| 
 | ||||
|   void AS7262::set_measurement_mode(measurement_mode mode) { | ||||
|     uint8_t temp = i2c_reg_read_uint8(reg::CONTROL) & ~0b00001100; | ||||
|     temp |= (uint8_t)mode << 2; | ||||
|     i2c_reg_write_uint8(reg::CONTROL, temp); | ||||
|   } | ||||
| 
 | ||||
|   void AS7262::set_indicator_current(indicator_current current) { | ||||
|     uint8_t temp = i2c_reg_read_uint8(reg::LED_CONTROL) & ~0b00000110; | ||||
|     temp |= (uint8_t)current << 1; | ||||
|     i2c_reg_write_uint8(reg::LED_CONTROL, temp); | ||||
|   } | ||||
| 
 | ||||
|   void AS7262::set_illumination_current(illumination_current current) { | ||||
|     uint8_t temp = i2c_reg_read_uint8(reg::LED_CONTROL) & ~0b00110000; | ||||
|     temp |= (uint8_t)current << 4; | ||||
|     i2c_reg_write_uint8(reg::LED_CONTROL, temp); | ||||
|   } | ||||
| 
 | ||||
|   void AS7262::set_leds(bool illumination, bool indicator) { | ||||
|     uint8_t temp = i2c_reg_read_uint8(reg::LED_CONTROL) & ~0b00001001; | ||||
|     temp |= indicator ? 1 : 0; | ||||
|     temp |= (illumination ? 1 : 0) << 3; | ||||
|     i2c_reg_write_uint8(reg::LED_CONTROL, temp); | ||||
|   } | ||||
| 
 | ||||
|   void AS7262::set_integration_time(float integration_time_ms) { | ||||
|     uint8_t integration_time = uint8_t(integration_time_ms * 2.88); | ||||
|     i2c_reg_write_uint8(reg::INT_T, integration_time); | ||||
|   } | ||||
| 
 | ||||
|   bool AS7262::data_ready() { | ||||
|     return i2c_reg_read_uint8(reg::CONTROL) & 0b00000010; | ||||
|   } | ||||
| 
 | ||||
|   // i2c IO wrappers around the weird virtual i2c nonsense
 | ||||
|   void AS7262::i2c_reg_write_uint8(uint8_t reg, uint8_t value) { | ||||
|     i2c_write(reg, &value, 1); | ||||
|   } | ||||
| 
 | ||||
|   // convert the AS7262s 4-byte big-endian float value into a native float
 | ||||
|   float AS7262::i2c_reg_read_float(uint8_t reg) { | ||||
|     uint32_t value; | ||||
|     i2c_read(reg, (uint8_t *)&value, 4); | ||||
|     value = __builtin_bswap32(value); | ||||
| 
 | ||||
|     // Fails due to -Werror=strict-aliasing in MicroPython build
 | ||||
|     // return reinterpret_cast<float &>(value);
 | ||||
| 
 | ||||
|     // Assumes sizeof(uint32_t) == sizeof(float)
 | ||||
|     float result; | ||||
|     memcpy(&result, &value, sizeof(float)); | ||||
|     return result; | ||||
|   } | ||||
| 
 | ||||
|   uint8_t AS7262::i2c_reg_read_uint8(uint8_t reg) { | ||||
|     uint8_t value; | ||||
|     i2c_read(reg, &value, 1); | ||||
|     return value; | ||||
|   } | ||||
| 
 | ||||
|   uint16_t AS7262::i2c_reg_read_uint16(uint8_t reg) { | ||||
|     uint16_t value; | ||||
|     i2c_read(reg, (uint8_t *)&value, 2); | ||||
|     return value; | ||||
|   } | ||||
| 
 | ||||
|   uint8_t AS7262::i2c_status() { | ||||
|     return _i2c_reg_read_uint8(0x00); | ||||
|   } | ||||
| 
 | ||||
|   uint8_t AS7262::i2c_read(uint8_t reg, uint8_t *values, uint8_t len) { | ||||
|     for(uint8_t i = 0; i < len; i++){ | ||||
|       while((i2c_status() & 0b10) != 0) {};   // Wait for write-ready
 | ||||
|       _i2c_reg_write_uint8(0x01, reg + i);     // Set address pointer
 | ||||
|       while((i2c_status() & 0b01) != 1) {};   // Wait for read-ready
 | ||||
|       values[i] = _i2c_reg_read_uint8(0x02);   // Read *one* byte :|
 | ||||
|     } | ||||
|     return 0; | ||||
|   } | ||||
| 
 | ||||
|   uint8_t AS7262::i2c_write(uint8_t reg, uint8_t *values, uint8_t len) { | ||||
|     for(uint8_t i = 0; i < len; i++){ | ||||
|       while((i2c_status() & 0b10) != 0) {};   // Wait for write-ready
 | ||||
|       _i2c_reg_write_uint8(0x01, reg | 0x80);  // Set address pointer
 | ||||
|       while((i2c_status() & 0b10) != 0) {};  // Wait for write-ready
 | ||||
|       _i2c_reg_write_uint8(0x01, values[i]);   // Write *one* byte :|
 | ||||
|     } | ||||
|     return 0; | ||||
|   } | ||||
| 
 | ||||
|     // Plumbing for virtual i2c
 | ||||
|   void AS7262::_i2c_reg_write_uint8(uint8_t reg, uint8_t value) { | ||||
|     uint8_t buffer[2] = {reg, value}; | ||||
|     i2c_write_blocking(i2c, address, buffer, 2, false); | ||||
|   } | ||||
| 
 | ||||
|   uint8_t AS7262::_i2c_reg_read_uint8(uint8_t reg) { | ||||
|     uint8_t value; | ||||
|     i2c_write_blocking(i2c, address, ®, 1, false); | ||||
|     i2c_read_blocking(i2c, address, (uint8_t *)&value, 1, false); | ||||
|     return value; | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,136 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <string> | ||||
| 
 | ||||
| #include "hardware/i2c.h" | ||||
| #include "hardware/gpio.h" | ||||
| 
 | ||||
| namespace pimoroni { | ||||
| 
 | ||||
|   class AS7262 { | ||||
|     //--------------------------------------------------
 | ||||
|     // Constants
 | ||||
|     //--------------------------------------------------
 | ||||
|   public: | ||||
|     static const uint8_t DEFAULT_I2C_ADDRESS  = 0x49; | ||||
|     static const uint8_t DEFAULT_SDA_PIN      = 20; | ||||
|     static const uint8_t DEFAULT_SCL_PIN      = 21; | ||||
|     static const uint8_t DEFAULT_INT_PIN      = 22; | ||||
|     static const uint8_t PIN_UNUSED           = UINT8_MAX; | ||||
| 
 | ||||
| 
 | ||||
|     //--------------------------------------------------
 | ||||
|     // Enums
 | ||||
|     //--------------------------------------------------
 | ||||
|   public: | ||||
|     enum class gain : uint8_t { | ||||
|       X1   = 0b00, | ||||
|       X3_7 = 0b01, | ||||
|       X16  = 0b10, | ||||
|       X64  = 0b11 | ||||
|     }; | ||||
| 
 | ||||
|     enum class illumination_current : uint8_t { | ||||
|       ma12  = 0b00, | ||||
|       ma25  = 0b01, | ||||
|       ma50  = 0b10, | ||||
|       ma100 = 0b11 | ||||
|     }; | ||||
| 
 | ||||
|     enum class indicator_current : uint8_t { | ||||
|       ma1 = 0b00, | ||||
|       ma2 = 0b01, | ||||
|       ma4 = 0b10, | ||||
|       ma8 = 0b11, | ||||
|     }; | ||||
| 
 | ||||
|     enum class measurement_mode : uint8_t { | ||||
|       cont_ygnv   = 0b00, // yellow, green, blue, violet - continuous
 | ||||
|       cont_royg   = 0b01, // red, orange, yellow, green - continuous
 | ||||
|       cont_roygbr = 0b10, // red, orange, yellow, green, violet - continuous
 | ||||
|       oneshot     = 0b11  // everything - one-shot
 | ||||
|     }; | ||||
| 
 | ||||
| 
 | ||||
|     //--------------------------------------------------
 | ||||
|     // Substructures
 | ||||
|     //--------------------------------------------------
 | ||||
|   public: | ||||
|     struct reading { | ||||
|         float red; | ||||
|         float orange; | ||||
|         float yellow; | ||||
|         float green; | ||||
|         float blue; | ||||
|         float violet; | ||||
|     }; | ||||
| 
 | ||||
| 
 | ||||
|     //--------------------------------------------------
 | ||||
|     // Variables
 | ||||
|     //--------------------------------------------------
 | ||||
|   private: | ||||
|     i2c_inst_t *i2c = i2c0; | ||||
| 
 | ||||
|     // interface pins with our standard defaults where appropriate
 | ||||
|     int8_t address    = DEFAULT_I2C_ADDRESS; | ||||
|     int8_t sda        = DEFAULT_SDA_PIN; | ||||
|     int8_t scl        = DEFAULT_SCL_PIN; | ||||
|     int8_t interrupt  = DEFAULT_INT_PIN; | ||||
| 
 | ||||
| 
 | ||||
|     //--------------------------------------------------
 | ||||
|     // Constructors/Destructor
 | ||||
|     //--------------------------------------------------
 | ||||
|   public: | ||||
|     AS7262() {} | ||||
| 
 | ||||
|     AS7262(i2c_inst_t *i2c, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED) : | ||||
|       i2c(i2c), sda(sda), scl(scl), interrupt(interrupt) {} | ||||
| 
 | ||||
| 
 | ||||
|     //--------------------------------------------------
 | ||||
|     // Methods
 | ||||
|     //--------------------------------------------------
 | ||||
|   public: | ||||
|     bool init(); | ||||
|     void reset(); | ||||
| 
 | ||||
|     // For print access in micropython
 | ||||
|     i2c_inst_t* get_i2c() const; | ||||
|     int get_sda() const; | ||||
|     int get_scl() const; | ||||
|     int get_int() const; | ||||
| 
 | ||||
|     uint8_t device_type(); | ||||
|     uint8_t hardware_version(); | ||||
|     void firmware_version(uint8_t &major_out, uint8_t &minor_out, uint8_t &sub_out); | ||||
|     reading read(); | ||||
|     uint8_t temperature(); | ||||
| 
 | ||||
|     void set_gain(gain gain); | ||||
|     void set_measurement_mode(measurement_mode mode); | ||||
|     void set_indicator_current(indicator_current current); | ||||
|     void set_illumination_current(illumination_current current); | ||||
|     void set_integration_time(float integration_time_ms); | ||||
|     void set_leds(bool illumination, bool indicator); | ||||
| 
 | ||||
| private: | ||||
|     bool data_ready(); | ||||
| 
 | ||||
|     // Virtual i2c transfers, routed through read/write/status regs
 | ||||
|     uint8_t i2c_reg_read_uint8(uint8_t reg); | ||||
|     void i2c_reg_write_uint8(uint8_t reg, uint8_t value); | ||||
|     uint16_t i2c_reg_read_uint16(uint8_t reg); | ||||
|     float i2c_reg_read_float(uint8_t reg); | ||||
| 
 | ||||
|     uint8_t i2c_status();  | ||||
|     uint8_t i2c_read(uint8_t reg, uint8_t *values, uint8_t len); | ||||
|     uint8_t i2c_write(uint8_t reg, uint8_t *values, uint8_t len); | ||||
| 
 | ||||
|     // *Real* single-byte i2c transfers
 | ||||
|     uint8_t _i2c_reg_read_uint8(uint8_t reg); | ||||
|     void _i2c_reg_write_uint8(uint8_t reg, uint8_t value); | ||||
|   }; | ||||
| 
 | ||||
| } | ||||
|  | @ -19,3 +19,4 @@ add_subdirectory(pico_tof_display) | |||
| add_subdirectory(pico_trackball_display) | ||||
| add_subdirectory(pico_audio) | ||||
| add_subdirectory(pico_wireless) | ||||
| add_subdirectory(breakout_as7262) | ||||
|  |  | |||
|  | @ -0,0 +1,2 @@ | |||
| include("${CMAKE_CURRENT_LIST_DIR}/basic_demo.cmake") | ||||
| include("${CMAKE_CURRENT_LIST_DIR}/explorer_bargraph.cmake") | ||||
|  | @ -0,0 +1,16 @@ | |||
| set(OUTPUT_NAME as7262_basic_demo) | ||||
| 
 | ||||
| add_executable( | ||||
|   ${OUTPUT_NAME} | ||||
|   basic_demo.cpp | ||||
| ) | ||||
| 
 | ||||
| # enable usb output, disable uart output | ||||
| pico_enable_stdio_usb(${OUTPUT_NAME} 1) | ||||
| pico_enable_stdio_uart(${OUTPUT_NAME} 0) | ||||
| 
 | ||||
| # Pull in pico libraries that we need | ||||
| target_link_libraries(${OUTPUT_NAME} pico_stdlib breakout_as7262) | ||||
| 
 | ||||
| # create map/bin/hex file etc. | ||||
| pico_add_extra_outputs(${OUTPUT_NAME}) | ||||
|  | @ -0,0 +1,44 @@ | |||
| #include "pico/stdlib.h" | ||||
| 
 | ||||
| #include "breakout_as7262.hpp" | ||||
| 
 | ||||
| using namespace pimoroni; | ||||
| 
 | ||||
| BreakoutAS7262 as7262; | ||||
| 
 | ||||
| int main() { | ||||
|   stdio_init_all(); | ||||
| 
 | ||||
|   as7262.init(); | ||||
| 
 | ||||
|   uint8_t dev_type = as7262.device_type(); | ||||
|   uint8_t hw_version = as7262.hardware_version(); | ||||
| 
 | ||||
|   uint8_t major, minor, sub; | ||||
|   as7262.firmware_version(major, minor, sub); | ||||
|   printf("Device: %d, HW: %d, FW: %d.%d.%d\n", dev_type, hw_version, major, minor, sub); | ||||
| 
 | ||||
|   as7262.set_gain(AS7262::gain::X64); | ||||
|   as7262.set_integration_time(17.857); | ||||
|   as7262.set_measurement_mode(AS7262::measurement_mode::cont_roygbr); | ||||
|   as7262.set_illumination_current(AS7262::illumination_current::ma12); | ||||
|   as7262.set_indicator_current(AS7262::indicator_current::ma4); | ||||
|   as7262.set_leds(true, true); | ||||
| 
 | ||||
|   while(true) { | ||||
| 
 | ||||
|     AS7262::reading reading = as7262.read(); | ||||
|     printf("R: %f O: %f Y: %f G: %f B: %f V: %f \n", | ||||
|       reading.red, | ||||
|       reading.orange, | ||||
|       reading.yellow, | ||||
|       reading.green, | ||||
|       reading.blue, | ||||
|       reading.violet | ||||
|     ); | ||||
| 
 | ||||
|     sleep_ms(1000); | ||||
|   } | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
|  | @ -0,0 +1,16 @@ | |||
| set(OUTPUT_NAME as7262_explorer_bargraph) | ||||
| 
 | ||||
| add_executable( | ||||
|   ${OUTPUT_NAME} | ||||
|   explorer_bargraph.cpp | ||||
| ) | ||||
| 
 | ||||
| # enable usb output, disable uart output | ||||
| pico_enable_stdio_usb(${OUTPUT_NAME} 1) | ||||
| pico_enable_stdio_uart(${OUTPUT_NAME} 0) | ||||
| 
 | ||||
| # Pull in pico libraries that we need | ||||
| target_link_libraries(${OUTPUT_NAME} pico_stdlib breakout_as7262 pico_explorer) | ||||
| 
 | ||||
| # create map/bin/hex file etc. | ||||
| pico_add_extra_outputs(${OUTPUT_NAME}) | ||||
|  | @ -0,0 +1,98 @@ | |||
| #include "pico/stdlib.h" | ||||
| 
 | ||||
| #include "breakout_as7262.hpp" | ||||
| #include "pico_explorer.hpp" | ||||
| 
 | ||||
| using namespace pimoroni; | ||||
| 
 | ||||
| constexpr float INTEGRATION_TIME = 10.0f; | ||||
| 
 | ||||
| BreakoutAS7262 as7262; | ||||
| uint16_t buffer[PicoExplorer::WIDTH * PicoExplorer::HEIGHT]; | ||||
| PicoExplorer pico_explorer(buffer); | ||||
| 
 | ||||
| uint8_t bar_width = PicoExplorer::WIDTH / 6; | ||||
| uint8_t bar_height = PicoExplorer::HEIGHT; | ||||
| 
 | ||||
| void draw_bar(float scale, uint16_t channel) { | ||||
|   int16_t bar_top = bar_height - (bar_height * scale); | ||||
|   bar_top = std::max((int16_t)0, bar_top); | ||||
|   int16_t current_bar_height = bar_height - bar_top; | ||||
|   pico_explorer.rectangle(Rect(channel * bar_width, bar_top, bar_width, current_bar_height - 1)); | ||||
| } | ||||
| 
 | ||||
| int main() { | ||||
|   stdio_init_all(); | ||||
| 
 | ||||
|   pico_explorer.init(); | ||||
|   as7262.init(); | ||||
| 
 | ||||
|   uint8_t dev_type = as7262.device_type(); | ||||
|   uint8_t hw_version = as7262.hardware_version(); | ||||
| 
 | ||||
|   uint8_t major, minor, sub; | ||||
|   as7262.firmware_version(major, minor, sub); | ||||
|   printf("Device: %d, HW: %d, FW: %d.%d.%d\n", dev_type, hw_version, major, minor, sub); | ||||
| 
 | ||||
|   as7262.set_gain(AS7262::gain::X64); | ||||
|   as7262.set_integration_time(INTEGRATION_TIME); | ||||
|   as7262.set_measurement_mode(AS7262::measurement_mode::cont_roygbr); | ||||
|   as7262.set_illumination_current(AS7262::illumination_current::ma12); | ||||
|   as7262.set_indicator_current(AS7262::indicator_current::ma4); | ||||
|   as7262.set_leds(true, true); | ||||
| 
 | ||||
|   while(true) { | ||||
|     pico_explorer.set_pen(0, 0, 0); | ||||
|     pico_explorer.clear(); | ||||
| 
 | ||||
|     AS7262::reading reading = as7262.read(); | ||||
|     printf("R: %f O: %f Y: %f G: %f B: %f V: %f \n", | ||||
|       reading.red, | ||||
|       reading.orange, | ||||
|       reading.yellow, | ||||
|       reading.green, | ||||
|       reading.blue, | ||||
|       reading.violet | ||||
|     ); | ||||
| 
 | ||||
|     float m = reading.red; | ||||
|     if(reading.orange > m) m = reading.orange; | ||||
|     if(reading.yellow > m) m = reading.yellow; | ||||
|     if(reading.green > m) m = reading.green; | ||||
|     if(reading.blue > m) m = reading.blue; | ||||
|     if(reading.violet > m) m = reading.violet; | ||||
| 
 | ||||
|     pico_explorer.set_pen(0, 0, 0); | ||||
|     pico_explorer.clear(); | ||||
| 
 | ||||
|     // Red
 | ||||
|     pico_explorer.set_pen(255, 0, 0); | ||||
|     draw_bar(reading.red / m, 0); | ||||
|      | ||||
|     // Orange
 | ||||
|     pico_explorer.set_pen(255, 128, 0); | ||||
|     draw_bar(reading.orange / m, 1); | ||||
| 
 | ||||
|     // Yellow
 | ||||
|     pico_explorer.set_pen(255, 255, 0); | ||||
|     draw_bar(reading.yellow / m, 2); | ||||
| 
 | ||||
|     // Green
 | ||||
|     pico_explorer.set_pen(0, 255, 0); | ||||
|     draw_bar(reading.green / m, 3); | ||||
| 
 | ||||
|     // Blue
 | ||||
|     pico_explorer.set_pen(0, 0, 255); | ||||
|     draw_bar(reading.blue / m, 4); | ||||
| 
 | ||||
|     // Violet
 | ||||
|     pico_explorer.set_pen(255, 0, 255); | ||||
|     draw_bar(reading.violet / m, 5); | ||||
| 
 | ||||
|     pico_explorer.update(); | ||||
| 
 | ||||
|     sleep_ms(INTEGRATION_TIME); | ||||
|   } | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
|  | @ -7,6 +7,7 @@ add_subdirectory(breakout_rgbmatrix5x5) | |||
| add_subdirectory(breakout_matrix11x7) | ||||
| add_subdirectory(breakout_trackball) | ||||
| add_subdirectory(breakout_sgp30) | ||||
| add_subdirectory(breakout_as7262) | ||||
| add_subdirectory(pico_graphics) | ||||
| add_subdirectory(pico_display) | ||||
| add_subdirectory(pico_unicorn) | ||||
|  |  | |||
|  | @ -0,0 +1 @@ | |||
| include(breakout_as7262.cmake) | ||||
|  | @ -0,0 +1,11 @@ | |||
| set(LIB_NAME breakout_as7262) | ||||
| add_library(${LIB_NAME} INTERFACE) | ||||
| 
 | ||||
| target_sources(${LIB_NAME} INTERFACE | ||||
|   ${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp | ||||
| ) | ||||
| 
 | ||||
| target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) | ||||
| 
 | ||||
| # Pull in pico libraries that we need | ||||
| target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib hardware_i2c as7262) | ||||
|  | @ -0,0 +1,5 @@ | |||
| #include "breakout_as7262.hpp" | ||||
| 
 | ||||
| namespace pimoroni { | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,8 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include "../../drivers/as7262/as7262.hpp" | ||||
| 
 | ||||
| namespace pimoroni { | ||||
| 
 | ||||
|   typedef AS7262 BreakoutAS7262; | ||||
| } | ||||
|  | @ -0,0 +1,27 @@ | |||
| import time | ||||
| from breakout_as7262 import BreakoutAS7262 | ||||
| 
 | ||||
| as7262 = BreakoutAS7262() | ||||
| 
 | ||||
| dev_type = as7262.device_type() | ||||
| hw_version = as7262.hardware_version() | ||||
| fw_version = as7262.firmware_version() | ||||
| 
 | ||||
| print("Device: ", dev_type, "HW: ", hw_version, sep="", end=", ") | ||||
| print("FW: ", fw_version[0], ".", fw_version[1], ".", fw_version[2]) | ||||
| 
 | ||||
| as7262.set_gain(BreakoutAS7262.X16) | ||||
| as7262.set_measurement_mode(BreakoutAS7262.CONT_ROYGBR) | ||||
| as7262.set_illumination_current(BreakoutAS7262.MA12) | ||||
| as7262.set_indicator_current(BreakoutAS7262.MA4) | ||||
| # as7262.set_leds(False, False) | ||||
| 
 | ||||
| while True: | ||||
|     reading = as7262.read() | ||||
|     print("R:", reading[0], end=" ") | ||||
|     print("O:", reading[1], end=" ") | ||||
|     print("Y:", reading[2], end=" ") | ||||
|     print("G:", reading[3], end=" ") | ||||
|     print("B:", reading[4], end=" ") | ||||
|     print("V:", reading[5]) | ||||
|     time.sleep(1.0) | ||||
|  | @ -0,0 +1,65 @@ | |||
| from breakout_as7262 import BreakoutAS7262 | ||||
| import picoexplorer as display | ||||
| import time | ||||
| 
 | ||||
| width = display.get_width() | ||||
| height = display.get_height() | ||||
| 
 | ||||
| bar_width = width // 6 | ||||
| bar_height = height | ||||
| 
 | ||||
| display_buffer = bytearray(width * height * 2)  # 2-bytes per pixel (RGB565) | ||||
| display.init(display_buffer) | ||||
| 
 | ||||
| as7 = BreakoutAS7262() | ||||
| 
 | ||||
| integration_time = 10  # integration time in milliseconds, max ~90ms | ||||
| 
 | ||||
| as7.set_gain(as7.X64) | ||||
| as7.set_integration_time(integration_time) | ||||
| as7.set_measurement_mode(as7.CONT_ROYGBR) | ||||
| as7.set_leds(True, True) | ||||
| 
 | ||||
| 
 | ||||
| def draw_bar(v, i): | ||||
|     current_bar_top = int(bar_height - (bar_height * v)) | ||||
|     # Drawing outside of the display region will cause horrible, horrible crashes | ||||
|     current_bar_top = max(0, current_bar_top) | ||||
|     current_bar_height = bar_height - current_bar_top | ||||
|     display.rectangle(i * bar_width, current_bar_top, bar_width, current_bar_height - 1) | ||||
| 
 | ||||
| 
 | ||||
| while True: | ||||
|     r, o, y, g, b, v = as7.read() | ||||
|     m = max(r, o, y, g, b, v) | ||||
| 
 | ||||
|     display.set_pen(0, 0, 0) | ||||
|     display.clear() | ||||
| 
 | ||||
|     # Red | ||||
|     display.set_pen(255, 0, 0) | ||||
|     draw_bar(r / m, 0) | ||||
| 
 | ||||
|     # Orange | ||||
|     display.set_pen(255, 128, 0) | ||||
|     draw_bar(o / m, 1) | ||||
| 
 | ||||
|     # Yellow | ||||
|     display.set_pen(255, 255, 0) | ||||
|     draw_bar(y / m, 2) | ||||
| 
 | ||||
|     # Green | ||||
|     display.set_pen(0, 255, 0) | ||||
|     draw_bar(g / m, 3) | ||||
| 
 | ||||
|     # Blue | ||||
|     display.set_pen(0, 0, 255) | ||||
|     draw_bar(b / m, 4) | ||||
| 
 | ||||
|     # Violet | ||||
|     display.set_pen(255, 0, 255) | ||||
|     draw_bar(v / m, 5) | ||||
| 
 | ||||
|     display.update() | ||||
| 
 | ||||
|     time.sleep(integration_time / 1000.0) | ||||
|  | @ -0,0 +1,84 @@ | |||
| #include "breakout_as7262.h" | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| // BreakoutAS7262 Class
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| /***** Methods *****/ | ||||
| MP_DEFINE_CONST_FUN_OBJ_1(BreakoutAS7262_reset_obj, BreakoutAS7262_reset); | ||||
| MP_DEFINE_CONST_FUN_OBJ_1(BreakoutAS7262_device_type_obj, BreakoutAS7262_device_type); | ||||
| MP_DEFINE_CONST_FUN_OBJ_1(BreakoutAS7262_hardware_version_obj, BreakoutAS7262_hardware_version); | ||||
| MP_DEFINE_CONST_FUN_OBJ_1(BreakoutAS7262_firmware_version_obj, BreakoutAS7262_firmware_version); | ||||
| MP_DEFINE_CONST_FUN_OBJ_1(BreakoutAS7262_read_obj, BreakoutAS7262_read); | ||||
| MP_DEFINE_CONST_FUN_OBJ_1(BreakoutAS7262_temperature_obj, BreakoutAS7262_temperature); | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutAS7262_set_gain_obj, 1, BreakoutAS7262_set_gain); | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutAS7262_set_measurement_mode_obj, 1, BreakoutAS7262_set_measurement_mode); | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutAS7262_set_indicator_current_obj, 1, BreakoutAS7262_set_indicator_current); | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutAS7262_set_illumination_current_obj, 1, BreakoutAS7262_set_illumination_current); | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutAS7262_set_integration_time_obj, 1, BreakoutAS7262_set_integration_time); | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutAS7262_set_leds_obj, 1, BreakoutAS7262_set_leds); | ||||
| 
 | ||||
| /***** Binding of Methods *****/ | ||||
| STATIC const mp_rom_map_elem_t BreakoutAS7262_locals_dict_table[] = { | ||||
|     { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&BreakoutAS7262_reset_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_device_type), MP_ROM_PTR(&BreakoutAS7262_device_type_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_hardware_version), MP_ROM_PTR(&BreakoutAS7262_hardware_version_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_firmware_version), MP_ROM_PTR(&BreakoutAS7262_firmware_version_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&BreakoutAS7262_read_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_temperature), MP_ROM_PTR(&BreakoutAS7262_temperature_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_set_gain), MP_ROM_PTR(&BreakoutAS7262_set_gain_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_set_measurement_mode), MP_ROM_PTR(&BreakoutAS7262_set_measurement_mode_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_set_indicator_current), MP_ROM_PTR(&BreakoutAS7262_set_indicator_current_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_set_illumination_current), MP_ROM_PTR(&BreakoutAS7262_set_illumination_current_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_set_integration_time), MP_ROM_PTR(&BreakoutAS7262_set_integration_time_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_set_leds), MP_ROM_PTR(&BreakoutAS7262_set_leds_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_X1), MP_ROM_INT(MP_X1) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_X3_7), MP_ROM_INT(MP_X3_7) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_X16), MP_ROM_INT(MP_X16) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_X64), MP_ROM_INT(MP_X64) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_MA12), MP_ROM_INT(MP_MA12) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_MA25), MP_ROM_INT(MP_MA25) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_MA50), MP_ROM_INT(MP_MA50) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_MA100), MP_ROM_INT(MP_MA100) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_MA1), MP_ROM_INT(MP_MA1) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_MA2), MP_ROM_INT(MP_MA2) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_MA4), MP_ROM_INT(MP_MA4) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_MA8), MP_ROM_INT(MP_MA8) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_CONT_YGNV), MP_ROM_INT(MP_CONT_YGNV) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_CONT_ROYG), MP_ROM_INT(MP_CONT_ROYG) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_CONT_ROYGBR), MP_ROM_INT(MP_CONT_ROYGBR) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_ONESHOT), MP_ROM_INT(MP_ONESHOT) }, | ||||
| }; | ||||
| STATIC MP_DEFINE_CONST_DICT(BreakoutAS7262_locals_dict, BreakoutAS7262_locals_dict_table); | ||||
| 
 | ||||
| /***** Class Definition *****/ | ||||
| const mp_obj_type_t breakout_as7262_BreakoutAS7262_type = { | ||||
|     { &mp_type_type }, | ||||
|     .name = MP_QSTR_breakout_as7262, | ||||
|     .print = BreakoutAS7262_print, | ||||
|     .make_new = BreakoutAS7262_make_new, | ||||
|     .locals_dict = (mp_obj_dict_t*)&BreakoutAS7262_locals_dict, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| // breakout_as7262 Module
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| /***** Globals Table *****/ | ||||
| STATIC const mp_map_elem_t breakout_as7262_globals_table[] = { | ||||
|     { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_breakout_as7262) }, | ||||
|     { MP_OBJ_NEW_QSTR(MP_QSTR_BreakoutAS7262), (mp_obj_t)&breakout_as7262_BreakoutAS7262_type }, | ||||
| }; | ||||
| STATIC MP_DEFINE_CONST_DICT(mp_module_breakout_as7262_globals, breakout_as7262_globals_table); | ||||
| 
 | ||||
| /***** Module Definition *****/ | ||||
| const mp_obj_module_t breakout_as7262_user_cmodule = { | ||||
|     .base = { &mp_type_module }, | ||||
|     .globals = (mp_obj_dict_t*)&mp_module_breakout_as7262_globals, | ||||
| }; | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| MP_REGISTER_MODULE(MP_QSTR_breakout_as7262, breakout_as7262_user_cmodule, MODULE_BREAKOUT_AS7262_ENABLED); | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
|  | @ -0,0 +1,266 @@ | |||
| #include "../../../libraries/breakout_as7262/breakout_as7262.hpp" | ||||
| 
 | ||||
| #define MP_OBJ_TO_PTR2(o, t) ((t *)(uintptr_t)(o)) | ||||
| 
 | ||||
| // SDA/SCL on even/odd pins, I2C0/I2C1 on even/odd pairs of pins.
 | ||||
| #define IS_VALID_SCL(i2c, pin) (((pin) & 1) == 1 && (((pin) & 2) >> 1) == (i2c)) | ||||
| #define IS_VALID_SDA(i2c, pin) (((pin) & 1) == 0 && (((pin) & 2) >> 1) == (i2c)) | ||||
| 
 | ||||
| 
 | ||||
| using namespace pimoroni; | ||||
| 
 | ||||
| extern "C" { | ||||
| #include "breakout_as7262.h" | ||||
| 
 | ||||
| /***** Variables Struct *****/ | ||||
| typedef struct _breakout_as7262_BreakoutAS7262_obj_t { | ||||
|     mp_obj_base_t base; | ||||
|     BreakoutAS7262 *breakout; | ||||
| } breakout_as7262_BreakoutAS7262_obj_t; | ||||
| 
 | ||||
| /***** Print *****/ | ||||
| void BreakoutAS7262_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { | ||||
|     (void)kind; //Unused input parameter    
 | ||||
|     breakout_as7262_BreakoutAS7262_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_as7262_BreakoutAS7262_obj_t); | ||||
|     BreakoutAS7262* breakout = self->breakout; | ||||
|     mp_print_str(print, "BreakoutAS7262("); | ||||
| 
 | ||||
|     mp_print_str(print, "i2c = "); | ||||
|     mp_obj_print_helper(print, mp_obj_new_int((breakout->get_i2c() == i2c0) ? 0 : 1), PRINT_REPR); | ||||
| 
 | ||||
|     mp_print_str(print, ", sda = "); | ||||
|     mp_obj_print_helper(print, mp_obj_new_int(breakout->get_sda()), PRINT_REPR); | ||||
| 
 | ||||
|     mp_print_str(print, ", scl = "); | ||||
|     mp_obj_print_helper(print, mp_obj_new_int(breakout->get_scl()), PRINT_REPR); | ||||
| 
 | ||||
|     mp_print_str(print, ", int = "); | ||||
|     mp_obj_print_helper(print, mp_obj_new_int(breakout->get_int()), PRINT_REPR); | ||||
| 
 | ||||
|     mp_print_str(print, ")"); | ||||
| } | ||||
| 
 | ||||
| /***** Constructor *****/ | ||||
| mp_obj_t BreakoutAS7262_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { | ||||
|     breakout_as7262_BreakoutAS7262_obj_t *self = nullptr; | ||||
| 
 | ||||
|     if(n_args == 0) { | ||||
|         mp_arg_check_num(n_args, n_kw, 0, 0, true); | ||||
|         self = m_new_obj(breakout_as7262_BreakoutAS7262_obj_t); | ||||
|         self->base.type = &breakout_as7262_BreakoutAS7262_type; | ||||
|         self->breakout = new BreakoutAS7262(); | ||||
|     } | ||||
|     else { | ||||
|         enum { ARG_i2c, ARG_sda, ARG_scl, ARG_int }; | ||||
|         static const mp_arg_t allowed_args[] = { | ||||
|             { MP_QSTR_i2c, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|             { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|             { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|             { MP_QSTR_int, MP_ARG_INT, {.u_int = BreakoutAS7262::PIN_UNUSED} }, | ||||
|         }; | ||||
| 
 | ||||
|         // Parse args.
 | ||||
|         mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; | ||||
|         mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); | ||||
| 
 | ||||
|         // Get I2C bus.
 | ||||
|         int i2c_id = args[ARG_i2c].u_int; | ||||
|         if(i2c_id < 0 || i2c_id > 1) { | ||||
|             mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%d) doesn't exist"), i2c_id); | ||||
|         } | ||||
| 
 | ||||
|         int sda = args[ARG_sda].u_int; | ||||
|         if(!IS_VALID_SDA(i2c_id, sda)) { | ||||
|             mp_raise_ValueError(MP_ERROR_TEXT("bad SDA pin")); | ||||
|         } | ||||
| 
 | ||||
|         int scl = args[ARG_scl].u_int; | ||||
|         if(!IS_VALID_SCL(i2c_id, scl)) { | ||||
|             mp_raise_ValueError(MP_ERROR_TEXT("bad SCL pin")); | ||||
|         } | ||||
| 
 | ||||
|         self = m_new_obj(breakout_as7262_BreakoutAS7262_obj_t); | ||||
|         self->base.type = &breakout_as7262_BreakoutAS7262_type; | ||||
|          | ||||
|         i2c_inst_t *i2c = (i2c_id == 0) ? i2c0 : i2c1; | ||||
|         self->breakout = new BreakoutAS7262(i2c, sda, scl, args[ARG_int].u_int); | ||||
|     } | ||||
| 
 | ||||
|     self->breakout->init(); | ||||
| 
 | ||||
|     return MP_OBJ_FROM_PTR(self); | ||||
| } | ||||
| 
 | ||||
| /***** Methods *****/ | ||||
| mp_obj_t BreakoutAS7262_reset(mp_obj_t self_in) { | ||||
|     breakout_as7262_BreakoutAS7262_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_as7262_BreakoutAS7262_obj_t); | ||||
|     self->breakout->reset(); | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
| 
 | ||||
| mp_obj_t BreakoutAS7262_device_type(mp_obj_t self_in) { | ||||
|     breakout_as7262_BreakoutAS7262_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_as7262_BreakoutAS7262_obj_t); | ||||
|     return mp_obj_new_int(self->breakout->device_type()); | ||||
| } | ||||
| 
 | ||||
| mp_obj_t BreakoutAS7262_hardware_version(mp_obj_t self_in) { | ||||
|     breakout_as7262_BreakoutAS7262_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_as7262_BreakoutAS7262_obj_t); | ||||
|     return mp_obj_new_int(self->breakout->hardware_version()); | ||||
| } | ||||
| 
 | ||||
| mp_obj_t BreakoutAS7262_firmware_version(mp_obj_t self_in) { | ||||
|     breakout_as7262_BreakoutAS7262_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_as7262_BreakoutAS7262_obj_t); | ||||
| 
 | ||||
|     uint8_t major, minor, sub; | ||||
|     self->breakout->firmware_version(major, minor, sub); | ||||
| 
 | ||||
|     mp_obj_t tuple[3]; | ||||
|     tuple[0] = mp_obj_new_int(major); | ||||
|     tuple[1] = mp_obj_new_float(minor); | ||||
|     tuple[2] = mp_obj_new_float(sub); | ||||
|     return mp_obj_new_tuple(3, tuple); | ||||
| } | ||||
| 
 | ||||
| mp_obj_t BreakoutAS7262_read(mp_obj_t self_in) { | ||||
|     breakout_as7262_BreakoutAS7262_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_as7262_BreakoutAS7262_obj_t); | ||||
|     BreakoutAS7262::reading reading = self->breakout->read(); | ||||
| 
 | ||||
|     mp_obj_t tuple[6]; | ||||
|     tuple[0] = mp_obj_new_float(reading.red); | ||||
|     tuple[1] = mp_obj_new_float(reading.orange); | ||||
|     tuple[2] = mp_obj_new_float(reading.yellow); | ||||
|     tuple[3] = mp_obj_new_float(reading.green); | ||||
|     tuple[4] = mp_obj_new_float(reading.blue); | ||||
|     tuple[5] = mp_obj_new_float(reading.violet); | ||||
|     return mp_obj_new_tuple(6, tuple); | ||||
| } | ||||
| 
 | ||||
| mp_obj_t BreakoutAS7262_temperature(mp_obj_t self_in) { | ||||
|     breakout_as7262_BreakoutAS7262_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_as7262_BreakoutAS7262_obj_t); | ||||
|     return mp_obj_new_int(self->breakout->temperature()); | ||||
| } | ||||
| 
 | ||||
| mp_obj_t BreakoutAS7262_set_gain(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { | ||||
|     enum { ARG_self, ARG_gain }; | ||||
|     static const mp_arg_t allowed_args[] = { | ||||
|         { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|         { MP_QSTR_gain, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|     }; | ||||
| 
 | ||||
|     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); | ||||
| 
 | ||||
|     int gain = args[ARG_gain].u_int; | ||||
|     if(gain < 0 || gain > 3) { | ||||
|         mp_raise_ValueError("mode not a valid value. Expected 0 to 3 (X1, X3_7, X16, X64)"); | ||||
|     } | ||||
|     else { | ||||
|         breakout_as7262_BreakoutAS7262_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_as7262_BreakoutAS7262_obj_t); | ||||
|         self->breakout->set_gain((BreakoutAS7262::gain)gain); | ||||
|     } | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
| 
 | ||||
| mp_obj_t BreakoutAS7262_set_measurement_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { | ||||
|     enum { ARG_self, ARG_mode }; | ||||
|     static const mp_arg_t allowed_args[] = { | ||||
|         { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|         { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|     }; | ||||
| 
 | ||||
|     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); | ||||
| 
 | ||||
|     int mode = args[ARG_mode].u_int; | ||||
|     if(mode < 0 || mode > 3) { | ||||
|         mp_raise_ValueError("mode not a valid value. Expected 0 to 3 (CONT_YGNV, CONT_ROYG, CONT_ROYGBR, ONESHOT)"); | ||||
|     } | ||||
|     else { | ||||
|         breakout_as7262_BreakoutAS7262_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_as7262_BreakoutAS7262_obj_t); | ||||
|         self->breakout->set_measurement_mode((BreakoutAS7262::measurement_mode)mode); | ||||
|     } | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
| 
 | ||||
| mp_obj_t BreakoutAS7262_set_indicator_current(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { | ||||
|     enum { ARG_self, ARG_current }; | ||||
|     static const mp_arg_t allowed_args[] = { | ||||
|         { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|         { MP_QSTR_current, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|     }; | ||||
| 
 | ||||
|     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); | ||||
|      | ||||
|     int current = args[ARG_current].u_int; | ||||
|     if(current < 0 || current > 3) { | ||||
|         mp_raise_ValueError("current not a valid value. Expected 0 to 3 (MA1, MA2, MA4, MA8)"); | ||||
|     } | ||||
|     else { | ||||
|         breakout_as7262_BreakoutAS7262_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_as7262_BreakoutAS7262_obj_t); | ||||
|         self->breakout->set_indicator_current((BreakoutAS7262::indicator_current)current); | ||||
|     } | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
| 
 | ||||
| mp_obj_t BreakoutAS7262_set_illumination_current(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { | ||||
|     enum { ARG_self, ARG_current }; | ||||
|     static const mp_arg_t allowed_args[] = { | ||||
|         { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|         { MP_QSTR_current, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|     }; | ||||
| 
 | ||||
|     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); | ||||
| 
 | ||||
|     int current = args[ARG_current].u_int; | ||||
|     if(current < 0 || current > 3) { | ||||
|         mp_raise_ValueError("current not a valid value. Expected 0 to 3 (MA12, MA25, MA50, MA100)"); | ||||
|     } | ||||
|     else {   | ||||
|         breakout_as7262_BreakoutAS7262_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_as7262_BreakoutAS7262_obj_t); | ||||
|         self->breakout->set_illumination_current((BreakoutAS7262::illumination_current)current); | ||||
|     } | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
| 
 | ||||
| mp_obj_t BreakoutAS7262_set_integration_time(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { | ||||
|     enum { ARG_self, ARG_integration_time }; | ||||
|     static const mp_arg_t allowed_args[] = { | ||||
|         { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|         { MP_QSTR_integration_time, 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); | ||||
| 
 | ||||
|     float integration_time = mp_obj_get_float(args[ARG_integration_time].u_obj); | ||||
| 
 | ||||
|     breakout_as7262_BreakoutAS7262_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_as7262_BreakoutAS7262_obj_t); | ||||
|     self->breakout->set_integration_time(integration_time); | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
| 
 | ||||
| mp_obj_t BreakoutAS7262_set_leds(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { | ||||
|     enum { ARG_self, ARG_illumination, ARG_indicator }; | ||||
|     static const mp_arg_t allowed_args[] = { | ||||
|         { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|         { MP_QSTR_illumination, MP_ARG_REQUIRED | MP_ARG_BOOL }, | ||||
|         { MP_QSTR_indicator, MP_ARG_REQUIRED | MP_ARG_BOOL }, | ||||
|     }; | ||||
| 
 | ||||
|     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); | ||||
|      | ||||
|     breakout_as7262_BreakoutAS7262_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_as7262_BreakoutAS7262_obj_t); | ||||
|     self->breakout->set_leds(args[ARG_illumination].u_bool, args[ARG_indicator].u_bool); | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
| } | ||||
|  | @ -0,0 +1,50 @@ | |||
| // Include MicroPython API.
 | ||||
| #include "py/runtime.h" | ||||
| 
 | ||||
| /***** Constants *****/ | ||||
| enum { | ||||
|     MP_X1   = 0b00, | ||||
|     MP_X3_7 = 0b01, | ||||
|     MP_X16  = 0b10, | ||||
|     MP_X64  = 0b11 | ||||
| }; | ||||
| 
 | ||||
| enum { | ||||
|     MP_MA12  = 0b00, | ||||
|     MP_MA25  = 0b01, | ||||
|     MP_MA50  = 0b10, | ||||
|     MP_MA100 = 0b11 | ||||
| }; | ||||
| 
 | ||||
| enum { | ||||
|     MP_MA1 = 0b00, | ||||
|     MP_MA2 = 0b01, | ||||
|     MP_MA4 = 0b10, | ||||
|     MP_MA8 = 0b11 | ||||
| }; | ||||
| 
 | ||||
| enum { | ||||
|     MP_CONT_YGNV    = 0b00, // yellow, green, blue, violet - continuous
 | ||||
|     MP_CONT_ROYG    = 0b01, // red, orange, yellow, green - continuous
 | ||||
|     MP_CONT_ROYGBR  = 0b10, // red, orange, yellow, green, violet - continuous
 | ||||
|     MP_ONESHOT      = 0b11  // everything - one-shot
 | ||||
| }; | ||||
| 
 | ||||
| /***** Extern of Class Definition *****/ | ||||
| extern const mp_obj_type_t breakout_as7262_BreakoutAS7262_type; | ||||
| 
 | ||||
| /***** Extern of Class Methods *****/ | ||||
| extern void BreakoutAS7262_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); | ||||
| extern mp_obj_t BreakoutAS7262_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); | ||||
| extern mp_obj_t BreakoutAS7262_reset(mp_obj_t self_in); | ||||
| extern mp_obj_t BreakoutAS7262_device_type(mp_obj_t self_in); | ||||
| extern mp_obj_t BreakoutAS7262_hardware_version(mp_obj_t self_in); | ||||
| extern mp_obj_t BreakoutAS7262_firmware_version(mp_obj_t self_in); | ||||
| extern mp_obj_t BreakoutAS7262_read(mp_obj_t self_in); | ||||
| extern mp_obj_t BreakoutAS7262_temperature(mp_obj_t self_in); | ||||
| extern mp_obj_t BreakoutAS7262_set_gain(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); | ||||
| extern mp_obj_t BreakoutAS7262_set_measurement_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); | ||||
| extern mp_obj_t BreakoutAS7262_set_indicator_current(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); | ||||
| extern mp_obj_t BreakoutAS7262_set_illumination_current(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); | ||||
| extern mp_obj_t BreakoutAS7262_set_integration_time(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); | ||||
| extern mp_obj_t BreakoutAS7262_set_leds(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); | ||||
|  | @ -0,0 +1,20 @@ | |||
| set(MOD_NAME breakout_as7262) | ||||
| string(TOUPPER ${MOD_NAME} MOD_NAME_UPPER) | ||||
| add_library(usermod_${MOD_NAME} INTERFACE) | ||||
| 
 | ||||
| target_sources(usermod_${MOD_NAME} INTERFACE | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.c | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/${MOD_NAME}/${MOD_NAME}.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/as7262/as7262.cpp | ||||
| ) | ||||
| 
 | ||||
| target_include_directories(usermod_${MOD_NAME} INTERFACE | ||||
|     ${CMAKE_CURRENT_LIST_DIR} | ||||
| ) | ||||
| 
 | ||||
| target_compile_definitions(usermod_${MOD_NAME} INTERFACE | ||||
|     -DMODULE_${MOD_NAME_UPPER}_ENABLED=1 | ||||
| ) | ||||
| 
 | ||||
| target_link_libraries(usermod INTERFACE usermod_${MOD_NAME}) | ||||
|  | @ -0,0 +1,13 @@ | |||
| set(MOD_NAME breakout_as7262) | ||||
| BREAKOUT_MOD_DIR := $(USERMOD_DIR) | ||||
| 
 | ||||
| # Add our source files to the respective variables.
 | ||||
| SRC_USERMOD += $(BREAKOUT_MOD_DIR)/${MOD_NAME}.c | ||||
| SRC_USERMOD_CXX += $(BREAKOUT_MOD_DIR)/${MOD_NAME}.cpp | ||||
| 
 | ||||
| # Add our module directory to the include path.
 | ||||
| CFLAGS_USERMOD += -I$(BREAKOUT_MOD_DIR) | ||||
| CXXFLAGS_USERMOD += -I$(BREAKOUT_MOD_DIR) | ||||
| 
 | ||||
| # We use C++ features so have to link against the standard library.
 | ||||
| LDFLAGS_USERMOD += -lstdc++ | ||||
|  | @ -1,6 +1,7 @@ | |||
| include(${CMAKE_CURRENT_LIST_DIR}/breakout_dotmatrix/micropython.cmake) | ||||
| include(${CMAKE_CURRENT_LIST_DIR}/breakout_ltr559/micropython.cmake) | ||||
| include(${CMAKE_CURRENT_LIST_DIR}/breakout_colourlcd160x80/micropython.cmake) | ||||
| include(${CMAKE_CURRENT_LIST_DIR}/breakout_as7262/micropython.cmake) | ||||
| include(${CMAKE_CURRENT_LIST_DIR}/breakout_roundlcd/micropython.cmake) | ||||
| include(${CMAKE_CURRENT_LIST_DIR}/breakout_rgbmatrix5x5/micropython.cmake) | ||||
| include(${CMAKE_CURRENT_LIST_DIR}/breakout_matrix11x7/micropython.cmake) | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Philip Howard
						Philip Howard