1
0
Fork 0
forked from len0rd/rockbox

New port: Anbernic RG Nano

A bit of context, this device is a clone of the FunKey-S with a different form factor, hardware is mostly identical, the relevant difference is it has audio out (via usb-c, adapter to 3.5mm is included), this is the reason why the FunKey-SDK is needed for bulding.

This port is based on the old SDL 1.2 code because the device doesn't have SDL2 support. Alongside what was supported in the SDL 1.2 builds this port supports battery level, charging status and backlight control.

Change-Id: I7fcb85be62748644b667c0efebabf59d6e9c5ade
This commit is contained in:
Hairo R. Carela 2025-07-14 23:04:37 -04:00 committed by Solomon Peachy
parent 9d3e286454
commit 48392bab94
94 changed files with 1517 additions and 29 deletions

View file

@ -0,0 +1,39 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50
* Copyright (C) 2014 by Mario Basister: iBasso DX90 port
* Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features
* Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef _BACKLIGHT_TARGET_H_
#define _BACKLIGHT_TARGET_H_
#include <stdbool.h>
/* See backlight.c */
bool backlight_hw_init(void);
void backlight_hw_on(void);
void backlight_hw_off(void);
void backlight_hw_brightness(int brightness);
#endif

View file

@ -0,0 +1,73 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2025 Hairo R. Carela
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************9*************************/
#include <stdio.h>
#include <SDL.h>
#include "button.h"
#include "button-target.h"
int key_to_button(int keyboard_key)
{
int new_btn = BUTTON_NONE;
switch (keyboard_key)
{
case SDLK_s:
new_btn = BUTTON_START;
break;
case SDLK_k:
new_btn = BUTTON_FN;
break;
case SDLK_a:
new_btn = BUTTON_A;
break;
case SDLK_b:
new_btn = BUTTON_B;
break;
case SDLK_x:
new_btn = BUTTON_X;
break;
case SDLK_y:
new_btn = BUTTON_Y;
break;
case SDLK_m:
new_btn = BUTTON_L;
break;
case SDLK_n:
new_btn = BUTTON_R;
break;
case SDLK_u:
new_btn = BUTTON_UP;
break;
case SDLK_d:
new_btn = BUTTON_DOWN;
break;
case SDLK_l:
new_btn = BUTTON_LEFT;
break;
case SDLK_r:
new_btn = BUTTON_RIGHT;
break;
default:
break;
}
return new_btn;
}

View file

@ -0,0 +1,47 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2025 Hairo R. Carela
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef _BUTTON_TARGET_H_
#define _BUTTON_TARGET_H_
/* Main unit's buttons */
#define BUTTON_START 0x00000001
#define BUTTON_FN 0x00000002
#define BUTTON_A 0x00000004
#define BUTTON_B 0x00000008
#define BUTTON_X 0x00000010
#define BUTTON_Y 0x00000020
#define BUTTON_L 0x00000040
#define BUTTON_R 0x00000080
#define BUTTON_UP 0x00000100
#define BUTTON_DOWN 0x00000200
#define BUTTON_LEFT 0x00000400
#define BUTTON_RIGHT 0x00000800
#define BUTTON_MAIN 0x1FFF
/* Software power-off */
#define POWEROFF_BUTTON BUTTON_POWER
#define POWEROFF_COUNT 10
int key_to_button(int keyboard_key);
#endif /* _BUTTON_TARGET_H_ */

View file

@ -0,0 +1,41 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2025 Hairo R. Carela
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include "system.h"
#include "power-rgnano.h"
#include "power.h"
#include "panic.h"
#include "sysfs.h"
const char * const sysfs_bat_level =
"/sys/class/power_supply/axp20x-battery/capacity";
unsigned int rgnano_power_get_battery_capacity(void)
{
int battery_level;
sysfs_get_int(sysfs_bat_level, &battery_level);
return battery_level;
}

View file

@ -0,0 +1,27 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2025 Hairo R. Carela
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef _POWER_RGNANO_H_
#define _POWER_RGNANO_H_
#include <stdbool.h>
#include "config.h"
unsigned int rgnano_power_get_battery_capacity(void);
#endif /* _POWER_RGNANO_H_ */

View file

@ -0,0 +1,28 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2025 Hairo R. Carela
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "powermgmt.h"
#include "power.h"
#include "power-rgnano.h"
int _battery_level(void)
{
return rgnano_power_get_battery_capacity();
}

