ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
cam_image.c
Go to the documentation of this file.
1
15
16#include "cam_image.h"
17
18#include <stdint.h>
19
20#include "ra8_cache.h"
21#include "ra8_check.h"
22
24typedef enum : uint32_t {
27
40
42typedef struct {
43 uint8_t red;
44 uint8_t green;
45 uint8_t blue;
46} cam_rgb_t;
47
48[[gnu::section(".sdram_data"), gnu::aligned(k_cam_image_cache_line_bytes)]]
50[[gnu::section(".sdram_data"), gnu::aligned(k_cam_image_cache_line_bytes)]]
52[[gnu::section(".sdram_data"), gnu::aligned(k_cam_image_cache_line_bytes)]]
54[[gnu::section(".sdram_data"), gnu::aligned(k_cam_image_cache_line_bytes)]]
56
58
73static uint8_t cam_image_clamp(int32_t component)
74{
75 if (component < 0) {
76 return 0U;
77 }
78 if (component > (int32_t)UINT8_MAX) {
79 return UINT8_MAX;
80 }
81 return (uint8_t)component;
82}
83
99static cam_rgb_t cam_image_ycbcr_to_rgb(uint8_t y, uint8_t cb, uint8_t cr)
100{
101 int32_t luma = (int32_t)y - (int32_t)k_cam_yuv_luma_black;
102 if (luma < 0) {
103 luma = 0;
104 }
105 const int32_t blue_delta = (int32_t)cb - (int32_t)k_cam_yuv_chroma_mid;
106 const int32_t red_delta = (int32_t)cr - (int32_t)k_cam_yuv_chroma_mid;
107 const cam_rgb_t rgb = {
108 .red = cam_image_clamp(((int32_t)k_cam_yuv_luma_scale * luma +
109 (int32_t)k_cam_yuv_red_cr * red_delta + (int32_t)k_cam_yuv_rounding) >>
110 (int32_t)k_cam_yuv_shift),
111 .green = cam_image_clamp(
112 ((int32_t)k_cam_yuv_luma_scale * luma - (int32_t)k_cam_yuv_green_cb * blue_delta -
113 (int32_t)k_cam_yuv_green_cr * red_delta + (int32_t)k_cam_yuv_rounding) >>
114 (int32_t)k_cam_yuv_shift),
115 .blue =
116 cam_image_clamp(((int32_t)k_cam_yuv_luma_scale * luma +
117 (int32_t)k_cam_yuv_blue_cb * blue_delta + (int32_t)k_cam_yuv_rounding) >>
118 (int32_t)k_cam_yuv_shift),
119 };
120 return rgb;
121}
122
136static void cam_image_scatter(uint32_t x, uint32_t y, cam_rgb_t rgb)
137{
138 const uint32_t width = (uint32_t)k_cam_image_width_px;
139 const uint32_t height = (uint32_t)k_cam_image_height_px;
140 const uint32_t idx_0 = ((y * width) + x) * (uint32_t)k_cam_rgb_bytes_per_px;
141 const uint32_t idx_90 = ((x * height) + (height - 1U - y)) * (uint32_t)k_cam_rgb_bytes_per_px;
142 const uint32_t idx_180 =
143 (((height - 1U - y) * width) + (width - 1U - x)) * (uint32_t)k_cam_rgb_bytes_per_px;
144 const uint32_t idx_270 = (((width - 1U - x) * height) + y) * (uint32_t)k_cam_rgb_bytes_per_px;
145 uint8_t* const outputs[4] = {
146 &g_cam_rgb_0[idx_0],
147 &g_cam_rgb_90[idx_90],
148 &g_cam_rgb_180[idx_180],
149 &g_cam_rgb_270[idx_270],
150 };
151 for (uint32_t output = 0U; output < 4U; output += 1U) {
152 outputs[output][0] = rgb.red;
153 outputs[output][1] = rgb.green;
154 outputs[output][2] = rgb.blue;
155 }
156}
157
167static void cam_image_convert(const uint8_t* uyvy)
168{
169 const uint32_t width = (uint32_t)k_cam_image_width_px;
170 const uint32_t height = (uint32_t)k_cam_image_height_px;
171 for (uint32_t y = 0U; y < height; y += 1U) {
172 for (uint32_t x = 0U; x < width; x += 2U) {
173 const uint32_t source = ((y * width) + x) * 2U;
174 const uint8_t cb = uyvy[source];
175 const uint8_t y0 = uyvy[source + 1U];
176 const uint8_t cr = uyvy[source + 2U];
177 const uint8_t y1 = uyvy[source + 3U];
178 cam_image_scatter(x, y, cam_image_ycbcr_to_rgb(y0, cb, cr));
179 cam_image_scatter(x + 1U, y, cam_image_ycbcr_to_rgb(y1, cb, cr));
180 }
181 }
182}
183
195{
197 "cam_image",
198 "clean rgb0");
200 "cam_image",
201 "clean rgb90");
204 "cam_image",
205 "clean rgb180");
207}
208
209ra8_err_t cam_image_generate(const uint8_t* uyvy, uint32_t source_bytes)
210{
211 RA8_CHECK_NULL_PTR(uyvy, "cam_image", "uyvy");
212 if (source_bytes != (uint32_t)k_cam_uyvy_frame_bytes) {
214 }
215 cam_image_convert(uyvy);
217}
cam_image_yuv_coeff_t
BT.601 limited-range fixed-point YCbCr-to-RGB coefficients.
Definition cam_image.c:29
@ k_cam_yuv_red_cr
BT.601 red-from-Cr coefficient.
Definition cam_image.c:33
@ k_cam_yuv_blue_cb
BT.601 blue-from-Cb coefficient.
Definition cam_image.c:36
@ k_cam_yuv_luma_scale
BT.601 fixed-point luma coefficient.
Definition cam_image.c:32
@ k_cam_yuv_luma_black
Limited-range black luma code.
Definition cam_image.c:30
@ k_cam_yuv_chroma_mid
Neutral limited-range chroma code.
Definition cam_image.c:31
@ k_cam_yuv_shift
Fixed-point fractional-bit count.
Definition cam_image.c:38
@ k_cam_yuv_green_cb
BT.601 green-from-Cb coefficient.
Definition cam_image.c:34
@ k_cam_yuv_green_cr
BT.601 green-from-Cr coefficient.
Definition cam_image.c:35
@ k_cam_yuv_rounding
Fixed-point rounding bias.
Definition cam_image.c:37
ra8_err_t cam_image_generate(const uint8_t *uyvy, uint32_t source_bytes)
Convert one packed Cb-Y0-Cr-Y1 VGA frame into all four RGB views.
Definition cam_image.c:209
static void cam_image_convert(const uint8_t *uyvy)
Convert one complete UYVY frame into all four RGB orientations.
Definition cam_image.c:167
static ra8_err_t cam_image_clean_outputs(void)
Clean all generated RGB views from the data cache.
Definition cam_image.c:194
static void cam_image_scatter(uint32_t x, uint32_t y, cam_rgb_t rgb)
Write one RGB pixel to all four rotated row-major destinations.
Definition cam_image.c:136
static uint8_t cam_image_clamp(int32_t component)
Clamp a signed RGB component to one byte.
Definition cam_image.c:73
cam_image_align_t
Cache-line alignment shared by the SDRAM buffers and cache API.
Definition cam_image.c:24
@ k_cam_image_cache_line_bytes
Cortex-M85 data-cache line size.
Definition cam_image.c:25
static cam_rgb_t cam_image_ycbcr_to_rgb(uint8_t y, uint8_t cb, uint8_t cr)
Convert one limited-range YCbCr pixel to RGB888.
Definition cam_image.c:99
SDRAM-backed RGB888 views of one packed VGA UYVY camera frame.
@ k_cam_uyvy_frame_bytes
640 x 480 x 2-byte packed UYVY input.
Definition cam_image.h:29
@ k_cam_image_height_px
Unrotated and 180-degree height.
Definition cam_image.h:28
@ k_cam_image_width_px
Unrotated and 180-degree width.
Definition cam_image.h:27
@ k_cam_rgb_frame_bytes
640 x 480 x 3 bytes.
Definition cam_image.h:31
@ k_cam_rgb_bytes_per_px
RGB888 bytes per output pixel.
Definition cam_image.h:30
const uint32_t g_cam_rgb_frame_bytes
Stable byte count of each exported RGB888 buffer.
Definition cam_image.c:57
uint8_t g_cam_rgb_180[k_cam_rgb_frame_bytes]
Clockwise-180-degree 640x480 RGB888 image in external SDRAM.
Definition cam_image.c:53
uint8_t g_cam_rgb_90[k_cam_rgb_frame_bytes]
Clockwise-90-degree 480x640 RGB888 image in external SDRAM.
Definition cam_image.c:51
uint8_t g_cam_rgb_0[k_cam_rgb_frame_bytes]
Unrotated 640x480 RGB888 image in external SDRAM.
Definition cam_image.c:49
uint8_t g_cam_rgb_270[k_cam_rgb_frame_bytes]
Clockwise-270-degree 480x640 RGB888 image in external SDRAM.
Definition cam_image.c:55
Cortex-M85 L1 cache maintenance, enable/disable, and I-cache invalidate.
ra8_err_t ra8_cache_dcache_clean_by_addr(const void *addr, uint32_t size)
Clean (write back) the D-cache lines covering a byte range.
Definition ra8_cache.c:180
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
Definition ra8_check.h:184
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
One RGB888 pixel used while scattering the four orientations.
Definition cam_image.c:42
uint8_t red
Red RGB888 component.
Definition cam_image.c:43
uint8_t blue
Blue RGB888 component.
Definition cam_image.c:45
uint8_t green
Green RGB888 component.
Definition cam_image.c:44