Add cleaned-up xDuoo X3 support

Cleaned up, rebased, and forward-ported from the xvortex fork.

(original credit to vsoftster@gmail.com)

Change-Id: Ibcc023a0271ea81e901450a88317708c2683236d
Signed-off-by: Solomon Peachy <pizza@shaftnet.org>
This commit is contained in:
Solomon Peachy 2018-06-28 06:24:26 -04:00 committed by Michael Giacomelli
parent b3e2bd619b
commit 0662793ca0
114 changed files with 17348 additions and 101 deletions

View File

@ -317,4 +317,6 @@ keymaps/keymap-ypr1.c
keymaps/keymap-dx50.c keymaps/keymap-dx50.c
#elif CONFIG_KEYPAD == AGPTEK_ROCKER_PAD #elif CONFIG_KEYPAD == AGPTEK_ROCKER_PAD
keymaps/keymap-agptekrocker.c keymaps/keymap-agptekrocker.c
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
keymaps/keymap-xduoox3.c
#endif #endif

View File

@ -0,0 +1,212 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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.
*
****************************************************************************/
/* Button Code Definitions for xDuoo X3 target */
#include "config.h"
#include "action.h"
#include "button.h"
#include "settings.h"
/* {Action Code, Button code, Prereq button code } */
/*
* The format of the list is as follows
* { Action Code, Button code, Prereq button code }
* if there's no need to check the previous button's value, use BUTTON_NONE
* Insert LAST_ITEM_IN_LIST at the end of each mapping
*/
static const struct button_mapping button_context_standard[] = {
{ ACTION_STD_PREV, BUTTON_PREV, BUTTON_NONE },
{ ACTION_STD_PREVREPEAT, BUTTON_PREV|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_NEXT, BUTTON_NEXT, BUTTON_NONE },
{ ACTION_STD_NEXTREPEAT, BUTTON_NEXT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_CONTEXT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
{ ACTION_STD_CANCEL, BUTTON_OPTION|BUTTON_REL, BUTTON_OPTION },
{ ACTION_STD_OK, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
{ ACTION_STD_MENU, BUTTON_HOME|BUTTON_REL, BUTTON_HOME },
LAST_ITEM_IN_LIST
}; /* button_context_standard */
static const struct button_mapping button_context_wps[] = {
{ ACTION_WPS_PLAY, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
{ ACTION_WPS_STOP, BUTTON_POWER|BUTTON_REL, BUTTON_POWER },
{ ACTION_WPS_SKIPPREV, BUTTON_PREV|BUTTON_REL, BUTTON_PREV },
{ ACTION_WPS_SEEKBACK, BUTTON_PREV|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_STOPSEEK, BUTTON_PREV|BUTTON_REL, BUTTON_PREV|BUTTON_REPEAT },
{ ACTION_WPS_SKIPNEXT, BUTTON_NEXT|BUTTON_REL, BUTTON_NEXT },
{ ACTION_WPS_SEEKFWD, BUTTON_NEXT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_STOPSEEK, BUTTON_NEXT|BUTTON_REL, BUTTON_NEXT|BUTTON_REPEAT },
{ ACTION_WPS_VOLUP, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_WPS_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_BROWSE, BUTTON_OPTION|BUTTON_REL, BUTTON_OPTION },
{ ACTION_WPS_CONTEXT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
{ ACTION_WPS_MENU, BUTTON_HOME|BUTTON_REL, BUTTON_HOME },
{ ACTION_WPS_QUICKSCREEN, BUTTON_HOME|BUTTON_REPEAT, BUTTON_HOME },
{ ACTION_WPS_HOTKEY, BUTTON_OPTION|BUTTON_REPEAT, BUTTON_OPTION },
LAST_ITEM_IN_LIST
}; /* button_context_wps */
static const struct button_mapping button_context_list[] = {
{ ACTION_LIST_VOLUP, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_LIST_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_list */
/** Bookmark Screen **/
static const struct button_mapping button_context_bmark[] = {
{ ACTION_BMS_DELETE, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST)
}; /* button_context_bmark */
/** Keyboard **/
static const struct button_mapping button_context_keyboard[] = {
{ ACTION_KBD_LEFT, BUTTON_PREV, BUTTON_NONE },
{ ACTION_KBD_LEFT, BUTTON_PREV|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_RIGHT, BUTTON_NEXT, BUTTON_NONE },
{ ACTION_KBD_RIGHT, BUTTON_NEXT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_DOWN, BUTTON_OPTION, BUTTON_NONE },
{ ACTION_KBD_DOWN, BUTTON_OPTION|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_CURSOR_LEFT, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_KBD_CURSOR_LEFT, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_CURSOR_RIGHT, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_KBD_CURSOR_RIGHT, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_BACKSPACE, BUTTON_HOME, BUTTON_NONE },
{ ACTION_KBD_BACKSPACE, BUTTON_HOME|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_SELECT, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
{ ACTION_KBD_DONE, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
{ ACTION_KBD_ABORT, BUTTON_POWER|BUTTON_REL, BUTTON_POWER },
LAST_ITEM_IN_LIST
}; /* button_context_keyboard */
/** Pitchscreen **/
static const struct button_mapping button_context_pitchscreen[] = {
{ ACTION_PS_INC_SMALL, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_PS_INC_BIG, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_PS_DEC_SMALL, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_PS_DEC_BIG, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_PS_NUDGE_LEFT, BUTTON_PREV, BUTTON_NONE },
{ ACTION_PS_NUDGE_LEFTOFF, BUTTON_PREV|BUTTON_REL, BUTTON_NONE },
{ ACTION_PS_NUDGE_RIGHT, BUTTON_NEXT, BUTTON_NONE },
{ ACTION_PS_NUDGE_RIGHTOFF, BUTTON_NEXT|BUTTON_REL, BUTTON_NONE },
{ ACTION_PS_TOGGLE_MODE, BUTTON_PLAY|BUTTON_REL, BUTTON_NONE },
{ ACTION_PS_RESET, BUTTON_POWER|BUTTON_REL, BUTTON_POWER },
{ ACTION_PS_EXIT, BUTTON_OPTION|BUTTON_REL, BUTTON_OPTION },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_pitchscreen */
/** Quickscreen **/
static const struct button_mapping button_context_quickscreen[] = {
{ ACTION_QS_TOP, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_QS_TOP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_QS_DOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_QS_DOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_QS_LEFT, BUTTON_PREV, BUTTON_NONE },
{ ACTION_QS_LEFT, BUTTON_PREV|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_QS_RIGHT, BUTTON_NEXT, BUTTON_NONE },
{ ACTION_QS_RIGHT, BUTTON_NEXT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_HOME|BUTTON_REL, BUTTON_HOME },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_quickscreen */
/** Settings - General Mappings **/
static const struct button_mapping button_context_settings[] = {
{ ACTION_SETTINGS_RESET, BUTTON_POWER|BUTTON_REL, BUTTON_POWER },
{ ACTION_STD_PREV, BUTTON_PREV, BUTTON_NONE },
{ ACTION_STD_PREVREPEAT, BUTTON_PREV|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_NEXT, BUTTON_NEXT, BUTTON_NONE },
{ ACTION_STD_NEXTREPEAT, BUTTON_NEXT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_OK, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
{ ACTION_STD_CANCEL, BUTTON_OPTION|BUTTON_REL, BUTTON_OPTION },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_settings */
static const struct button_mapping button_context_settings_vol_is_inc[] = {
{ ACTION_SETTINGS_INC, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_SETTINGS_INCREPEAT,BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT,BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_settings_right_is_inc */
/** Tree **/
static const struct button_mapping button_context_tree[] = {
{ ACTION_TREE_WPS, BUTTON_HOME|BUTTON_REL, BUTTON_HOME },
{ ACTION_TREE_STOP, BUTTON_POWER|BUTTON_REL, BUTTON_POWER },
{ ACTION_TREE_HOTKEY, BUTTON_OPTION|BUTTON_REPEAT, BUTTON_OPTION },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST)
}; /* button_context_tree */
/** Yes/No Screen **/
static const struct button_mapping button_context_yesnoscreen[] = {
{ ACTION_YESNO_ACCEPT, BUTTON_PLAY, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_settings_yesnoscreen */
/* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
const struct button_mapping* get_context_mapping(int context)
{
switch (context)
{
case CONTEXT_LIST:
return button_context_list;
case CONTEXT_STD:
return button_context_standard;
case CONTEXT_BOOKMARKSCREEN:
return button_context_bmark;
case CONTEXT_KEYBOARD:
return button_context_keyboard;
case CONTEXT_PITCHSCREEN:
return button_context_pitchscreen;
case CONTEXT_QUICKSCREEN:
return button_context_quickscreen;
case CONTEXT_SETTINGS:
return button_context_settings;
case CONTEXT_SETTINGS_TIME:
case CONTEXT_SETTINGS_COLOURCHOOSER:
case CONTEXT_SETTINGS_EQ:
case CONTEXT_SETTINGS_RECTRIGGER:
return button_context_settings_vol_is_inc;
case CONTEXT_TREE:
case CONTEXT_MAINMENU:
return button_context_tree;
case CONTEXT_WPS:
return button_context_wps;
case CONTEXT_YESNOSCREEN:
return button_context_yesnoscreen;
}
return button_context_standard;
}

View File

@ -132,6 +132,10 @@ MENUITEM_SETTING(depth_3d, &global_settings.depth_3d, NULL);
MENUITEM_SETTING(roll_off, &global_settings.roll_off, NULL); MENUITEM_SETTING(roll_off, &global_settings.roll_off, NULL);
#endif #endif
#ifdef AUDIOHW_HAVE_FUNCTIONAL_MODE
MENUITEM_SETTING(func_mode, &global_settings.func_mode, NULL);
#endif
#if CONFIG_CODEC == SWCODEC #if CONFIG_CODEC == SWCODEC
/* Crossfeed Submenu */ /* Crossfeed Submenu */
MENUITEM_SETTING(crossfeed, &global_settings.crossfeed, lowlatency_callback); MENUITEM_SETTING(crossfeed, &global_settings.crossfeed, lowlatency_callback);
@ -256,6 +260,9 @@ MAKE_MENU(sound_settings, ID2P(LANG_SOUND_SETTINGS), NULL, Icon_Audio,
#ifdef AUDIOHW_HAVE_FILTER_ROLL_OFF #ifdef AUDIOHW_HAVE_FILTER_ROLL_OFF
,&roll_off ,&roll_off
#endif #endif
#ifdef AUDIOHW_HAVE_FUNCTIONAL_MODE
,&func_mode
#endif
#if CONFIG_CODEC == SWCODEC #if CONFIG_CODEC == SWCODEC
,&crossfeed_menu, &equalizer_menu, &dithering_enabled ,&crossfeed_menu, &equalizer_menu, &dithering_enabled
,&surround_menu, &pbe_menu, &afr_enabled ,&surround_menu, &pbe_menu, &afr_enabled

View File

@ -279,6 +279,12 @@
#define BATTERY_OFF_TXT "Right" #define BATTERY_OFF_TXT "Right"
#define BATTERY_ON_TXT "Left - start" #define BATTERY_ON_TXT "Left - start"
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define BATTERY_ON BUTTON_PLAY
#define BATTERY_OFF BUTTON_POWER
#define BATTERY_ON_TXT "PLAY - start"
#define BATTERY_OFF_TXT "POWER"
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -573,6 +573,22 @@ enum {
#define BJACK_QUIT_NAME "Volume up" #define BJACK_QUIT_NAME "Volume up"
#define BJACK_DOUBLE_NAME "Option+Down" #define BJACK_DOUBLE_NAME "Option+Down"
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define BJACK_SELECT_NAME "PLAY"
#define BJACK_STAY_NAME "NEXT"
#define BJACK_QUIT_NAME "POWER"
#define BJACK_DOUBLE_NAME "PREV"
#define BJACK_SELECT BUTTON_PLAY
#define BJACK_QUIT BUTTON_POWER
#define BJACK_MAX BUTTON_VOL_UP
#define BJACK_MIN BUTTON_VOL_DOWN
#define BJACK_STAY BUTTON_NEXT
#define BJACK_DOUBLEDOWN BUTTON_PREV
#define BJACK_UP BUTTON_HOME
#define BJACK_DOWN BUTTON_OPTION
#define BJACK_RIGHT BUTTON_NEXT
#define BJACK_LEFT BUTTON_PREV
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -332,6 +332,16 @@ CONFIG_KEYPAD == SANSA_CONNECT_PAD
#define UP BUTTON_UP #define UP BUTTON_UP
#define DOWN BUTTON_DOWN #define DOWN BUTTON_DOWN
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define QUIT BUTTON_POWER
#define LEFT BUTTON_PREV
#define RIGHT BUTTON_NEXT
#define ALTLEFT BUTTON_VOL_DOWN
#define ALTRIGHT BUTTON_VOL_UP
#define SELECT BUTTON_PLAY
#define UP BUTTON_HOME
#define DOWN BUTTON_OPTION
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -525,6 +525,17 @@ F3: equal to "="
#define CALCULATOR_CALC BUTTON_VOLUP #define CALCULATOR_CALC BUTTON_VOLUP
#define CALCULATOR_CLEAR (BUTTON_SELECT|BUTTON_REPEAT) #define CALCULATOR_CLEAR (BUTTON_SELECT|BUTTON_REPEAT)
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define CALCULATOR_LEFT BUTTON_PREV
#define CALCULATOR_RIGHT BUTTON_NEXT
#define CALCULATOR_UP BUTTON_HOME
#define CALCULATOR_DOWN BUTTON_OPTION
#define CALCULATOR_QUIT BUTTON_POWER
#define CALCULATOR_INPUT_CALC_PRE (BUTTON_OPTION|BUTTON_REPEAT)
#define CALCULATOR_INPUT (BUTTON_PLAY|BUTTON_REL)
#define CALCULATOR_CALC (BUTTON_PLAY|BUTTON_REPEAT)
#define CALCULATOR_CLEAR (BUTTON_POWER|BUTTON_REPEAT)
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -413,6 +413,16 @@
#define CALENDAR_NEXT_MONTH (BUTTON_VOLDOWN) #define CALENDAR_NEXT_MONTH (BUTTON_VOLDOWN)
#define CALENDAR_PREV_MONTH (BUTTON_VOLUP) #define CALENDAR_PREV_MONTH (BUTTON_VOLUP)
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define CALENDAR_QUIT BUTTON_POWER
#define CALENDAR_SELECT BUTTON_PLAY
#define CALENDAR_NEXT_WEEK BUTTON_OPTION
#define CALENDAR_PREV_WEEK BUTTON_HOME
#define CALENDAR_NEXT_DAY BUTTON_NEXT
#define CALENDAR_PREV_DAY BUTTON_PREV
#define CALENDAR_NEXT_MONTH BUTTON_VOL_UP
#define CALENDAR_PREV_MONTH BUTTON_VOL_DOWN
#else #else
#error "No keypad setting." #error "No keypad setting."
#endif #endif

View File

@ -558,6 +558,20 @@
#define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) #define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT)
#define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT)
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define CB_SELECT BUTTON_PLAY
#define CB_UP BUTTON_HOME
#define CB_DOWN BUTTON_OPTION
#define CB_LEFT BUTTON_PREV
#define CB_RIGHT BUTTON_NEXT
#define CB_PLAY BUTTON_VOL_UP
#define CB_LEVEL (BUTTON_PLAY|BUTTON_REPEAT)
#define CB_MENU BUTTON_POWER
#define CB_SCROLL_UP (BUTTON_HOME|BUTTON_REPEAT)
#define CB_SCROLL_DOWN (BUTTON_OPTION|BUTTON_REPEAT)
#define CB_SCROLL_LEFT (BUTTON_PREV|BUTTON_REPEAT)
#define CB_SCROLL_RIGHT (BUTTON_NEXT|BUTTON_REPEAT)
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -412,6 +412,16 @@
#define CHC_SETTINGS_CANCEL BUTTON_RIGHT #define CHC_SETTINGS_CANCEL BUTTON_RIGHT
#define CHC_SETTINGS_OK (BUTTON_SELECT|BUTTON_REPEAT) #define CHC_SETTINGS_OK (BUTTON_SELECT|BUTTON_REPEAT)
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define CHC_QUIT BUTTON_POWER
#define CHC_STARTSTOP BUTTON_PLAY
#define CHC_RESET BUTTON_OPTION
#define CHC_MENU BUTTON_HOME
#define CHC_SETTINGS_INC BUTTON_NEXT
#define CHC_SETTINGS_DEC BUTTON_PREV
#define CHC_SETTINGS_OK BUTTON_PLAY
#define CHC_SETTINGS_CANCEL BUTTON_POWER
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -1283,6 +1283,14 @@ CONFIG_KEYPAD == MROBE500_PAD
#define CHIP8_KEY6 BUTTON_RIGHT #define CHIP8_KEY6 BUTTON_RIGHT
#define CHIP8_KEY8 BUTTON_LEFT #define CHIP8_KEY8 BUTTON_LEFT
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define CHIP8_OFF BUTTON_POWER
#define CHIP8_KEY2 BUTTON_HOME
#define CHIP8_KEY4 BUTTON_PREV
#define CHIP8_KEY5 BUTTON_PLAY
#define CHIP8_KEY6 BUTTON_NEXT
#define CHIP8_KEY8 BUTTON_OPTION
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -209,6 +209,10 @@ CONFIG_KEYPAD == MROBE500_PAD
#define ACTION BUTTON_SELECT #define ACTION BUTTON_SELECT
#define ACTIONTEXT "Select" #define ACTIONTEXT "Select"
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define QUIT BUTTON_POWER
#define ACTION BUTTON_PLAY
#define ACTIONTEXT "PLAY"
#elif !defined(HAVE_TOUCHSCREEN) #elif !defined(HAVE_TOUCHSCREEN)
#error No keymap defined! #error No keymap defined!

View File

@ -276,6 +276,14 @@
#define CLIX_BUTTON_RIGHT BUTTON_RIGHT #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
#define CLIX_BUTTON_CLICK BUTTON_SELECT #define CLIX_BUTTON_CLICK BUTTON_SELECT
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define CLIX_BUTTON_QUIT BUTTON_POWER
#define CLIX_BUTTON_UP BUTTON_HOME
#define CLIX_BUTTON_DOWN BUTTON_OPTION
#define CLIX_BUTTON_LEFT BUTTON_PREV
#define CLIX_BUTTON_RIGHT BUTTON_NEXT
#define CLIX_BUTTON_CLICK BUTTON_PLAY
#else #else
#error "no keymap" #error "no keymap"
#endif #endif

View File

@ -413,6 +413,16 @@
#define CUBE_HIGHSPEED (BUTTON_SELECT | BUTTON_REPEAT) #define CUBE_HIGHSPEED (BUTTON_SELECT | BUTTON_REPEAT)
#define CUBE_PAUSE (BUTTON_LEFT | BUTTON_REPEAT) #define CUBE_PAUSE (BUTTON_LEFT | BUTTON_REPEAT)
#elif (CONFIG_KEYPAD == XDUOO_X3_PAD)
#define CUBE_QUIT BUTTON_POWER
#define CUBE_NEXT BUTTON_NEXT
#define CUBE_PREV BUTTON_PREV
#define CUBE_INC BUTTON_VOL_UP
#define CUBE_DEC BUTTON_VOL_DOWN
#define CUBE_MODE BUTTON_OPTION
#define CUBE_PAUSE BUTTON_HOME
#define CUBE_HIGHSPEED BUTTON_PLAY
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -555,6 +555,17 @@ void I_ShutdownGraphics(void)
#define DOOMBUTTON_WEAPON BUTTON_VOLUP #define DOOMBUTTON_WEAPON BUTTON_VOLUP
#define DOOMBUTTON_MAP (BUTTON_VOLUP|BUTTON_REPEAT) #define DOOMBUTTON_MAP (BUTTON_VOLUP|BUTTON_REPEAT)
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define DOOMBUTTON_UP BUTTON_HOME
#define DOOMBUTTON_DOWN BUTTON_OPTION
#define DOOMBUTTON_LEFT BUTTON_PREV
#define DOOMBUTTON_RIGHT BUTTON_NEXT
#define DOOMBUTTON_SHOOT BUTTON_PLAY
#define DOOMBUTTON_OPEN (BUTTON_HOME | BUTTON_POWER)
#define DOOMBUTTON_ESC BUTTON_POWER
#define DOOMBUTTON_ENTER BUTTON_PLAY
#define DOOMBUTTON_WEAPON BUTTON_VOL_UP
#else #else
#error Keymap not defined! #error Keymap not defined!
#endif #endif

View File

@ -334,6 +334,15 @@ GREY_INFO_STRUCT
# define FFT_ORIENTATION BUTTON_SELECT # define FFT_ORIENTATION BUTTON_SELECT
# define FFT_WINDOW BUTTON_VOLDOWN # define FFT_WINDOW BUTTON_VOLDOWN
#elif (CONFIG_KEYPAD == XDUOO_X3_PAD)
# define FFT_PREV_GRAPH BUTTON_PREV
# define FFT_NEXT_GRAPH BUTTON_NEXT
# define FFT_ORIENTATION BUTTON_HOME
# define FFT_FREQ_SCALE BUTTON_OPTION
# define FFT_WINDOW (BUTTON_HOME|BUTTON_POWER)
# define FFT_AMP_SCALE BUTTON_PLAY
# define FFT_QUIT BUTTON_POWER
#elif !defined(HAVE_TOUCHSCREEN) #elif !defined(HAVE_TOUCHSCREEN)
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -482,6 +482,18 @@
#define FLIPIT_STEP_BY_STEP (BUTTON_LEFT|BUTTON_VOLUP) #define FLIPIT_STEP_BY_STEP (BUTTON_LEFT|BUTTON_VOLUP)
#define FLIPIT_TOGGLE BUTTON_SELECT #define FLIPIT_TOGGLE BUTTON_SELECT
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define FLIPIT_LEFT BUTTON_PREV
#define FLIPIT_RIGHT BUTTON_NEXT
#define FLIPIT_UP BUTTON_HOME
#define FLIPIT_DOWN BUTTON_OPTION
#define FLIPIT_QUIT BUTTON_POWER
#define FLIPIT_SHUFFLE (BUTTON_HOME | BUTTON_PREV)
#define FLIPIT_SOLVE (BUTTON_HOME | BUTTON_NEXT)
#define FLIPIT_STEP_BY_STEP (BUTTON_HOME | BUTTON_PLAY)
#define FLIPIT_TOGGLE BUTTON_PLAY
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -484,6 +484,18 @@
#define FRACTAL_PRECISION_DEC (BUTTON_VOLUP|BUTTON_LEFT) #define FRACTAL_PRECISION_DEC (BUTTON_VOLUP|BUTTON_LEFT)
#define FRACTAL_RESET BUTTON_SELECT #define FRACTAL_RESET BUTTON_SELECT
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define FRACTAL_QUIT BUTTON_POWER
#define FRACTAL_UP BUTTON_HOME
#define FRACTAL_DOWN BUTTON_OPTION
#define FRACTAL_LEFT BUTTON_PREV
#define FRACTAL_RIGHT BUTTON_NEXT
#define FRACTAL_ZOOM_IN BUTTON_VOL_UP
#define FRACTAL_ZOOM_OUT BUTTON_VOL_DOWN
#define FRACTAL_PRECISION_INC (BUTTON_PLAY | BUTTON_NEXT)
#define FRACTAL_PRECISION_DEC (BUTTON_PLAY | BUTTON_PREV)
#define FRACTAL_RESET (BUTTON_HOME | BUTTON_POWER)
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -452,6 +452,18 @@
#define GBN_BUTTON_PLAY (BUTTON_SELECT | BUTTON_REL) #define GBN_BUTTON_PLAY (BUTTON_SELECT | BUTTON_REL)
#define GBN_BUTTON_NAV_MODE BUTTON_VOLUP #define GBN_BUTTON_NAV_MODE BUTTON_VOLUP
#elif (CONFIG_KEYPAD == XDUOO_X3_PAD)
#define GBN_BUTTON_UP BUTTON_HOME
#define GBN_BUTTON_DOWN BUTTON_OPTION
#define GBN_BUTTON_LEFT BUTTON_PREV
#define GBN_BUTTON_RIGHT BUTTON_NEXT
#define GBN_BUTTON_RETREAT BUTTON_VOL_DOWN
#define GBN_BUTTON_ADVANCE BUTTON_VOL_UP
#define GBN_BUTTON_MENU BUTTON_POWER
#define GBN_BUTTON_PLAY BUTTON_PLAY | BUTTON_REL
#define GBN_BUTTON_CONTEXT BUTTON_PLAY | BUTTON_REPEAT
#define GBN_BUTTON_NEXT_VAR BUTTON_HOME | BUTTON_POWER
#else #else
#error Unsupported keypad #error Unsupported keypad
#endif #endif

View File

@ -108,6 +108,14 @@
#define GREYSCALE_RIGHT BUTTON_RIGHT #define GREYSCALE_RIGHT BUTTON_RIGHT
#define GREYSCALE_OFF BUTTON_PLAY #define GREYSCALE_OFF BUTTON_PLAY
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define GREYSCALE_SHIFT BUTTON_PLAY
#define GREYSCALE_UP BUTTON_HOME
#define GREYSCALE_DOWN BUTTON_OPTION
#define GREYSCALE_LEFT BUTTON_PREV
#define GREYSCALE_RIGHT BUTTON_NEXT
#define GREYSCALE_OFF BUTTON_POWER
#endif #endif
#define GFX_HEIGHT (LCD_HEIGHT-8) #define GFX_HEIGHT (LCD_HEIGHT-8)

View File

@ -495,6 +495,21 @@
#define IMGVIEW_QUIT (BUTTON_POWER|BUTTON_REL) #define IMGVIEW_QUIT (BUTTON_POWER|BUTTON_REL)
#define IMGVIEW_MENU (BUTTON_SELECT|BUTTON_REL) #define IMGVIEW_MENU (BUTTON_SELECT|BUTTON_REL)
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define IMGVIEW_ZOOM_PRE BUTTON_PLAY
#define IMGVIEW_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
#define IMGVIEW_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
#define IMGVIEW_UP BUTTON_HOME
#define IMGVIEW_DOWN BUTTON_OPTION
#define IMGVIEW_LEFT BUTTON_PREV
#define IMGVIEW_RIGHT BUTTON_NEXT
#define IMGVIEW_NEXT BUTTON_VOL_UP
#define IMGVIEW_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
#define IMGVIEW_PREVIOUS BUTTON_VOL_DOWN
#define IMGVIEW_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
#define IMGVIEW_MENU BUTTON_POWER
#define IMGVIEW_SLIDE_SHOW (BUTTON_HOME|BUTTON_POWER)
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -377,6 +377,16 @@ CONFIG_KEYPAD == MROBE500_PAD
#define JEWELS_CANCEL BUTTON_POWER #define JEWELS_CANCEL BUTTON_POWER
#define HK_CANCEL "Power" #define HK_CANCEL "Power"
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define JEWELS_UP BUTTON_HOME
#define JEWELS_DOWN BUTTON_OPTION
#define JEWELS_LEFT BUTTON_PREV
#define JEWELS_RIGHT BUTTON_NEXT
#define JEWELS_SELECT BUTTON_PLAY
#define JEWELS_CANCEL BUTTON_POWER
#define HK_SELECT "PLAY"
#define HK_CANCEL "POWER"
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -215,6 +215,14 @@
#define BTN_FIRE BUTTON_MENU #define BTN_FIRE BUTTON_MENU
#define BTN_PAUSE BUTTON_POWER #define BTN_PAUSE BUTTON_POWER
#elif (CONFIG_KEYPAD == XDUOO_X3_PAD)
#define BTN_UP BUTTON_VOL_UP
#define BTN_DOWN BUTTON_VOL_DOWN
#define BTN_LEFT BUTTON_PREV
#define BTN_RIGHT BUTTON_NEXT
#define BTN_FIRE BUTTON_PLAY
#define BTN_PAUSE BUTTON_OPTION
#else #else
#error Unsupported keypad #error Unsupported keypad
#endif #endif

View File

@ -228,6 +228,15 @@ const struct button_mapping pla_main_ctx[] =
{ PLA_DOWN_REPEAT, BUTTON_FF|BUTTON_REPEAT, BUTTON_NONE}, { PLA_DOWN_REPEAT, BUTTON_FF|BUTTON_REPEAT, BUTTON_NONE},
{ PLA_LEFT_REPEAT, BUTTON_REW|BUTTON_M|BUTTON_REPEAT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_REW|BUTTON_M|BUTTON_REPEAT, BUTTON_NONE},
{ PLA_RIGHT_REPEAT, BUTTON_FF|BUTTON_M|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_FF|BUTTON_M|BUTTON_REPEAT, BUTTON_NONE},
#elif (CONFIG_KEYPAD == XDUOO_X3_PAD)
{ PLA_UP, BUTTON_HOME, BUTTON_NONE },
{ PLA_DOWN, BUTTON_OPTION, BUTTON_NONE },
{ PLA_LEFT, BUTTON_PREV, BUTTON_NONE },
{ PLA_RIGHT, BUTTON_NEXT, BUTTON_NONE },
{ PLA_UP_REPEAT, BUTTON_HOME|BUTTON_REPEAT, BUTTON_NONE },
{ PLA_DOWN_REPEAT, BUTTON_OPTION|BUTTON_REPEAT, BUTTON_NONE },
{ PLA_LEFT_REPEAT, BUTTON_PREV|BUTTON_REPEAT, BUTTON_NONE },
{ PLA_RIGHT_REPEAT, BUTTON_NEXT|BUTTON_REPEAT, BUTTON_NONE },
#else #else
# ifndef HAVE_TOUCHSCREEN # ifndef HAVE_TOUCHSCREEN
# error pluginlib_actions: No directions defined # error pluginlib_actions: No directions defined
@ -447,6 +456,12 @@ const struct button_mapping pla_main_ctx[] =
{PLA_SELECT, BUTTON_PLAY, BUTTON_NONE}, {PLA_SELECT, BUTTON_PLAY, BUTTON_NONE},
{PLA_SELECT_REL, BUTTON_PLAY|BUTTON_REL, BUTTON_NONE}, {PLA_SELECT_REL, BUTTON_PLAY|BUTTON_REL, BUTTON_NONE},
{PLA_SELECT_REPEAT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE}, {PLA_SELECT_REPEAT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE},
#elif (CONFIG_KEYPAD == XDUOO_X3_PAD)
{PLA_CANCEL, BUTTON_POWER|BUTTON_REL, BUTTON_POWER},
{PLA_EXIT, BUTTON_POWER|BUTTON_REPEAT, BUTTON_NONE},
{PLA_SELECT, BUTTON_PLAY, BUTTON_NONE},
{PLA_SELECT_REL, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY},
{PLA_SELECT_REPEAT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE},
#else #else
# ifndef HAVE_TOUCHSCREEN # ifndef HAVE_TOUCHSCREEN

View File

@ -293,6 +293,14 @@
#define MIDI_VOL_DOWN BUTTON_VOLDOWN #define MIDI_VOL_DOWN BUTTON_VOLDOWN
#define MIDI_PLAYPAUSE BUTTON_SELECT #define MIDI_PLAYPAUSE BUTTON_SELECT
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define MIDI_QUIT BUTTON_POWER
#define MIDI_FFWD BUTTON_NEXT
#define MIDI_REWIND BUTTON_PREV
#define MIDI_VOL_UP BUTTON_VOL_UP
#define MIDI_VOL_DOWN BUTTON_VOL_DOWN
#define MIDI_PLAYPAUSE BUTTON_PLAY
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -404,6 +404,19 @@ CONFIG_KEYPAD == MROBE500_PAD
#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD #elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD
# define MINESWP_QUIT BUTTON_POWER # define MINESWP_QUIT BUTTON_POWER
#elif (CONFIG_KEYPAD == XDUOO_X3_PAD)
# define MINESWP_LEFT BUTTON_PREV
# define MINESWP_RIGHT BUTTON_NEXT
# define MINESWP_UP BUTTON_HOME
# define MINESWP_DOWN BUTTON_OPTION
# define MINESWP_QUIT BUTTON_POWER
# define MINESWP_TOGGLE_PRE BUTTON_PLAY
# define MINESWP_TOGGLE (BUTTON_PLAY | BUTTON_REL)
# define MINESWP_TOGGLE2 BUTTON_VOL_DOWN
# define MINESWP_DISCOVER (BUTTON_PLAY | BUTTON_REPEAT)
# define MINESWP_DISCOVER2 BUTTON_VOL_UP
# define MINESWP_INFO (BUTTON_PLAY | BUTTON_OPTION)
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -2556,6 +2556,12 @@ CONFIG_KEYPAD == MROBE500_PAD
#define MP3ENC_DONE BUTTON_POWER #define MP3ENC_DONE BUTTON_POWER
#define MP3ENC_SELECT BUTTON_SELECT #define MP3ENC_SELECT BUTTON_SELECT
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define MP3ENC_PREV BUTTON_HOME
#define MP3ENC_NEXT BUTTON_OPTION
#define MP3ENC_DONE BUTTON_POWER
#define MP3ENC_SELECT BUTTON_PLAY
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -306,6 +306,16 @@ struct mpeg_settings settings;
#define MPEG_START_TIME_DOWN BUTTON_DOWN #define MPEG_START_TIME_DOWN BUTTON_DOWN
#define MPEG_START_TIME_EXIT BUTTON_POWER #define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define MPEG_START_TIME_SELECT BUTTON_PLAY
#define MPEG_START_TIME_LEFT BUTTON_PREV
#define MPEG_START_TIME_RIGHT BUTTON_NEXT
#define MPEG_START_TIME_UP BUTTON_HOME
#define MPEG_START_TIME_DOWN BUTTON_OPTION
#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP
#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN
#define MPEG_START_TIME_EXIT BUTTON_POWER
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -441,6 +441,15 @@ CONFIG_KEYPAD == SANSA_M200_PAD
#define MPEG_RW BUTTON_LEFT #define MPEG_RW BUTTON_LEFT
#define MPEG_FF BUTTON_RIGHT #define MPEG_FF BUTTON_RIGHT
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define MPEG_MENU BUTTON_PLAY
#define MPEG_STOP BUTTON_POWER
#define MPEG_PAUSE BUTTON_HOME
#define MPEG_VOLDOWN BUTTON_VOL_DOWN
#define MPEG_VOLUP BUTTON_VOL_UP
#define MPEG_RW BUTTON_PREV
#define MPEG_FF BUTTON_NEXT
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -504,6 +504,20 @@
#define OSCILLOSCOPE_VOL_UP BUTTON_VOLUP #define OSCILLOSCOPE_VOL_UP BUTTON_VOLUP
#define OSCILLOSCOPE_VOL_DOWN BUTTON_VOLDOWN #define OSCILLOSCOPE_VOL_DOWN BUTTON_VOLDOWN
#elif (CONFIG_KEYPAD == XDUOO_X3_PAD)
#define OSCILLOSCOPE_QUIT BUTTON_POWER
#define OSCILLOSCOPE_DRAWMODE_PRE BUTTON_PLAY
#define OSCILLOSCOPE_DRAWMODE (BUTTON_PLAY | BUTTON_REL)
#define OSCILLOSCOPE_ORIENTATION_PRE BUTTON_PLAY
#define OSCILLOSCOPE_ORIENTATION (BUTTON_PLAY | BUTTON_REPEAT)
#define OSCILLOSCOPE_ADVMODE BUTTON_HOME
#define OSCILLOSCOPE_PAUSE BUTTON_OPTION
#define OSCILLOSCOPE_SPEED_UP BUTTON_NEXT
#define OSCILLOSCOPE_SPEED_DOWN BUTTON_PREV
#define OSCILLOSCOPE_VOL_UP BUTTON_VOL_UP
#define OSCILLOSCOPE_VOL_DOWN BUTTON_VOL_DOWN
#define NEED_LASTBUTTON
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -643,6 +643,23 @@ CONFIG_KEYPAD == MROBE500_PAD
#define QUIT_TEXT "POWER" #define QUIT_TEXT "POWER"
#define SELECT_TEXT "MENU" #define SELECT_TEXT "MENU"
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define PEGBOX_SELECT BUTTON_PLAY
#define PEGBOX_QUIT BUTTON_POWER
#define PEGBOX_RESTART (BUTTON_POWER | BUTTON_HOME)
#define PEGBOX_LVL_UP BUTTON_VOL_UP
#define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
#define PEGBOX_UP BUTTON_HOME
#define PEGBOX_DOWN BUTTON_OPTION
#define PEGBOX_RIGHT BUTTON_NEXT
#define PEGBOX_LEFT BUTTON_PREV
#define SELECT_TEXT "PLAY"
#define QUIT_TEXT "POWER"
#define RESTART_TEXT "HOME"
#define LVL_UP_TEXT "VOL+"
#define LVL_DOWN_TEXT "VOL-"
#else #else
#error Unsupported keymap! #error Unsupported keymap!
#endif #endif

View File

@ -118,7 +118,8 @@ const struct button_mapping pf_context_buttons[] =
CONFIG_KEYPAD == GIGABEAT_PAD || CONFIG_KEYPAD == GIGABEAT_S_PAD || \ CONFIG_KEYPAD == GIGABEAT_PAD || CONFIG_KEYPAD == GIGABEAT_S_PAD || \
CONFIG_KEYPAD == MROBE100_PAD || CONFIG_KEYPAD == MROBE500_PAD || \ CONFIG_KEYPAD == MROBE100_PAD || CONFIG_KEYPAD == MROBE500_PAD || \
CONFIG_KEYPAD == PHILIPS_SA9200_PAD || CONFIG_KEYPAD == SANSA_CLIP_PAD || \ CONFIG_KEYPAD == PHILIPS_SA9200_PAD || CONFIG_KEYPAD == SANSA_CLIP_PAD || \
CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD || CONFIG_KEYPAD == CREATIVE_ZENXFI3_PAD CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD || CONFIG_KEYPAD == CREATIVE_ZENXFI3_PAD || \
CONFIG_KEYPAD == XDUOO_X3_PAD
{PF_QUIT, BUTTON_POWER, BUTTON_NONE}, {PF_QUIT, BUTTON_POWER, BUTTON_NONE},
#if CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD #if CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
{PF_MENU, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT}, {PF_MENU, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT},

View File

@ -163,8 +163,14 @@ OUTPUT_FORMAT(elf32-littlemips)
#define IRAMORIG (0x00000000 + (56*1024)) #define IRAMORIG (0x00000000 + (56*1024))
#define IRAMSIZE (200*1024) #define IRAMSIZE (200*1024)
#elif CONFIG_CPU == JZ4732 #elif CONFIG_CPU == JZ4732 || CONFIG_CPU == JZ4760B
#define DRAMORIG 0x80004000 + STUBOFFSET #undef STUBOFFSET
#ifdef DEBUG
#define STUBOFFSET 0x14000
#else
#define STUBOFFSET 0x4000
#endif
#define DRAMORIG 0x80000000 + STUBOFFSET
#define IRAM DRAM #define IRAM DRAM
#define IRAMSIZE 0 #define IRAMSIZE 0
/* The bit of IRAM that is available is used in the core */ /* The bit of IRAM that is available is used in the core */

View File

@ -309,6 +309,14 @@ CONFIG_KEYPAD == MROBE500_PAD
#define PONG_QUIT BUTTON_POWER #define PONG_QUIT BUTTON_POWER
#define PONG_PAUSE BUTTON_MENU #define PONG_PAUSE BUTTON_MENU
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define PONG_QUIT BUTTON_POWER
#define PONG_PAUSE BUTTON_PLAY
#define PONG_LEFT_UP BUTTON_PREV
#define PONG_LEFT_DOWN BUTTON_OPTION
#define PONG_RIGHT_UP BUTTON_HOME
#define PONG_RIGHT_DOWN BUTTON_NEXT
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -328,6 +328,17 @@
#define REVERSI_BUTTON_MAKE_MOVE BUTTON_SELECT #define REVERSI_BUTTON_MAKE_MOVE BUTTON_SELECT
#define REVERSI_BUTTON_MENU BUTTON_POWER #define REVERSI_BUTTON_MENU BUTTON_POWER
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define REVERSI_BUTTON_QUIT BUTTON_POWER
#define REVERSI_BUTTON_UP BUTTON_HOME
#define REVERSI_BUTTON_DOWN BUTTON_OPTION
#define REVERSI_BUTTON_LEFT BUTTON_PREV
#define REVERSI_BUTTON_RIGHT BUTTON_NEXT
#define REVERSI_BUTTON_MAKE_MOVE BUTTON_PLAY
#define REVERSI_BUTTON_MAKE_MOVE_SHORTPRESS
#define REVERSI_BUTTON_MENU BUTTON_PLAY
#define REVERSI_BUTTON_MENU_LONGPRESS
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -480,6 +480,18 @@
#define ROCKBLOX_ROTATE_CCW BUTTON_VOLDOWN #define ROCKBLOX_ROTATE_CCW BUTTON_VOLDOWN
#define ROCKBLOX_DOWN BUTTON_DOWN #define ROCKBLOX_DOWN BUTTON_DOWN
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define ROCKBLOX_OFF BUTTON_POWER
#define ROCKBLOX_ROTATE_CCW BUTTON_HOME
#define ROCKBLOX_ROTATE_CCW2 BUTTON_VOL_DOWN
#define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
#define ROCKBLOX_DOWN BUTTON_OPTION
#define ROCKBLOX_LEFT BUTTON_PREV
#define ROCKBLOX_RIGHT BUTTON_NEXT
#define ROCKBLOX_DROP (BUTTON_PLAY|BUTTON_REL)
#define ROCKBLOX_RESTART (BUTTON_PLAY|BUTTON_REPEAT)
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -423,6 +423,16 @@ static void setoptions (void)
options.A = BUTTON_VOLDOWN; options.A = BUTTON_VOLDOWN;
options.B = BUTTON_VOLUP; options.B = BUTTON_VOLUP;
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
options.UP = BUTTON_PREV;
options.DOWN = BUTTON_NEXT;
options.A = BUTTON_HOME;
options.B = BUTTON_OPTION;
options.START = BUTTON_VOL_DOWN;
options.SELECT = BUTTON_VOL_UP;
options.MENU = BUTTON_POWER;
#else #else
#error No Keymap Defined! #error No Keymap Defined!
#endif #endif

View File

@ -327,6 +327,17 @@
#define ROCKPAINT_QUIT BUTTON_POWER #define ROCKPAINT_QUIT BUTTON_POWER
#define ROCKPAINT_MENU BUTTON_MENU #define ROCKPAINT_MENU BUTTON_MENU
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define ROCKPAINT_QUIT BUTTON_POWER
#define ROCKPAINT_DRAW BUTTON_PLAY
#define ROCKPAINT_MENU (BUTTON_HOME | BUTTON_POWER)
#define ROCKPAINT_TOOLBAR BUTTON_VOL_UP
#define ROCKPAINT_TOOLBAR2 BUTTON_VOL_DOWN
#define ROCKPAINT_UP BUTTON_HOME
#define ROCKPAINT_DOWN BUTTON_OPTION
#define ROCKPAINT_LEFT BUTTON_PREV
#define ROCKPAINT_RIGHT BUTTON_NEXT
#else #else
#error "Please define keys for this keypad" #error "Please define keys for this keypad"
#endif #endif

View File

@ -331,6 +331,15 @@ CONFIG_KEYPAD == MROBE500_PAD
#define PUZZLE_SHUFFLE BUTTON_POWER #define PUZZLE_SHUFFLE BUTTON_POWER
#define PUZZLE_PICTURE BUTTON_SELECT #define PUZZLE_PICTURE BUTTON_SELECT
#elif (CONFIG_KEYPAD == XDUOO_X3_PAD)
#define PUZZLE_QUIT BUTTON_POWER
#define PUZZLE_LEFT BUTTON_PREV
#define PUZZLE_RIGHT BUTTON_NEXT
#define PUZZLE_UP BUTTON_HOME
#define PUZZLE_DOWN BUTTON_OPTION
#define PUZZLE_SHUFFLE (BUTTON_HOME | BUTTON_POWER)
#define PUZZLE_PICTURE BUTTON_PLAY
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -289,6 +289,14 @@ dir is the current direction of the snake - 0=up, 1=right, 2=down, 3=left;
#define SNAKE_DOWN BUTTON_DOWN #define SNAKE_DOWN BUTTON_DOWN
#define SNAKE_PLAYPAUSE BUTTON_SELECT #define SNAKE_PLAYPAUSE BUTTON_SELECT
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define SNAKE_QUIT BUTTON_POWER
#define SNAKE_LEFT BUTTON_PREV
#define SNAKE_RIGHT BUTTON_NEXT
#define SNAKE_UP BUTTON_HOME
#define SNAKE_DOWN BUTTON_OPTION
#define SNAKE_PLAYPAUSE BUTTON_PLAY
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -419,6 +419,15 @@ CONFIG_KEYPAD == MROBE500_PAD
#define SNAKE2_PLAYPAUSE BUTTON_SELECT #define SNAKE2_PLAYPAUSE BUTTON_SELECT
#define SNAKE2_PLAYPAUSE_TEXT "Select" #define SNAKE2_PLAYPAUSE_TEXT "Select"
#elif (CONFIG_KEYPAD == XDUOO_X3_PAD)
#define SNAKE2_LEFT BUTTON_PREV
#define SNAKE2_RIGHT BUTTON_NEXT
#define SNAKE2_UP BUTTON_HOME
#define SNAKE2_DOWN BUTTON_OPTION
#define SNAKE2_QUIT BUTTON_POWER
#define SNAKE2_PLAYPAUSE BUTTON_PLAY
#define SNAKE2_PLAYPAUSE_TEXT "PLAY"
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -651,6 +651,22 @@
#define SOKOBAN_MENU BUTTON_MENU #define SOKOBAN_MENU BUTTON_MENU
#define SOKOBAN_MENU_NAME "[MENU]" #define SOKOBAN_MENU_NAME "[MENU]"
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define SOKOBAN_LEFT BUTTON_PREV
#define SOKOBAN_RIGHT BUTTON_NEXT
#define SOKOBAN_UP BUTTON_HOME
#define SOKOBAN_DOWN BUTTON_OPTION
#define SOKOBAN_MENU BUTTON_POWER
#define SOKOBAN_UNDO_PRE BUTTON_PLAY
#define SOKOBAN_UNDO (BUTTON_PLAY | BUTTON_REL)
#define SOKOBAN_REDO (BUTTON_POWER | BUTTON_PLAY)
#define SOKOBAN_LEVEL_DOWN BUTTON_VOL_DOWN
#define SOKOBAN_LEVEL_REPEAT (BUTTON_PLAY | BUTTON_NEXT)
#define SOKOBAN_LEVEL_UP BUTTON_VOL_UP
#define SOKOBAN_PAUSE BUTTON_PLAY
#define BUTTON_SAVE BUTTON_PLAY
#define BUTTON_SAVE_NAME "PLAY"
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -687,6 +687,25 @@ CONFIG_KEYPAD == MROBE500_PAD
#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD #elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD
# define SOL_QUIT BUTTON_POWER # define SOL_QUIT BUTTON_POWER
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
# define SOL_QUIT BUTTON_POWER
# define SOL_UP BUTTON_HOME
# define SOL_DOWN BUTTON_OPTION
# define SOL_LEFT BUTTON_PREV
# define SOL_RIGHT BUTTON_NEXT
# define SOL_MOVE_PRE BUTTON_PLAY
# define SOL_MOVE (BUTTON_PLAY | BUTTON_REL)
# define SOL_DRAW (BUTTON_POWER | BUTTON_REPEAT)
# define SOL_REM2CUR BUTTON_VOL_DOWN
# define SOL_CUR2STACK_PRE BUTTON_PLAY
# define SOL_CUR2STACK (BUTTON_PLAY | BUTTON_REPEAT)
# define SOL_REM2STACK BUTTON_VOL_UP
# define HK_MOVE "PLAY"
# define HK_DRAW "DBL HOME"
# define HK_REM2CUR "PREV"
# define HK_CUR2STACK "DBL PLAY"
# define HK_REM2STACK "NEXT"
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -354,6 +354,15 @@
#define AST_RIGHT BUTTON_RIGHT #define AST_RIGHT BUTTON_RIGHT
#define AST_FIRE BUTTON_SELECT #define AST_FIRE BUTTON_SELECT
#elif (CONFIG_KEYPAD == XDUOO_X3_PAD)
#define AST_PAUSE BUTTON_VOL_UP
#define AST_QUIT BUTTON_POWER
#define AST_THRUST BUTTON_HOME
#define AST_HYPERSPACE BUTTON_OPTION
#define AST_LEFT BUTTON_PREV
#define AST_RIGHT BUTTON_NEXT
#define AST_FIRE BUTTON_PLAY
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -623,6 +623,22 @@
#define STAR_TOGGLE_CONTROL_NAME "Play" #define STAR_TOGGLE_CONTROL_NAME "Play"
#define STAR_QUIT_NAME "Back" #define STAR_QUIT_NAME "Back"
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define STAR_QUIT BUTTON_POWER
#define STAR_LEFT BUTTON_PREV
#define STAR_RIGHT BUTTON_NEXT
#define STAR_UP BUTTON_HOME
#define STAR_DOWN BUTTON_OPTION
#define STAR_TOGGLE_CONTROL BUTTON_PLAY
#define STAR_LEVEL_UP (BUTTON_PLAY | BUTTON_NEXT)
#define STAR_LEVEL_DOWN (BUTTON_PLAY | BUTTON_PREV)
#define STAR_LEVEL_REPEAT (BUTTON_PLAY | BUTTON_OPTION)
#define STAR_TOGGLE_CONTROL_NAME "PLAY"
#define STAR_QUIT_NAME "POWER"
#define STAR_LEVEL_UP_NAME "PLAY + NEXT"
#define STAR_LEVEL_DOWN_NAME "PLAY + PREV"
#define STAR_LEVEL_REPEAT_NAME "PLAY + OPTION"
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -313,6 +313,14 @@
#define STOPWATCH_SCROLL_UP BUTTON_UP #define STOPWATCH_SCROLL_UP BUTTON_UP
#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN #define STOPWATCH_SCROLL_DOWN BUTTON_DOWN
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define STOPWATCH_QUIT BUTTON_POWER
#define STOPWATCH_START_STOP BUTTON_NEXT
#define STOPWATCH_RESET_TIMER BUTTON_PREV
#define STOPWATCH_LAP_TIMER BUTTON_PLAY
#define STOPWATCH_SCROLL_UP BUTTON_HOME
#define STOPWATCH_SCROLL_DOWN BUTTON_OPTION
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -423,6 +423,20 @@
#define SUDOKU_BUTTON_TOGGLE BUTTON_SELECT #define SUDOKU_BUTTON_TOGGLE BUTTON_SELECT
#define SUDOKU_BUTTON_POSSIBLE BUTTON_VOLUP #define SUDOKU_BUTTON_POSSIBLE BUTTON_VOLUP
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define SUDOKU_BUTTON_QUIT_PRE BUTTON_POWER
#define SUDOKU_BUTTON_QUIT (BUTTON_POWER | BUTTON_REPEAT)
#define SUDOKU_BUTTON_UP BUTTON_HOME
#define SUDOKU_BUTTON_DOWN BUTTON_OPTION
#define SUDOKU_BUTTON_LEFT BUTTON_PREV
#define SUDOKU_BUTTON_RIGHT BUTTON_NEXT
#define SUDOKU_BUTTON_TOGGLEBACK BUTTON_VOL_DOWN
#define SUDOKU_BUTTON_TOGGLE BUTTON_VOL_UP
#define SUDOKU_BUTTON_ALTTOGGLE BUTTON_PLAY
#define SUDOKU_BUTTON_MENU_PRE BUTTON_POWER
#define SUDOKU_BUTTON_MENU (BUTTON_POWER | BUTTON_REL)
#define SUDOKU_BUTTON_POSSIBLE (BUTTON_HOME | BUTTON_POWER)
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -550,6 +550,18 @@
#define TV_AUTOSCROLL BUTTON_VOLDOWN #define TV_AUTOSCROLL BUTTON_VOLDOWN
#define TV_BOOKMARK BUTTON_VOLUP #define TV_BOOKMARK BUTTON_VOLUP
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define TV_QUIT BUTTON_POWER
#define TV_SCROLL_UP BUTTON_VOL_UP
#define TV_SCROLL_DOWN BUTTON_VOL_DOWN
#define TV_SCREEN_LEFT BUTTON_PREV
#define TV_SCREEN_RIGHT BUTTON_NEXT
#define TV_MENU BUTTON_PLAY
#define TV_AUTOSCROLL (BUTTON_POWER | BUTTON_HOME)
#define TV_LINE_UP BUTTON_HOME
#define TV_LINE_DOWN BUTTON_OPTION
#define TV_BOOKMARK (BUTTON_OPTION | BUTTON_PLAY)
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -421,6 +421,17 @@
#define LABEL_VOLUME "Vol Up/Down" #define LABEL_VOLUME "Vol Up/Down"
#define LABEL_MENU "Select" #define LABEL_MENU "Select"
#elif (CONFIG_KEYPAD == XDUOO_X3_PAD)
#define VUMETER_QUIT BUTTON_POWER
#define VUMETER_HELP BUTTON_HOME
#define VUMETER_MENU BUTTON_PLAY
#define VUMETER_UP BUTTON_VOL_UP
#define VUMETER_DOWN BUTTON_VOL_DOWN
#define LABEL_HELP "HOME"
#define LABEL_QUIT "POWER"
#define LABEL_MENU "PLAY"
#define LABEL_VOLUME "VOL UP/DN"
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -393,6 +393,15 @@ CONFIG_KEYPAD == MROBE500_PAD
#define BTN_QUIT BUTTON_POWER #define BTN_QUIT BUTTON_POWER
#define BTN_STOPRESET (BUTTON_SELECT|BUTTON_REPEAT) #define BTN_STOPRESET (BUTTON_SELECT|BUTTON_REPEAT)
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define BTN_DIR_UP BUTTON_HOME
#define BTN_DIR_DOWN BUTTON_OPTION
#define BTN_DIR_LEFT BUTTON_PREV
#define BTN_DIR_RIGHT BUTTON_NEXT
#define BTN_STARTPAUSE BUTTON_PLAY
#define BTN_QUIT BUTTON_POWER
#define BTN_STOPRESET (BUTTON_HOME | BUTTON_POWER)
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -342,6 +342,15 @@ CONFIG_KEYPAD == MROBE500_PAD
#define DOWN BUTTON_DOWN #define DOWN BUTTON_DOWN
#define PAUSE BUTTON_SELECT #define PAUSE BUTTON_SELECT
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define QUIT BUTTON_POWER
#define LEFT BUTTON_PREV
#define RIGHT BUTTON_NEXT
#define UP BUTTON_HOME
#define DOWN BUTTON_OPTION
#define PAUSE BUTTON_PLAY
#else #else
#error No keymap defined! #error No keymap defined!
#endif #endif

View File

@ -282,6 +282,14 @@
#define ZX_RIGHT BUTTON_RIGHT #define ZX_RIGHT BUTTON_RIGHT
#define ZX_SELECT BUTTON_SELECT #define ZX_SELECT BUTTON_SELECT
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define ZX_SELECT BUTTON_PLAY
#define ZX_MENU BUTTON_POWER
#define ZX_LEFT BUTTON_PREV
#define ZX_RIGHT BUTTON_NEXT
#define ZX_UP BUTTON_HOME
#define ZX_DOWN BUTTON_OPTION
#else #else
#error Keymap not defined! #error Keymap not defined!

View File

@ -278,6 +278,15 @@
#define KBD_UP BUTTON_UP #define KBD_UP BUTTON_UP
#define KBD_DOWN BUTTON_DOWN #define KBD_DOWN BUTTON_DOWN
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
#define KBD_SELECT BUTTON_PLAY
#define KBD_ABORT BUTTON_POWER
#define KBD_LEFT BUTTON_PREV
#define KBD_RIGHT BUTTON_NEXT
#define KBD_UP BUTTON_HOME
#define KBD_DOWN BUTTON_OPTION
#endif #endif
#ifdef HAVE_TOUCHSCREEN #ifdef HAVE_TOUCHSCREEN

View File

@ -811,6 +811,10 @@ struct user_settings
int roll_off; int roll_off;
#endif #endif
#ifdef AUDIOHW_HAVE_FUNCTIONAL_MODE
int func_mode;
#endif
#ifdef AUDIOHW_HAVE_EQ #ifdef AUDIOHW_HAVE_EQ
/** Hardware EQ tone controls **/ /** Hardware EQ tone controls **/
struct hw_eq_band struct hw_eq_band

View File

@ -53,6 +53,9 @@ samsung_yps3.c
#elif defined(ONDA_VX747) || defined(ONDA_VX747P) || defined(ONDA_VX767) || defined(ONDA_VX777) #elif defined(ONDA_VX747) || defined(ONDA_VX747P) || defined(ONDA_VX767) || defined(ONDA_VX777)
ondavx747.c ondavx747.c
show_logo.c show_logo.c
#elif defined(XDUOO_X3)
xduoox3.c
show_logo.c
#elif defined(CREATIVE_ZVx) #elif defined(CREATIVE_ZVx)
creativezvm.c creativezvm.c
#elif CONFIG_CPU==AS3525 || CONFIG_CPU==AS3525v2 #elif CONFIG_CPU==AS3525 || CONFIG_CPU==AS3525v2

View File

@ -54,7 +54,7 @@
|| defined(SAMSUNG_YH820) || defined(PHILIPS_SA9200) \ || defined(SAMSUNG_YH820) || defined(PHILIPS_SA9200) \
|| defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) \ || defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) \
|| defined(ONDA_VX747) || defined(PBELL_VIBE500) \ || defined(ONDA_VX747) || defined(PBELL_VIBE500) \
|| defined(TOSHIBA_GIGABEAT_S) || defined(TOSHIBA_GIGABEAT_S) || defined(XDUOO_X3)
bool verbose = false; bool verbose = false;
#else #else
bool verbose = true; bool verbose = true;

184
bootloader/xduoox3.c Normal file
View File

@ -0,0 +1,184 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 "config.h"
#include "jz4760b.h"
#include "../kernel-internal.h"
#include "backlight.h"
#include "font.h"
#include "lcd.h"
#include "file.h"
#include "usb.h"
#include "system.h"
#include "button.h"
#include "common.h"
#include "rb-loader.h"
#include "loader_strerror.h"
#include "storage.h"
#include "file_internal.h"
#include "disk.h"
#include "string.h"
#include "adc.h"
#include "version.h"
#include "xdebug.h"
extern void show_logo(void);
extern void power_off(void);
static void show_splash(int timeout, const char *msg)
{
reset_screen();
lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2,
(LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg);
lcd_update();
sleep(timeout);
}
static void usb_mode(void)
{
int button;
/* Init USB */
usb_init();
usb_start_monitoring();
/* Wait for threads to connect */
show_splash(HZ/2, "Waiting for USB");
while (1)
{
button = button_get_w_tmo(HZ/2);
if (button == SYS_USB_CONNECTED)
break; /* Hit */
}
if (button == SYS_USB_CONNECTED)
{
/* Got the message - wait for disconnect */
show_splash(0, "Bootloader USB mode");
usb_acknowledge(SYS_USB_CONNECTED_ACK);
while (1)
{
button = button_get(true);
if (button == SYS_USB_DISCONNECTED)
break;
}
}
}
static int boot_rockbox(void)
{
int rc;
void (*kernel_entry)(void);
printf("Mounting disk...\n");
rc = disk_mount_all();
if (rc <= 0)
{
verbose = true;
error(EDISK,rc, true);
}
printf("Loading firmware...\n");
rc = load_firmware((unsigned char *)CONFIG_SDRAM_START, BOOTFILE, 0x400000);
if(rc <= EFILE_EMPTY)
return rc;
else
{
printf("Starting Rockbox...\n");
adc_close(); /* Disable SADC, seems to fix the re-init Rockbox does */
disable_interrupt();
kernel_entry = (void*) CONFIG_SDRAM_START;
kernel_entry();
return 0; /* Shouldn't happen */
}
}
static void reset_configuration(void)
{
int rc;
rc = disk_mount_all();
if (rc <= 0)
{
verbose = true;
error(EDISK,rc, true);
}
if(rename(ROCKBOX_DIR "/config.cfg", ROCKBOX_DIR "/config.old") == 0)
show_splash(HZ/2, "Configuration reset successfully!");
else
show_splash(HZ/2, "Couldn't reset configuration!");
}
int main(void)
{
int rc;
serial_puts("\n\nSPL Stage 2\n\n");
kernel_init();
lcd_init();
font_init();
lcd_setfont(FONT_SYSFIXED);
button_init();
backlight_init();
show_logo();
filesystem_init();
rc = storage_init();
if(rc)
{
verbose = true;
error(EATA, rc, true);
}
/* Don't mount the disks yet, there could be file system/partition errors
which are fixable in USB mode */
reset_screen();
printf(MODEL_NAME" Rockbox Bootloader\n");
printf("Version %s\n", rbversion);
rc = boot_rockbox();
if(rc <= EFILE_EMPTY)
{
verbose = true;
printf("Error: %s", loader_strerror(rc));
}
/* Halt */
while (1)
core_idle();
return 0;
}

View File

@ -663,6 +663,9 @@ Constantine Mountantonakis
Ivan Pesic Ivan Pesic
Jonatan Nyberg Jonatan Nyberg
Alessandro Stoppani Alessandro Stoppani
Alexander Yurenin
Roman Stolyarov
Solomon Peachy
The libmad team The libmad team
The wavpack team The wavpack team

View File

@ -366,8 +366,10 @@ drivers/rtc/rtc_mr100.c
drivers/rtc/rtc_mc13783.c drivers/rtc/rtc_mc13783.c
#elif (CONFIG_RTC == RTC_TCC77X) #elif (CONFIG_RTC == RTC_TCC77X)
drivers/rtc/rtc_tcc77x.c drivers/rtc/rtc_tcc77x.c
#elif (CONFIG_RTC == RTC_JZ47XX) #elif (CONFIG_RTC == RTC_JZ4740)
drivers/rtc/rtc_jz4740.c drivers/rtc/rtc_jz4740.c
#elif (CONFIG_RTC == RTC_JZ4760)
drivers/rtc/rtc_jz4760.c
#elif (CONFIG_RTC == RTC_S35390A) #elif (CONFIG_RTC == RTC_S35390A)
drivers/rtc/rtc_s35390a.c drivers/rtc/rtc_s35390a.c
#elif (CONFIG_RTC == RTC_S35380A) #elif (CONFIG_RTC == RTC_S35380A)
@ -477,6 +479,8 @@ drivers/audio/dummy_codec.c
drivers/audio/df1704.c drivers/audio/df1704.c
#elif defined (HAVE_PCM1792_CODEC) #elif defined (HAVE_PCM1792_CODEC)
drivers/audio/pcm1792.c drivers/audio/pcm1792.c
#elif defined (HAVE_CS4398)
drivers/audio/cs4398.c
#endif /* defined(HAVE_*) */ #endif /* defined(HAVE_*) */
#else /* PLATFORM_HOSTED */ #else /* PLATFORM_HOSTED */
#if defined(SAMSUNG_YPR0) && defined(HAVE_AS3514) #if defined(SAMSUNG_YPR0) && defined(HAVE_AS3514)
@ -739,9 +743,9 @@ target/arm/crt0.S
#elif defined(CPU_MIPS) && (CONFIG_PLATFORM & PLATFORM_NATIVE) #elif defined(CPU_MIPS) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
target/mips/mmu-mips.c target/mips/mmu-mips.c
#if CONFIG_CPU==JZ4732 #if CONFIG_CPU==JZ4732 || CONFIG_CPU==JZ4760B
target/mips/ingenic_jz47xx/crt0.S target/mips/ingenic_jz47xx/crt0.S
#endif /* CONFIG_CPU == JZ4732 */ #endif /* CONFIG_CPU == JZ4732 || JZ4760B */
#else #else
@ -1725,6 +1729,24 @@ target/mips/ingenic_jz47xx/pcm-jz4740.c
drivers/nand_id.c drivers/nand_id.c
#endif /* CONFIG_CPU == JZ4732 */ #endif /* CONFIG_CPU == JZ4732 */
#if CONFIG_CPU == JZ4760B
target/mips/ingenic_jz47xx/dma_acc-jz4760.c
target/mips/ingenic_jz47xx/ata-nand-jz4760.c
target/mips/ingenic_jz47xx/ata-sd-jz4760.c
target/mips/ingenic_jz47xx/debug-jz4760.c
target/mips/ingenic_jz47xx/kernel-jz4760.c
target/mips/ingenic_jz47xx/i2c-jz4760.c
target/mips/ingenic_jz47xx/lcd-jz4760.c
target/mips/ingenic_jz47xx/system-jz4760.c
target/mips/ingenic_jz47xx/usb-jz4760.c
target/mips/ingenic_jz47xx/timer-jz4760.c
#ifndef BOOTLOADER
target/mips/ingenic_jz47xx/codec-jz4760.c
target/mips/ingenic_jz47xx/pcm-jz4760.c
#endif /* BOOTLOADER */
drivers/nand_id.c
#endif /* CONFIG_CPU == JZ4760B */
#if defined(ONDA_VX747) || defined(ONDA_VX747P) || defined(ONDA_VX777) #if defined(ONDA_VX747) || defined(ONDA_VX747P) || defined(ONDA_VX777)
target/mips/ingenic_jz47xx/onda_vx747/backlight-onda_vx7X7.c target/mips/ingenic_jz47xx/onda_vx747/backlight-onda_vx7X7.c
target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c
@ -1741,6 +1763,13 @@ target/mips/ingenic_jz47xx/onda_vx767/power-onda_vx767.c
target/mips/ingenic_jz47xx/onda_vx767/sadc-onda_vx767.c target/mips/ingenic_jz47xx/onda_vx767/sadc-onda_vx767.c
#endif /* ONDA_VX767 */ #endif /* ONDA_VX767 */
#if defined(XDUOO_X3)
target/mips/ingenic_jz47xx/xduoo_x3/backlight-xduoo_x3.c
target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c
target/mips/ingenic_jz47xx/xduoo_x3/power-xduoo_x3.c
target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c
#endif /* XDUOO_X3 */
#if defined(LYRE_PROTO1) #if defined(LYRE_PROTO1)
target/arm/at91sam/lyre_proto1/adc-lyre_proto1.c target/arm/at91sam/lyre_proto1/adc-lyre_proto1.c
target/arm/at91sam/lyre_proto1/backlight-lyre_proto1.c target/arm/at91sam/lyre_proto1/backlight-lyre_proto1.c

View File

@ -0,0 +1,41 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 "system.h"
#include "cs4398.h"
#include "config.h"
#include "audio.h"
#include "audiohw.h"
#include "i2c.h"
void cs4398_write_reg(uint8_t reg, uint8_t val)
{
unsigned char buf[2] = {reg, val};
i2c_write(CS4398_I2C_ADDR, (unsigned char *)&buf, 2);
}
uint8_t cs4398_read_reg(uint8_t reg)
{
unsigned char buf[2] = {reg, 0xff};
i2c_write(CS4398_I2C_ADDR, (unsigned char *)&buf[0], 1);
i2c_read(CS4398_I2C_ADDR, (unsigned char *)&buf[1], 1);
return buf[1];
}

View File

@ -122,6 +122,10 @@ void audiohw_set_depth_3d(int value)
void audiohw_set_lineout_volume(int vol_l, int vol_r) void audiohw_set_lineout_volume(int vol_l, int vol_r)
{ (void)vol_l; (void)vol_r; } { (void)vol_l; (void)vol_r; }
#endif #endif
#if defined(AUDIOHW_HAVE_FILTER_ROLL_OFF)
void audiohw_set_filter_roll_off(int value)
{ (void)value; }
#endif
void audiohw_close(void) {} void audiohw_close(void) {}

View File

@ -34,27 +34,38 @@ static const struct nand_info samsung[] =
/* /*
id1, id2 id1, id2
pages/block, blocks, page_size, spare_size, col_cycles, row_cycles, planes pages/block, blocks, page_size, spare_size, col_cycles, row_cycles, planes
*/ */
{0xDC, 0x10, /* K9F4G08UOM */ {0xDC, 0x10, /* K9F4G08UOM */
64, 4096, 2048, 64, 2, 3, 1 }, 64, 4096, 2048, 64, 2, 3, 1 },
{0xD3, 0x51, /* K9K8G08UOM */ {0xD3, 0x51, /* K9K8G08UOM */
64, 8192, 2048, 64, 2, 3, 1 }, 64, 8192, 2048, 64, 2, 3, 1 },
{0xD5, 0x14, /* K9GAG08UOM */ {0xD5, 0x14, /* K9GAG08UOM */
128, 4096, 4096, 128, 2, 3, 2 }, 128, 4096, 4096, 128, 2, 3, 2 },
{0xD5, 0x55, /* K9LAG08UOM, K9HBG08U1M, K9MCG08U5M */ {0xD5, 0x55, /* K9LAG08UOM, K9HBG08U1M, K9MCG08U5M */
128, 8192, 2048, 64, 2, 3, 4 }, 128, 8192, 2048, 64, 2, 3, 4 },
{0xD7, 0x55, /* K9LBG08UOM */ {0xD7, 0x55, /* K9LBG08UOM */
128, 8192, 4096, 128, 2, 3, 4 }, 128, 8192, 4096, 128, 2, 3, 4 },
}; };
static const struct nand_info gigadevice[] =
{
/*
id1, id2
pages/block, blocks, page_size, spare_size, col_cycles, row_cycles, planes
*/
{0xB1, 0x80, /* MD5N01G51MSD1B */
64, 1024, 2048, 64, 2, 2, 1 },
};
#define NI(id, x) {id, (struct nand_info*)x, (sizeof(x)/sizeof(struct nand_info))} #define NI(id, x) {id, (struct nand_info*)x, (sizeof(x)/sizeof(struct nand_info))}
static const struct nand_manufacturer all[] = static const struct nand_manufacturer all[] =
{ {
NI(0xEC, samsung), NI(0xEC, samsung),
NI(0x98, gigadevice),
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -63,7 +74,7 @@ struct nand_info* nand_identify(unsigned char data[5])
{ {
unsigned int i; unsigned int i;
int found = -1; int found = -1;
for(i = 0; i < (sizeof(all)/sizeof(struct nand_manufacturer)); i++) for(i = 0; i < (sizeof(all)/sizeof(struct nand_manufacturer)); i++)
{ {
if(data[0] == all[i].id) if(data[0] == all[i].id)
@ -72,16 +83,16 @@ struct nand_info* nand_identify(unsigned char data[5])
break; break;
} }
} }
if(found < 0) if(found < 0)
return NULL; return NULL;
for(i = 0; i < all[found].total; i++) for(i = 0; i < all[found].total; i++)
{ {
if(data[1] == all[found].info[i].dev_id && if(data[1] == all[found].info[i].dev_id &&
data[2] == all[found].info[i].dev_id2) data[2] == all[found].info[i].dev_id2)
return &all[found].info[i]; return &all[found].info[i];
} }
return NULL; return NULL;
} }

View File

@ -0,0 +1,124 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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.
*
****************************************************************************/
/*
* Real Time Clock interface for Jz4760.
*
*/
#include "config.h"
#include "cpu.h"
#include "rtc.h"
#include "timefuncs.h"
#include "logf.h"
#define RTC_FREQ_DIVIDER (32768 - 1)
/* Stolen from dietlibc-0.29/libugly/gmtime_r.c (GPLv2) */
#define SPD (24*60*60)
#define ISLEAP(year) (!(year%4) && ((year%100) || !(year%400)))
static void _localtime(const time_t t, struct tm *r)
{
time_t i;
register time_t work = t % SPD;
static int m_to_d[12] = /* This could be shared with mktime() */
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
r->tm_sec = work % 60;
work /= 60;
r->tm_min = work % 60;
r->tm_hour = work / 60;
work = t / SPD;
r->tm_wday = (4 + work) % 7;
for (i=1970; ; ++i)
{
register time_t k = ISLEAP(i) ? 366 : 365;
if (work >= k)
work -= k;
else
break;
}
r->tm_year = i - 1900;
r->tm_yday = work;
r->tm_mday = 1;
if (ISLEAP(i) && (work>58))
{
if (work==59)
r->tm_mday=2; /* 29.2. */
work-=1;
}
for (i=11; i && (m_to_d[i] > work); --i);
r->tm_mon = i;
r->tm_mday += work - m_to_d[i];
}
int rtc_read_datetime(struct tm *tm)
{
_localtime(rtc_read_reg(RTC_RTCSR), tm);
return 1;
}
int rtc_write_datetime(const struct tm *tm)
{
rtc_write_reg(RTC_RTCSR, mktime((struct tm*)tm));
return 0;
}
void rtc_init(void)
{
unsigned int cfc,hspr,rgr_1hz;
__cpm_select_rtcclk_rtc();
cfc = HSPR_RTCV;
hspr = rtc_read_reg(RTC_HSPR);
rgr_1hz = rtc_read_reg(RTC_RTCGR) & RTCGR_NC1HZ_MASK;
if((hspr != cfc) || (rgr_1hz != RTC_FREQ_DIVIDER))
{
/* We are powered on for the first time !!! */
/* Set 32768 rtc clocks per seconds */
rtc_write_reg(RTC_RTCGR, RTC_FREQ_DIVIDER);
/* Set minimum wakeup_n pin low-level assertion time for wakeup: 100ms */
rtc_write_reg(RTC_HWFCR, HWFCR_WAIT_TIME(100));
rtc_write_reg(RTC_HRCR, HRCR_WAIT_TIME(60));
/* Reset to the default time */
rtc_write_reg(RTC_RTCSR, 946681200); /* 01/01/2000 */
/* start rtc */
rtc_write_reg(RTC_RTCCR, RTCCR_RTCE);
rtc_write_reg(RTC_HSPR, cfc);
}
/* clear all rtc flags */
rtc_write_reg(RTC_HWRSR, 0);
}

View File

@ -209,6 +209,8 @@ struct sound_settings_info
#include "pcm1792.h" #include "pcm1792.h"
#elif defined(HAVE_NWZ_LINUX_CODEC) #elif defined(HAVE_NWZ_LINUX_CODEC)
#include "nwzlinux_codec.h" #include "nwzlinux_codec.h"
#elif defined(HAVE_CS4398)
#include "cs4398.h"
#elif (CONFIG_PLATFORM & (PLATFORM_ANDROID | PLATFORM_MAEMO\ #elif (CONFIG_PLATFORM & (PLATFORM_ANDROID | PLATFORM_MAEMO\
| PLATFORM_PANDORA | PLATFORM_SDL)) | PLATFORM_PANDORA | PLATFORM_SDL))
#include "hosted_codec.h" #include "hosted_codec.h"
@ -576,7 +578,6 @@ void audiohw_set_depth_3d(int val);
void audiohw_set_filter_roll_off(int val); void audiohw_set_filter_roll_off(int val);
#endif #endif
void audiohw_set_frequency(int fsel); void audiohw_set_frequency(int fsel);
#ifdef HAVE_RECORDING #ifdef HAVE_RECORDING

View File

@ -113,6 +113,9 @@ AUDIOHW_SETTINGS(
#if defined(AUDIOHW_HAVE_FILTER_ROLL_OFF) #if defined(AUDIOHW_HAVE_FILTER_ROLL_OFF)
AUDIOHW_SETTING_ENT(FILTER_ROLL_OFF, sound_set_filter_roll_off) AUDIOHW_SETTING_ENT(FILTER_ROLL_OFF, sound_set_filter_roll_off)
#endif #endif
#if defined(AUDIOHW_HAVE_FUNCTIONAL_MODE)
AUDIOHW_SETTING_ENT(FUNCTIONAL_MODE, sound_set_functional_mode)
#endif
/* Hardware EQ tone controls */ /* Hardware EQ tone controls */
#if defined(AUDIOHW_HAVE_EQ) #if defined(AUDIOHW_HAVE_EQ)
AUDIOHW_SETTING_ENT(EQ_BAND1_GAIN, sound_set_hw_eq_band1_gain) AUDIOHW_SETTING_ENT(EQ_BAND1_GAIN, sound_set_hw_eq_band1_gain)

View File

@ -82,6 +82,7 @@
#define S5L8701 8701 #define S5L8701 8701
#define S5L8702 8702 #define S5L8702 8702
#define JZ4732 4732 #define JZ4732 4732
#define JZ4760B 47602
#define AS3525 3525 #define AS3525 3525
#define AT91SAM9260 9260 #define AT91SAM9260 9260
#define AS3525v2 35252 #define AS3525v2 35252
@ -162,11 +163,12 @@
#define CREATIVE_ZEN_PAD 58 #define CREATIVE_ZEN_PAD 58
#define SAMSUNG_YPZ5_PAD 59 #define SAMSUNG_YPZ5_PAD 59
#define IHIFI_PAD 60 #define IHIFI_PAD 60
#define SAMSUNG_YPR1_PAD 61 #define SAMSUNG_YPR1_PAD 61
#define SAMSUNG_YH92X_PAD 62 #define SAMSUNG_YH92X_PAD 62
#define DX50_PAD 63 #define DX50_PAD 63
#define SONY_NWZA860_PAD 64 /* The NWZ-A860 is too different (touchscreen) */ #define SONY_NWZA860_PAD 64 /* The NWZ-A860 is too different (touchscreen) */
#define AGPTEK_ROCKER_PAD 65 #define AGPTEK_ROCKER_PAD 65
#define XDUOO_X3_PAD 66
/* CONFIG_POWER_SAVE combinable bit flags*/ /* CONFIG_POWER_SAVE combinable bit flags*/
#define POWERSV_CPU 0x1 #define POWERSV_CPU 0x1
@ -287,6 +289,7 @@
#define LCD_SAMSUNGYPR1 62 /* as used by Samsung YP-R1 */ #define LCD_SAMSUNGYPR1 62 /* as used by Samsung YP-R1 */
#define LCD_NWZ_LINUX 63 /* as used in the Linux-based NWZ series */ #define LCD_NWZ_LINUX 63 /* as used in the Linux-based NWZ series */
#define LCD_INGENIC_LINUX 64 #define LCD_INGENIC_LINUX 64
#define LCD_XDUOOX3 65 /* as used by the xDuoo X3 */
/* LCD_PIXELFORMAT */ /* LCD_PIXELFORMAT */
#define HORIZONTAL_PACKING 1 #define HORIZONTAL_PACKING 1
@ -358,12 +361,13 @@ Lyre prototype 1 */
#define RTC_MC13783 13 /* Freescale MC13783 PMIC */ #define RTC_MC13783 13 /* Freescale MC13783 PMIC */
#define RTC_S5L8700 14 #define RTC_S5L8700 14
#define RTC_S35390A 15 #define RTC_S35390A 15
#define RTC_JZ47XX 16 /* Ingenic Jz47XX */ #define RTC_JZ4740 16 /* Ingenic Jz4740 */
#define RTC_NANO2G 17 /* This seems to be a PCF5063x */ #define RTC_NANO2G 17 /* This seems to be a PCF5063x */
#define RTC_D2 18 /* Either PCF50606 or PCF50635 */ #define RTC_D2 18 /* Either PCF50606 or PCF50635 */
#define RTC_S35380A 19 #define RTC_S35380A 19
#define RTC_IMX233 20 #define RTC_IMX233 20
#define RTC_STM41T62 21 /* ST M41T62 */ #define RTC_STM41T62 21 /* ST M41T62 */
#define RTC_JZ4760 22 /* Ingenic Jz4760 */
/* USB On-the-go */ /* USB On-the-go */
#define USBOTG_M66591 6591 /* M:Robe 500 */ #define USBOTG_M66591 6591 /* M:Robe 500 */
@ -372,6 +376,7 @@ Lyre prototype 1 */
#define USBOTG_M5636 5636 /* iAudio X5 */ #define USBOTG_M5636 5636 /* iAudio X5 */
#define USBOTG_ARC 5020 /* PortalPlayer 502x and IMX233 */ #define USBOTG_ARC 5020 /* PortalPlayer 502x and IMX233 */
#define USBOTG_JZ4740 4740 /* Ingenic Jz4740/Jz4732 */ #define USBOTG_JZ4740 4740 /* Ingenic Jz4740/Jz4732 */
#define USBOTG_JZ4760 4760 /* Ingenic Jz4760/Jz4760B */
#define USBOTG_AS3525 3525 /* AMS AS3525 */ #define USBOTG_AS3525 3525 /* AMS AS3525 */
#define USBOTG_S3C6400X 6400 /* Samsung S3C6400X, also used in the S5L8701/S5L8702/S5L8720 */ #define USBOTG_S3C6400X 6400 /* Samsung S3C6400X, also used in the S5L8701/S5L8702/S5L8720 */
#define USBOTG_DESIGNWARE 6401 /* Synopsys DesignWare OTG, used in S5L8701/S5L8702/S5L8720/AS3252v2 */ #define USBOTG_DESIGNWARE 6401 /* Synopsys DesignWare OTG, used in S5L8701/S5L8702/S5L8720/AS3252v2 */
@ -612,6 +617,8 @@ Lyre prototype 1 */
#include "config/sonynwze350.h" #include "config/sonynwze350.h"
#elif defined(AGPTEK_ROCKER) #elif defined(AGPTEK_ROCKER)
#include "config/agptekrocker.h" #include "config/agptekrocker.h"
#elif defined(XDUOO_X3)
#include "config/xduoox3.h"
#else #else
/* no known platform */ /* no known platform */
#endif #endif
@ -980,7 +987,7 @@ Lyre prototype 1 */
#endif /* BOOTLOADER */ #endif /* BOOTLOADER */
#if defined(HAVE_USBSTACK) || (CONFIG_CPU == JZ4732) \ #if defined(HAVE_USBSTACK) || (CONFIG_CPU == JZ4732) || (CONFIG_CPU == JZ4760B) \
|| (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) \ || (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) \
|| defined(CPU_S5L870X) || (CONFIG_CPU == S3C2440) \ || defined(CPU_S5L870X) || (CONFIG_CPU == S3C2440) \
|| defined(APPLICATION) || (CONFIG_CPU == PP5002) \ || defined(APPLICATION) || (CONFIG_CPU == PP5002) \
@ -1057,14 +1064,14 @@ Lyre prototype 1 */
(CONFIG_CPU == TCC7801) || \ (CONFIG_CPU == TCC7801) || \
(CONFIG_CPU == IMX233 && !defined(PLUGIN) && !defined(CODEC)) || /* IMX233: core only */ \ (CONFIG_CPU == IMX233 && !defined(PLUGIN) && !defined(CODEC)) || /* IMX233: core only */ \
defined(CPU_S5L870X)) || /* Samsung S5L8700: core, plugins, codecs */ \ defined(CPU_S5L870X)) || /* Samsung S5L8700: core, plugins, codecs */ \
(CONFIG_CPU == JZ4732 && !defined(PLUGIN) && !defined(CODEC)) /* Jz4740: core only */ ((CONFIG_CPU == JZ4732 || CONFIG_CPU == JZ4760B) && !defined(PLUGIN) && !defined(CODEC)) /* Jz47XX: core only */
#define ICODE_ATTR __attribute__ ((section(".icode"))) #define ICODE_ATTR __attribute__ ((section(".icode")))
#define ICONST_ATTR __attribute__ ((section(".irodata"))) #define ICONST_ATTR __attribute__ ((section(".irodata")))
#define IDATA_ATTR __attribute__ ((section(".idata"))) #define IDATA_ATTR __attribute__ ((section(".idata")))
#define IBSS_ATTR __attribute__ ((section(".ibss"))) #define IBSS_ATTR __attribute__ ((section(".ibss")))
#define USE_IRAM #define USE_IRAM
#if CONFIG_CPU != SH7034 && (CONFIG_CPU != AS3525 || MEMORYSIZE > 2) \ #if CONFIG_CPU != SH7034 && (CONFIG_CPU != AS3525 || MEMORYSIZE > 2) \
&& CONFIG_CPU != JZ4732 && CONFIG_CPU != AS3525v2 && CONFIG_CPU != IMX233 && CONFIG_CPU != JZ4732 && CONFIG_CPU != JZ4760B && CONFIG_CPU != AS3525v2 && CONFIG_CPU != IMX233
#define PLUGIN_USE_IRAM #define PLUGIN_USE_IRAM
#endif #endif
#else #else
@ -1207,6 +1214,7 @@ Lyre prototype 1 */
#define USB_HAS_BULK #define USB_HAS_BULK
#elif (CONFIG_USBOTG == USBOTG_ARC) || \ #elif (CONFIG_USBOTG == USBOTG_ARC) || \
(CONFIG_USBOTG == USBOTG_JZ4740) || \ (CONFIG_USBOTG == USBOTG_JZ4740) || \
(CONFIG_USBOTG == USBOTG_JZ4760) || \
(CONFIG_USBOTG == USBOTG_M66591) || \ (CONFIG_USBOTG == USBOTG_M66591) || \
(CONFIG_USBOTG == USBOTG_DESIGNWARE) || \ (CONFIG_USBOTG == USBOTG_DESIGNWARE) || \
(CONFIG_USBOTG == USBOTG_AS3525) (CONFIG_USBOTG == USBOTG_AS3525)
@ -1231,7 +1239,8 @@ Lyre prototype 1 */
#if defined(HAVE_BOOTLOADER_USB_MODE) || \ #if defined(HAVE_BOOTLOADER_USB_MODE) || \
defined(CREATIVE_ZVx) || defined(CPU_TCC77X) || defined(CPU_TCC780X) || \ defined(CREATIVE_ZVx) || defined(CPU_TCC77X) || defined(CPU_TCC780X) || \
CONFIG_USBOTG == USBOTG_JZ4740 || CONFIG_USBOTG == USBOTG_AS3525 || \ CONFIG_USBOTG == USBOTG_JZ4740 || CONFIG_USBOTG == USBOTG_AS3525 || \
CONFIG_USBOTG == USBOTG_S3C6400X || CONFIG_USBOTG == USBOTG_DESIGNWARE CONFIG_USBOTG == USBOTG_S3C6400X || CONFIG_USBOTG == USBOTG_DESIGNWARE || \
CONFIG_USBOTG == USBOTG_JZ4760
#define USB_ENABLE_STORAGE #define USB_ENABLE_STORAGE
#endif #endif

View File

@ -91,7 +91,7 @@
#define CONFIG_CODEC SWCODEC #define CONFIG_CODEC SWCODEC
/* define this if you have a real-time clock */ /* define this if you have a real-time clock */
#define CONFIG_RTC RTC_JZ47XX #define CONFIG_RTC RTC_JZ4740
/* Tuner config */ /* Tuner config */
#define CONFIG_TUNER TEA5767 #define CONFIG_TUNER TEA5767

View File

@ -80,7 +80,7 @@
#define CONFIG_CODEC SWCODEC #define CONFIG_CODEC SWCODEC
/* define this if you have a real-time clock */ /* define this if you have a real-time clock */
#define CONFIG_RTC RTC_JZ47XX #define CONFIG_RTC RTC_JZ4740
/* Define this for LCD backlight available */ /* Define this for LCD backlight available */
#define HAVE_BACKLIGHT #define HAVE_BACKLIGHT

View File

@ -85,7 +85,7 @@
#define CONFIG_CODEC SWCODEC #define CONFIG_CODEC SWCODEC
/* define this if you have a real-time clock */ /* define this if you have a real-time clock */
#define CONFIG_RTC RTC_JZ47XX #define CONFIG_RTC RTC_JZ4740
/* Tuner config */ /* Tuner config */
#define CONFIG_TUNER TEA5767 #define CONFIG_TUNER TEA5767

View File

@ -0,0 +1,195 @@
/*
* This config file is for xDuoo X3
*/
#define MODEL_NAME "xDuoo X3"
#define MODEL_NUMBER 106
/* Offset ( in the firmware file's header ) to the file CRC */
#define FIRMWARE_OFFSET_FILE_CRC 0
/* Offset ( in the firmware file's header ) to the real data */
#define FIRMWARE_OFFSET_FILE_DATA 8
/* Support FAT16 for SD cards <= 2GB */
#define HAVE_FAT16SUPPORT
/* ChinaChip NAND FTL */
#define CONFIG_NAND NAND_CC
/* define this if you have a bitmap LCD display */
#define HAVE_LCD_BITMAP
/* define this if you have access to the quickscreen */
#define HAVE_QUICKSCREEN
/* define this if you would like tagcache to build on this target */
#define HAVE_TAGCACHE
/* define this if the target has volume keys which can be used in the lists */
#define HAVE_VOLUME_IN_LIST
/* LCD dimensions */
#define LCD_WIDTH 128
#define LCD_HEIGHT 64
/* sqrt(128^2 + 64^2) / 1.0 = 143.1 */
#define LCD_DPI 143
#define LCD_DEPTH 1
#define LCD_PIXELFORMAT VERTICAL_PACKING
#define HAVE_NEGATIVE_LCD /* bright on dark */
/* Display colours, for screenshots and sim (0xRRGGBB) */
#define LCD_DARKCOLOR 0x000000
#define LCD_BRIGHTCOLOR 0x000000
#define LCD_BL_DARKCOLOR 0x000000
#define LCD_BL_BRIGHTCOLOR 0x0de2e5
/* define this if you have LCD enable function */
#define HAVE_LCD_ENABLE
#ifndef BOOTLOADER
/* Define this if your LCD can be put to sleep.
* HAVE_LCD_ENABLE should be defined as well. */
#define HAVE_LCD_SLEEP
#define HAVE_LCD_SLEEP_SETTING
#endif
/* define this if you can flip your LCD */
#define HAVE_LCD_FLIP
/* define this if you can invert the pixels */
#define HAVE_LCD_INVERT
/* Define this for LCD backlight available */
#define HAVE_BACKLIGHT
#define HAVE_BACKLIGHT_BRIGHTNESS
/* Which backlight fading type? */
#define CONFIG_BACKLIGHT_FADING BACKLIGHT_FADING_SW_SETTING
#define IRAM_LCDFRAMEBUFFER IDATA_ATTR /* put the lcd frame buffer in IRAM */
/* Define this if you can detect headphones */
#define HAVE_HEADPHONE_DETECTION
#define CONFIG_KEYPAD XDUOO_X3_PAD
/* Define this if a programmable hotkey is mapped */
#define HAVE_HOTKEY
/* Define this if you do software codec */
#define CONFIG_CODEC SWCODEC
/* Define this for LCD backlight available */
#define HAVE_BACKLIGHT
#ifndef BOOTLOADER
/* define this if you have a real-time clock */
#define CONFIG_RTC RTC_JZ4760
#endif
/* Define this if you have a software controlled poweroff */
#define HAVE_SW_POWEROFF
/* The number of bytes reserved for loadable codecs */
#define CODEC_SIZE 0x100000
/* The number of bytes reserved for loadable plugins */
#define PLUGIN_BUFFER_SIZE 0x100000
#define HAVE_CS4398
#define CODEC_SLAVE
/* has no tone controls, so we use the software ones */
#define HAVE_SW_TONE_CONTROLS
/* define the bitmask of hardware sample rates */
#define HW_SAMPR_CAPS SAMPR_CAP_ALL
#define AB_REPEAT_ENABLE
#define BATTERY_CAPACITY_DEFAULT 2000 /* default battery capacity */
#define BATTERY_CAPACITY_MIN 500 /* min. capacity selectable */
#define BATTERY_CAPACITY_MAX 2000 /* max. capacity selectable */
#define BATTERY_CAPACITY_INC 100 /* capacity increment */
#define BATTERY_TYPES_COUNT 1 /* only one type */
#define CONFIG_BATTERY_MEASURE VOLTAGE_MEASURE
/* Hardware controlled charging with monitoring */
#define CONFIG_CHARGING CHARGING_MONITOR
/* There is only USB charging */
#define HAVE_USB_POWER
#define CFG_EXTAL 12000000 /* EXT clock: 12 Mhz */
/* define this if the flash memory uses the SecureDigital Memory Card protocol */
#define CONFIG_STORAGE (STORAGE_SD /* | STORAGE_NAND */)
#define HAVE_MULTIDRIVE
#define NUM_DRIVES 2
/* Define this if media can be exchanged on the fly */
#ifndef BOOTLOADER
#define HAVE_HOTSWAP
#define HAVE_HOTSWAP_STORAGE_AS_MAIN
#endif
/* define this if you have a flash memory storage */
#define HAVE_FLASH_STORAGE
/** Non-simulator section **/
#ifndef SIMULATOR
/* Define this if you have a Ingenic JZ4760B */
#define CONFIG_CPU JZ4760B
/* Define this to the CPU frequency */
#define CPU_FREQ 492000000 /* CPU clock: 492 MHz */
/* Define this if you want to use the JZ47XX i2c interface */
#define CONFIG_I2C I2C_JZ47XX
#define NEED_ADC_CLOSE 1
/* define this if the hardware can be powered off while charging */
/* #define HAVE_POWEROFF_WHILE_CHARGING */
/* Type of LCD */
#define CONFIG_LCD LCD_XDUOOX3
/* USB On-the-go */
#define CONFIG_USBOTG USBOTG_JZ4760
/* enable these for the experimental usb stack */
#define HAVE_USBSTACK
/* Connect by events, not by tick polling */
#define USB_STATUS_BY_EVENT
#define USB_VENDOR_ID 0x0525
#define USB_PRODUCT_ID 0xA4A5
#define USB_NUM_ENDPOINTS 3
#define USB_DEVBSS_ATTR IBSS_ATTR
#define BOOTFILE_EXT "x3"
#define BOOTFILE "rockbox." BOOTFILE_EXT
#define BOOTDIR "/.rockbox"
#define INCLUDE_TIMEOUT_API
#define ICODE_ATTR_TREMOR_NOT_MDCT
#endif /* SIMULATOR */
/** Port-specific settings **/
#define CONFIG_SDRAM_START 0x80004000
/* Main LCD backlight brightness range and defaults */
#define MIN_BRIGHTNESS_SETTING 1
#define MAX_BRIGHTNESS_SETTING 16
#define DEFAULT_BRIGHTNESS_SETTING 16 /* "full brightness" */

View File

@ -68,6 +68,9 @@
#if CONFIG_CPU == JZ4732 #if CONFIG_CPU == JZ4732
#include "jz4740.h" #include "jz4740.h"
#endif #endif
#if CONFIG_CPU == JZ4760B
#include "jz4760b.h"
#endif
#if CONFIG_CPU == AS3525 #if CONFIG_CPU == AS3525
#include "as3525.h" #include "as3525.h"
#endif #endif

116
firmware/export/cs4398.h Normal file
View File

@ -0,0 +1,116 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 _CS4398_H
#define _CS4398_H
#define CS4398_VOLUME_MIN -1270
#define CS4398_VOLUME_MAX 0
#define AUDIOHW_CAPS (FILTER_ROLL_OFF_CAP | LINEOUT_CAP)
AUDIOHW_SETTING(VOLUME, "dB", 0, 1, CS4398_VOLUME_MIN/10, CS4398_VOLUME_MAX/10, 0)
AUDIOHW_SETTING(FILTER_ROLL_OFF, "", 0, 1, 0, 1, 0)
void cs4398_write_reg(uint8_t reg, uint8_t val);
uint8_t cs4398_read_reg(uint8_t reg);
#define CS4398_I2C_ADDR 0x4f /* 1001111 */
#define CS4398_REG_CHIPID 0x01
#define CS4398_REG_MODECTL 0x02
#define CS4398_REG_VOLMIX 0x03
#define CS4398_REG_MUTE 0x04
#define CS4398_REG_VOL_A 0x05
#define CS4398_REG_VOL_B 0x06
#define CS4398_REG_RAMPFILT 0x07
#define CS4398_REG_MISC 0x08
#define CS4398_REG_MISC2 0x09
/* REG_CHIPID */
#define CS4398_REV_MASK 0x07
#define CS4398_PART_MASK 0xf8
#define CS4398_PART_CS4398 0x70
/* REG_MODECTL */
#define CS4398_FM_MASK 0x03
#define CS4398_FM_SINGLE 0x00
#define CS4398_FM_DOUBLE 0x01
#define CS4398_FM_QUAD 0x02
#define CS4398_FM_DSD 0x03
#define CS4398_DEM_MASK 0x0c
#define CS4398_DEM_NONE 0x00
#define CS4398_DEM_44100 0x04
#define CS4398_DEM_48000 0x08
#define CS4398_DEM_32000 0x0c
#define CS4398_DIF_MASK 0x70
#define CS4398_DIF_LJUST 0x00
#define CS4398_DIF_I2S 0x10
#define CS4398_DIF_RJUST_16 0x20
#define CS4398_DIF_RJUST_24 0x30
#define CS4398_DIF_RJUST_20 0x40
#define CS4398_DIF_RJUST_18 0x50
#define CS4398_DSD_SRC 0x80
/* REG_VOLMIX */
#define CS4398_ATAPI_MASK 0x1f
#define CS4398_ATAPI_B_MUTE 0x00
#define CS4398_ATAPI_B_R 0x01
#define CS4398_ATAPI_B_L 0x02
#define CS4398_ATAPI_B_LR 0x03
#define CS4398_ATAPI_A_MUTE 0x00
#define CS4398_ATAPI_A_R 0x04
#define CS4398_ATAPI_A_L 0x08
#define CS4398_ATAPI_A_LR 0x0c
#define CS4398_ATAPI_MIX_LR_VOL 0x10
#define CS4398_INVERT_B 0x20
#define CS4398_INVERT_A 0x40
#define CS4398_VOL_B_EQ_A 0x80
/* REG_MUTE */
#define CS4398_MUTEP_MASK 0x03
#define CS4398_MUTEP_AUTO 0x00
#define CS4398_MUTEP_LOW 0x02
#define CS4398_MUTEP_HIGH 0x03
#define CS4398_MUTE_B 0x08
#define CS4398_MUTE_A 0x10
#define CS4398_MUTEC_A_EQ_B 0x20
#define CS4398_DAMUTE 0x40
#define CS4398_PAMUTE 0x80
/* REG_VOL_A */
#define CS4398_VOL_A_MASK 0xff
/* REG_VOL_B */
#define CS4398_VOL_B_MASK 0xff
/* REG_RAMPFILT */
#define CS4398_DIR_DSD 0x01
#define CS4398_FILT_SEL 0x04
#define CS4398_RMP_DN 0x10
#define CS4398_RMP_UP 0x20
#define CS4398_ZERO_CROSS 0x40
#define CS4398_SOFT_RAMP 0x80
/* REG_MISC */
#define CS4398_MCLKDIV3 0x08
#define CS4398_MCLKDIV2 0x10
#define CS4398_FREEZE 0x20
#define CS4398_CPEN 0x40
#define CS4398_PDN 0x80
/* REG_MISC2 */
#define CS4398_DSD_PM_EN 0x01
#define CS4398_DSD_PM_MODE 0x02
#define CS4398_INVALID_DSD 0x04
#define CS4398_STATIC_DSD 0x08
#endif

9643
firmware/export/jz4760b.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -129,7 +129,7 @@ static int battery_type = 0;
/* Power history: power_history[0] is the newest sample */ /* Power history: power_history[0] is the newest sample */
unsigned short power_history[POWER_HISTORY_LEN] = {0}; unsigned short power_history[POWER_HISTORY_LEN] = {0};
#if CONFIG_CPU == JZ4732 /* FIXME! */ || (CONFIG_PLATFORM & PLATFORM_HOSTED) #if (CONFIG_CPU == JZ4732) || (CONFIG_CPU == JZ4760B) || (CONFIG_PLATFORM & PLATFORM_HOSTED)
static char power_stack[DEFAULT_STACK_SIZE + POWERMGMT_DEBUG_STACK]; static char power_stack[DEFAULT_STACK_SIZE + POWERMGMT_DEBUG_STACK];
#else #else
static char power_stack[DEFAULT_STACK_SIZE/2 + POWERMGMT_DEBUG_STACK]; static char power_stack[DEFAULT_STACK_SIZE/2 + POWERMGMT_DEBUG_STACK];

View File

@ -324,6 +324,16 @@ void sound_set_filter_roll_off(int value)
} }
#endif #endif
#if defined(AUDIOHW_HAVE_FUNCTIONAL_MODE)
void sound_set_functional_mode(int value)
{
if (!audio_is_initialized)
return;
audiohw_set_functional_mode(value);
}
#endif
#if defined(AUDIOHW_HAVE_EQ) #if defined(AUDIOHW_HAVE_EQ)
int sound_enum_hw_eq_band_setting(unsigned int band, int sound_enum_hw_eq_band_setting(unsigned int band,
unsigned int band_setting) unsigned int band_setting)

View File

@ -508,6 +508,7 @@
#define UI_LCD_POSX 46 #define UI_LCD_POSX 46
#define UI_LCD_POSY 40 #define UI_LCD_POSY 40
<<<<<<< HEAD
#elif defined(SONY_NWZA860) #elif defined(SONY_NWZA860)
#define UI_TITLE "Sony NWZ-A860 Series" #define UI_TITLE "Sony NWZ-A860 Series"
#define UI_WIDTH 390 /* width of GUI window */ #define UI_WIDTH 390 /* width of GUI window */
@ -521,6 +522,12 @@
#define UI_HEIGHT 380 #define UI_HEIGHT 380
#define UI_LCD_POSX 29 #define UI_LCD_POSX 29
#define UI_LCD_POSY 25 #define UI_LCD_POSY 25
#elif defined(XDUOO_X3)
#define UI_TITLE "xDuoo X3"
#define UI_WIDTH 192 /* width of GUI window */
#define UI_HEIGHT 457 /* height of GUI window */
#define UI_LCD_POSX 34
#define UI_LCD_POSY 73
#elif defined(SIMULATOR) #elif defined(SIMULATOR)
#error no UI defines #error no UI defines
#endif #endif

View File

@ -5,8 +5,10 @@ OUTPUT_ARCH(MIPS)
ENTRY(_start) ENTRY(_start)
STARTUP(target/mips/ingenic_jz47xx/crt0.o) STARTUP(target/mips/ingenic_jz47xx/crt0.o)
#define DRAMORIG 0x80004000 #define STUBOFFSET 0x4000
#define DRAMSIZE (MEMORYSIZE * 0x100000)
#define DRAMORIG (0x80000000 + STUBOFFSET)
#define DRAMSIZE (MEMORYSIZE * 0x100000 - STUBOFFSET)
#define IRAMORIG 0x80000000 #define IRAMORIG 0x80000000
#define IRAMSIZE 16K #define IRAMSIZE 16K

View File

@ -20,7 +20,7 @@
****************************************************************************/ ****************************************************************************/
#include "config.h" #include "config.h"
#include "jz4740.h" #include "cpu.h"
#include "nand.h" #include "nand.h"
#include "nand_id.h" #include "nand_id.h"
#include "system.h" #include "system.h"

View File

@ -0,0 +1,692 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 "config.h"
#include "cpu.h"
#include "nand.h"
#include "nand_id.h"
#include "system.h"
#include "panic.h"
#include "kernel.h"
#include "storage.h"
#include "string.h"
/*#define LOGF_ENABLE*/
#include "logf.h"
//#define USE_DMA
//#define USE_ECC
/*
* Standard NAND flash commands
*/
#define NAND_CMD_READ0 0
#define NAND_CMD_READ1 1
#define NAND_CMD_RNDOUT 5
#define NAND_CMD_PAGEPROG 0x10
#define NAND_CMD_READOOB 0x50
#define NAND_CMD_ERASE1 0x60
#define NAND_CMD_STATUS 0x70
#define NAND_CMD_STATUS_MULTI 0x71
#define NAND_CMD_SEQIN 0x80
#define NAND_CMD_RNDIN 0x85
#define NAND_CMD_READID 0x90
#define NAND_CMD_ERASE2 0xd0
#define NAND_CMD_RESET 0xff
/* Extended commands for large page devices */
#define NAND_CMD_READSTART 0x30
#define NAND_CMD_RNDOUTSTART 0xE0
#define NAND_CMD_CACHEDPROG 0x15
/* Status bits */
#define NAND_STATUS_FAIL 0x01
#define NAND_STATUS_FAIL_N1 0x02
#define NAND_STATUS_TRUE_READY 0x20
#define NAND_STATUS_READY 0x40
#define NAND_STATUS_WP 0x80
/*
* NAND parameter struct
*/
struct nand_param {
unsigned int bus_width; /* data bus width: 8-bit/16-bit */
unsigned int row_cycle; /* row address cycles: 2/3 */
unsigned int page_size; /* page size in bytes: 512/2048/4096 */
unsigned int oob_size; /* oob size in bytes: 16/64/128 */
unsigned int page_per_block; /* pages per block: 32/64/128 */
unsigned int bad_block_pos; /* bad block pos in oob: 0/5 */
};
/*
* jz4760_nand.c
*
* NAND read routine for JZ4760
*
* Copyright (c) 2005-2008 Ingenic Semiconductor Inc.
*
*/
#define CFG_NAND_BASE 0xBA000000
#define NAND_ADDR_OFFSET 0x00800000
#define NAND_CMD_OFFSET 0x00400000
#define CFG_NAND_SMCR1 0x0d444400
#define NAND_DATAPORT CFG_NAND_BASE
#define NAND_ADDRPORT (CFG_NAND_BASE | NAND_ADDR_OFFSET)
#define NAND_COMMPORT (CFG_NAND_BASE | NAND_CMD_OFFSET)
#define ECC_BLOCK 512
#define ECC_POS 24
#define PAR_SIZE 13
#define __nand_cmd(n) (REG8(NAND_COMMPORT) = (n))
#define __nand_addr(n) (REG8(NAND_ADDRPORT) = (n))
#define __nand_data8() (REG8(NAND_DATAPORT))
#define __nand_data16() (REG16(NAND_DATAPORT))
#define __nand_select() (REG_NEMC_NFCSR |= NEMC_NFCSR_NFE1 | NEMC_NFCSR_NFCE1)
#define __nand_deselect() (REG_NEMC_NFCSR &= ~(NEMC_NFCSR_NFE1 | NEMC_NFCSR_NFCE1))
/*--------------------------------------------------------------*/
static struct nand_info* chip_info = NULL;
static struct nand_info* bank;
static unsigned long nand_size;
static struct nand_param internal_param;
static struct mutex nand_mtx;
#ifdef USE_DMA
static struct mutex nand_dma_mtx;
static struct semaphore nand_dma_complete;
#endif
static unsigned char temp_page[2048]; /* Max page size */
static inline void jz_nand_wait_ready(void)
{
unsigned int timeout = 1000;
while ((REG_GPIO_PXPIN(0) & 0x00100000) && timeout--);
while (!(REG_GPIO_PXPIN(0) & 0x00100000));
}
#ifndef USE_DMA
static inline void jz_nand_read_buf16(void *buf, int count)
{
register int i;
register unsigned short *p = (unsigned short *)buf;
for (i = 0; i < count; i += 2)
*p++ = __nand_data16();
}
static inline void jz_nand_read_buf8(void *buf, int count)
{
register int i;
register unsigned char *p = (unsigned char *)buf;
for (i = 0; i < count; i++)
*p++ = __nand_data8();
}
#else
static void jz_nand_write_dma(void *source, unsigned int len, int bw)
{
mutex_lock(&nand_dma_mtx);
if(((unsigned int)source < 0xa0000000) && len)
dma_cache_wback_inv((unsigned long)source, len);
dma_enable();
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES;
REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)source);
REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT);
REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 16;
REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO;
REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_16BYTE |
(bw == 8 ? DMAC_DCMD_DWDH_8 : DMAC_DCMD_DWDH_16));
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
#if 1
while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) )
yield();
#else
REG_DMAC_DCMD(DMA_NAND_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */
semaphore_wait(&nand_dma_complete, TIMEOUT_BLOCK);
#endif
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
dma_disable();
mutex_unlock(&nand_dma_mtx);
}
static void jz_nand_read_dma(void *target, unsigned int len, int bw)
{
mutex_lock(&nand_dma_mtx);
if(((unsigned int)target < 0xa0000000) && len)
dma_cache_wback_inv((unsigned long)target, len);
dma_enable();
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES ;
REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT);
REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)target);
REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 4;
REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO;
REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT |
(bw == 8 ? DMAC_DCMD_SWDH_8 : DMAC_DCMD_SWDH_16));
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
#if 1
while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) )
yield();
#else
REG_DMAC_DCMD(DMA_NAND_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */
semaphore_wait(&nand_dma_complete, TIMEOUT_BLOCK);
#endif
//REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
dma_disable();
mutex_unlock(&nand_dma_mtx);
}
void DMA_CALLBACK(DMA_NAND_CHANNEL)(void)
{
if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_HLT)
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_HLT;
if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_AR)
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_AR;
if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_CT)
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_CT;
if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_TT)
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_TT;
semaphore_release(&nand_dma_complete);
}
#endif /* USE_DMA */
static inline void jz_nand_read_buf(void *buf, int count, int bw)
{
#ifdef USE_DMA
if (bw == 8)
jz_nand_read_dma(buf, count, 8);
else
jz_nand_read_dma(buf, count, 16);
#else
if (bw == 8)
jz_nand_read_buf8(buf, count);
else
jz_nand_read_buf16(buf, count);
#endif
}
#ifdef USE_ECC
/*
* Correct 1~9-bit errors in 512-bytes data
*/
static void jz_rs_correct(unsigned char *dat, int idx, int mask)
{
int i, j;
unsigned short d, d1, dm;
i = (idx * 9) >> 3;
j = (idx * 9) & 0x7;
i = (j == 0) ? (i - 1) : i;
j = (j == 0) ? 7 : (j - 1);
if (i > 512)
return;
if (i == 512)
d = dat[i - 1];
else
d = (dat[i] << 8) | dat[i - 1];
d1 = (d >> j) & 0x1ff;
d1 ^= mask;
dm = ~(0x1ff << j);
d = (d & dm) | (d1 << j);
dat[i - 1] = d & 0xff;
if (i < 512)
dat[i] = (d >> 8) & 0xff;
}
#endif
/*
* Read oob
*/
static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int size)
{
struct nand_param *nandp = &internal_param;
int page_size, row_cycle, bus_width;
int col_addr;
page_size = nandp->page_size;
row_cycle = nandp->row_cycle;
bus_width = nandp->bus_width;
if (page_size >= 2048)
col_addr = page_size;
else
col_addr = 0;
if (page_size >= 2048)
/* Send READ0 command */
__nand_cmd(NAND_CMD_READ0);
else
/* Send READOOB command */
__nand_cmd(NAND_CMD_READOOB);
/* Send column address */
__nand_addr(col_addr & 0xff);
if (page_size >= 2048)
__nand_addr((col_addr >> 8) & 0xff);
/* Send page address */
__nand_addr(page_addr & 0xff);
__nand_addr((page_addr >> 8) & 0xff);
if (row_cycle == 3)
__nand_addr((page_addr >> 16) & 0xff);
/* Send READSTART command for 2048 ps NAND */
if (page_size >= 2048)
__nand_cmd(NAND_CMD_READSTART);
/* Wait for device ready */
jz_nand_wait_ready();
/* Read oob data */
jz_nand_read_buf(buf, size, bus_width);
return 0;
}
/*
* nand_read_page()
*
* Input:
*
* block - block number: 0, 1, 2, ...
* page - page number within a block: 0, 1, 2, ...
* dst - pointer to target buffer
*/
static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst)
{
struct nand_param *nandp = &internal_param;
int page_size, oob_size, page_per_block;
int row_cycle, bus_width, ecc_count;
int i;
#ifdef USE_ECC
int j;
#endif
unsigned char *data_buf;
unsigned char oob_buf[nandp->oob_size];
page_size = nandp->page_size;
oob_size = nandp->oob_size;
page_per_block = nandp->page_per_block;
row_cycle = nandp->row_cycle;
bus_width = nandp->bus_width;
/*
* Read oob data
*/
jz_nand_read_oob(page_addr, oob_buf, oob_size);
/*
* Read page data
*/
/* Send READ0 command */
__nand_cmd(NAND_CMD_READ0);
/* Send column address */
__nand_addr(0);
if (page_size >= 2048)
__nand_addr(0);
/* Send page address */
__nand_addr(page_addr & 0xff);
__nand_addr((page_addr >> 8) & 0xff);
if (row_cycle >= 3)
__nand_addr((page_addr >> 16) & 0xff);
/* Send READSTART command for 2048 ps NAND */
if (page_size >= 2048)
__nand_cmd(NAND_CMD_READSTART);
/* Wait for device ready */
jz_nand_wait_ready();
/* Read page data */
data_buf = dst;
ecc_count = page_size / ECC_BLOCK;
for (i = 0; i < ecc_count; i++)
{
#ifdef USE_ECC
volatile unsigned char *paraddr = (volatile unsigned char *)EMC_NFPAR0;
unsigned int stat;
/* Enable RS decoding */
REG_EMC_NFINTS = 0x0;
__ecc_decoding_4bit();
#endif
/* Read data */
jz_nand_read_buf((void *)data_buf, ECC_BLOCK, bus_width);
#ifdef USE_ECC
/* Set PAR values */
for (j = 0; j < PAR_SIZE; j++)
*paraddr++ = oob_buf[ECC_POS + i*PAR_SIZE + j];
/* Set PRDY */
REG_EMC_NFECR |= EMC_NFECR_PRDY;
/* Wait for completion */
__ecc_decode_sync();
/* Disable decoding */
__ecc_disable();
/* Check result of decoding */
stat = REG_EMC_NFINTS;
if (stat & EMC_NFINTS_ERR)
{
/* Error occurred */
if (stat & EMC_NFINTS_UNCOR)
{
/* Uncorrectable error occurred */
logf("Uncorrectable ECC error at NAND page address 0x%lx", page_addr);
return -1;
}
else
{
unsigned int errcnt, index, mask;
errcnt = (stat & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT;
switch (errcnt)
{
case 4:
index = (REG_EMC_NFERR3 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
mask = (REG_EMC_NFERR3 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
jz_rs_correct(data_buf, index, mask);
case 3:
index = (REG_EMC_NFERR2 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
mask = (REG_EMC_NFERR2 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
jz_rs_correct(data_buf, index, mask);
case 2:
index = (REG_EMC_NFERR1 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
mask = (REG_EMC_NFERR1 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
jz_rs_correct(data_buf, index, mask);
case 1:
index = (REG_EMC_NFERR0 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
mask = (REG_EMC_NFERR0 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
jz_rs_correct(data_buf, index, mask);
break;
default:
break;
}
}
}
#endif
data_buf += ECC_BLOCK;
}
return 0;
}
static int jz_nand_init(void)
{
unsigned char cData[5];
__gpio_as_nand_16bit(1);
REG_NEMC_SMCR1 = CFG_NAND_SMCR1 | 0x40;
__nand_select();
__nand_cmd(NAND_CMD_READID);
__nand_addr(NAND_CMD_READ0);
cData[0] = __nand_data8();
cData[1] = __nand_data8();
cData[2] = __nand_data8();
cData[3] = __nand_data8();
cData[4] = __nand_data8();
__nand_deselect();
logf("NAND chip %d: 0x%x 0x%x 0x%x 0x%x 0x%x", i+1, cData[0], cData[1],
cData[2], cData[3], cData[4]);
bank = nand_identify(cData);
if(bank == NULL)
{
panicf("Unknown NAND flash chip: 0x%x 0x%x 0x%x 0x%x 0x%x", cData[0],
cData[1], cData[2], cData[3], cData[4]);
return -1; /* panicf() doesn't return though */
}
chip_info = bank;
internal_param.bus_width = 16;
internal_param.row_cycle = chip_info->row_cycles;
internal_param.page_size = chip_info->page_size;
internal_param.oob_size = chip_info->spare_size;
internal_param.page_per_block = chip_info->pages_per_block;
internal_param.bad_block_pos = 0;
nand_size = ((chip_info->page_size * chip_info->blocks_per_bank * chip_info->pages_per_block) - 0x200000) / 512;
return 0;
}
int nand_init(void)
{
int res = 0;
static bool inited = false;
if(!inited)
{
res = jz_nand_init();
mutex_init(&nand_mtx);
#ifdef USE_DMA
mutex_init(&nand_dma_mtx);
semaphore_init(&nand_dma_complete, 1, 0);
system_enable_irq(DMA_IRQ(DMA_NAND_CHANNEL));
#endif
inited = true;
}
return res;
}
static inline int read_sector(unsigned long start, unsigned int count,
void* buf, unsigned int chip_size)
{
register int ret;
if(UNLIKELY(start % chip_size == 0 && count == chip_size))
ret = jz_nand_read_page(start / chip_size, buf);
else
{
ret = jz_nand_read_page(start / chip_size, temp_page);
memcpy(buf, temp_page + (start % chip_size), count);
}
return ret;
}
static inline int write_sector(unsigned long start, unsigned int count,
const void* buf, unsigned int chip_size)
{
int ret = 0;
(void)start;
(void)count;
(void)buf;
(void)chip_size;
/* TODO */
return ret;
}
int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* buf)
{
#ifdef HAVE_MULTIVOLUME
(void)drive;
#endif
int ret = 0;
unsigned int _count, chip_size = chip_info->page_size;
unsigned long _start;
logf("start");
mutex_lock(&nand_mtx);
_start = start << 9;
_start += 0x200000; /* skip BL */
_count = count << 9;
__nand_select();
ret = read_sector(_start, _count, buf, chip_size);
__nand_deselect();
mutex_unlock(&nand_mtx);
logf("nand_read_sectors(%ld, %d, 0x%x): %d", start, count, (int)buf, ret);
return ret;
}
int nand_write_sectors(IF_MV(int drive,) unsigned long start, int count, const void* buf)
{
#ifdef HAVE_MULTIVOLUME
(void)drive;
#endif
int ret = 0;
unsigned int _count, chip_size = chip_info->page_size;
unsigned long _start;
logf("start");
mutex_lock(&nand_mtx);
_start = start << 9;
_start += chip_info->page_size * chip_info->pages_per_block; /* skip BL */
_count = count << 9;
__nand_select();
ret = write_sector(_start, _count, buf, chip_size);
__nand_deselect();
mutex_unlock(&nand_mtx);
logf("nand_write_sectors(%ld, %d, 0x%x): %d", start, count, (int)buf, ret);
return ret;
}
#ifdef HAVE_STORAGE_FLUSH
int nand_flush(void)
{
return 0;
}
#endif
void nand_spindown(int seconds)
{
/* null */
(void)seconds;
}
void nand_sleep(void)
{
/* null */
}
void nand_spin(void)
{
/* null */
}
void nand_enable(bool on)
{
/* null - flash controller is enabled/disabled as needed. */
(void)on;
}
/* TODO */
long nand_last_disk_activity(void)
{
return 0;
}
int nand_spinup_time(void)
{
return 0;
}
void nand_sleepnow(void)
{
}
#ifdef STORAGE_GET_INFO
void nand_get_info(IF_MV(int drive,) struct storage_info *info)
{
#ifdef HAVE_MULTIVOLUME
(void)drive;
#endif
/* firmware version */
info->revision="0.00";
info->vendor="Rockbox";
info->product="NAND Storage";
/* blocks count */
info->num_sectors = nand_size;
info->sector_size = 512;
}
#endif
#ifdef CONFIG_STORAGE_MULTI
int nand_num_drives(int first_drive)
{
/* We don't care which logical drive number(s) we have been assigned */
(void)first_drive;
return 1;
}
#endif

View File

@ -21,7 +21,7 @@
#include "config.h" #include "config.h"
#include "gcc_extensions.h" #include "gcc_extensions.h"
#include "jz4740.h" #include "cpu.h"
#include "ata-sd-target.h" #include "ata-sd-target.h"
#include "led.h" #include "led.h"
#include "sdmmc.h" #include "sdmmc.h"

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,8 @@
bool backlight_hw_init(void); bool backlight_hw_init(void);
void backlight_hw_on(void); void backlight_hw_on(void);
void backlight_hw_off(void); void backlight_hw_off(void);
#ifdef HAVE_BACKLIGHT_BRIGHTNESS
void backlight_hw_brightness(int brightness); void backlight_hw_brightness(int brightness);
#endif /* HAVE_BACKLIGHT_BRIGHTNESS */
#endif /* BACKLIGHT_TARGET_H */ #endif /* BACKLIGHT_TARGET_H */

View File

@ -0,0 +1,293 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 "config.h"
#include "audio.h"
#include "sound.h"
#include "cpu.h"
#include "system.h"
#include "pcm_sw_volume.h"
#include "cs4398.h"
#include "kernel.h"
#define PIN_CS_RST (32*1+10)
#define PIN_CODEC_PWRON (32*1+13)
#define PIN_AP_MUTE (32*1+14)
#define PIN_JD_CON (32*1+16)
static void pop_ctrl(const int val)
{
if(val)
__gpio_clear_pin(PIN_JD_CON);
else
__gpio_set_pin(PIN_JD_CON);
}
static void amp_enable(const int val)
{
if(val)
__gpio_set_pin(PIN_CODEC_PWRON);
else
__gpio_clear_pin(PIN_CODEC_PWRON);
}
static void dac_enable(const int val)
{
if(val)
__gpio_set_pin(PIN_CS_RST);
else
__gpio_clear_pin(PIN_CS_RST);
}
static void ap_mute(bool mute)
{
if(mute)
__gpio_clear_pin(PIN_AP_MUTE);
else
__gpio_set_pin(PIN_AP_MUTE);
}
static void audiohw_mute(bool mute)
{
if(mute)
cs4398_write_reg(CS4398_REG_MUTE, cs4398_read_reg(CS4398_REG_MUTE) | CS4398_MUTE_A | CS4398_MUTE_B);
else
cs4398_write_reg(CS4398_REG_MUTE, cs4398_read_reg(CS4398_REG_MUTE) & ~(CS4398_MUTE_A | CS4398_MUTE_B));
}
void audiohw_preinit(void)
{
cs4398_write_reg(CS4398_REG_MISC, CS4398_CPEN | CS4398_PDN);
cs4398_write_reg(CS4398_REG_MODECTL, CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST);
cs4398_write_reg(CS4398_REG_VOLMIX, CS4398_ATAPI_A_L | CS4398_ATAPI_B_R);
cs4398_write_reg(CS4398_REG_MUTE, CS4398_MUTEP_LOW);
cs4398_write_reg(CS4398_REG_VOL_A, 0xff);
cs4398_write_reg(CS4398_REG_VOL_B, 0xff);
cs4398_write_reg(CS4398_REG_RAMPFILT, CS4398_ZERO_CROSS | CS4398_SOFT_RAMP);
cs4398_write_reg(CS4398_REG_MISC, CS4398_CPEN);
}
void audiohw_init(void)
{
__gpio_as_func1(3*32+12); // BCK
__gpio_as_func0(3*32+13); // LRCK
__gpio_as_func2(4*32+5); // MCLK
__gpio_as_func0(4*32+7); // DO
pop_ctrl(0);
ap_mute(true);
amp_enable(0);
dac_enable(0);
__gpio_as_output(PIN_JD_CON);
__gpio_as_output(PIN_AP_MUTE);
__gpio_as_output(PIN_CODEC_PWRON);
__gpio_as_output(PIN_CS_RST);
mdelay(100);
amp_enable(1);
/* set AIC clk PLL1 */
__cpm_select_i2sclk_pll();
__cpm_select_i2sclk_pll1();
__cpm_enable_pll_change();
__cpm_set_i2sdiv(43-1);
__cpm_start_aic();
/* Init AIC */
__i2s_enable_sclk();
__i2s_external_codec();
__i2s_select_msbjustified();
__i2s_as_master();
__i2s_enable_transmit_dma();
__i2s_set_transmit_trigger(24);
__i2s_set_oss_sample_size(16);
__i2s_enable();
/* Init DAC */
dac_enable(1);
udelay(1);
audiohw_preinit();
}
static int vol_tenthdb2hw(const int tdb)
{
if (tdb < CS4398_VOLUME_MIN) {
return 0xff;
} else if (tdb > CS4398_VOLUME_MAX) {
return 0x00;
} else {
return (-tdb/5);
}
}
void audiohw_set_volume(int vol_l, int vol_r)
{
cs4398_write_reg(CS4398_REG_VOL_A, vol_tenthdb2hw(vol_l));
cs4398_write_reg(CS4398_REG_VOL_B, vol_tenthdb2hw(vol_r));
}
void audiohw_set_lineout_volume(int vol_l, int vol_r)
{
#if 0 /* unused */
cs4398_write_reg(CS4398_REG_VOL_A, vol_tenthdb2hw(vol_l));
cs4398_write_reg(CS4398_REG_VOL_B, vol_tenthdb2hw(vol_r));
#else
(void)vol_l;
(void)vol_r;
#endif
}
void audiohw_set_filter_roll_off(int value)
{
/* 0 = fast (sharp);
1 = slow */
if (value == 0) {
cs4398_write_reg(CS4398_REG_RAMPFILT, cs4398_read_reg(CS4398_REG_RAMPFILT) & ~CS4398_FILT_SEL);
} else {
cs4398_write_reg(CS4398_REG_RAMPFILT, cs4398_read_reg(CS4398_REG_RAMPFILT) | CS4398_FILT_SEL);
}
}
void pll1_init(unsigned int freq);
void audiohw_set_frequency(int fsel)
{
unsigned int pll1_speed;
unsigned char mclk_div, bclk_div, func_mode;
switch(fsel)
{
case HW_FREQ_8:
pll1_speed = 426000000;
mclk_div = 52;
bclk_div = 16;
func_mode = 0;
break;
case HW_FREQ_11:
pll1_speed = 508000000;
mclk_div = 45;
bclk_div = 16;
func_mode = 0;
break;
case HW_FREQ_12:
pll1_speed = 516000000;
mclk_div = 42;
bclk_div = 16;
func_mode = 0;
break;
case HW_FREQ_16:
pll1_speed = 426000000;
mclk_div = 52;
bclk_div = 8;
func_mode = 0;
break;
case HW_FREQ_22:
pll1_speed = 508000000;
mclk_div = 45;
bclk_div = 8;
func_mode = 0;
break;
case HW_FREQ_24:
pll1_speed = 516000000;
mclk_div = 42;
bclk_div = 8;
func_mode = 0;
break;
case HW_FREQ_32:
pll1_speed = 426000000;
mclk_div = 52;
bclk_div = 4;
func_mode = 0;
break;
case HW_FREQ_44:
pll1_speed = 508000000;
mclk_div = 45;
bclk_div = 4;
func_mode = 0;
break;
case HW_FREQ_48:
pll1_speed = 516000000;
mclk_div = 42;
bclk_div = 4;
func_mode = 0;
break;
case HW_FREQ_64:
pll1_speed = 426000000;
mclk_div = 52;
bclk_div = 2;
func_mode = 1;
break;
case HW_FREQ_88:
pll1_speed = 508000000;
mclk_div = 45;
bclk_div = 2;
func_mode = 1;
break;
case HW_FREQ_96:
pll1_speed = 516000000;
mclk_div = 42;
bclk_div = 2;
func_mode = 1;
break;
default:
return;
}
__i2s_stop_bitclk();
/* 0 = Single-Speed Mode (<50KHz);
1 = Double-Speed Mode (50-100KHz);
2 = Quad-Speed Mode; (100-200KHz) */
cs4398_write_reg(CS4398_REG_MODECTL, (cs4398_read_reg(CS4398_REG_MODECTL) & ~CS4398_FM_MASK) | func_mode);
if (func_mode == 2)
cs4398_write_reg(CS4398_REG_MISC, cs4398_read_reg(CS4398_REG_MISC) | CS4398_MCLKDIV2);
else
cs4398_write_reg(CS4398_REG_MISC, cs4398_read_reg(CS4398_REG_MISC) & ~CS4398_MCLKDIV2);
pll1_init(pll1_speed);
__cpm_enable_pll_change();
__cpm_set_i2sdiv(mclk_div-1);
__i2s_set_i2sdiv(bclk_div-1);
__i2s_start_bitclk();
}
void audiohw_postinit(void)
{
sleep(HZ);
audiohw_mute(false);
ap_mute(false);
pop_ctrl(1);
}
void audiohw_close(void)
{
pop_ctrl(0);
sleep(HZ/10);
ap_mute(true);
audiohw_mute(true);
amp_enable(0);
dac_enable(0);
__i2s_disable();
__cpm_stop_aic();
sleep(HZ);
pop_ctrl(1);
}

View File

@ -50,6 +50,7 @@
.set noat .set noat
#ifdef BOOTLOADER #ifdef BOOTLOADER
#ifndef XDUOO_X3
/* These will get filled in by scramble */ /* These will get filled in by scramble */
.word 0 /* Empty */ .word 0 /* Empty */
.word 0 /* Filesize */ .word 0 /* Filesize */
@ -65,6 +66,7 @@ _relocate_loop:
bne t1, t2, _relocate_loop bne t1, t2, _relocate_loop
sw t3, -4(t1) sw t3, -4(t1)
#endif #endif
#endif
_start: _start:
la ra, _start la ra, _start

View File

@ -0,0 +1,146 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 "config.h"
#include "system.h"
#include "cpu.h"
#include <stdarg.h>
#include <stdio.h>
#include "lcd.h"
#include "kernel.h"
#include "font.h"
#include "button.h"
#include "timefuncs.h"
#define CFG_UART_BASE UART1_BASE /* Base of the UART channel */
void serial_putc (const char c)
{
volatile u8 *uart_lsr = (volatile u8 *)(CFG_UART_BASE + OFF_LSR);
volatile u8 *uart_tdr = (volatile u8 *)(CFG_UART_BASE + OFF_TDR);
if (c == '\n') serial_putc ('\r');
/* Wait for fifo to shift out some bytes */
while ( !((*uart_lsr & (UARTLSR_TDRQ | UARTLSR_TEMT)) == 0x60) );
*uart_tdr = (u8)c;
}
void serial_puts (const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
void serial_putsf(const char *format, ...)
{
static char printfbuf[256];
int len;
unsigned char *ptr;
va_list ap;
va_start(ap, format);
ptr = printfbuf;
len = vsnprintf(ptr, sizeof(printfbuf), format, ap);
va_end(ap);
serial_puts(ptr);
serial_putc('\n');
}
void serial_put_hex(unsigned int d)
{
char c[12];
int i;
for(i = 0; i < 8;i++)
{
c[i] = (d >> ((7 - i) * 4)) & 0xf;
if(c[i] < 10)
c[i] += 0x30;
else
c[i] += (0x41 - 10);
}
c[8] = '\n';
c[9] = 0;
serial_puts(c);
}
void serial_put_dec(unsigned int d)
{
char c[16];
int i;
int j = 0;
int x = d;
while (x /= 10)
j++;
for (i = j; i >= 0; i--) {
c[i] = d % 10;
c[i] += 0x30;
d /= 10;
}
c[j + 1] = '\n';
c[j + 2] = 0;
serial_puts(c);
}
void serial_dump_data(unsigned char* data, int len)
{
int i;
for(i=0; i<len; i++)
{
unsigned char a = ((*data)>>4) & 0xf;
if(a < 10)
a += 0x30;
else
a += (0x41 - 10);
serial_putc( a );
a = (*data) & 0xf;
if(a < 10)
a += 0x30;
else
a += (0x41 - 10);
serial_putc( a );
serial_putc( ' ' );
data++;
}
serial_putc( '\n' );
}
bool dbg_ports(void)
{
serial_puts("dbg_ports\n");
return false;
}
bool dbg_hw_info(void)
{
serial_puts("dbg_hw_info\n");
return false;
}

View File

@ -0,0 +1,31 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 __DMA_TARGET_H_
#define __DMA_TARGET_H_
#include "system.h"
#include <string.h>
void memset_dma(void *target, int c, size_t len, unsigned int bits);
void memcpy_dma(void *target, const void *source, size_t len, unsigned int bits);
#endif /* __DMA_TARGET_H_ */

View File

@ -0,0 +1,102 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 "dma-target.h"
#define MDMA_CHANNEL 0
void memset_dma(void *target, int c, size_t len, unsigned int bits)
{
unsigned int d;
unsigned char *dp;
if(((unsigned int)target < 0xa0000000) && len)
dma_cache_wback_inv((unsigned long)target, len);
dp = (unsigned char *)((unsigned int)(&d) | 0xa0000000);
*(dp + 0) = c;
*(dp + 1) = c;
*(dp + 2) = c;
*(dp + 3) = c;
REG_MDMAC_DCCSR(MDMA_CHANNEL) = 0;
REG_MDMAC_DSAR(MDMA_CHANNEL) = PHYSADDR((unsigned long)dp);
REG_MDMAC_DTAR(MDMA_CHANNEL) = PHYSADDR((unsigned long)target);
REG_MDMAC_DRSR(MDMA_CHANNEL) = DMAC_DRSR_RS_AUTO;
switch (bits)
{
case 8:
REG_MDMAC_DTCR(MDMA_CHANNEL) = len;
REG_MDMAC_DCMD(MDMA_CHANNEL) = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_8 | DMAC_DCMD_DWDH_8 | DMAC_DCMD_DS_8BIT;
break;
case 16:
REG_MDMAC_DTCR(MDMA_CHANNEL) = len / 2;
REG_MDMAC_DCMD(MDMA_CHANNEL) = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BIT;
break;
case 32:
REG_MDMAC_DTCR(MDMA_CHANNEL) = len / 4;
REG_MDMAC_DCMD(MDMA_CHANNEL) = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT;
break;
default:
return;
}
REG_MDMAC_DCCSR(MDMA_CHANNEL) = DMAC_DCCSR_EN | DMAC_DCCSR_NDES;
while (REG_MDMAC_DTCR(MDMA_CHANNEL));
REG_MDMAC_DCCSR(MDMA_CHANNEL) = 0;
}
void memcpy_dma(void *target, const void *source, size_t len, unsigned int bits)
{
if(((unsigned int)source < 0xa0000000) && len)
dma_cache_wback_inv((unsigned long)source, len);
if(((unsigned int)target < 0xa0000000) && len)
dma_cache_wback_inv((unsigned long)target, len);
REG_MDMAC_DCCSR(MDMA_CHANNEL) = 0;
REG_MDMAC_DSAR(MDMA_CHANNEL) = PHYSADDR((unsigned long)source);
REG_MDMAC_DTAR(MDMA_CHANNEL) = PHYSADDR((unsigned long)target);
REG_MDMAC_DRSR(MDMA_CHANNEL) = DMAC_DRSR_RS_AUTO;
switch (bits)
{
case 8:
REG_MDMAC_DTCR(MDMA_CHANNEL) = len;
REG_MDMAC_DCMD(MDMA_CHANNEL) = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_SWDH_8 | DMAC_DCMD_DWDH_8 | DMAC_DCMD_DS_8BIT;
break;
case 16:
REG_MDMAC_DTCR(MDMA_CHANNEL) = len / 2;
REG_MDMAC_DCMD(MDMA_CHANNEL) = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BIT;
break;
case 32:
REG_MDMAC_DTCR(MDMA_CHANNEL) = len / 4;
REG_MDMAC_DCMD(MDMA_CHANNEL) = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT;
break;
default:
return;
}
REG_MDMAC_DCCSR(MDMA_CHANNEL) = DMAC_DCCSR_EN | DMAC_DCCSR_NDES;
while (REG_MDMAC_DTCR(MDMA_CHANNEL));
REG_MDMAC_DCCSR(MDMA_CHANNEL) = 0;
}

View File

@ -0,0 +1,355 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 "config.h"
#include "system.h"
#include "cpu.h"
#include "logf.h"
#include "i2c.h"
#define I2C_CHN 1
#define I2C_CLK 100000
#define I2C_READ 1
#define I2C_WRITE 0
#define I2C_M_RD 1
#define I2C_M_WR 2
#define TIMEOUT 100000
static char i2c_rwflags;
static int i2c_ctrl_rest = 0;
static unsigned char *msg_buf;
static int cmd_cnt;
static volatile int cmd_flag;
static int r_cnt;
static unsigned char i2c_subaddr = 0;
/*
* I2C bus protocol basic routines
*/
/* Interrupt handler */
void I2C1(void)
{
int timeout = TIMEOUT;
if (__i2c_abrt_7b_addr_nack(I2C_CHN)) {
int ret;
cmd_flag = -1;
__i2c_clear_interrupts(ret,I2C_CHN);
REG_I2C_INTM(I2C_CHN) = 0x0;
return;
}
/* first byte,when length > 1 */
if (cmd_flag == 0 && cmd_cnt > 1) {
cmd_flag = 1;
if (i2c_rwflags == I2C_M_RD) {
REG_I2C_DC(I2C_CHN) = I2C_READ << 8;
} else {
REG_I2C_DC(I2C_CHN) = (I2C_WRITE << 8) | *msg_buf++;
}
cmd_cnt--;
}
if (i2c_rwflags == I2C_M_RD) {
if (REG_I2C_STA(I2C_CHN) & I2C_STA_RFNE) {
*msg_buf++ = REG_I2C_DC(I2C_CHN) & 0xff;
r_cnt--;
}
REG_I2C_DC(I2C_CHN) = I2C_READ << 8;
} else {
REG_I2C_DC(I2C_CHN) = (I2C_WRITE << 8) | *msg_buf++;
}
cmd_cnt--;
if (!(cmd_cnt)) {
REG_I2C_INTM(I2C_CHN) = 0x0;
cmd_flag = 2;
if (i2c_rwflags == I2C_M_RD){
while (r_cnt > 2) {
if ((REG_I2C_STA(I2C_CHN) & I2C_STA_RFNE) && timeout) {
*msg_buf++ = REG_I2C_DC(I2C_CHN) & 0xff;
r_cnt--;
}
if (!(timeout--)) {
cmd_flag = -1;
return;
}
}
}
}
return;
}
static int i2c_set_clk(int i2c_clk)
{
int dev_clk = __cpm_get_pclk();
int count = 0;
if (i2c_clk < 0 || i2c_clk > 400000)
goto Set_clk_err;
count = dev_clk/i2c_clk - 23;
if (count < 0)
goto Set_clk_err;
if (i2c_clk <= 100000) {
REG_I2C_CTRL(I2C_CHN) = 0x43 | i2c_ctrl_rest; /* standard speed mode*/
if (count%2 == 0) {
REG_I2C_SHCNT(I2C_CHN) = count/2 + 6 - 5;
REG_I2C_SLCNT(I2C_CHN) = count/2 + 8 + 5;
} else {
REG_I2C_SHCNT(I2C_CHN) = count/2 + 6 -5;
REG_I2C_SLCNT(I2C_CHN) = count/2 + 8 +5 + 1;
}
} else {
REG_I2C_CTRL(I2C_CHN) = 0x45 | i2c_ctrl_rest; /* high speed mode*/
if (count%2 == 0) {
REG_I2C_FHCNT(I2C_CHN) = count/2 + 6;
REG_I2C_FLCNT(I2C_CHN) = count/2 + 8;
} else {
REG_I2C_FHCNT(I2C_CHN) = count/2 + 6;
REG_I2C_FLCNT(I2C_CHN) = count/2 + 8 + 1;
}
}
return 0;
Set_clk_err:
logf("i2c set sclk faild,i2c_clk=%d,dev_clk=%d.\n",i2c_clk,dev_clk);
return -1;
}
static int i2c_disable(void)
{
int timeout = TIMEOUT;
__i2c_disable(I2C_CHN);
while(__i2c_is_enable(I2C_CHN) && (timeout > 0)) {
udelay(1);
timeout--;
}
if(timeout)
return 0;
else
return 1;
}
static int i2c_enable(void)
{
int timeout = TIMEOUT;
__i2c_enable(I2C_CHN);
while(__i2c_is_disable(I2C_CHN) && (timeout > 0)) {
udelay(1);
timeout--;
}
if(timeout)
return 0;
else
return 1;
}
static void i2c_init_as_master(unsigned char address)
{
if(i2c_disable())
logf("i2c not disable\n");
i2c_set_clk(I2C_CLK);
REG_I2C_TAR(I2C_CHN) = address; /* slave id needed write only once */
REG_I2C_INTM(I2C_CHN) = 0x0; /* unmask all interrupts */
REG_I2C_TXTL(I2C_CHN) = 0x1;
if(i2c_enable())
logf("i2c not enable\n");
}
int xfer_read_subaddr(unsigned char subaddr, unsigned char device, unsigned char *buf, int length)
{
int timeout,r_i = 0;
cmd_cnt = length;
r_cnt = length;
msg_buf = buf;
i2c_rwflags = I2C_M_RD;
i2c_ctrl_rest = I2C_CTRL_REST;
i2c_init_as_master(device);
REG_I2C_DC(I2C_CHN) = (I2C_WRITE << 8) | subaddr;
cmd_flag = 0;
REG_I2C_INTM(I2C_CHN) = 0x10;
timeout = TIMEOUT;
while (cmd_flag != 2 && --timeout) {
if (cmd_flag == -1) {
r_i = 1;
goto R_dev_err;
}
udelay(10);
}
if (!timeout) {
r_i = 4;
goto R_timeout;
}
while (r_cnt) {
while (!(REG_I2C_STA(I2C_CHN) & I2C_STA_RFNE)) {
if ((cmd_flag == -1) ||
(REG_I2C_INTST(I2C_CHN) & I2C_INTST_TXABT) ||
REG_I2C_TXABRT(I2C_CHN)) {
int ret;
r_i = 2;
__i2c_clear_interrupts(ret,I2C_CHN);
goto R_dev_err;
}
}
*msg_buf++ = REG_I2C_DC(I2C_CHN) & 0xff;
r_cnt--;
}
timeout = TIMEOUT;
while ((REG_I2C_STA(I2C_CHN) & I2C_STA_MSTACT) && --timeout)
udelay(10);
if (!timeout){
r_i = 3;
goto R_timeout;
}
return 0;
R_dev_err:
R_timeout:
i2c_init_as_master(device);
if (r_i == 1) {
logf("Read i2c device 0x%2x failed in r_i = %d :device no ack.\n",device,r_i);
} else if (r_i == 2) {
logf("Read i2c device 0x%2x failed in r_i = %d :i2c abort.\n",device,r_i);
} else if (r_i == 3) {
logf("Read i2c device 0x%2x failed in r_i = %d :waite master inactive timeout.\n",device,r_i);
} else if (r_i == 4) {
logf("Read i2c device 0x%2x failed in r_i = %d.\n",device,r_i);
} else {
logf("Read i2c device 0x%2x failed in r_i = %d.\n",device,r_i);
}
return -1;
}
int xfer_write_subaddr(unsigned char subaddr, unsigned char device, const unsigned char *buf, int length)
{
int timeout,w_i = 0;
cmd_cnt = length;
r_cnt = length;
msg_buf = (unsigned char *)buf;
i2c_rwflags = I2C_M_WR;
i2c_ctrl_rest = I2C_CTRL_REST;
i2c_init_as_master(device);
REG_I2C_DC(I2C_CHN) = (I2C_WRITE << 8) | subaddr;
cmd_flag = 0;
REG_I2C_INTM(I2C_CHN) = 0x10;
timeout = TIMEOUT;
while ((cmd_flag != 2) && (--timeout))
{
if (cmd_flag == -1){
w_i = 1;
goto W_dev_err;
}
udelay(10);
}
timeout = TIMEOUT;
while((!(REG_I2C_STA(I2C_CHN) & I2C_STA_TFE)) && --timeout){
udelay(10);
}
if (!timeout){
w_i = 2;
goto W_timeout;
}
timeout = TIMEOUT;
while (__i2c_master_active(I2C_CHN) && --timeout);
if (!timeout){
w_i = 3;
goto W_timeout;
}
if ((length == 1)&&
((cmd_flag == -1) ||
(REG_I2C_INTST(I2C_CHN) & I2C_INTST_TXABT) ||
REG_I2C_TXABRT(I2C_CHN))) {
int ret;
w_i = 5;
__i2c_clear_interrupts(ret,I2C_CHN);
goto W_dev_err;
}
return 0;
W_dev_err:
W_timeout:
i2c_init_as_master(device);
if (w_i == 1) {
logf("Write i2c device 0x%2x failed in w_i=%d:device no ack. I2C_CHN:[%d]sxyzhang\n",device,w_i,I2C_CHN);
} else if (w_i == 2) {
logf("Write i2c device 0x%2x failed in w_i=%d:waite TF buff empty timeout.\n",device,w_i);
} else if (w_i == 3) {
logf("Write i2c device 0x%2x failed in w_i=%d:waite master inactive timeout.\n",device,w_i);
} else if (w_i == 5) {
logf("Write i2c device 0x%2x failed in w_i=%d:device no ack or abort.I2C_CHN:[%d]sxyzhang \n",device,w_i,I2C_CHN);
} else {
logf("Write i2c device 0x%2x failed in w_i=%d.\n",device,w_i);
}
return -1;
}
int i2c_read(int device, unsigned char* buf, int count)
{
return xfer_read_subaddr(i2c_subaddr, device, &buf[0], count);
}
int i2c_write(int device, const unsigned char* buf, int count)
{
if (count < 2)
{
i2c_subaddr = buf[0];
return 0;
}
return xfer_write_subaddr(buf[0], device, &buf[1], count-1);
}
void i2c_init(void)
{
__gpio_as_i2c(I2C_CHN);
__cpm_start_i2c1();
system_enable_irq(IRQ_I2C1);
}

View File

@ -0,0 +1,53 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 "config.h"
#include "system.h"
#include "kernel.h"
#include "cpu.h"
void tick_start(unsigned int interval_in_ms)
{
unsigned int latch;
/* 12Mhz / 4 = 3Mhz */
latch = interval_in_ms*1000 * 3;
REG_OST_OSTCSR = OSTCSR_PRESCALE4 | OSTCSR_EXT_EN;
REG_OST_OSTDR = latch;
REG_OST_OSTCNTL = 0;
REG_OST_OSTCNTH = 0;
system_enable_irq(IRQ_TCU0);
REG_TCU_TMCR = TMCR_OSTMASK; /* unmask match irq */
REG_TCU_TSCR = TSCR_OST; /* enable timer clock */
REG_TCU_TESR = TESR_OST; /* start counting up */
}
/* Interrupt handler */
void TCU0(void)
{
REG_TCU_TFCR = TFCR_OSTFLAG; /* ACK timer */
/* Run through the list of tick tasks */
call_tick_tasks();
}

View File

@ -0,0 +1,28 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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> /* off_t */
#include "config.h"
#include "cpu.h"
#include "lcd.h"
#include "lcd-target.h"
#include "system.h"
#include "kernel.h"

View File

@ -0,0 +1,240 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 "system.h"
#include "kernel.h"
#include "logf.h"
#include "audio.h"
#include "sound.h"
#include "pcm.h"
#include "pcm-internal.h"
#include "cpu.h"
/****************************************************************************
** Playback DMA transfer
**/
void pcm_play_dma_postinit(void)
{
audiohw_postinit();
/* Flush FIFO */
__aic_flush_tfifo();
}
void pcm_play_dma_init(void)
{
system_enable_irq(DMA_IRQ(DMA_AIC_TX_CHANNEL));
/* Initialize default register values. */
audiohw_init();
}
void pcm_dma_apply_settings(void)
{
audiohw_set_frequency(pcm_fsel);
}
static const void* playback_address;
static inline void set_dma(const void *addr, size_t size)
{
int burst_size;
logf("%x %d %x", (unsigned int)addr, size, REG_AIC_SR);
dma_cache_wback_inv((unsigned long)addr, size);
if(size % 16)
{
if(size % 4)
{
size /= 2;
burst_size = DMAC_DCMD_DS_16BIT;
}
else
{
size /= 4;
burst_size = DMAC_DCMD_DS_32BIT;
}
}
else
{
size /= 16;
burst_size = DMAC_DCMD_DS_16BYTE;
}
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = 0;
REG_DMAC_DSAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)addr);
REG_DMAC_DTAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)AIC_DR);
REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) = size;
REG_DMAC_DRSR(DMA_AIC_TX_CHANNEL) = DMAC_DRSR_RS_AICOUT;
REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) = (DMAC_DCMD_SAI | DMAC_DCMD_SWDH_32 | burst_size | DMAC_DCMD_DWDH_16 | DMAC_DCMD_TIE);
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN;
playback_address = addr;
}
static inline void play_dma_callback(void)
{
const void *start;
size_t size;
if (pcm_play_dma_complete_callback(PCM_DMAST_OK, &start, &size))
{
set_dma(start, size);
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN;
pcm_play_dma_status_callback(PCM_DMAST_STARTED);
}
}
void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void) __attribute__ ((section(".icode")));
void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void)
{
if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_AR)
{
logf("PCM DMA address error");
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_AR;
}
if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_HLT)
{
logf("PCM DMA halt");
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_HLT;
}
if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_TT)
{
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_TT;
play_dma_callback();
}
}
void pcm_play_dma_start(const void *addr, size_t size)
{
__dmac_channel_enable_clk(DMA_AIC_TX_CHANNEL);
set_dma(addr, size);
__aic_enable_replay();
__dmac_channel_enable_irq(DMA_AIC_TX_CHANNEL);
}
void pcm_play_dma_stop(void)
{
int flags = disable_irq_save();
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) | DMAC_DCCSR_HLT) & ~DMAC_DCCSR_EN;
__dmac_channel_disable_clk(DMA_AIC_TX_CHANNEL);
__aic_disable_replay();
restore_irq(flags);
}
static unsigned int play_lock = 0;
void pcm_play_lock(void)
{
int flags = disable_irq_save();
if (++play_lock == 1)
__dmac_channel_disable_irq(DMA_AIC_TX_CHANNEL);
restore_irq(flags);
}
void pcm_play_unlock(void)
{
int flags = disable_irq_save();
if (--play_lock == 0)
__dmac_channel_enable_irq(DMA_AIC_TX_CHANNEL);
restore_irq(flags);
}
void pcm_play_dma_pause(bool pause)
{
int flags = disable_irq_save();
if(pause)
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_EN;
else
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN;
restore_irq(flags);
}
static int get_dma_count(void)
{
int count = REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL);
switch(REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) & DMAC_DCMD_DS_MASK)
{
case DMAC_DCMD_DS_16BIT:
count *= 2;
break;
case DMAC_DCMD_DS_32BIT:
count *= 4;
break;
case DMAC_DCMD_DS_16BYTE:
count *= 16;
break;
}
return count;
}
size_t pcm_get_bytes_waiting(void)
{
int bytes, flags = disable_irq_save();
if(REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_EN)
bytes = get_dma_count() & ~3;
else
bytes = 0;
restore_irq(flags);
return bytes;
}
const void * pcm_play_dma_get_peak_buffer(int *count)
{
int flags = disable_irq_save();
const void* addr;
if(REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_EN)
{
int bytes = get_dma_count();
*count = bytes >> 2;
addr = (const void*)((int)(playback_address + bytes + 2) & ~3);
}
else
{
*count = 0;
addr = NULL;
}
restore_irq(flags);
return addr;
}

