]> Chaos Git - corbenik/ctrulib.git/commitdiff
Add cam:u support and basic documentation.
authorSteven Smith <Steveice10@gmail.com>
Thu, 3 Sep 2015 06:22:45 +0000 (23:22 -0700)
committerSteven Smith <Steveice10@gmail.com>
Tue, 8 Sep 2015 23:26:56 +0000 (16:26 -0700)
libctru/include/3ds.h
libctru/include/3ds/services/cam.h [new file with mode: 0644]
libctru/source/services/cam.c [new file with mode: 0644]

index 301d782c39cf26d78b6ddb821e118b81b7239425..bfcf5429fd7f4c366dd0a5e5699fc0729938959b 100644 (file)
@@ -18,6 +18,7 @@ extern "C" {
 #include <3ds/services/ac.h>
 #include <3ds/services/am.h>
 #include <3ds/services/apt.h>
+#include <3ds/services/cam.h>
 #include <3ds/services/cfgnor.h>
 #include <3ds/services/cfgu.h>
 #include <3ds/services/csnd.h>
@@ -110,4 +111,4 @@ extern "C" {
  * @example threads/event/source/main.c
  * @example time/rtc/source/main.c
  */
\ No newline at end of file
diff --git a/libctru/include/3ds/services/cam.h b/libctru/include/3ds/services/cam.h
new file mode 100644 (file)
index 0000000..c0fde59
--- /dev/null
@@ -0,0 +1,570 @@
+/**
+ * @file cam.h
+ * @brief CAM service for using the 3DS's front and back cameras.
+ */
+#pragma once
+#include <3ds/services/y2r.h>
+#include <3ds/types.h>
+
+/**
+ * @brief Camera connection target ports.
+ */
+typedef enum {
+       PORT_NONE = 0x0,
+       PORT_CAM1 = BIT(0),
+       PORT_CAM2 = BIT(1),
+
+       // Port combinations.
+       PORT_BOTH = PORT_CAM1 | PORT_CAM2,
+} CAMU_Port;
+
+/**
+ * @brief Camera combinations.
+ */
+typedef enum {
+       SELECT_NONE = 0x0,
+       SELECT_OUT1 = BIT(0),
+       SELECT_IN1  = BIT(1),
+       SELECT_OUT2 = BIT(2),
+
+       // Camera combinations.
+       SELECT_IN1_OUT1  = SELECT_OUT1 | SELECT_IN1,
+       SELECT_OUT1_OUT2 = SELECT_OUT1 | SELECT_OUT2,
+       SELECT_IN1_OUT2  = SELECT_IN1 | SELECT_OUT2,
+       SELECT_ALL       = SELECT_OUT1 | SELECT_IN1 | SELECT_OUT2,
+} CAMU_CameraSelect;
+
+/**
+ * @brief Camera contexts.
+ */
+typedef enum {
+       CONTEXT_NONE = 0x0,
+       CONTEXT_A    = BIT(0),
+       CONTEXT_B    = BIT(1),
+
+       // Context combinations.
+       CONTEXT_BOTH = CONTEXT_A | CONTEXT_B,
+} CAMU_Context;
+
+/**
+ * @brief Ways to flip the camera image.
+ */
+typedef enum {
+       FLIP_NONE       = 0x0,
+       FLIP_HORIZONTAL = 0x1,
+       FLIP_VERTICAL   = 0x2,
+       FLIP_REVERSE    = 0x3,
+} CAMU_Flip;
+
+/**
+ * @brief Camera image resolutions.
+ */
+typedef enum {
+       SIZE_VGA         = 0x0,
+       SIZE_QVGA        = 0x1,
+       SIZE_QQVGA       = 0x2,
+       SIZE_CIF         = 0x3,
+       SIZE_QCIF        = 0x4,
+       SIZE_DS_LCD      = 0x5,
+       SIZE_DS_LCDx4    = 0x6,
+       SIZE_CTR_TOP_LCD = 0x7,
+
+       // Alias for bottom screen to match top screen naming.
+       SIZE_CTR_BOTTOM_LCD = SIZE_QVGA,
+} CAMU_Size;
+
+/**
+ * @brief Camera capture frame rates.
+ */
+typedef enum {
+       FRAME_RATE_15       = 0x0,
+       FRAME_RATE_15_TO_5  = 0x1,
+       FRAME_RATE_15_TO_2  = 0x2,
+       FRAME_RATE_10       = 0x3,
+       FRAME_RATE_8_5      = 0x4,
+       FRAME_RATE_5        = 0x5,
+       FRAME_RATE_20       = 0x6,
+       FRAME_RATE_20_TO_5  = 0x7,
+       FRAME_RATE_30       = 0x8,
+       FRAME_RATE_30_TO_5  = 0x9,
+       FRAME_RATE_15_TO_10 = 0xA,
+       FRAME_RATE_20_TO_10 = 0xB,
+       FRAME_RATE_30_TO_10 = 0xC,
+} CAMU_FrameRate;
+
+/**
+ * @brief Camera white balance modes.
+ */
+typedef enum {
+       WHITE_BALANCE_AUTO  = 0x0,
+       WHITE_BALANCE_3200K = 0x1,
+       WHITE_BALANCE_4150K = 0x2,
+       WHITE_BALANCE_5200K = 0x3,
+       WHITE_BALANCE_6000K = 0x4,
+       WHITE_BALANCE_7000K = 0x5,
+       WHITE_BALANCE_MAX   = 0x6,
+
+       // White balance aliases.
+       WHITE_BALANCE_NORMAL                  = WHITE_BALANCE_AUTO,
+       WHITE_BALANCE_TUNGSTEN                = WHITE_BALANCE_3200K,
+       WHITE_BALANCE_WHITE_FLUORESCENT_LIGHT = WHITE_BALANCE_4150K,
+       WHITE_BALANCE_DAYLIGHT                = WHITE_BALANCE_5200K,
+       WHITE_BALANCE_CLOUDY                  = WHITE_BALANCE_6000K,
+       WHITE_BALANCE_HORIZON                 = WHITE_BALANCE_6000K,
+       WHITE_BALANCE_SHADE                   = WHITE_BALANCE_7000K,
+} CAMU_WhiteBalance;
+
+/**
+ * @brief Camera photo modes.
+ */
+typedef enum {
+       PHOTO_MODE_NORMAL    = 0x0,
+       PHOTO_MODE_PORTRAIT  = 0x1,
+       PHOTO_MODE_LANDSCAPE = 0x2,
+       PHOTO_MODE_NIGHTVIEW = 0x3,
+       PHOTO_MODE_LETTER    = 0x4,
+} CAMU_PhotoMode;
+
+/**
+ * @brief Camera special effects.
+ */
+typedef enum {
+       EFFECT_NONE     = 0x0,
+       EFFECT_MONO     = 0x1,
+       EFFECT_SEPIA    = 0x2,
+       EFFECT_NEGATIVE = 0x3,
+       EFFECT_NEGAFILM = 0x4,
+       EFFECT_SEPIA01  = 0x5,
+} CAMU_Effect;
+
+/**
+ * @brief Camera contrast patterns.
+ */
+typedef enum {
+       CONTRAST_PATTERN_01 = 0x0,
+       CONTRAST_PATTERN_02 = 0x1,
+       CONTRAST_PATTERN_03 = 0x2,
+       CONTRAST_PATTERN_04 = 0x3,
+       CONTRAST_PATTERN_05 = 0x4,
+       CONTRAST_PATTERN_06 = 0x5,
+       CONTRAST_PATTERN_07 = 0x6,
+       CONTRAST_PATTERN_08 = 0x7,
+       CONTRAST_PATTERN_09 = 0x8,
+       CONTRAST_PATTERN_10 = 0x9,
+       CONTRAST_PATTERN_11 = 0xA,
+
+       // Contrast aliases.
+       CONTRAST_LOW    = CONTRAST_PATTERN_05,
+       CONTRAST_NORMAL = CONTRAST_PATTERN_06,
+       CONTRAST_HIGH   = CONTRAST_PATTERN_07,
+} CAMU_Contrast;
+
+/**
+ * @brief Camera lens correction modes.
+ */
+typedef enum {
+       LENS_CORRECTION_OFF   = 0x0,
+       LENS_CORRECTION_ON_70 = 0x1,
+       LENS_CORRECTION_ON_90 = 0x2,
+
+       // Lens correction aliases.
+       LENS_CORRECTION_DARK   = LENS_CORRECTION_OFF,
+       LENS_CORRECTION_NORMAL = LENS_CORRECTION_ON_70,
+       LENS_CORRECTION_BRIGHT = LENS_CORRECTION_ON_90,
+} CAMU_LensCorrection;
+
+/**
+ * @brief Camera image output formats.
+ */
+typedef enum {
+       OUTPUT_YUV_422 = 0x0,
+       OUTPUT_RGB_565 = 0x1,
+} CAMU_OutputFormat;
+
+/**
+ * @brief Camera shutter sounds.
+ */
+typedef enum {
+       SHUTTER_SOUND_TYPE_NORMAL    = 0x0,
+       SHUTTER_SOUND_TYPE_MOVIE     = 0x1,
+       SHUTTER_SOUND_TYPE_MOVIE_END = 0x2,
+} CAMU_ShutterSoundType;
+
+/**
+ * @brief Image quality calibration data.
+ */
+typedef struct {
+       s16 aeBaseTarget;   ///< Auto exposure base target brightness.
+       s16 kRL;            ///< Left color correction matrix red normalization coefficient.
+       s16 kGL;            ///< Left color correction matrix green normalization coefficient.
+       s16 kBL;            ///< Left color correction matrix blue normalization coefficient.
+       s16 ccmPosition;    ///< Color correction matrix position.
+       u16 awbCcmL9Right;  ///< Right camera, left color correction matrix red/green gain.
+       u16 awbCcmL9Left;   ///< Left camera, left color correction matrix red/green gain.
+       u16 awbCcmL10Right; ///< Right camera, left color correction matrix blue/green gain.
+       u16 awbCcmL10Left;  ///< Left camera, left color correction matrix blue/green gain.
+       u16 awbX0Right;     ///< Right camera, color correction matrix position threshold.
+       u16 awbX0Left;      ///< Left camera, color correction matrix position threshold.
+} CAMU_ImageQualityCalibrationData;
+
+/**
+ * @brief Stereo camera calibration data.
+ */
+typedef struct {
+       u8 isValidRotationXY;   ///< #bool Whether the X and Y rotation data is valid.
+       u8 padding[3];          ///< Padding. (Aligns isValidRotationXY to 4 bytes)
+       float scale;            ///< Scale to match the left camera image with the right.
+       float rotationZ;        ///< Z axis rotation to match the left camera image with the right.
+       float translationX;     ///< X axis translation to match the left camera image with the right.
+       float translationY;     ///< Y axis translation to match the left camera image with the right.
+       float rotationX;        ///< X axis rotation to match the left camera image with the right.
+       float rotationY;        ///< Y axis rotation to match the left camera image with the right.
+       float angleOfViewRight; ///< Right camera angle of view.
+       float angleOfViewLeft;  ///< Left camera angle of view.
+       float distanceToChart;  ///< Distance between cameras and measurement chart.
+       float distanceCameras;  ///< Distance between left and right cameras.
+       s16 imageWidth;         ///< Image width.
+       s16 imageHeight;        ///< Image height.
+       u8 reserved[16];        ///< Reserved for future use. (unused)
+} CAMU_StereoCameraCalibrationData;
+
+/**
+ * @brief Batch camera configuration for use without a context.
+ */
+typedef struct {
+       u8 camera;                        ///< #CAMU_CameraSelect Selected camera.
+       s8 exposure;                      ///< Camera exposure.
+       u8 whiteBalance;                  ///< #CAMU_WhiteBalance Camera white balance.
+       s8 sharpness;                     ///< Camera sharpness.
+       u8 autoExposureOn;                ///< #bool Whether to automatically determine the proper exposure.
+       u8 autoWhiteBalanceOn;            ///< #bool Whether to automatically determine the white balance mode.
+       u8 frameRate;                     ///< #CAMU_FrameRate Camera frame rate.
+       u8 photoMode;                     ///< #CAMU_PhotoMode Camera photo mode.
+       u8 contrast;                      ///< #CAMU_Contrast Camera contrast.
+       u8 lensCorrection;                ///< #CAMU_LensCorrection Camera lens correction.
+       u8 noiseFilterOn;                 ///< #bool Whether to enable the camera's noise filter.
+       u8 padding;                       ///< Padding. (Aligns last 3 fields to 4 bytes)
+       s16 autoExposureWindowX;          ///< X of the region to use for auto exposure.
+       s16 autoExposureWindowY;          ///< Y of the region to use for auto exposure.
+       s16 autoExposureWindowWidth;      ///< Width of the region to use for auto exposure.
+       s16 autoExposureWindowHeight;     ///< Height of the region to use for auto exposure.
+       s16 autoWhiteBalanceWindowX;      ///< X of the region to use for auto white balance.
+       s16 autoWhiteBalanceWindowY;      ///< Y of the region to use for auto white balance.
+       s16 autoWhiteBalanceWindowWidth;  ///< Width of the region to use for auto white balance.
+       s16 autoWhiteBalanceWindowHeight; ///< Height of the region to use for auto white balance.
+} CAMU_PackageParameterCameraSelect;
+
+/**
+ * @brief Batch camera configuration for use with a context.
+ */
+typedef struct {
+       u8 camera;  ///< #CAMU_CameraSelect Selected camera.
+       u8 context; ///< #CAMU_Context Selected context.
+       u8 flip;    ///< #CAMU_Flip Camera image flip mode.
+       u8 effect;  ///< #CAMU_Effect Camera image special effects.
+       u8 size;    ///< #CAMU_Size Camera image resolution.
+} CAMU_PackageParameterContext;
+
+/**
+ * @brief Batch camera configuration for use with a context and with detailed size information.
+ */
+typedef struct {
+       u8 camera;  ///< #CAMU_CameraSelect Selected camera.
+       u8 context; ///< #CAMU_Context Selected context.
+       u8 flip;    ///< #CAMU_Flip Camera image flip mode.
+       u8 effect;  ///< #CAMU_Effect Camera image special effects.
+       s16 width;  ///< Image width.
+       s16 height; ///< Image height.
+       s16 cropX0; ///< First crop point X.
+       s16 cropY0; ///< First crop point Y.
+       s16 cropX1; ///< Second crop point X.
+       s16 cropY1; ///< Second crop point Y.
+} CAMU_PackageParameterContextDetail;
+
+/**
+ * @brief Initializes the cam service.
+ *
+ * This will internally get the handle of the service, and on success call CAMU_DriverInitialize.
+ */
+Result camInit();
+
+/**
+ * @brief Closes the cam service.
+ *
+ * This will internally call CAMU_DriverFinalize and close the handle of the service.
+ */
+Result camExit();
+
+/// Begins capture on the specified camera port.
+Result CAMU_StartCapture(CAMU_Port port);
+
+///Terminates capture on the specified camera port.
+Result CAMU_StopCapture(CAMU_Port port);
+
+/**
+ * @brief Gets whether the specified camera port is busy.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_IsBusy(bool* busy, CAMU_Port port);
+
+///Clears the buffer and error flags of the specified camera port.
+Result CAMU_ClearBuffer(CAMU_Port port);
+
+/**
+ * @brief Gets a handle to the event signaled on vsync interrupts.
+ *
+ * Writes the event handle to the provided output pointer.
+ */
+Result CAMU_GetVsyncInterruptEvent(Handle* event, CAMU_Port port);
+
+/**
+ * @brief Gets a handle to the event signaled on camera buffer errors.
+ *
+ * Writes the event handle to the provided output pointer.
+ */
+Result CAMU_GetBufferErrorInterruptEvent(Handle* event, CAMU_Port port);
+
+/**
+ * @brief Initiates the process of receiving a camera frame.
+ *
+ * Writes a completion event handle to the provided pointer and writes image data to the provided buffer.
+ */
+Result CAMU_SetReceiving(Handle* event, void* dst, CAMU_Port port, u32 imageSize, s16 transferUnit);
+
+/**
+ * @brief Gets whether the specified camera port has finished receiving image data.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_IsFinishedReceiving(bool* finishedReceiving, CAMU_Port port);
+
+///Sets the number of lines to transfer into an image buffer.
+Result CAMU_SetTransferLines(CAMU_Port port, s16 lines, s16 width, s16 height);
+
+/**
+ * @brief Gets the maximum number of lines that can be saved to an image buffer.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_GetMaxLines(s16* maxLines, s16 width, s16 height);
+
+///Sets the number of bytes to transfer into an image buffer.
+Result CAMU_SetTransferBytes(CAMU_Port port, u32 bytes, s16 width, s16 height);
+
+/**
+ * @brief Gets the number of bytes to transfer into an image buffer.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_GetTransferBytes(u32* transferBytes, CAMU_Port port);
+
+/**
+ * @brief Gets the maximum number of bytes that can be saved to an image buffer.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_GetMaxBytes(u32* maxBytes, s16 width, s16 height);
+
+///Sets whether image trimming is enabled.
+Result CAMU_SetTrimming(CAMU_Port port, bool trimming);
+
+/**
+ * @brief Gets whether image trimming is enabled.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_IsTrimming(bool* trimming, CAMU_Port port);
+
+///Sets the parameters used for trimming images.
+Result CAMU_SetTrimmingParams(CAMU_Port port, s16 xStart, s16 yStart, s16 xEnd, s16 yEnd);
+
+/**
+ * @brief Gets the parameters used for trimming images.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_GetTrimmingParams(s16* xStart, s16* yStart, s16* xEnd, s16* yEnd, CAMU_Port port);
+
+///Sets the parameters used for trimming images, relative to the center of the image.
+Result CAMU_SetTrimmingParamsCenter(CAMU_Port port, s16 trimWidth, s16 trimHeight, s16 camWidth, s16 camHeight);
+
+///Activates the specified camera.
+Result CAMU_Activate(CAMU_CameraSelect select);
+
+///Switches the specified camera's active context.
+Result CAMU_SwitchContext(CAMU_CameraSelect select, CAMU_Context context);
+
+///Sets the exposure value of the specified camera.
+Result CAMU_SetExposure(CAMU_CameraSelect select, s8 exposure);
+
+///Sets the white balance mode of the specified camera.
+Result CAMU_SetWhiteBalance(CAMU_CameraSelect select, CAMU_WhiteBalance whiteBalance);
+
+/**
+ * @brief Sets the white balance mode of the specified camera.
+ *
+ * TODO: Explain "without base up"?
+ */
+Result CAMU_SetWhiteBalanceWithoutBaseUp(CAMU_CameraSelect select, CAMU_WhiteBalance whiteBalance);
+
+///Sets the sharpness of the specified camera.
+Result CAMU_SetSharpness(CAMU_CameraSelect select, s8 sharpness);
+
+///Sets whether auto exposure is enabled on the specified camera.
+Result CAMU_SetAutoExposure(CAMU_CameraSelect select, bool autoExposure);
+
+/**
+ * @brief Gets whether auto exposure is enabled on the specified camera.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_IsAutoExposure(bool* autoExposure, CAMU_CameraSelect select);
+
+///Sets whether auto white balance is enabled on the specified camera.
+Result CAMU_SetAutoWhiteBalance(CAMU_CameraSelect select, bool autoWhiteBalance);
+
+/**
+ * @brief Gets whether auto white balance is enabled on the specified camera.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_IsAutoWhiteBalance(bool* autoWhiteBalance, CAMU_CameraSelect select);
+
+///Flips the image of the specified camera in the specified context.
+Result CAMU_FlipImage(CAMU_CameraSelect select, CAMU_Flip flip, CAMU_Context context);
+
+///Sets the image resolution of the given camera in the given context, in detail.
+Result CAMU_SetDetailSize(CAMU_CameraSelect select, s16 width, s16 height, s16 cropX0, s16 cropY0, s16 cropX1, s16 cropY1, CAMU_Context context);
+
+///Sets the image resolution of the given camera in the given context.
+Result CAMU_SetSize(CAMU_CameraSelect select, CAMU_Size size, CAMU_Context context);
+
+///Sets the frame rate of the given camera.
+Result CAMU_SetFrameRate(CAMU_CameraSelect select, CAMU_FrameRate frameRate);
+
+///Sets the photo mode of the given camera.
+Result CAMU_SetPhotoMode(CAMU_CameraSelect select, CAMU_PhotoMode photoMode);
+
+///Sets the special effects of the given camera in the given context.
+Result CAMU_SetEffect(CAMU_CameraSelect select, CAMU_Effect effect, CAMU_Context context);
+
+///Sets the contrast mode of the given camera.
+Result CAMU_SetContrast(CAMU_CameraSelect select, CAMU_Contrast contrast);
+
+///Sets the lens correction mode of the given camera.
+Result CAMU_SetLensCorrection(CAMU_CameraSelect select, CAMU_LensCorrection lensCorrection);
+
+///Sets the output format of the given camera in the given context.
+Result CAMU_SetOutputFormat(CAMU_CameraSelect select, CAMU_OutputFormat format, CAMU_Context context);
+
+///Sets the region to base auto exposure off of for the specified camera.
+Result CAMU_SetAutoExposureWindow(CAMU_CameraSelect select, s16 x, s16 y, s16 width, s16 height);
+
+///Sets the region to base auto white balance off of for the specified camera.
+Result CAMU_SetAutoWhiteBalanceWindow(CAMU_CameraSelect select, s16 x, s16 y, s16 width, s16 height);
+
+///Sets whether the specified camera's noise filter is enabled.
+Result CAMU_SetNoiseFilter(CAMU_CameraSelect select, bool noiseFilter);
+
+///Synchronizes the specified cameras' vsync timing.
+Result CAMU_SynchronizeVsyncTiming(CAMU_CameraSelect select1, CAMU_CameraSelect select2);
+
+/**
+ * @brief Gets the vsync timing record of the specified camera for the specified number of signals.
+ *
+ * Writes the result to the provided output pointer, which should be of size "past * sizeof(s64)".
+ */
+Result CAMU_GetLatestVsyncTiming(s64* timing, CAMU_Port port, u32 past);
+
+/**
+ * @brief Gets the specified camera's stereo camera calibration data.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_GetStereoCameraCalibrationData(CAMU_StereoCameraCalibrationData* data);
+
+///Sets the specified camera's stereo camera calibration data.
+Result CAMU_SetStereoCameraCalibrationData(CAMU_StereoCameraCalibrationData data);
+
+/**
+ * @brief Writes to the specified I2C register of the specified camera.
+ *
+ * Use with caution.
+ */
+Result CAMU_WriteRegisterI2c(CAMU_CameraSelect select, u16 addr, u16 data);
+
+/**
+ * @brief Writes to the specified MCU variable of the specified camera.
+ *
+ * Use with caution.
+ */
+Result CAMU_WriteMcuVariableI2c(CAMU_CameraSelect select, u16 addr, u16 data);
+
+/**
+ * @brief Reads the specified I2C register of the specified camera.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_ReadRegisterI2cExclusive(u16* data, CAMU_CameraSelect select, u16 addr);
+
+/**
+ * @brief Reads the specified MCU variable of the specified camera.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_ReadMcuVariableI2cExclusive(u16* data, CAMU_CameraSelect select, u16 addr);
+
+/**
+ * @brief Sets the specified camera's image quality calibration data.
+ */
+Result CAMU_SetImageQualityCalibrationData(CAMU_ImageQualityCalibrationData data);
+
+/**
+ * @brief Gets the specified camera's image quality calibration data.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_GetImageQualityCalibrationData(CAMU_ImageQualityCalibrationData* data);
+
+///Configures a camera with pre-packaged configuration data without a context.
+Result CAMU_SetPackageParameterWithoutContext(CAMU_PackageParameterCameraSelect param);
+
+///Configures a camera with pre-packaged configuration data with a context.
+Result CAMU_SetPackageParameterWithContext(CAMU_PackageParameterContext param);
+
+///Configures a camera with pre-packaged configuration data without a context and extra resolution details.
+Result CAMU_SetPackageParameterWithContextDetail(CAMU_PackageParameterContextDetail param);
+
+///Gets the Y2R coefficient applied to image data by the camera.
+Result CAMU_GetSuitableY2rStandardCoefficient(Y2R_StandardCoefficient* coefficient);
+
+///Plays the specified shutter sound.
+Result CAMU_PlayShutterSound(CAMU_ShutterSoundType sound);
+
+///Initializes the camera driver.
+Result CAMU_DriverInitialize();
+
+///Finalizes the camera driver.
+Result CAMU_DriverFinalize();
+
+/**
+ * @brief Gets the current activated camera.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_GetActivatedCamera(CAMU_CameraSelect* select);
+
+/**
+ * @brief Gets the current sleep camera.
+ *
+ * Writes the result to the provided output pointer.
+ */
+Result CAMU_GetSleepCamera(CAMU_CameraSelect* select);
+
+///Sets the current sleep camera.
+Result CAMU_SetSleepCamera(CAMU_CameraSelect select);
+
+///Sets whether to enable synchronization of left and right camera brightnesses.
+Result CAMU_SetBrightnessSynchronization(bool brightnessSynchronization);
+
diff --git a/libctru/source/services/cam.c b/libctru/source/services/cam.c
new file mode 100644 (file)
index 0000000..ea1ffc5
--- /dev/null
@@ -0,0 +1,738 @@
+#include <3ds/services/cam.h>
+#include <3ds/services/y2r.h>
+#include <3ds/srv.h>
+#include <3ds/svc.h>
+#include <3ds/types.h>
+
+Handle camHandle;
+static bool initialized = false;
+
+Result camInit() {
+       Result ret = 0;
+
+       if (initialized) return 0;
+
+       if (camHandle == 0)
+       {
+               ret = srvGetServiceHandle(&camHandle, "cam:u");
+               if (ret < 0) return ret;
+       }
+
+       ret = CAMU_DriverInitialize();
+       if (ret < 0) return ret;
+       initialized = true;
+
+       return 0;
+}
+
+Result camExit() {
+       Result ret = 0;
+
+       if (initialized)
+       {
+               ret = CAMU_DriverFinalize();
+               if (ret < 0) return ret;
+       }
+
+       if (camHandle != 0)
+       {
+               ret = svcCloseHandle(camHandle);
+               if (ret < 0) return ret;
+               camHandle = 0;
+       }
+
+       return 0;
+}
+
+Result CAMU_StartCapture(CAMU_Port port) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00010040;
+       cmdbuf[1] = port;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_StopCapture(CAMU_Port port) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00020040;
+       cmdbuf[1] = port;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_IsBusy(bool* busy, CAMU_Port port) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00030040;
+       cmdbuf[1] = port;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *busy = (bool) cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_ClearBuffer(CAMU_Port port) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00040040;
+       cmdbuf[1] = port;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_GetVsyncInterruptEvent(Handle* event, CAMU_Port port) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00050040;
+       cmdbuf[1] = port;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *event = cmdbuf[3];
+       return cmdbuf[1];
+}
+
+Result CAMU_GetBufferErrorInterruptEvent(Handle* event, CAMU_Port port) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00060040;
+       cmdbuf[1] = port;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *event = cmdbuf[3];
+       return cmdbuf[1];
+}
+
+Result CAMU_SetReceiving(Handle* event, void* dst, CAMU_Port port, u32 imageSize, s16 transferUnit) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00070102;
+       cmdbuf[1] = (u32) dst;
+       cmdbuf[2] = port;
+       cmdbuf[3] = imageSize;
+       cmdbuf[4] = transferUnit;
+       cmdbuf[5] = 0;
+       cmdbuf[6] = 0xFFFF8001;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *event = cmdbuf[3];
+       return cmdbuf[1];
+}
+
+Result CAMU_IsFinishedReceiving(bool* finishedReceiving, CAMU_Port port) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00080040;
+       cmdbuf[1] = port;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *finishedReceiving = (bool) cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_SetTransferLines(CAMU_Port port, s16 lines, s16 width, s16 height) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00090100;
+       cmdbuf[1] = port;
+       cmdbuf[2] = lines;
+       cmdbuf[3] = width;
+       cmdbuf[4] = height;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_GetMaxLines(s16* maxLines, s16 width, s16 height) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x000A0080;
+       cmdbuf[1] = width;
+       cmdbuf[2] = height;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *maxLines = (s16) cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_SetTransferBytes(CAMU_Port port, u32 bytes, s16 width, s16 height) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x000B0100;
+       cmdbuf[1] = port;
+       cmdbuf[2] = bytes;
+       cmdbuf[3] = width;
+       cmdbuf[4] = height;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_GetTransferBytes(u32* transferBytes, CAMU_Port port) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x000C0040;
+       cmdbuf[1] = port;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *transferBytes = cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_GetMaxBytes(u32* maxBytes, s16 width, s16 height) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x000D0080;
+       cmdbuf[1] = width;
+       cmdbuf[2] = height;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *maxBytes = cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_SetTrimming(CAMU_Port port, bool trimming) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x000E0080;
+       cmdbuf[1] = port;
+       cmdbuf[2] = trimming;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_IsTrimming(bool* trimming, CAMU_Port port) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x000F0040;
+       cmdbuf[1] = port;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *trimming = (bool) cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_SetTrimmingParams(CAMU_Port port, s16 xStart, s16 yStart, s16 xEnd, s16 yEnd) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00100140;
+       cmdbuf[1] = port;
+       cmdbuf[2] = xStart;
+       cmdbuf[3] = yStart;
+       cmdbuf[4] = xEnd;
+       cmdbuf[5] = yEnd;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_GetTrimmingParams(s16* xStart, s16* yStart, s16* xEnd, s16* yEnd, CAMU_Port port) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00110040;
+       cmdbuf[1] = port;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *xStart = (s16) cmdbuf[2];
+       *yStart = (s16) cmdbuf[3];
+       *xEnd = (s16) cmdbuf[4];
+       *yEnd = (s16) cmdbuf[5];
+       return cmdbuf[1];
+}
+
+Result CAMU_SetTrimmingParamsCenter(CAMU_Port port, s16 trimWidth, s16 trimHeight, s16 camWidth, s16 camHeight) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00120140;
+       cmdbuf[1] = port;
+       cmdbuf[2] = trimWidth;
+       cmdbuf[3] = trimHeight;
+       cmdbuf[4] = camWidth;
+       cmdbuf[5] = camHeight;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_Activate(CAMU_CameraSelect select) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00130040;
+       cmdbuf[1] = select;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SwitchContext(CAMU_CameraSelect select, CAMU_Context context) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00140080;
+       cmdbuf[1] = select;
+       cmdbuf[2] = context;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetExposure(CAMU_CameraSelect select, s8 exposure) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00150080;
+       cmdbuf[1] = select;
+       cmdbuf[2] = exposure;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetWhiteBalance(CAMU_CameraSelect select, CAMU_WhiteBalance whiteBalance) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00160080;
+       cmdbuf[1] = select;
+       cmdbuf[2] = whiteBalance;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetWhiteBalanceWithoutBaseUp(CAMU_CameraSelect select, CAMU_WhiteBalance whiteBalance) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00170080;
+       cmdbuf[1] = select;
+       cmdbuf[2] = whiteBalance;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetSharpness(CAMU_CameraSelect select, s8 sharpness) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00180080;
+       cmdbuf[1] = select;
+       cmdbuf[2] = sharpness;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetAutoExposure(CAMU_CameraSelect select, bool autoExposure) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00190080;
+       cmdbuf[1] = select;
+       cmdbuf[2] = autoExposure;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_IsAutoExposure(bool* autoExposure, CAMU_CameraSelect select) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x001A0040;
+       cmdbuf[1] = select;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *autoExposure = (bool) cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_SetAutoWhiteBalance(CAMU_CameraSelect select, bool autoWhiteBalance) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x001B0080;
+       cmdbuf[1] = select;
+       cmdbuf[2] = autoWhiteBalance;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_IsAutoWhiteBalance(bool* autoWhiteBalance, CAMU_CameraSelect select) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x001C0040;
+       cmdbuf[1] = select;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *autoWhiteBalance = (bool) cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_FlipImage(CAMU_CameraSelect select, CAMU_Flip flip, CAMU_Context context) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x001D00C0;
+       cmdbuf[1] = select;
+       cmdbuf[2] = flip;
+       cmdbuf[3] = context;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetDetailSize(CAMU_CameraSelect select, s16 width, s16 height, s16 cropX0, s16 cropY0, s16 cropX1, s16 cropY1, CAMU_Context context) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x001E0200;
+       cmdbuf[1] = select;
+       cmdbuf[2] = width;
+       cmdbuf[3] = height;
+       cmdbuf[4] = cropX0;
+       cmdbuf[5] = cropY0;
+       cmdbuf[6] = cropX1;
+       cmdbuf[7] = cropY1;
+       cmdbuf[8] = context;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetSize(CAMU_CameraSelect select, CAMU_Size size, CAMU_Context context) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x001F00C0;
+       cmdbuf[1] = select;
+       cmdbuf[2] = size;
+       cmdbuf[3] = context;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetFrameRate(CAMU_CameraSelect select, CAMU_FrameRate frameRate) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00200080;
+       cmdbuf[1] = select;
+       cmdbuf[2] = frameRate;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetPhotoMode(CAMU_CameraSelect select, CAMU_PhotoMode photoMode) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00210080;
+       cmdbuf[1] = select;
+       cmdbuf[2] = photoMode;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetEffect(CAMU_CameraSelect select, CAMU_Effect effect, CAMU_Context context) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x002200C0;
+       cmdbuf[1] = select;
+       cmdbuf[2] = effect;
+       cmdbuf[3] = context;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetContrast(CAMU_CameraSelect select, CAMU_Contrast contrast) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00230080;
+       cmdbuf[1] = select;
+       cmdbuf[2] = contrast;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetLensCorrection(CAMU_CameraSelect select, CAMU_LensCorrection lensCorrection) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00240080;
+       cmdbuf[1] = select;
+       cmdbuf[2] = lensCorrection;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetOutputFormat(CAMU_CameraSelect select, CAMU_OutputFormat format, CAMU_Context context) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x002500C0;
+       cmdbuf[1] = select;
+       cmdbuf[2] = format;
+       cmdbuf[3] = context;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetAutoExposureWindow(CAMU_CameraSelect select, s16 x, s16 y, s16 width, s16 height) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00260140;
+       cmdbuf[1] = select;
+       cmdbuf[2] = x;
+       cmdbuf[3] = y;
+       cmdbuf[4] = width;
+       cmdbuf[5] = height;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetAutoWhiteBalanceWindow(CAMU_CameraSelect select, s16 x, s16 y, s16 width, s16 height) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00270140;
+       cmdbuf[1] = select;
+       cmdbuf[2] = x;
+       cmdbuf[3] = y;
+       cmdbuf[4] = width;
+       cmdbuf[5] = height;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetNoiseFilter(CAMU_CameraSelect select, bool noiseFilter) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00280080;
+       cmdbuf[1] = select;
+       cmdbuf[2] = noiseFilter;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SynchronizeVsyncTiming(CAMU_CameraSelect select1, CAMU_CameraSelect select2) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00290080;
+       cmdbuf[1] = select1;
+       cmdbuf[2] = select2;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_GetLatestVsyncTiming(s64* timing, CAMU_Port port, u32 past) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x002A0080;
+       cmdbuf[1] = port;
+       cmdbuf[2] = past;
+       cmdbuf[49] = (past << 17) | 2;
+       cmdbuf[50] = (u32) timing;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_GetStereoCameraCalibrationData(CAMU_StereoCameraCalibrationData* data) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x002B0000;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *data = *(CAMU_StereoCameraCalibrationData*) cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_SetStereoCameraCalibrationData(CAMU_StereoCameraCalibrationData data) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x002C0400;
+       *(CAMU_StereoCameraCalibrationData*) cmdbuf[1] = data;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_WriteRegisterI2c(CAMU_CameraSelect select, u16 addr, u16 data) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x002D00C0;
+       cmdbuf[1] = select;
+       cmdbuf[2] = addr;
+       cmdbuf[3] = data;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_WriteMcuVariableI2c(CAMU_CameraSelect select, u16 addr, u16 data) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x002E00C0;
+       cmdbuf[1] = select;
+       cmdbuf[2] = addr;
+       cmdbuf[3] = data;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_ReadRegisterI2cExclusive(u16* data, CAMU_CameraSelect select, u16 addr) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x002F0080;
+       cmdbuf[1] = select;
+       cmdbuf[2] = addr;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *data = (u16) cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_ReadMcuVariableI2cExclusive(u16* data, CAMU_CameraSelect select, u16 addr) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00300080;
+       cmdbuf[1] = select;
+       cmdbuf[2] = addr;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *data = (u16) cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_SetImageQualityCalibrationData(CAMU_ImageQualityCalibrationData data) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00310180;
+       *(CAMU_ImageQualityCalibrationData*) cmdbuf[1] = data;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_GetImageQualityCalibrationData(CAMU_ImageQualityCalibrationData* data) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00320000;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *data = *(CAMU_ImageQualityCalibrationData*) cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_SetPackageParameterWithoutContext(CAMU_PackageParameterCameraSelect param) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x003302C0;
+       *(CAMU_PackageParameterCameraSelect*) cmdbuf[1] = param;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetPackageParameterWithContext(CAMU_PackageParameterContext param) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00340140;
+       *(CAMU_PackageParameterContext*) cmdbuf[1] = param;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetPackageParameterWithContextDetail(CAMU_PackageParameterContextDetail param) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x003501C0;
+       *(CAMU_PackageParameterContextDetail*) cmdbuf[1] = param;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_GetSuitableY2rStandardCoefficient(Y2R_StandardCoefficient* coefficient) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00360000;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *coefficient = (Y2R_StandardCoefficient) cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_PlayShutterSound(CAMU_ShutterSoundType sound) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00380040;
+       cmdbuf[1] = sound;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_DriverInitialize() {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x00390000;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_DriverFinalize() {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x003A0000;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_GetActivatedCamera(CAMU_CameraSelect* select) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x003B0000;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *select = (CAMU_CameraSelect) cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_GetSleepCamera(CAMU_CameraSelect* select) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x003C0000;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       *select = (CAMU_CameraSelect) cmdbuf[2];
+       return cmdbuf[1];
+}
+
+Result CAMU_SetSleepCamera(CAMU_CameraSelect select) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x003D0040;
+       cmdbuf[1] = select;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+
+Result CAMU_SetBrightnessSynchronization(bool brightnessSynchronization) {
+       Result ret = 0;
+       u32* cmdbuf = getThreadCommandBuffer();
+       cmdbuf[0] = 0x003E0040;
+       cmdbuf[1] = brightnessSynchronization;
+
+       if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
+       return cmdbuf[1];
+}
+