View file

@ -0,0 +1,7 @@
#ifndef __SYSTEM_TARGET_H__
#define __SYSTEM_TARGET_H__
#include "../sdl/system-sdl.h"
#define NEED_GENERIC_BYTESWAPS
#endif /* __SYSTEM_TARGET_H__ */

View file

@ -31,11 +31,19 @@
#include "panic.h"
#include "lcd.h"
#ifdef BACKLIGHT_RG_NANO
static const char * const sysfs_bl_brightness =
"/sys/class/backlight/backlight/brightness";
static const char * const sysfs_bl_power =
"/sys/class/backlight/backlight/bl_power";
#else
static const char * const sysfs_bl_brightness =
"/sys/class/backlight/pwm-backlight.0/brightness";
static const char * const sysfs_bl_power =
"/sys/class/backlight/pwm-backlight.0/bl_power";
#endif
bool backlight_hw_init(void)
{

View file

@ -49,7 +49,11 @@ const char * handle_special_dirs(const char *dir, unsigned flags,
#endif /* _FILESYSTEM_APP_H_ */
#ifdef HAVE_SDL
#ifdef RG_NANO
#include "../sdl/filesystem-sdl.h"
#else
#include "filesystem-sdl.h"
#endif /* RG_NANO */
#endif /* HAVE_SDL */
#ifdef WIN32
#include "filesystem-win32.h"

View file

@ -32,7 +32,9 @@
#include "backlight.h"
#include "system.h"
#include "button-sdl.h"
#if SDL_MAJOR_VERSION > 1
#include "window-sdl.h"
#endif
#include "sim_tasks.h"
#include "buttonmap.h"
#include "debug.h"
@ -241,10 +243,15 @@ static void mouse_event(SDL_MouseButtonEvent *event, bool button_up)
static bool event_handler(SDL_Event *event)
{
#if SDL_MAJOR_VERSION > 1
SDL_Keycode ev_key;
#else
SDLKey ev_key;
#endif
switch(event->type)
{
#if SDL_MAJOR_VERSION > 1
case SDL_WINDOWEVENT:
if (event->window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
sdl_app_has_input_focus = 1;
@ -263,6 +270,7 @@ static bool event_handler(SDL_Event *event)
last_tick = current_tick;
#endif
}
#endif /* SDL_MAJOR_VERSION */
#ifdef SIMULATOR
if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST
|| event->window.event == SDL_WINDOWEVENT_LEAVE
@ -578,8 +586,12 @@ static void button_event(int key, bool pressed)
return;
#endif
#endif
#if (CONFIG_PLATFORM & PLATFORM_PANDORA)
#if (CONFIG_PLATFORM & PLATFORM_PANDORA) || defined(RG_NANO)
#ifdef RG_NANO
case SDLK_q:
#else
case SDLK_LCTRL:
#endif
/* Will post SDL_USEREVENT in shutdown_hw() if successful. */
sys_poweroff();
break;

View file

@ -142,7 +142,7 @@ void lcd_update_rect(int x_start, int y_start, int width, int height)
background ? UI_LCD_POSX : 0, background? UI_LCD_POSY : 0);
}
#ifdef HAVE_BACKLIGHT
#if defined(HAVE_BACKLIGHT) && (SDL_MAJOR_VERSION > 1)
void sim_backlight(int value)
{
#if LCD_DEPTH <= 8
@ -185,7 +185,9 @@ void lcd_init_device(void)
#if LCD_DEPTH >= 16
lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
LCD_DEPTH, 0, 0, 0, 0);
#if SDL_MAJOR_VERSION > 1
SDL_SetSurfaceBlendMode(lcd_surface, SDL_BLENDMODE_BLEND);
#endif
#elif LCD_DEPTH <= 8
lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
8, 0, 0, 0, 0);

View file

@ -23,7 +23,9 @@
#include "lcd-sdl.h"
#include "sim-ui-defines.h"
#include "system.h" /* for MIN() and MAX() */
#if SDL_MAJOR_VERSION > 1
#include "window-sdl.h"
#endif
void sdl_update_rect(SDL_Surface *surface, int x_start, int y_start, int width,
int height, int max_x, int max_y,
@ -101,6 +103,8 @@ void sdl_gui_update(SDL_Surface *surface, int x_start, int y_start, int width,
SDL_Rect src = {x_start, y_start, width, height};
SDL_Rect dest= {ui_x + x_start, ui_y + y_start, width, height};
#if SDL_MAJOR_VERSION > 1
uint8_t alpha;
SDL_LockMutex(window_mutex);
@ -115,6 +119,14 @@ void sdl_gui_update(SDL_Surface *surface, int x_start, int y_start, int width,
if (!sdl_window_adjust()) /* already calls sdl_window_render itself */
sdl_window_render();
SDL_UnlockMutex(window_mutex);
#else
if (surface->flags & SDL_SRCALPHA) /* alpha needs a black background */
SDL_FillRect(gui_surface, &dest, 0);
SDL_BlitSurface(surface, &src, gui_surface, &dest);
SDL_Flip(gui_surface);
#endif
}
/* set a range of bitmap indices to a gradient from startcolour to endcolour */
@ -130,7 +142,11 @@ void sdl_set_gradient(SDL_Surface *surface, SDL_Color *start, SDL_Color *end,
palette[i].b = start->b + (end->b - start->b) * i / (steps - 1);
}
#if SDL_MAJOR_VERSION > 1
SDL_SetPaletteColors(surface->format->palette, palette, first , steps);
#else
SDL_SetPalette(surface, SDL_LOGPAL|SDL_PHYSPAL, palette, first, steps);
#endif
}
int lcd_get_dpi(void)

View file

@ -25,6 +25,10 @@
#include "lcd.h"
#include "SDL.h"
#if SDL_MAJOR_VERSION == 1
extern SDL_Surface *gui_surface;
#endif
void sdl_update_rect(SDL_Surface *surface, int x_start, int y_start, int width,
int height, int max_x, int max_y,
unsigned long (*getpixel)(int, int));

View file

@ -61,7 +61,9 @@ static const void *pcm_data;
static size_t pcm_data_size;
static size_t pcm_sample_bytes;
static size_t pcm_channel_bytes;
#if SDL_MAJOR_VERSION > 1
static SDL_AudioDeviceID pcm_devid = 0;
#endif
static struct pcm_udata
{
@ -104,18 +106,26 @@ static void pcm_dma_apply_settings_nolock(void)
wanted_spec.samples = MIX_FRAME_SAMPLES * 2; /* Should be 2048, ie ~5ms @44KHz */
wanted_spec.callback = sdl_audio_callback;
wanted_spec.userdata = &udata;
#if SDL_MAJOR_VERSION > 1
if (pcm_devid)
SDL_CloseAudioDevice(pcm_devid);
/* pulseaudio seems to be happier with smaller buffers */
if (!strcmp("pulseaudio", SDL_GetCurrentAudioDriver()))
wanted_spec.samples = MIX_FRAME_SAMPLES;
#endif
/* Open the audio device and start playing sound! */
#if SDL_MAJOR_VERSION > 1
if((pcm_devid = SDL_OpenAudioDevice(audiodev, 0, &wanted_spec, &obtained, SDL_AUDIO_ALLOW_SAMPLES_CHANGE)) == 0) {
#else
if(SDL_OpenAudio(&wanted_spec, &obtained) < 0) {
#endif
panicf("Unable to open audio: %s", SDL_GetError());
return;
}
switch (obtained.format)
{
case AUDIO_U8:
@ -128,12 +138,14 @@ static void pcm_dma_apply_settings_nolock(void)
case AUDIO_S16MSB:
pcm_channel_bytes = 2;
break;
#if SDL_MAJOR_VERSION > 1 /* Not supported by SDL 1.2 */
case AUDIO_S32MSB:
case AUDIO_S32LSB:
case AUDIO_F32MSB:
case AUDIO_F32LSB:
pcm_channel_bytes = 4;
break;
#endif
default:
panicf("Unknown sample format obtained: %u",
(unsigned)obtained.format);
@ -161,12 +173,21 @@ void pcm_play_dma_start(const void *addr, size_t size)
pcm_data = addr;
pcm_data_size = size;
#if SDL_MAJOR_VERSION > 1
SDL_PauseAudioDevice(pcm_devid, 0);
#else
SDL_PauseAudio(0);
#endif
}
void pcm_play_dma_stop(void)
{
#if SDL_MAJOR_VERSION > 1
SDL_PauseAudioDevice(pcm_devid, 1);
#else
SDL_PauseAudio(1);
#endif
#ifdef DEBUG
if (udata.debug != NULL) {
fclose(udata.debug);

View file

@ -33,7 +33,9 @@
#include "thread-sdl.h"
#include "system-sdl.h"
#include "sim-ui-defines.h"
#if SDL_MAJOR_VERSION > 1
#include "window-sdl.h"
#endif
#include "button-sdl.h"
#include "lcd-bitmap.h"
#ifdef HAVE_REMOTE_LCD
@ -50,6 +52,10 @@
#define SIMULATOR_DEFAULT_ROOT "simdisk"
#if SDL_MAJOR_VERSION == 1
SDL_Surface *gui_surface;
#endif
bool background = true; /* use backgrounds by default */
#ifdef HAVE_REMOTE_LCD
bool showremote = true; /* include remote by default */
@ -92,7 +98,7 @@ static int sdl_event_thread(void * param)
SDL_sem *wait_for_maemo_startup;
#endif
#if (CONFIG_PLATFORM & (PLATFORM_MAEMO|PLATFORM_PANDORA))
#if (CONFIG_PLATFORM & (PLATFORM_MAEMO|PLATFORM_PANDORA)) || defined(RG_NANO)
/* SDL touch screen fix: Work around a SDL assumption that returns
relative mouse coordinates when you get to the screen edges
using the touchscreen and a disabled mouse cursor.
@ -112,6 +118,27 @@ static int sdl_event_thread(void * param)
SDL_DestroySemaphore(wait_for_maemo_startup);
#endif
#if SDL_MAJOR_VERSION == 1
SDL_InitSubSystem(SDL_INIT_VIDEO);
SDL_Surface *picture_surface = NULL;
int depth;
Uint32 flags;
depth = LCD_DEPTH;
if (depth < 8)
depth = 16;
flags = SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN;
if ((gui_surface = SDL_SetVideoMode(LCD_WIDTH, LCD_HEIGHT, depth, flags)) == NULL) {
panicf("%s", SDL_GetError());
}
if (background && picture_surface != NULL)
SDL_BlitSurface(picture_surface, NULL, gui_surface, NULL);
#endif
/* let system_init proceed */
SDL_SemPost((SDL_sem *)param);
@ -189,8 +216,11 @@ void sim_do_exit()
#endif
sim_kernel_shutdown();
#if SDL_MAJOR_VERSION > 1
SDL_UnlockMutex(window_mutex);
SDL_DestroyMutex(window_mutex);
#endif
SDL_Quit();
exit(EXIT_SUCCESS);
@ -228,12 +258,21 @@ void system_init(void)
#ifndef __WIN32 /* Fails on Windows */
SDL_InitSubSystem(SDL_INIT_VIDEO);
#if SDL_MAJOR_VERSION > 1
sdl_window_setup();
#endif
#endif
#ifndef __APPLE__ /* MacOS requires events to be handled on main thread */
s = SDL_CreateSemaphore(0); /* 0-count so it blocks */
evt_thread = SDL_CreateThread(sdl_event_thread, NULL, s);
#if SDL_MAJOR_VERSION > 1
evt_thread = SDL_CreateThread(sdl_event_thread, NULL, s);
#else
evt_thread = SDL_CreateThread(sdl_event_thread, s);
#endif /* SDL_MAJOR_VERSION */
SDL_SemWait(s);
/* cleanup */
SDL_DestroySemaphore(s);
@ -311,6 +350,7 @@ void sys_handle_argv(int argc, char *argv[])
printf("Disabling remote image.\n");
}
#endif
#if SDL_MAJOR_VERSION > 1
else if (!strcmp("--zoom", argv[x]))
{
x++;
@ -320,6 +360,7 @@ void sys_handle_argv(int argc, char *argv[])
display_zoom = 2;
printf("Window zoom is %f\n", display_zoom);
}
#endif
else if (!strcmp("--alarm", argv[x]))
{
sim_alarm_wakeup = true;
@ -374,7 +415,9 @@ void sys_handle_argv(int argc, char *argv[])
}
}
}
#if SDL_MAJOR_VERSION > 1
if (display_zoom != 1) {
background = false;
}
#endif
}

View file

@ -340,7 +340,12 @@ unsigned int create_thread(void (*function)(void),
return 0;
}
#if SDL_MAJOR_VERSION > 1
SDL_Thread *t = SDL_CreateThread(runthread, NULL, thread);
#else
SDL_Thread *t = SDL_CreateThread(runthread, thread);
#endif
if (t == NULL)
{
DEBUGF("Failed to create SDL thread\n");