View File

@ -0,0 +1,710 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 "config.h"
#include "cpu.h"
#include "mips.h"
#include "mmu-mips.h"
#include "panic.h"
#include "system.h"
#include "kernel.h"
#include "power.h"
static int irq;
static void UIRQ(void)
{
panicf("Unhandled interrupt occurred: %d", irq);
}
#define intr(name) extern __attribute__((weak,alias("UIRQ"))) void name (void)
intr(I2C1);intr(I2C0);intr(UART3);intr(UART2);intr(UART1);intr(UART0);intr(GPU);
intr(SSI1);intr(SSI0);intr(TSSI);intr(KBC);intr(SADC);intr(ETH);intr(UHC);
intr(OTG);intr(TCU2);intr(TCU1);intr(TCU0);intr(GPS);intr(IPU);intr(CIM);
intr(LCD);intr(RTC);intr(OWI);intr(AIC);intr(MSC2);intr(MSC1);intr(MSC0);
intr(SCC);intr(BCH);intr(PCM);intr(HARB0);intr(HARB2);intr(AOSD);intr(CPM);
intr(DMA0);intr(DMA1);intr(DMA2);intr(DMA3);intr(DMA4);intr(DMA5);
intr(DMA6);intr(DMA7);intr(DMA8);intr(DMA9);intr(DMA10);intr(DMA11);
intr(MDMA0);intr(MDMA1);intr(MDMA2);
intr(BDMA0);intr(BDMA1);intr(BDMA2);
intr(GPIO0);intr(GPIO1);intr(GPIO2);intr(GPIO3);intr(GPIO4);intr(GPIO5);
intr(GPIO6);intr(GPIO7);intr(GPIO8);intr(GPIO9);intr(GPIO10);intr(GPIO11);
intr(GPIO12);intr(GPIO13);intr(GPIO14);intr(GPIO15);intr(GPIO16);intr(GPIO17);
intr(GPIO18);intr(GPIO19);intr(GPIO20);intr(GPIO21);intr(GPIO22);intr(GPIO23);
intr(GPIO24);intr(GPIO25);intr(GPIO26);intr(GPIO27);intr(GPIO28);intr(GPIO29);
intr(GPIO30);intr(GPIO31);intr(GPIO32);intr(GPIO33);intr(GPIO34);intr(GPIO35);
intr(GPIO36);intr(GPIO37);intr(GPIO38);intr(GPIO39);intr(GPIO40);intr(GPIO41);
intr(GPIO42);intr(GPIO43);intr(GPIO44);intr(GPIO45);intr(GPIO46);intr(GPIO47);
intr(GPIO48);intr(GPIO49);intr(GPIO50);intr(GPIO51);intr(GPIO52);intr(GPIO53);
intr(GPIO54);intr(GPIO55);intr(GPIO56);intr(GPIO57);intr(GPIO58);intr(GPIO59);
intr(GPIO60);intr(GPIO61);intr(GPIO62);intr(GPIO63);intr(GPIO64);intr(GPIO65);
intr(GPIO66);intr(GPIO67);intr(GPIO68);intr(GPIO69);intr(GPIO70);intr(GPIO71);
intr(GPIO72);intr(GPIO73);intr(GPIO74);intr(GPIO75);intr(GPIO76);intr(GPIO77);
intr(GPIO78);intr(GPIO79);intr(GPIO80);intr(GPIO81);intr(GPIO82);intr(GPIO83);
intr(GPIO84);intr(GPIO85);intr(GPIO86);intr(GPIO87);intr(GPIO88);intr(GPIO89);
intr(GPIO90);intr(GPIO91);intr(GPIO92);intr(GPIO93);intr(GPIO94);intr(GPIO95);
intr(GPIO96);intr(GPIO97);intr(GPIO98);intr(GPIO99);intr(GPIO100);intr(GPIO101);
intr(GPIO102);intr(GPIO103);intr(GPIO104);intr(GPIO105);intr(GPIO106);
intr(GPIO107);intr(GPIO108);intr(GPIO109);intr(GPIO110);intr(GPIO111);
intr(GPIO112);intr(GPIO113);intr(GPIO114);intr(GPIO115);intr(GPIO116);
intr(GPIO117);intr(GPIO118);intr(GPIO119);intr(GPIO120);intr(GPIO121);
intr(GPIO122);intr(GPIO123);intr(GPIO124);intr(GPIO125);intr(GPIO126);
intr(GPIO127);intr(GPIO128);intr(GPIO129);intr(GPIO130);intr(GPIO131);
intr(GPIO132);intr(GPIO133);intr(GPIO134);intr(GPIO135);intr(GPIO136);
intr(GPIO137);intr(GPIO138);intr(GPIO139);intr(GPIO140);intr(GPIO141);
intr(GPIO142);intr(GPIO143);intr(GPIO144);intr(GPIO145);intr(GPIO146);
intr(GPIO147);intr(GPIO148);intr(GPIO149);intr(GPIO150);intr(GPIO151);
intr(GPIO152);intr(GPIO153);intr(GPIO154);intr(GPIO155);intr(GPIO156);
intr(GPIO157);intr(GPIO158);intr(GPIO159);intr(GPIO160);intr(GPIO161);
intr(GPIO162);intr(GPIO163);intr(GPIO164);intr(GPIO165);intr(GPIO166);
intr(GPIO167);intr(GPIO168);intr(GPIO169);intr(GPIO170);intr(GPIO171);
intr(GPIO172);intr(GPIO173);intr(GPIO174);intr(GPIO175);intr(GPIO176);
intr(GPIO177);intr(GPIO178);intr(GPIO179);intr(GPIO180);intr(GPIO181);
intr(GPIO182);intr(GPIO183);intr(GPIO184);intr(GPIO185);intr(GPIO186);
intr(GPIO187);intr(GPIO188);intr(GPIO189);intr(GPIO190);intr(GPIO191);
static void (* const irqvector[])(void) =
{
I2C1,I2C0,UART3,UART2,UART1,UART0,GPU,SSI1,
SSI0,TSSI,UIRQ,KBC,UIRQ,UIRQ,UIRQ,UIRQ,
UIRQ,UIRQ,SADC,ETH,UHC,OTG,UIRQ,UIRQ,
UIRQ,TCU2,TCU1,TCU0,GPS,IPU,CIM,LCD,
RTC,OWI,AIC,MSC2,MSC1,MSC0,SCC,BCH, // 32
PCM,HARB0,HARB2,AOSD,CPM,UIRQ,
DMA0,DMA1,DMA2,DMA3,DMA4,DMA5,DMA6,DMA7, // 46
DMA8,DMA9,DMA10,DMA11,MDMA0,MDMA1,MDMA2,BDMA0,
BDMA1,BDMA2,
GPIO0,GPIO1,GPIO2,GPIO3,GPIO4,GPIO5,GPIO6,GPIO7, // 64
GPIO8,GPIO9,GPIO10,GPIO11,GPIO12,GPIO13,GPIO14,GPIO15,
GPIO16,GPIO17,GPIO18,GPIO19,GPIO20,GPIO21,GPIO22,GPIO23,
GPIO24,GPIO25,GPIO26,GPIO27,GPIO28,GPIO29,GPIO30,GPIO31,
GPIO32,GPIO33,GPIO34,GPIO35,GPIO36,GPIO37,GPIO38,GPIO39,
GPIO40,GPIO41,GPIO42,GPIO43,GPIO44,GPIO45,GPIO46,GPIO47,
GPIO48,GPIO49,GPIO50,GPIO51,GPIO52,GPIO53,GPIO54,GPIO55,
GPIO56,GPIO57,GPIO58,GPIO59,GPIO60,GPIO61,GPIO62,GPIO63,
GPIO64,GPIO65,GPIO66,GPIO67,GPIO68,GPIO69,GPIO70,GPIO71,
GPIO72,GPIO73,GPIO74,GPIO75,GPIO76,GPIO77,GPIO78,GPIO79,
GPIO80,GPIO81,GPIO82,GPIO83,GPIO84,GPIO85,GPIO86,GPIO87,
GPIO88,GPIO89,GPIO90,GPIO91,GPIO92,GPIO93,GPIO94,GPIO95,
GPIO96,GPIO97,GPIO98,GPIO99,GPIO100,GPIO101,GPIO102,GPIO103,
GPIO104,GPIO105,GPIO106,GPIO107,GPIO108,GPIO109,GPIO110,GPIO111,
GPIO112,GPIO113,GPIO114,GPIO115,GPIO116,GPIO117,GPIO118,GPIO119,
GPIO120,GPIO121,GPIO122,GPIO123,GPIO124,GPIO125,GPIO126,GPIO127,
GPIO128,GPIO129,GPIO130,GPIO131,GPIO132,GPIO133,GPIO134,GPIO135,
GPIO136,GPIO137,GPIO138,GPIO139,GPIO140,GPIO141,GPIO142,GPIO143,
GPIO144,GPIO145,GPIO146,GPIO147,GPIO148,GPIO149,GPIO150,GPIO151,
GPIO152,GPIO153,GPIO154,GPIO155,GPIO156,GPIO157,GPIO158,GPIO159,
GPIO160,GPIO161,GPIO162,GPIO163,GPIO164,GPIO165,GPIO166,GPIO167,
GPIO168,GPIO169,GPIO170,GPIO171,GPIO172,GPIO173,GPIO174,GPIO175,
GPIO176,GPIO177,GPIO178,GPIO179,GPIO180,GPIO181,GPIO182,GPIO183,
GPIO184,GPIO185,GPIO186,GPIO187,GPIO188,GPIO189,GPIO190,GPIO191
};
static unsigned int dma_irq_mask = 0;
static unsigned char mdma_irq_mask = 0;
static unsigned char bdma_irq_mask = 0;
static unsigned int gpio_irq_mask[6] = {0};
void system_enable_irq(unsigned int irq)
{
register unsigned int t;
if ((irq >= IRQ_GPIO_0) && (irq <= IRQ_GPIO_0 + NUM_GPIO))
{
__gpio_unmask_irq(irq - IRQ_GPIO_0);
t = (irq - IRQ_GPIO_0) >> 5;
gpio_irq_mask[t] |= (1 << ((irq - IRQ_GPIO_0) & 0x1f));
__intc_unmask_irq(IRQ_GPIO0 - t);
}
else if ((irq >= IRQ_DMA_0) && (irq <= IRQ_DMA_0 + NUM_DMA))
{
__dmac_channel_enable_irq(irq - IRQ_DMA_0);
t = (irq - IRQ_DMA_0) / HALF_DMA_NUM;
dma_irq_mask |= (1 << (irq - IRQ_DMA_0));
__intc_unmask_irq(IRQ_DMAC0 - t);
}
else if ((irq >= IRQ_MDMA_0) && (irq <= IRQ_MDMA_0 + NUM_MDMA))
{
__mdmac_channel_enable_irq(irq - IRQ_MDMA_0);
mdma_irq_mask |= (1 << (irq - IRQ_MDMA_0));
__intc_unmask_irq(IRQ_MDMA);
}
else if ((irq >= IRQ_BDMA_0) && (irq <= IRQ_BDMA_0 + NUM_BDMA))
{
__bdmac_channel_enable_irq(irq - IRQ_BDMA_0);
bdma_irq_mask |= (1 << (irq - IRQ_BDMA_0));
__intc_unmask_irq(IRQ_BDMA);
}
else if (irq < IRQ_INTC_MAX)
__intc_unmask_irq(irq);
}
static void dis_irq(unsigned int irq)
{
register unsigned int t;
if ((irq >= IRQ_GPIO_0) && (irq <= IRQ_GPIO_0 + NUM_GPIO))
{
__gpio_mask_irq(irq - IRQ_GPIO_0);
t = (irq - IRQ_GPIO_0) >> 5;
gpio_irq_mask[t] &= ~(1 << ((irq - IRQ_GPIO_0) & 0x1f));
if (!gpio_irq_mask[t])
__intc_mask_irq(IRQ_GPIO0 - t);
}
else if ((irq >= IRQ_DMA_0) && (irq < IRQ_DMA_0 + NUM_DMA))
{
__dmac_channel_disable_irq(irq - IRQ_DMA_0);
dma_irq_mask &= ~(1 << (irq - IRQ_DMA_0));
if (!(dma_irq_mask & 0x003F))
__intc_mask_irq(IRQ_DMAC0);
if (!(dma_irq_mask & 0x0FC0))
__intc_mask_irq(IRQ_DMAC1);
}
else if ((irq >= IRQ_MDMA_0) && (irq < IRQ_MDMA_0 + NUM_MDMA))
{
__mdmac_channel_disable_irq(irq - IRQ_MDMA_0);
mdma_irq_mask &= ~(1 << (irq - IRQ_MDMA_0));
if (!mdma_irq_mask)
__intc_mask_irq(IRQ_MDMA);
}
else if ((irq >= IRQ_BDMA_0) && (irq < IRQ_BDMA_0 + NUM_BDMA))
{
__bdmac_channel_disable_irq(irq - IRQ_BDMA_0);
bdma_irq_mask &= ~(1 << (irq - IRQ_BDMA_0));
if (!bdma_irq_mask)
__intc_mask_irq(IRQ_BDMA);
}
else if (irq < IRQ_INTC_MAX)
__intc_mask_irq(irq);
}
static void ack_irq(unsigned int irq)
{
if ((irq >= IRQ_GPIO_0) && (irq <= IRQ_GPIO_0 + NUM_GPIO))
{
__gpio_ack_irq(irq - IRQ_GPIO_0);
}
}
static int get_irq_number(void)
{
static unsigned long ipl0, ipl1;
register int irq0, irq1;
ipl0 |= REG_INTC_ICPR(0);
ipl1 |= REG_INTC_ICPR(1);
if (!(ipl0 || ipl1))
return -1;
__asm__ __volatile__("negu $8, %0 \n"
"and $8, %0, $8 \n"
"clz %0, %1 \n"
"li $8, 31 \n"
"subu %0, $8, %0 \n"
: "=r" (irq0)
: "r" (ipl0)
: "t0"
);
__asm__ __volatile__("negu $8, %0 \n"
"and $8, %0, $8 \n"
"clz %0, %1 \n"
"li $8, 31 \n"
"subu %0, $8, %0 \n"
: "=r" (irq1)
: "r" (ipl1)
: "t0"
);
if (UNLIKELY(irq0 < 0) && UNLIKELY(irq1 < 0))
return -1;
if (!(ipl0 & 3)) {
if (ipl0) {
irq = irq0;
ipl0 &= ~(1<<irq0);
} else {
irq = irq1 + 32;
ipl1 &= ~(1<<irq1);
}
} else {
if (ipl0 & 2) {
irq = 1;
ipl0 &= ~(1<<irq);
} else {
irq = 0;
ipl0 &= ~(1<<irq);
}
}
switch (irq)
{
case IRQ_GPIO0:
case IRQ_GPIO1:
case IRQ_GPIO2:
case IRQ_GPIO3:
case IRQ_GPIO4:
case IRQ_GPIO5:
irq = __gpio_get_irq() + IRQ_GPIO_0;
break;
case IRQ_DMAC0:
case IRQ_DMAC1:
irq = __dmac_get_irq() + IRQ_DMA_0;
break;
case IRQ_MDMA:
irq = __mdmac_get_irq() + IRQ_MDMA_0;
break;
case IRQ_BDMA:
irq = __bdmac_get_irq() + IRQ_BDMA_0;
break;
}
return irq;
}
void intr_handler(void)
{
register int irq = get_irq_number();
if(UNLIKELY(irq < 0))
return;
ack_irq(irq);
if(LIKELY(irq >= 0))
irqvector[irq]();
}
#define EXC(x,y) case (x): return (y);
static char* parse_exception(unsigned int cause)
{
switch(cause & M_CauseExcCode)
{
EXC(EXC_INT, "Interrupt");
EXC(EXC_MOD, "TLB Modified");
EXC(EXC_TLBL, "TLB Exception (Load or Ifetch)");
EXC(EXC_ADEL, "Address Error (Load or Ifetch)");
EXC(EXC_ADES, "Address Error (Store)");
EXC(EXC_TLBS, "TLB Exception (Store)");
EXC(EXC_IBE, "Instruction Bus Error");
EXC(EXC_DBE, "Data Bus Error");
EXC(EXC_SYS, "Syscall");
EXC(EXC_BP, "Breakpoint");
EXC(EXC_RI, "Reserved Instruction");
EXC(EXC_CPU, "Coprocessor Unusable");
EXC(EXC_OV, "Overflow");
EXC(EXC_TR, "Trap Instruction");
EXC(EXC_FPE, "Floating Point Exception");
EXC(EXC_C2E, "COP2 Exception");
EXC(EXC_MDMX, "MDMX Exception");
EXC(EXC_WATCH, "Watch Exception");
EXC(EXC_MCHECK, "Machine Check Exception");
EXC(EXC_CacheErr, "Cache error caused re-entry to Debug Mode");
default:
return NULL;
}
}
void exception_handler(void* stack_ptr, unsigned int cause, unsigned int epc)
{
panicf("Exception occurred: %s [0x%08x] at 0x%08x (stack at 0x%08x)", parse_exception(cause), read_c0_badvaddr(), epc, (unsigned int)stack_ptr);
}
void tlb_refill_handler(void)
{
panicf("TLB refill handler at 0x%08lx! [0x%x]", read_c0_epc(), read_c0_badvaddr());
}
void udelay(unsigned int usec)
{
unsigned int i = usec * (__cpm_get_cclk() / 2000000);
__asm__ __volatile__ (
".set noreorder \n"
"1: \n"
"bne %0, $0, 1b \n"
"addi %0, %0, -1 \n"
".set reorder \n"
: "=r" (i)
: "0" (i)
);
}
void mdelay(unsigned int msec)
{
unsigned int i;
for(i=0; i<msec; i++)
udelay(1000);
}
#define MHZ (1000 * 1000)
static inline unsigned int pll_calc_m_n_od(unsigned int speed, unsigned int xtal)
{
const int pll_m_max = 0x7f, pll_m_min = 4;
const int pll_n_max = 0x0f, pll_n_min = 2;
int od[] = {1, 2, 4, 8};
unsigned int plcr_m_n_od = 0;
unsigned int distance;
unsigned int tmp, raw;
int i, j, k;
int m, n;
distance = 0xFFFFFFFF;
for (i = 0; i < (int)sizeof (od) / (int)sizeof(int); i++) {
/* Limit: 500MHZ <= CLK_OUT * OD <= 1500MHZ */
if ((speed * od[i]) < 500 * MHZ || (speed * od[i]) > 1500 * MHZ)
continue;
for (k = pll_n_min; k <= pll_n_max; k++) {
n = k;
/* Limit: 1MHZ <= XIN/N <= 50MHZ */
if ((xtal / n) < (1 * MHZ))
break;
if ((xtal / n) > (15 * MHZ))
continue;
for (j = pll_m_min; j <= pll_m_max; j++) {
m = j*2;
raw = xtal * m / n;
tmp = raw / od[i];
tmp = (tmp > speed) ? (tmp - speed) : (speed - tmp);
if (tmp < distance) {
distance = tmp;
plcr_m_n_od = (j << CPPCR0_PLLM_LSB)
| (k << CPPCR0_PLLN_LSB)
| (i << CPPCR0_PLLOD_LSB);
if (!distance) { /* Match. */
return plcr_m_n_od;
}
}
}
}
}
return plcr_m_n_od;
}
/* PLL output clock = EXTAL * NF / (NR * NO)
*
* NF = FD + 2, NR = RD + 2
* NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3)
*/
static void pll0_init(unsigned int freq)
{
register unsigned int cfcr, plcr1;
int n2FR[9] = {
0, 0, 1, 2, 3, 0, 4, 0, 5
};
/** divisors,
* for jz4760b,I:H:H2:P:M:S.
* DIV should be one of [1, 2, 3, 4, 6, 8]
*/
int div[6] = {1, 4, 4, 4, 4, 4};
int usbdiv;
/* set ahb **/
REG32(HARB0_BASE) = 0x00300000;
REG32(0xb3070048) = 0x00000000;
REG32(HARB2_BASE) = 0x00FFFFFF;
cfcr = CPCCR_PCS |
(n2FR[div[0]] << CPCCR_CDIV_LSB) |
(n2FR[div[1]] << CPCCR_HDIV_LSB) |
(n2FR[div[2]] << CPCCR_H2DIV_LSB) |
(n2FR[div[3]] << CPCCR_PDIV_LSB) |
(n2FR[div[4]] << CPCCR_MDIV_LSB) |
(n2FR[div[5]] << CPCCR_SDIV_LSB);
// write REG_DDRC_CTRL 8 times to clear ddr fifo
REG_DDRC_CTRL = 0;
REG_DDRC_CTRL = 0;
REG_DDRC_CTRL = 0;
REG_DDRC_CTRL = 0;
REG_DDRC_CTRL = 0;
REG_DDRC_CTRL = 0;
REG_DDRC_CTRL = 0;
REG_DDRC_CTRL = 0;
if (CFG_EXTAL > 16000000)
cfcr |= CPCCR_ECS;
else
cfcr &= ~CPCCR_ECS;
cfcr &= ~CPCCR_MEM; /* mddr */
cfcr |= CPCCR_CE;
plcr1 = pll_calc_m_n_od(freq, CFG_EXTAL);
plcr1 |= (0x20 << CPPCR0_PLLST_LSB) /* PLL stable time */
| CPPCR0_PLLEN; /* enable PLL */
/*
* Init USB Host clock, pllout2 must be n*48MHz
* For JZ4760b UHC - River.
*/
usbdiv = (cfcr & CPCCR_PCS) ? CPU_FREQ : (CPU_FREQ / 2);
REG_CPM_UHCCDR = usbdiv / 48000000 - 1;
/* init PLL */
REG_CPM_CPCCR = cfcr;
REG_CPM_CPPCR0 = plcr1;
__cpm_enable_pll_change();
/*wait for pll output stable ...*/
while (!(REG_CPM_CPPCR0 & CPPCR0_PLLS));
REG_CPM_CPPCR0 &= ~CPPCR0_LOCK;
}
void pll1_init(unsigned int freq)
{
register unsigned int plcr2;
/* set CPM_CPCCR_MEM only for ddr1 or ddr2 */
plcr2 = pll_calc_m_n_od(freq, CFG_EXTAL)
| CPPCR1_PLL1EN; /* enable PLL1 */
/* init PLL_1 , source clock is extal clock */
REG_CPM_CPPCR1 = plcr2;
__cpm_enable_pll_change();
/*wait for pll_1 output stable ...*/
while (!(REG_CPM_CPPCR1 & CPPCR1_PLL1S));
REG_CPM_CPPCR1 &= ~CPPCR1_LOCK;
}
static void serial_setbrg(void)
{
volatile u8 *uart_lcr = (volatile u8 *)(CFG_UART_BASE + OFF_LCR);
volatile u8 *uart_dlhr = (volatile u8 *)(CFG_UART_BASE + OFF_DLHR);
volatile u8 *uart_dllr = (volatile u8 *)(CFG_UART_BASE + OFF_DLLR);
volatile u8 *uart_umr = (volatile u8 *)(CFG_UART_BASE + OFF_UMR);
volatile u8 *uart_uacr = (volatile u8 *)(CFG_UART_BASE + OFF_UACR);
u16 baud_div, tmp;
*uart_umr = 16;
*uart_uacr = 0;
baud_div = 13; /* 57600 */
tmp = *uart_lcr;
tmp |= UARTLCR_DLAB;
*uart_lcr = tmp;
*uart_dlhr = (baud_div >> 8) & 0xff;
*uart_dllr = baud_div & 0xff;
tmp &= ~UARTLCR_DLAB;
*uart_lcr = tmp;
}
int serial_preinit(void)
{
volatile u8 *uart_fcr = (volatile u8 *)(CFG_UART_BASE + OFF_FCR);
volatile u8 *uart_lcr = (volatile u8 *)(CFG_UART_BASE + OFF_LCR);
volatile u8 *uart_ier = (volatile u8 *)(CFG_UART_BASE + OFF_IER);
volatile u8 *uart_sircr = (volatile u8 *)(CFG_UART_BASE + OFF_SIRCR);
__gpio_as_uart1();
__cpm_start_uart1();
/* Disable port interrupts while changing hardware */
*uart_ier = 0;
/* Disable UART unit function */
*uart_fcr = ~UARTFCR_UUE;
/* Set both receiver and transmitter in UART mode (not SIR) */
*uart_sircr = ~(SIRCR_RSIRE | SIRCR_TSIRE);
/* Set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */
*uart_lcr = UARTLCR_WLEN_8 | UARTLCR_STOP1;
/* Set baud rate */
serial_setbrg();
/* Enable UART unit, enable and clear FIFO */
*uart_fcr = UARTFCR_UUE | UARTFCR_FE | UARTFCR_TFLS | UARTFCR_RFLS;
return 0;
}
void usb_preinit(void)
{
/* Clear ECS bit of CPCCR, 0:clock source is EXCLK, 1:clock source is EXCLK/2 */
REG_CPM_CPCCR &= ~CPCCR_ECS;
/* Clear all bits of USBCDR, 0:OTG clock source is pin EXCLK, PLL0 output, divider = 1:12MHZ */
REG_CPM_USBCDR = 0;
/* Set CE bit of CPCCR, it means frequence is changed immediately */
REG_CPM_CPCCR |= CPCCR_CE;
udelay(3);
/* Clear OTG bit of CLKGR0, 0:device can be accessed */
REG_CPM_CLKGR0 &= ~CLKGR0_OTG;
/* fil */
REG_CPM_USBVBFIL = 0x80;
/* rdt */
REG_CPM_USBRDT = (600 * (CPU_FREQ / 1000000)) / 1000;
/* rdt - filload_en */
REG_CPM_USBRDT |= (1 << 25);
/* TXRISETUNE & TXVREFTUNE. */
REG_CPM_USBPCR &= ~0x3f;
REG_CPM_USBPCR |= 0x35;
/* enable tx pre-emphasis */
REG_CPM_USBPCR |= 0x40;
/* most DC leave of tx */
REG_CPM_USBPCR |= 0xf;
/* Device Mode. */
REG_CPM_USBPCR &= ~(1 << 31);
REG_CPM_USBPCR |= USBPCR_VBUSVLDEXT;
/* phy reset */
REG_CPM_USBPCR |= USBPCR_POR;
udelay(30);
REG_CPM_USBPCR &= ~USBPCR_POR;
udelay(300);
/* Enable the USB PHY */
REG_CPM_OPCR |= OPCR_OTGPHY_ENABLE;
/* Wait PHY Clock Stable. */
udelay(300);
}
void dma_preinit(void)
{
__cpm_start_mdma();
__cpm_start_dmac();
REG_MDMAC_DMACKES = 0x1;
REG_DMAC_DMACR(DMA_AIC_TX_CHANNEL) = DMAC_DMACR_DMAE | DMAC_DMACR_FAIC;
REG_DMAC_DMACR(DMA_SD_RX_CHANNEL) = DMAC_DMACR_DMAE | DMAC_DMACR_FMSC;
REG_DMAC_DMACR(DMA_SD_TX_CHANNEL) = DMAC_DMACR_DMAE | DMAC_DMACR_FMSC;
}
/* Gets called *before* main */
void ICODE_ATTR system_main(void)
{
int i;
__dcache_writeback_all();
__icache_invalidate_all();
write_c0_status(1 << 28 | 1 << 10 ); /* Enable CP | Mask interrupt 2 */
/* Disable all interrupts */
for(i=0; i<IRQ_INTC_MAX; i++)
dis_irq(i);
mmu_init();
pll0_init(CPU_FREQ);
pll1_init(CPU_FREQ);
serial_preinit();
usb_preinit();
dma_preinit();
/* Enable interrupts at core level */
enable_interrupt();
}
void system_reboot(void)
{
REG_WDT_WCSR = WCSR_PRESCALE4 | WCSR_CLKIN_EXT;
REG_WDT_WCNT = 0;
REG_WDT_WDR = JZ_EXTAL/1000; /* reset after 4ms */
REG_TCU_TSCR = TSCR_WDT; /* enable wdt clock */
REG_WDT_WCER = WCER_TCEN; /* wdt start */
while (1);
}
void system_exception_wait(void)
{
/* check for power button without including any .h file */
while(1)
{
if( (~REG_GPIO_PXPIN(0)) & (1 << 30) )
return;
asm volatile("nop");
}
}
void power_off(void)
{
REG_CPM_RSR = 0x0;
/* Set minimum wakeup_n pin low-level assertion time for wakeup: 100ms */
rtc_write_reg(RTC_HWFCR, HWFCR_WAIT_TIME(1000));
/* Set reset pin low-level assertion time after wakeup: must > 60ms */
rtc_write_reg(RTC_HRCR, HRCR_WAIT_TIME(60));
/* clear wakeup status register */
rtc_write_reg(RTC_HWRSR, 0x0);
/* set wake up valid level as low */
rtc_write_reg(RTC_HWCR,0x8);
/* Put CPU to hibernate mode */
rtc_write_reg(RTC_HCR, HCR_PD);
while (1);
}
void system_init(void)
{
}
int system_memory_guard(int newmode)
{
(void)newmode;
return 0;
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
void set_cpu_frequency(long frequency)
{
serial_putsf("set_cpu_frequency: %d\n", frequency);
}
#endif

View File

@ -25,7 +25,7 @@
#include <inttypes.h> #include <inttypes.h>
#include "config.h" #include "config.h"
#include "jz4740.h" #include "cpu.h"
#include "mipsregs.h" #include "mipsregs.h"
#define CACHE_SIZE 16*1024 #define CACHE_SIZE 16*1024
@ -35,6 +35,8 @@
/* no optimized byteswap functions implemented for mips, yet */ /* no optimized byteswap functions implemented for mips, yet */
#define NEED_GENERIC_BYTESWAPS #define NEED_GENERIC_BYTESWAPS
#define STORAGE_WANTS_ALIGN
/* This one returns the old status */ /* This one returns the old status */
static inline int set_interrupt_status(int status, int mask) static inline int set_interrupt_status(int status, int mask)
{ {
@ -86,10 +88,18 @@ void mdelay(unsigned int msec);
void dma_enable(void); void dma_enable(void);
void dma_disable(void); void dma_disable(void);
#if CONFIG_CPU == JZ4732
#define DMA_AIC_TX_CHANNEL 0 #define DMA_AIC_TX_CHANNEL 0
#define DMA_NAND_CHANNEL 1 #define DMA_NAND_CHANNEL 1
#define DMA_USB_CHANNEL 2 #define DMA_USB_CHANNEL 2
#define DMA_LCD_CHANNEL 3 #define DMA_LCD_CHANNEL 3
#elif CONFIG_CPU == JZ4760B
#define DMA_AIC_TX_CHANNEL 0
#define DMA_NAND_CHANNEL 1
#define DMA_USB_CHANNEL 2
#define DMA_SD_RX_CHANNEL 3
#define DMA_SD_TX_CHANNEL 4
#endif
#define XDMA_CALLBACK(n) DMA ## n #define XDMA_CALLBACK(n) DMA ## n
#define DMA_CALLBACK(n) XDMA_CALLBACK(n) #define DMA_CALLBACK(n) XDMA_CALLBACK(n)
@ -103,7 +113,7 @@ void dma_disable(void);
*/ */
static inline void core_sleep(void) static inline void core_sleep(void)
{ {
#if CONFIG_CPU == JZ4732 #if CONFIG_CPU == JZ4732 || CONFIG_CPU == JZ4760B
__cpm_idle_mode(); __cpm_idle_mode();
#endif #endif
asm volatile(".set mips32r2 \n" asm volatile(".set mips32r2 \n"

View File

@ -0,0 +1,101 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 "config.h"
#include "cpu.h"
#include "system.h"
#include "timer.h"
/* Interrupt handler */
void TCU1(void)
{
__tcu_clear_full_match_flag(5);
if (pfn_timer != NULL)
pfn_timer();
}
bool timer_set(long cycles, bool start)
{
unsigned int divider = cycles, prescaler_bit = 0, prescaler = 1, old_irq;
if(cycles < 1)
return false;
if(start && pfn_unregister != NULL)
{
pfn_unregister();
pfn_unregister = NULL;
}
/* Increase prescale values starting from 0 to make the cycle count fit */
while(divider > 65535 && prescaler <= 1024)
{
prescaler <<= 2; /* 1, 4, 16, 64, 256, 1024 */
prescaler_bit++;
divider = cycles / prescaler;
}
old_irq = disable_irq_save();
__tcu_stop_counter(5);
if(start)
{
__tcu_disable_pwm_output(5);
__tcu_mask_half_match_irq(5);
__tcu_unmask_full_match_irq(5);
/* EXTAL clock = CFG_EXTAL (12Mhz in most targets) */
__tcu_select_extalclk(5);
}
REG_TCU_TCSR(5) = (REG_TCU_TCSR(5) & ~TCSR_PRESCALE_MASK) | (prescaler_bit << TCSR_PRESCALE_LSB);
REG_TCU_TCNT(5) = 0;
REG_TCU_TDHR(5) = 0;
REG_TCU_TDFR(5) = divider;
__tcu_clear_full_match_flag(5);
if(start)
{
system_enable_irq(IRQ_TCU1);
__tcu_start_counter(5);
}
restore_irq(old_irq);
return true;
}
bool timer_start(void)
{
__tcu_start_counter(5);
return true;
}
void timer_stop(void)
{
unsigned int old_irq = disable_irq_save();
__tcu_stop_counter(5);
restore_irq(old_irq);
}

View File

@ -0,0 +1,870 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 "config.h"
/*#define LOGF_ENABLE*/
#include "logf.h"
#include "system.h"
#include "usb_ch9.h"
#include "usb_drv.h"
#include "usb_core.h"
#include "cpu.h"
#include "thread.h"
#define PIN_USB_DET (32*4+19)
#define IRQ_USB_DET GPIO_IRQ(PIN_USB_DET)
#define GPIO_USB_DET GPIO147
#define PIN_USB_DRVVBUS (32*4+10)
#define PIN_USB_OTG_ID (32*3+7)
#define EP_BUF_LEFT(ep) ((ep)->length - (ep)->sent)
#define EP_PTR(ep) ((void*)((unsigned int)(ep)->buf + (ep)->sent))
#define EP_NUMBER(ep) (((int)(ep) - (int)&endpoints[0])/sizeof(struct usb_endpoint))
#define EP_NUMBER2(ep) (EP_NUMBER((ep))/2)
#define TOTAL_EP() (sizeof(endpoints)/sizeof(struct usb_endpoint))
#define EP_IS_IN(ep) (EP_NUMBER((ep))%2)
enum ep_type
{
ep_control,
ep_bulk,
ep_interrupt,
ep_isochronous
};
struct usb_endpoint
{
void *buf;
size_t length;
union
{
size_t sent;
size_t received;
};
bool busy;
const enum ep_type type;
const bool use_dma;
const long fifo_addr;
unsigned short fifo_size;
bool wait;
struct semaphore complete;
};
#define EP_INIT(_type, _fifo_addr, _fifo_size, _buf, _use_dma) \
{ .type = (_type), .fifo_addr = (_fifo_addr), .fifo_size = (_fifo_size), \
.buf = (_buf), .use_dma = (_use_dma), .length = 0, .busy = false, .wait = false }
static unsigned char ep0_rx_buf[64];
static struct usb_endpoint endpoints[] =
{
EP_INIT(ep_control, USB_FIFO_EP(0), 64, NULL, false),
EP_INIT(ep_control, USB_FIFO_EP(0), 64, &ep0_rx_buf, false),
EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL, false),
EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL, false),
EP_INIT(ep_interrupt, USB_FIFO_EP(2), 64, NULL, false),
EP_INIT(ep_interrupt, USB_FIFO_EP(2), 64, NULL, false),
};
static inline void select_endpoint(int ep)
{
REG_USB_INDEX = ep;
}
static void readFIFO(struct usb_endpoint *ep, unsigned int size)
{
logf("%s(EP%d, %d)", __func__, EP_NUMBER2(ep), size);
register unsigned char *ptr = (unsigned char*)EP_PTR(ep);
register unsigned int *ptr32 = (unsigned int*)ptr;
register unsigned int s = size >> 2;
register unsigned int x;
if(size > 0)
{
if( ((unsigned int)ptr & 3) == 0 )
{
while(s--)
*ptr32++ = REG32(ep->fifo_addr);
ptr = (unsigned char*)ptr32;
}
else
{
while(s--)
{
x = REG32(ep->fifo_addr);
*ptr++ = x & 0xFF; x >>= 8;
*ptr++ = x & 0xFF; x >>= 8;
*ptr++ = x & 0xFF; x >>= 8;
*ptr++ = x;
}
}
s = size & 3;
while(s--)
*ptr++ = REG8(ep->fifo_addr);
}
}
static void writeFIFO(struct usb_endpoint *ep, size_t size)
{
logf("%s(EP%d, %d)", __func__, EP_NUMBER2(ep), size);
register unsigned int *d32 = (unsigned int *)EP_PTR(ep);
register size_t s = size >> 2;
if(size > 0)
{
while (s--)
REG32(ep->fifo_addr) = *d32++;
if( (s = size & 3) )
{
register unsigned char *d8 = (unsigned char *)d32;
while (s--)
REG8(ep->fifo_addr) = *d8++;
}
}
}
static void flushFIFO(struct usb_endpoint *ep)
{
logf("%s(%d)", __func__, EP_NUMBER(ep));
switch (ep->type)
{
case ep_control:
break;
case ep_bulk:
case ep_interrupt:
case ep_isochronous:
if(EP_IS_IN(ep))
REG_USB_INCSR |= (USB_INCSR_FF | USB_INCSR_CDT);
else
REG_USB_OUTCSR |= (USB_OUTCSR_FF | USB_OUTCSR_CDT);
break;
}
}
static inline void ep_transfer_completed(struct usb_endpoint* ep)
{
ep->sent = 0;
ep->length = 0;
ep->buf = NULL;
ep->busy = false;
if(ep->wait)
semaphore_release(&ep->complete);
}
static void EP0_send(void)
{
struct usb_endpoint* ep = &endpoints[0];
unsigned int length;
unsigned char csr0;
select_endpoint(0);
csr0 = REG_USB_CSR0;
if(ep->sent == 0)
length = MIN(ep->length, ep->fifo_size);
else
length = MIN(EP_BUF_LEFT(ep), ep->fifo_size);
writeFIFO(ep, length);
ep->sent += length;
if(ep->sent >= ep->length)
{
REG_USB_CSR0 = (csr0 | USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */
usb_core_transfer_complete(0, USB_DIR_IN, 0, ep->sent);
ep_transfer_completed(ep);
}
else
REG_USB_CSR0 = (csr0 | USB_CSR0_INPKTRDY);
}
static void EP0_handler(void)
{
logf("%s()", __func__);
unsigned char csr0;
struct usb_endpoint *ep_send = &endpoints[0];
struct usb_endpoint *ep_recv = &endpoints[1];
/* Read CSR0 */
select_endpoint(0);
csr0 = REG_USB_CSR0;
/* Check for SentStall:
This bit is set when a STALL handshake is transmitted. The CPU should clear this bit.
*/
if(csr0 & USB_CSR0_SENTSTALL)
{
REG_USB_CSR0 = csr0 & ~USB_CSR0_SENTSTALL;
return;
}
/* Check for SetupEnd:
This bit will be set when a control transaction ends before the DataEnd bit has been set.
An interrupt will be generated and the FIFO flushed at this time.
The bit is cleared by the CPU writing a 1 to the ServicedSetupEnd bit.
*/
if(csr0 & USB_CSR0_SETUPEND)
{
REG_USB_CSR0 = csr0 | USB_CSR0_SVDSETUPEND;
return;
}
/* Call relevant routines for endpoint 0 state */
if(ep_send->busy)
EP0_send();
else if(csr0 & USB_CSR0_OUTPKTRDY) /* There is a packet in the fifo */
{
readFIFO(ep_recv, REG_USB_COUNT0);
REG_USB_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */
usb_core_control_request((struct usb_ctrlrequest*)ep_recv->buf);
}
}
static void EPIN_handler(unsigned int endpoint)
{
struct usb_endpoint* ep = &endpoints[endpoint*2];
unsigned int length, csr;
select_endpoint(endpoint);
csr = REG_USB_INCSR;
logf("%s(%d): 0x%x", __func__, endpoint, csr);
if(!ep->busy)
{
logf("Entered EPIN handler without work!");
return;
}
if(csr & USB_INCSR_SENTSTALL)
{
REG_USB_INCSR = csr & ~USB_INCSR_SENTSTALL;
return;
}
if(ep->use_dma)
return;
if(csr & USB_INCSR_FFNOTEMPT)
{
logf("FIFO is not empty! 0x%x", csr);
return;
}
logf("EP%d: %d -> %d", endpoint, ep->sent, ep->length);
if(ep->sent == 0)
length = MIN(ep->length, ep->fifo_size);
else
length = MIN(EP_BUF_LEFT(ep), ep->fifo_size);
writeFIFO(ep, length);
REG_USB_INCSR = csr | USB_INCSR_INPKTRDY;
ep->sent += length;
if(ep->sent >= ep->length)
{
usb_core_transfer_complete(endpoint, USB_DIR_IN, 0, ep->sent);
ep_transfer_completed(ep);
logf("sent complete");
}
}
static void EPOUT_handler(unsigned int endpoint)
{
struct usb_endpoint* ep = &endpoints[endpoint*2+1];
unsigned int size, csr;
if(!ep->busy)
{
logf("Entered EPOUT handler without work!");
return;
}
select_endpoint(endpoint);
while((csr = REG_USB_OUTCSR) & (USB_OUTCSR_SENTSTALL|USB_OUTCSR_OUTPKTRDY))
{
logf("%s(%d): 0x%x", __func__, endpoint, csr);
if(csr & USB_OUTCSR_SENTSTALL)
{
logf("stall sent, flushing fifo..");
flushFIFO(ep);
REG_USB_OUTCSR = csr & ~USB_OUTCSR_SENTSTALL;
return;
}
if(ep->use_dma)
return;
if(csr & USB_OUTCSR_OUTPKTRDY) /* There is a packet in the fifo */
{
size = REG_USB_OUTCOUNT;
readFIFO(ep, size);
ep->received += size;
/*if(csr & USB_OUTCSR_FFFULL)
csr &= ~USB_OUTCSR_FFFULL;*/
REG_USB_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY;
logf("received: %d max length: %d", ep->received, ep->length);
if(size < ep->fifo_size || ep->received >= ep->length)
{
usb_core_transfer_complete(endpoint, USB_DIR_OUT, 0, ep->received);
ep_transfer_completed(ep);
logf("receive transfer_complete");
}
}
}
}
static void EPDMA_handler(int number)
{
int endpoint = -1;
unsigned int size = 0;
if(number == USB_INTR_DMA_BULKIN)
endpoint = (REG_USB_CNTL(0) >> 4) & 0xF;
else if(number == USB_INTR_DMA_BULKOUT)
endpoint = (REG_USB_CNTL(1) >> 4) & 0xF;
struct usb_endpoint* ep = &endpoints[endpoint];
logf("DMA_BULK%d %d", number, endpoint);
if(number == USB_INTR_DMA_BULKIN)
size = (unsigned int)ep->buf - REG_USB_ADDR(0);
else if(number == USB_INTR_DMA_BULKOUT)
size = (unsigned int)ep->buf - REG_USB_ADDR(1);
if(number == USB_INTR_DMA_BULKOUT)
{
/* Disable DMA */
REG_USB_CNTL(1) = 0;
__dcache_invalidate_all();
select_endpoint(endpoint);
/* Read out last packet manually */
unsigned int lpack_size = REG_USB_OUTCOUNT;
if(lpack_size > 0)
{
ep->buf += ep->length - lpack_size;
readFIFO(ep, lpack_size);
REG_USB_OUTCSR &= ~USB_OUTCSR_OUTPKTRDY;
}
}
else if(number == USB_INTR_DMA_BULKIN && size % ep->fifo_size)
{
/* If the last packet is less than MAXP, set INPKTRDY manually */
REG_USB_INCSR |= USB_INCSR_INPKTRDY;
}
usb_core_transfer_complete(endpoint, EP_IS_IN(ep) ? USB_DIR_IN : USB_DIR_OUT,
0, ep->length);
ep_transfer_completed(ep);
}
static void setup_endpoint(struct usb_endpoint *ep)
{
int csr, csrh;
select_endpoint(EP_NUMBER2(ep));
ep->busy = false;
ep->wait = false;
ep->sent = 0;
ep->length = 0;
if(ep->type == ep_bulk)
{
if(REG_USB_POWER & USB_POWER_HSMODE)
ep->fifo_size = 512;
else
ep->fifo_size = 64;
}
if(EP_IS_IN(ep))
{
csr = (USB_INCSR_FF | USB_INCSR_CDT);
csrh = USB_INCSRH_MODE;
if(ep->use_dma)
csrh |= (USB_INCSRH_DMAREQENAB | USB_INCSRH_AUTOSET | USB_INCSRH_DMAREQMODE);
if(ep->type == ep_interrupt)
csrh |= USB_INCSRH_FRCDATATOG;
REG_USB_INMAXP = ep->fifo_size;
REG_USB_INCSR = csr;
REG_USB_INCSRH = csrh;
REG_USB_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep));
}
else
{
csr = (USB_OUTCSR_FF | USB_OUTCSR_CDT);
csrh = 0;
if(ep->type == ep_interrupt)
csrh |= USB_OUTCSRH_DNYT;
if(ep->use_dma)
csrh |= (USB_OUTCSRH_DMAREQENAB | USB_OUTCSRH_AUTOCLR | USB_OUTCSRH_DMAREQMODE);
REG_USB_OUTMAXP = ep->fifo_size;
REG_USB_OUTCSR = csr;
REG_USB_OUTCSRH = csrh;
REG_USB_INTROUTE |= USB_INTR_EP(EP_NUMBER2(ep));
}
}
static void udc_reset(void)
{
/* From the datasheet:
When a reset condition is detected on the USB, the controller performs the following actions:
* Sets FAddr to 0.
* Sets Index to 0.
* Flushes all endpoint FIFOs.
* Clears all control/status registers.
* Enables all endpoint interrupts.
* Generates a Reset interrupt.
*/
logf("%s()", __func__);
unsigned int i;
REG_USB_FADDR = 0;
REG_USB_INDEX = 0;
/* Disable interrupts */
REG_USB_INTRINE = 0;
REG_USB_INTROUTE = 0;
REG_USB_INTRUSBE = 0;
/* Disable DMA */
REG_USB_CNTL(0) = 0;
REG_USB_CNTL(1) = 0;
/* High speed, softconnect */
REG_USB_POWER = (USB_POWER_SOFTCONN | USB_POWER_HSENAB);
/* Reset EP0 */
select_endpoint(0);
REG_USB_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND | USB_CSR0_FLUSHFIFO);
/* Reset other endpoints */
for(i=2; i<TOTAL_EP(); i++)
setup_endpoint(&endpoints[i]);
/* Enable interrupts */
REG_USB_INTRINE |= USB_INTR_EP(0);
REG_USB_INTRUSBE |= USB_INTR_RESET;
usb_core_bus_reset();
}
/* Interrupt handler */
void OTG(void)
{
/* Read interrupt registers */
unsigned char intrUSB = REG_USB_INTRUSB & 0x07; /* Mask SOF */
unsigned short intrIn = REG_USB_INTRIN;
unsigned short intrOut = REG_USB_INTROUT;
unsigned char intrDMA = REG_USB_INTR;
logf("%x %x %x %x", intrUSB, intrIn, intrOut, intrDMA);
/* EPIN & EPOUT are all handled in DMA */
if(intrIn & USB_INTR_EP(0))
EP0_handler();
if(intrIn & USB_INTR_EP(1))
EPIN_handler(1);
if(intrIn & USB_INTR_EP(2))
EPIN_handler(2);
if(intrOut & USB_INTR_EP(1))
EPOUT_handler(1);
if(intrOut & USB_INTR_EP(2))
EPOUT_handler(2);
if(intrUSB & USB_INTR_RESET)
udc_reset();
if(intrUSB & USB_INTR_SUSPEND)
logf("USB suspend");
if(intrUSB & USB_INTR_RESUME)
logf("USB resume");
if(intrDMA & USB_INTR_DMA_BULKIN)
EPDMA_handler(USB_INTR_DMA_BULKIN);
if(intrDMA & USB_INTR_DMA_BULKOUT)
EPDMA_handler(USB_INTR_DMA_BULKOUT);
}
bool usb_drv_stalled(int endpoint, bool in)
{
endpoint &= 0x7F;
logf("%s(%d, %s)", __func__, endpoint, in?"IN":"OUT");
select_endpoint(endpoint);
if(endpoint == EP_CONTROL)
return (REG_USB_CSR0 & USB_CSR0_SENDSTALL) != 0;
else
{
if(in)
return (REG_USB_INCSR & USB_INCSR_SENDSTALL) != 0;
else
return (REG_USB_OUTCSR & USB_OUTCSR_SENDSTALL) != 0;
}
}
void usb_drv_stall(int endpoint, bool stall, bool in)
{
endpoint &= 0x7F;
logf("%s(%d,%s,%s)", __func__, endpoint, stall?"Y":"N", in?"IN":"OUT");
select_endpoint(endpoint);
if(endpoint == EP_CONTROL)
{
if(stall)
REG_USB_CSR0 |= USB_CSR0_SENDSTALL;
else
REG_USB_CSR0 &= ~USB_CSR0_SENDSTALL;
}
else
{
if(in)
{
if(stall)
REG_USB_INCSR |= USB_INCSR_SENDSTALL;
else
REG_USB_INCSR = (REG_USB_INCSR & ~USB_INCSR_SENDSTALL) | USB_INCSR_CDT;
}
else
{
if(stall)
REG_USB_OUTCSR |= USB_OUTCSR_SENDSTALL;
else
REG_USB_OUTCSR = (REG_USB_OUTCSR & ~USB_OUTCSR_SENDSTALL) | USB_OUTCSR_CDT;
}
}
}
int usb_detect(void)
{
return (__gpio_get_pin(PIN_USB_DET) == 1)
? USB_INSERTED : USB_EXTRACTED;
}
void usb_init_device(void)
{
__gpio_clear_pin(PIN_USB_DRVVBUS);
__gpio_as_output(PIN_USB_DRVVBUS);
__gpio_as_input(PIN_USB_OTG_ID);
__gpio_as_input(PIN_USB_DET);
__gpio_disable_pull(PIN_USB_OTG_ID);
__gpio_disable_pull(PIN_USB_DET);
#ifdef USB_STATUS_BY_EVENT
__gpio_as_irq_rise_edge(PIN_USB_DET);
system_enable_irq(IRQ_USB_DET);
#endif
system_enable_irq(IRQ_OTG);
for(unsigned i=0; i<TOTAL_EP(); i++)
semaphore_init(&endpoints[i].complete, 1, 0);
}
#ifdef USB_STATUS_BY_EVENT
static int usb_oneshot_callback(struct timeout *tmo)
{
(void)tmo;
int state = usb_detect();
/* This is called only if the state was stable for HZ/16 - check state
* and post appropriate event. */
usb_status_event(state);
if(state == USB_EXTRACTED)
__gpio_as_irq_rise_edge(PIN_USB_DET);
else
__gpio_as_irq_fall_edge(PIN_USB_DET);
return 0;
}
void GPIO_USB_DET(void)
{
static struct timeout usb_oneshot;
timeout_register(&usb_oneshot, usb_oneshot_callback, (HZ/16), 0);
}
#endif
void usb_enable(bool on)
{
if(on)
usb_core_init();
else
usb_core_exit();
}
void usb_attach(void)
{
usb_enable(true);
}
void usb_drv_init(void)
{
logf("%s()", __func__);
/* Dis- and reconnect from USB */
REG_USB_POWER &= ~USB_POWER_SOFTCONN;
mdelay(20);
REG_USB_POWER |= USB_POWER_SOFTCONN;
mdelay(20);
udc_reset();
}
void usb_drv_exit(void)
{
logf("%s()", __func__);
REG_USB_FADDR = 0;
REG_USB_INDEX = 0;
/* Disable interrupts */
REG_USB_INTRINE = 0;
REG_USB_INTROUTE = 0;
REG_USB_INTRUSBE = 0;
/* Disable DMA */
REG_USB_CNTL(0) = 0;
REG_USB_CNTL(1) = 0;
/* Disconnect from USB */
REG_USB_POWER &= ~USB_POWER_SOFTCONN;
}
void usb_drv_set_address(int address)
{
logf("%s(%d)", __func__, address);
REG_USB_FADDR = address;
}
static void usb_drv_send_internal(struct usb_endpoint* ep, void* ptr, int length, bool blocking)
{
if(ep->type == ep_control && ptr == NULL && length == 0)
return; /* ACK request, handled in the ISR */
int flags = disable_irq_save();
ep->buf = ptr;
ep->sent = 0;
ep->length = length;
ep->busy = true;
if(blocking)
ep->wait = true;
if(ep->type == ep_control)
{
EP0_send();
}
else
{
if(ep->use_dma)
{
//dma_cache_wback_inv((unsigned long)ptr, length);
__dcache_writeback_all();
REG_USB_ADDR(0) = PHYSADDR((unsigned long)ptr);
REG_USB_COUNT(0) = length;
REG_USB_CNTL(0) = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 |
USB_CNTL_DIR_IN | USB_CNTL_ENA |
USB_CNTL_EP(EP_NUMBER2(ep)) | USB_CNTL_BURST_16);
}
else
EPIN_handler(EP_NUMBER2(ep));
}
restore_irq(flags);
if(blocking)
{
semaphore_wait(&ep->complete, TIMEOUT_BLOCK);
ep->wait = false;
}
}
int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
{
logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length);
usb_drv_send_internal(&endpoints[(endpoint & 0x7F)*2], ptr, length, false);
return 0;
}
int usb_drv_send(int endpoint, void* ptr, int length)
{
logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length);
usb_drv_send_internal(&endpoints[(endpoint & 0x7F)*2], ptr, length, true);
return 0;
}
int usb_drv_recv(int endpoint, void* ptr, int length)
{
int flags;
struct usb_endpoint *ep;
endpoint &= 0x7F;
logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length);
if(endpoint == EP_CONTROL)
return 0; /* all EP0 OUT transactions are handled within the ISR */
else
{
flags = disable_irq_save();
ep = &endpoints[endpoint*2+1];
ep->buf = ptr;
ep->received = 0;
ep->length = length;
ep->busy = true;
if(ep->use_dma)
{
//dma_cache_wback_inv((unsigned long)ptr, length);
__dcache_writeback_all();
REG_USB_ADDR(1) = PHYSADDR((unsigned long)ptr);
REG_USB_COUNT(1) = length;
REG_USB_CNTL(1) = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 |
USB_CNTL_ENA | USB_CNTL_EP(endpoint) |
USB_CNTL_BURST_16);
}
else
EPOUT_handler(endpoint);
restore_irq(flags);
return 0;
}
}
void usb_drv_set_test_mode(int mode)
{
logf("%s(%d)", __func__, mode);
switch(mode)
{
case 0:
REG_USB_TESTMODE &= ~USB_TEST_ALL;
break;
case 1:
REG_USB_TESTMODE |= USB_TEST_J;
break;
case 2:
REG_USB_TESTMODE |= USB_TEST_K;
break;
case 3:
REG_USB_TESTMODE |= USB_TEST_SE0NAK;
break;
case 4:
REG_USB_TESTMODE |= USB_TEST_PACKET;
break;
}
}
int usb_drv_port_speed(void)
{
return (REG_USB_POWER & USB_POWER_HSMODE) ? 1 : 0;
}
void usb_drv_cancel_all_transfers(void)
{
logf("%s()", __func__);
unsigned int i, flags;
flags = disable_irq_save();
for(i=0; i<TOTAL_EP(); i++)
{
if(i != 1) /* ep0 out needs special handling */
endpoints[i].buf = NULL;
endpoints[i].sent = 0;
endpoints[i].length = 0;
select_endpoint(i/2);
flushFIFO(&endpoints[i]);
}
restore_irq(flags);
}
void usb_drv_release_endpoint(int ep)
{
(void)ep;
logf("%s(%d, %s)", __func__, (ep & 0x7F), (ep >> 7) ? "IN" : "OUT");
}
int usb_drv_request_endpoint(int type, int dir)
{
logf("%s(%d, %s)", __func__, type, (dir == USB_DIR_IN) ? "IN" : "OUT");
dir &= USB_ENDPOINT_DIR_MASK;
type &= USB_ENDPOINT_XFERTYPE_MASK;
/* There are only 3+2 endpoints, so hardcode this ... */
switch(type)
{
case USB_ENDPOINT_XFER_BULK:
if(dir == USB_DIR_IN)
return (1 | USB_DIR_IN);
else
return (1 | USB_DIR_OUT);
case USB_ENDPOINT_XFER_INT:
if(dir == USB_DIR_IN)
return (2 | USB_DIR_IN);
else
return (2 | USB_DIR_OUT);
default:
return -1;
}
}

