Landfall

Annotated pkg/landfall-examples/keypad_ds_client/keypad_ds_client.cc

229:810ca800993b
11 months ago Paul Boddie Employ a picture representation compatible with 16-bit SPI transfers over DMA. cpm-library-improvements
paul@0 1
/*
paul@0 2
 * Display the keypad matrix using the specified dimensions.
paul@0 3
 *
paul@142 4
 * Copyright (C) 2018, 2023 Paul Boddie <paul@boddie.org.uk>
paul@0 5
 *
paul@0 6
 * This program is free software; you can redistribute it and/or
paul@0 7
 * modify it under the terms of the GNU General Public License as
paul@0 8
 * published by the Free Software Foundation; either version 2 of
paul@0 9
 * the License, or (at your option) any later version.
paul@0 10
 *
paul@0 11
 * This program is distributed in the hope that it will be useful,
paul@0 12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
paul@0 13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
paul@0 14
 * GNU General Public License for more details.
paul@0 15
 *
paul@0 16
 * You should have received a copy of the GNU General Public License
paul@0 17
 * along with this program; if not, write to the Free Software
paul@0 18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
paul@0 19
 * Boston, MA  02110-1301, USA
paul@0 20
 */
paul@0 21
paul@153 22
#include <l4/re/c/dataspace.h>
paul@153 23
#include <l4/re/c/rm.h>
paul@153 24
#include <l4/re/env.h>
paul@0 25
paul@0 26
#include <l4/re/c/util/video/goos_fb.h>
paul@0 27
#include <l4/re/c/video/view.h>
paul@0 28
paul@0 29
#include <stdio.h>
paul@0 30
#include <unistd.h>
paul@0 31
#include <stdint.h>
paul@0 32
#include <stdlib.h>
paul@0 33
paul@153 34
#include "keypad_client.h"
paul@153 35
paul@153 36
paul@153 37
paul@0 38
/* Video abstractions. */
paul@0 39
paul@0 40
static l4re_util_video_goos_fb_t gfb;
paul@0 41
static l4re_video_view_info_t fbi;
paul@0 42
static void *fb;
paul@0 43
paul@0 44
/* Keypad status and dimensions. */
paul@0 45
paul@153 46
uint32_t *keymem = 0;
paul@0 47
int columns, rows;
paul@0 48
paul@0 49
paul@0 50
paul@0 51
static uint32_t bitmask(uint32_t size)
paul@0 52
{
paul@0 53
  return (1 << size) - 1;
paul@0 54
}
paul@0 55
paul@0 56
static uint32_t truncate_channel(uint32_t value, uint32_t size)
paul@0 57
{
paul@0 58
  return (value >> (8 - size)) & bitmask(size);
paul@0 59
}
paul@0 60
paul@0 61
static void set_pixel(uint32_t pos, uint8_t bpp, uint32_t value)
paul@0 62
{
paul@0 63
  if (bpp <= 8) *(uint8_t *) pos = value;
paul@0 64
  else if (bpp <= 16) *(uint16_t *) pos = value;
paul@0 65
  else *(uint32_t *) pos = value;
paul@0 66
}
paul@0 67
paul@0 68
/* Show the state of a key on the display. */
paul@0 69
paul@0 70
static void show_keystate(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t rgb)
paul@0 71
{
paul@0 72
  uint8_t bpp = l4re_video_bits_per_pixel(&fbi.pixel_info);
paul@0 73
  uint8_t bytes_per_pixel = fbi.pixel_info.bytes_per_pixel;
paul@0 74
  uint32_t bytes_per_line = fbi.bytes_per_line;
paul@0 75
  uint32_t pos;
paul@0 76
  uint32_t col, row;
paul@0 77
paul@0 78
  rgb = (truncate_channel(rgb >> 16, fbi.pixel_info.r.size) << fbi.pixel_info.r.shift) |
paul@0 79
        (truncate_channel(rgb >> 8, fbi.pixel_info.g.size) << fbi.pixel_info.g.shift) |
paul@0 80
        (truncate_channel(rgb, fbi.pixel_info.b.size) << fbi.pixel_info.b.shift);
paul@0 81
paul@0 82
  for (row = 0; row < h; row++)
paul@0 83
  {
paul@0 84
    pos = (uint32_t) fb + (y + row) * bytes_per_line + x * bytes_per_pixel;
paul@0 85
paul@0 86
    for (col = 0; col < w; col++)
paul@0 87
    {
paul@0 88
      set_pixel(pos, bpp, rgb);
paul@0 89
      pos += bytes_per_pixel;
paul@0 90
    }
paul@0 91
  }
paul@0 92
}
paul@0 93
paul@0 94
/* Show the keypad status on the display. */
paul@0 95
paul@0 96
static void show_keypad(void)
paul@0 97
{
paul@0 98
  uint32_t colsize = fbi.width / columns,
paul@0 99
           rowsize = fbi.height / rows;
paul@0 100
  uint8_t column, row;
paul@0 101
  uint32_t mask;
paul@0 102
paul@0 103
  for (column = 0; column < columns; column++)
paul@0 104
paul@0 105
    for (row = 0, mask = 1 << (rows - 1);
paul@0 106
         row < rows;
paul@0 107
         row++, mask >>= 1)
paul@0 108
paul@0 109
      show_keystate(column * colsize, row * rowsize, colsize, rowsize,
paul@153 110
                    keymem[column] & mask ? 0xffffff : 0);
paul@0 111
paul@0 112
  /* Refresh the display. */
paul@0 113
paul@0 114
  l4re_util_video_goos_fb_refresh(&gfb, 0, 0, fbi.width, fbi.height);
paul@0 115
}
paul@0 116
paul@0 117
paul@0 118
paul@0 119
int main(int argc, char *argv[])
paul@0 120
{
paul@153 121
  l4_cap_idx_t keypad_cap;
paul@153 122
  l4re_ds_t mem;
paul@0 123
paul@0 124
  /* Obtain the keypad matrix dimensions. */
paul@0 125
paul@0 126
  if (argc < 3)
paul@0 127
    return 1;
paul@0 128
paul@0 129
  columns = atoi(argv[1]);
paul@0 130
  rows = atoi(argv[2]);
paul@0 131
paul@0 132
  if (l4re_util_video_goos_fb_setup_name(&gfb, "fb"))
paul@0 133
    return 1;
paul@0 134
paul@0 135
  if (l4re_util_video_goos_fb_view_info(&gfb, &fbi))
paul@0 136
    return 1;
paul@0 137
paul@0 138
  if (!(fb = l4re_util_video_goos_fb_attach_buffer(&gfb)))
paul@0 139
    return 1;
paul@0 140
paul@0 141
  /* Obtain a reference to the keypad. */
paul@0 142
paul@153 143
  keypad_cap = l4re_env_get_cap("keypad");
paul@153 144
paul@153 145
  if (l4_is_invalid_cap(keypad_cap))
paul@153 146
    return 1;
paul@0 147
paul@0 148
  /* Obtain a reference to the keypad data. */
paul@0 149
paul@153 150
  client_Keypad keypad(keypad_cap);
paul@153 151
paul@153 152
  if (keypad.get_keypad_data(&mem))
paul@153 153
    return 1;
paul@0 154
paul@0 155
  /* Attach the keypad data to a region in this task. */
paul@0 156
paul@153 157
  if (l4re_rm_attach((void **) &keymem, l4re_ds_size(mem),
paul@153 158
                     L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_R,
paul@153 159
                     mem, 0,
paul@153 160
                     L4_PAGESHIFT))
paul@0 161
    return 1;
paul@0 162
paul@0 163
  /* Show the keypad state. */
paul@0 164
paul@153 165
  while (1)
paul@153 166
    show_keypad();
paul@0 167
paul@0 168
  return 0;
paul@0 169
}