View File

@ -0,0 +1,31 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 __XDEBUG_H_
#define __XDEBUG_H_
void serial_puts(const char *s);
void serial_putsf(const char *format, ...);
void serial_put_hex(unsigned int d);
void serial_put_dec(unsigned int d);
void serial_dump_data(unsigned char* data, int len);
#endif /* __XDEBUG_H_ */

View File

@ -0,0 +1,28 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 _ADC_TARGET_H_
#define _ADC_TARGET_H_
#define NUM_ADC_CHANNELS 4
#define ADC_BUTTONS 0
#endif /* _ADC_TARGET_H_ */

View File

@ -0,0 +1,48 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 ATA_SD_TARGET_H
#define ATA_SD_TARGET_H
#include "cpu.h"
#include "system.h"
#define PIN_SD1_CD (32*0+29) /* Pin to check card insertion */
#define IRQ_SD1_CD GPIO_IRQ(PIN_SD1_CD)
#define GPIO_SD1_CD GPIO29
#define PIN_SD2_CD (32*0+28) /* Pin to check card insertion */
#define IRQ_SD2_CD GPIO_IRQ(PIN_SD2_CD)
#define GPIO_SD2_CD GPIO28
static inline void sd_init_gpio(void)
{
__gpio_as_msc1_pd_4bit();
__gpio_as_msc2_pb_4bit();
__gpio_as_input(PIN_SD1_CD);
__gpio_as_input(PIN_SD2_CD);
__gpio_disable_pull(PIN_SD1_CD);
__gpio_disable_pull(PIN_SD2_CD);
}
#endif

View File

@ -0,0 +1,50 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 "config.h"
#include "cpu.h"
#include "backlight-target.h"
#include "lcd.h"
bool backlight_hw_init(void)
{
return true;
}
void backlight_hw_on(void)
{
lcd_enable(true);
}
void backlight_hw_off(void)
{
lcd_enable(false);
}
void backlight_hw_brightness(int brightness)
{
lcd_set_contrast(brightness*16-1);
}
void lcd_sleep(void)
{
backlight_hw_off();
}

View File

@ -0,0 +1,46 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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
#define HAS_BUTTON_HOLD
/* Main unit's buttons */
#define BUTTON_POWER 0x00000001
#define BUTTON_HOME 0x00000002
#define BUTTON_OPTION 0x00000004
#define BUTTON_PREV 0x00000008
#define BUTTON_NEXT 0x00000010
#define BUTTON_PLAY 0x00000020
#define BUTTON_VOL_UP 0x00000040
#define BUTTON_VOL_DOWN 0x00000080
#define BUTTON_LEFT 0
#define BUTTON_RIGHT 0
#define BUTTON_MAIN (BUTTON_POWER | BUTTON_HOME | BUTTON_OPTION | BUTTON_PREV | \
BUTTON_NEXT | BUTTON_PLAY | BUTTON_VOL_UP | BUTTON_VOL_DOWN)
/* Software power-off */
#define POWEROFF_BUTTON BUTTON_POWER
#define POWEROFF_COUNT 10
#endif /* BUTTON_TARGET_H */

Some files were not shown because too many files have changed in this diff Show More