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
#elif CONFIG_KEYPAD == AGPTEK_ROCKER_PAD
keymaps/keymap-agptekrocker.c
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
keymaps/keymap-xduoox3.c
#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);
#endif
#ifdef AUDIOHW_HAVE_FUNCTIONAL_MODE
MENUITEM_SETTING(func_mode, &global_settings.func_mode, NULL);
#endif
#if CONFIG_CODEC == SWCODEC
/* Crossfeed Submenu */
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
,&roll_off
#endif
#ifdef AUDIOHW_HAVE_FUNCTIONAL_MODE
,&func_mode
#endif
#if CONFIG_CODEC == SWCODEC
,&crossfeed_menu, &equalizer_menu, &dithering_enabled
,&surround_menu, &pbe_menu, &afr_enabled

View file

@ -279,6 +279,12 @@
#define BATTERY_OFF_TXT "Right"
#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
#error No keymap defined!
#endif

View file

@ -573,6 +573,22 @@ enum {
#define BJACK_QUIT_NAME "Volume up"
#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
#error No keymap defined!
#endif

View file

@ -332,6 +332,16 @@ CONFIG_KEYPAD == SANSA_CONNECT_PAD
#define UP BUTTON_UP
#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
#error No keymap defined!
#endif

View file

@ -525,6 +525,17 @@ F3: equal to "="
#define CALCULATOR_CALC BUTTON_VOLUP
#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
#error No keymap defined!
#endif

View file

@ -413,6 +413,16 @@
#define CALENDAR_NEXT_MONTH (BUTTON_VOLDOWN)
#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
#error "No keypad setting."
#endif

View file

@ -558,6 +558,20 @@
#define CB_SCROLL_LEFT (BUTTON_LEFT|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
#error No keymap defined!
#endif

View file

@ -412,6 +412,16 @@
#define CHC_SETTINGS_CANCEL BUTTON_RIGHT
#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
#error No keymap defined!
#endif

View file

@ -1283,6 +1283,14 @@ CONFIG_KEYPAD == MROBE500_PAD
#define CHIP8_KEY6 BUTTON_RIGHT
#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
#error No keymap defined!
#endif

View file

@ -209,6 +209,10 @@ CONFIG_KEYPAD == MROBE500_PAD
#define ACTION BUTTON_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)
#error No keymap defined!

View file

@ -276,6 +276,14 @@
#define CLIX_BUTTON_RIGHT BUTTON_RIGHT
#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
#error "no keymap"
#endif

View file

@ -413,6 +413,16 @@
#define CUBE_HIGHSPEED (BUTTON_SELECT | 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
#error No keymap defined!
#endif

View file

@ -555,6 +555,17 @@ void I_ShutdownGraphics(void)
#define DOOMBUTTON_WEAPON BUTTON_VOLUP
#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
#error Keymap not defined!
#endif

View file

@ -334,6 +334,15 @@ GREY_INFO_STRUCT
# define FFT_ORIENTATION BUTTON_SELECT
# 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)
#error No keymap defined!
#endif

View file

@ -482,6 +482,18 @@
#define FLIPIT_STEP_BY_STEP (BUTTON_LEFT|BUTTON_VOLUP)
#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
#error No keymap defined!
#endif

View file

@ -484,6 +484,18 @@
#define FRACTAL_PRECISION_DEC (BUTTON_VOLUP|BUTTON_LEFT)
#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
#error No keymap defined!
#endif

View file

@ -452,6 +452,18 @@
#define GBN_BUTTON_PLAY (BUTTON_SELECT | BUTTON_REL)
#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
#error Unsupported keypad
#endif

View file

@ -108,6 +108,14 @@
#define GREYSCALE_RIGHT BUTTON_RIGHT
#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
#define GFX_HEIGHT (LCD_HEIGHT-8)

View file

@ -495,6 +495,21 @@
#define IMGVIEW_QUIT (BUTTON_POWER|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
#error No keymap defined!
#endif

View file

@ -377,6 +377,16 @@ CONFIG_KEYPAD == MROBE500_PAD
#define JEWELS_CANCEL BUTTON_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
#error No keymap defined!
#endif

View file

@ -215,6 +215,14 @@
#define BTN_FIRE BUTTON_MENU
#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
#error Unsupported keypad
#endif

View file

@ -228,6 +228,15 @@ const struct button_mapping pla_main_ctx[] =
{ PLA_DOWN_REPEAT, BUTTON_FF|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},
#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
# ifndef HAVE_TOUCHSCREEN
# 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_REL, BUTTON_PLAY|BUTTON_REL, 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
# ifndef HAVE_TOUCHSCREEN

View file

@ -293,6 +293,14 @@
#define MIDI_VOL_DOWN BUTTON_VOLDOWN
#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
#error No keymap defined!
#endif

View file

@ -404,6 +404,19 @@ CONFIG_KEYPAD == MROBE500_PAD
#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD
# 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
#error No keymap defined!
#endif

View file

@ -2556,6 +2556,12 @@ CONFIG_KEYPAD == MROBE500_PAD
#define MP3ENC_DONE BUTTON_POWER
#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
#error No keymap defined!
#endif

View file

@ -306,6 +306,16 @@ struct mpeg_settings settings;
#define MPEG_START_TIME_DOWN BUTTON_DOWN
#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
#error No keymap defined!
#endif

View file

@ -441,6 +441,15 @@ CONFIG_KEYPAD == SANSA_M200_PAD
#define MPEG_RW BUTTON_LEFT
#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
#error No keymap defined!
#endif

View file

@ -504,6 +504,20 @@
#define OSCILLOSCOPE_VOL_UP BUTTON_VOLUP
#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
#error No keymap defined!
#endif

View file

@ -643,6 +643,23 @@ CONFIG_KEYPAD == MROBE500_PAD
#define QUIT_TEXT "POWER"
#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
#error Unsupported keymap!
#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 == MROBE100_PAD || CONFIG_KEYPAD == MROBE500_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},
#if CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
{PF_MENU, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT},

View file

@ -163,8 +163,14 @@ OUTPUT_FORMAT(elf32-littlemips)
#define IRAMORIG (0x00000000 + (56*1024))
#define IRAMSIZE (200*1024)
#elif CONFIG_CPU == JZ4732
#define DRAMORIG 0x80004000 + STUBOFFSET
#elif CONFIG_CPU == JZ4732 || CONFIG_CPU == JZ4760B
#undef STUBOFFSET
#ifdef DEBUG
#define STUBOFFSET 0x14000
#else
#define STUBOFFSET 0x4000
#endif
#define DRAMORIG 0x80000000 + STUBOFFSET
#define IRAM DRAM
#define IRAMSIZE 0
/* 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_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
#error No keymap defined!
#endif

View file

@ -328,6 +328,17 @@
#define REVERSI_BUTTON_MAKE_MOVE BUTTON_SELECT
#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
#error No keymap defined!
#endif

View file

@ -480,6 +480,18 @@
#define ROCKBLOX_ROTATE_CCW BUTTON_VOLDOWN
#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
#error No keymap defined!
#endif

View file

@ -423,6 +423,16 @@ static void setoptions (void)
options.A = BUTTON_VOLDOWN;
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
#error No Keymap Defined!
#endif

View file

@ -327,6 +327,17 @@
#define ROCKPAINT_QUIT BUTTON_POWER
#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
#error "Please define keys for this keypad"
#endif

View file

@ -331,6 +331,15 @@ CONFIG_KEYPAD == MROBE500_PAD
#define PUZZLE_SHUFFLE BUTTON_POWER
#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
#error No keymap defined!
#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_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
#error No keymap defined!
#endif

View file

@ -419,6 +419,15 @@ CONFIG_KEYPAD == MROBE500_PAD
#define SNAKE2_PLAYPAUSE BUTTON_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
#error No keymap defined!
#endif

View file

@ -651,6 +651,22 @@
#define SOKOBAN_MENU BUTTON_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
#error No keymap defined!
#endif

View file

@ -687,6 +687,25 @@ CONFIG_KEYPAD == MROBE500_PAD
#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD
# 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
#error No keymap defined!
#endif

View file

@ -354,6 +354,15 @@
#define AST_RIGHT BUTTON_RIGHT
#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
#error No keymap defined!
#endif

View file

@ -623,6 +623,22 @@
#define STAR_TOGGLE_CONTROL_NAME "Play"
#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
#error No keymap defined!
#endif

View file

@ -313,6 +313,14 @@
#define STOPWATCH_SCROLL_UP BUTTON_UP
#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
#error No keymap defined!
#endif

View file

@ -423,6 +423,20 @@
#define SUDOKU_BUTTON_TOGGLE BUTTON_SELECT
#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
#error No keymap defined!
#endif

View file

@ -550,6 +550,18 @@
#define TV_AUTOSCROLL BUTTON_VOLDOWN
#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
#error No keymap defined!
#endif

View file

@ -421,6 +421,17 @@
#define LABEL_VOLUME "Vol Up/Down"
#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
#error No keymap defined!
#endif

View file

@ -393,6 +393,15 @@ CONFIG_KEYPAD == MROBE500_PAD
#define BTN_QUIT BUTTON_POWER
#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
#error No keymap defined!
#endif

View file

@ -342,6 +342,15 @@ CONFIG_KEYPAD == MROBE500_PAD
#define DOWN BUTTON_DOWN
#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
#error No keymap defined!
#endif

View file

@ -282,6 +282,14 @@
#define ZX_RIGHT BUTTON_RIGHT
#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
#error Keymap not defined!

View file

@ -278,6 +278,15 @@
#define KBD_UP BUTTON_UP
#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
#ifdef HAVE_TOUCHSCREEN

View file

@ -811,6 +811,10 @@ struct user_settings
int roll_off;
#endif
#ifdef AUDIOHW_HAVE_FUNCTIONAL_MODE
int func_mode;
#endif
#ifdef AUDIOHW_HAVE_EQ
/** Hardware EQ tone controls **/
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)
ondavx747.c
show_logo.c
#elif defined(XDUOO_X3)
xduoox3.c
show_logo.c
#elif defined(CREATIVE_ZVx)
creativezvm.c
#elif CONFIG_CPU==AS3525 || CONFIG_CPU==AS3525v2

View file

@ -54,7 +54,7 @@
|| defined(SAMSUNG_YH820) || defined(PHILIPS_SA9200) \
|| defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) \
|| defined(ONDA_VX747) || defined(PBELL_VIBE500) \
|| defined(TOSHIBA_GIGABEAT_S)
|| defined(TOSHIBA_GIGABEAT_S) || defined(XDUOO_X3)
bool verbose = false;
#else
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
Jonatan Nyberg
Alessandro Stoppani
Alexander Yurenin
Roman Stolyarov
Solomon Peachy
The libmad team
The wavpack team

View file

@ -366,8 +366,10 @@ drivers/rtc/rtc_mr100.c
drivers/rtc/rtc_mc13783.c
#elif (CONFIG_RTC == RTC_TCC77X)
drivers/rtc/rtc_tcc77x.c
#elif (CONFIG_RTC == RTC_JZ47XX)
#elif (CONFIG_RTC == RTC_JZ4740)
drivers/rtc/rtc_jz4740.c
#elif (CONFIG_RTC == RTC_JZ4760)
drivers/rtc/rtc_jz4760.c
#elif (CONFIG_RTC == RTC_S35390A)
drivers/rtc/rtc_s35390a.c
#elif (CONFIG_RTC == RTC_S35380A)
@ -477,6 +479,8 @@ drivers/audio/dummy_codec.c
drivers/audio/df1704.c
#elif defined (HAVE_PCM1792_CODEC)
drivers/audio/pcm1792.c
#elif defined (HAVE_CS4398)
drivers/audio/cs4398.c
#endif /* defined(HAVE_*) */
#else /* PLATFORM_HOSTED */
#if defined(SAMSUNG_YPR0) && defined(HAVE_AS3514)
@ -739,9 +743,9 @@ target/arm/crt0.S
#elif defined(CPU_MIPS) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
target/mips/mmu-mips.c
#if CONFIG_CPU==JZ4732
#if CONFIG_CPU==JZ4732 || CONFIG_CPU==JZ4760B
target/mips/ingenic_jz47xx/crt0.S
#endif /* CONFIG_CPU == JZ4732 */
#endif /* CONFIG_CPU == JZ4732 || JZ4760B */
#else
@ -1725,6 +1729,24 @@ target/mips/ingenic_jz47xx/pcm-jz4740.c
drivers/nand_id.c
#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)
target/mips/ingenic_jz47xx/onda_vx747/backlight-onda_vx7X7.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
#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)
target/arm/at91sam/lyre_proto1/adc-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)vol_l; (void)vol_r; }
#endif
#if defined(AUDIOHW_HAVE_FILTER_ROLL_OFF)
void audiohw_set_filter_roll_off(int value)
{ (void)value; }
#endif
void audiohw_close(void) {}

View file

@ -51,10 +51,21 @@ static const struct nand_info samsung[] =
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))}
static const struct nand_manufacturer all[] =
{
NI(0xEC, samsung),
NI(0x98, gigadevice),
};
// -----------------------------------------------------------------------------

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

View file

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

View file

@ -82,6 +82,7 @@
#define S5L8701 8701
#define S5L8702 8702
#define JZ4732 4732
#define JZ4760B 47602
#define AS3525 3525
#define AT91SAM9260 9260
#define AS3525v2 35252
@ -167,6 +168,7 @@
#define DX50_PAD 63
#define SONY_NWZA860_PAD 64 /* The NWZ-A860 is too different (touchscreen) */
#define AGPTEK_ROCKER_PAD 65
#define XDUOO_X3_PAD 66
/* CONFIG_POWER_SAVE combinable bit flags*/
#define POWERSV_CPU 0x1
@ -287,6 +289,7 @@
#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_INGENIC_LINUX 64
#define LCD_XDUOOX3 65 /* as used by the xDuoo X3 */
/* LCD_PIXELFORMAT */
#define HORIZONTAL_PACKING 1
@ -358,12 +361,13 @@ Lyre prototype 1 */
#define RTC_MC13783 13 /* Freescale MC13783 PMIC */
#define RTC_S5L8700 14
#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_D2 18 /* Either PCF50606 or PCF50635 */
#define RTC_S35380A 19
#define RTC_IMX233 20
#define RTC_STM41T62 21 /* ST M41T62 */
#define RTC_JZ4760 22 /* Ingenic Jz4760 */
/* USB On-the-go */
#define USBOTG_M66591 6591 /* M:Robe 500 */
@ -372,6 +376,7 @@ Lyre prototype 1 */
#define USBOTG_M5636 5636 /* iAudio X5 */
#define USBOTG_ARC 5020 /* PortalPlayer 502x and IMX233 */
#define USBOTG_JZ4740 4740 /* Ingenic Jz4740/Jz4732 */
#define USBOTG_JZ4760 4760 /* Ingenic Jz4760/Jz4760B */
#define USBOTG_AS3525 3525 /* AMS AS3525 */
#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 */
@ -612,6 +617,8 @@ Lyre prototype 1 */
#include "config/sonynwze350.h"
#elif defined(AGPTEK_ROCKER)
#include "config/agptekrocker.h"
#elif defined(XDUOO_X3)
#include "config/xduoox3.h"
#else
/* no known platform */
#endif
@ -980,7 +987,7 @@ Lyre prototype 1 */
#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) \
|| defined(CPU_S5L870X) || (CONFIG_CPU == S3C2440) \
|| defined(APPLICATION) || (CONFIG_CPU == PP5002) \
@ -1057,14 +1064,14 @@ Lyre prototype 1 */
(CONFIG_CPU == TCC7801) || \
(CONFIG_CPU == IMX233 && !defined(PLUGIN) && !defined(CODEC)) || /* IMX233: core only */ \
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 ICONST_ATTR __attribute__ ((section(".irodata")))
#define IDATA_ATTR __attribute__ ((section(".idata")))
#define IBSS_ATTR __attribute__ ((section(".ibss")))
#define USE_IRAM
#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
#endif
#else
@ -1207,6 +1214,7 @@ Lyre prototype 1 */
#define USB_HAS_BULK
#elif (CONFIG_USBOTG == USBOTG_ARC) || \
(CONFIG_USBOTG == USBOTG_JZ4740) || \
(CONFIG_USBOTG == USBOTG_JZ4760) || \
(CONFIG_USBOTG == USBOTG_M66591) || \
(CONFIG_USBOTG == USBOTG_DESIGNWARE) || \
(CONFIG_USBOTG == USBOTG_AS3525)
@ -1231,7 +1239,8 @@ Lyre prototype 1 */
#if defined(HAVE_BOOTLOADER_USB_MODE) || \
defined(CREATIVE_ZVx) || defined(CPU_TCC77X) || defined(CPU_TCC780X) || \
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
#endif

View file

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

View file

@ -80,7 +80,7 @@
#define CONFIG_CODEC SWCODEC
/* 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 HAVE_BACKLIGHT

View file

@ -85,7 +85,7 @@
#define CONFIG_CODEC SWCODEC
/* define this if you have a real-time clock */
#define CONFIG_RTC RTC_JZ47XX
#define CONFIG_RTC RTC_JZ4740
/* Tuner config */
#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
#include "jz4740.h"
#endif
#if CONFIG_CPU == JZ4760B
#include "jz4760b.h"
#endif
#if CONFIG_CPU == AS3525
#include "as3525.h"
#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 */
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];
#else
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
#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)
int sound_enum_hw_eq_band_setting(unsigned int band,
unsigned int band_setting)

View file

@ -508,6 +508,7 @@
#define UI_LCD_POSX 46
#define UI_LCD_POSY 40
<<<<<<< HEAD
#elif defined(SONY_NWZA860)
#define UI_TITLE "Sony NWZ-A860 Series"
#define UI_WIDTH 390 /* width of GUI window */
@ -521,6 +522,12 @@
#define UI_HEIGHT 380
#define UI_LCD_POSX 29
#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)
#error no UI defines
#endif

View file

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

View file

@ -20,7 +20,7 @@
****************************************************************************/
#include "config.h"
#include "jz4740.h"
#include "cpu.h"
#include "nand.h"
#include "nand_id.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 "gcc_extensions.h"
#include "jz4740.h"
#include "cpu.h"
#include "ata-sd-target.h"
#include "led.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);
void backlight_hw_on(void);
void backlight_hw_off(void);
#ifdef HAVE_BACKLIGHT_BRIGHTNESS
void backlight_hw_brightness(int brightness);
#endif /* HAVE_BACKLIGHT_BRIGHTNESS */
#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
#ifdef BOOTLOADER
#ifndef XDUOO_X3
/* These will get filled in by scramble */
.word 0 /* Empty */
.word 0 /* Filesize */
@ -65,6 +66,7 @@ _relocate_loop:
bne t1, t2, _relocate_loop
sw t3, -4(t1)
#endif
#endif
_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 "config.h"
#include "jz4740.h"
#include "cpu.h"
#include "mipsregs.h"
#define CACHE_SIZE 16*1024
@ -35,6 +35,8 @@
/* no optimized byteswap functions implemented for mips, yet */
#define NEED_GENERIC_BYTESWAPS
#define STORAGE_WANTS_ALIGN
/* This one returns the old status */
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_disable(void);
#if CONFIG_CPU == JZ4732
#define DMA_AIC_TX_CHANNEL 0
#define DMA_NAND_CHANNEL 1
#define DMA_USB_CHANNEL 2
#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 DMA_CALLBACK(n) XDMA_CALLBACK(n)
@ -103,7 +113,7 @@ void dma_disable(void);
*/
static inline void core_sleep(void)
{
#if CONFIG_CPU == JZ4732
#if CONFIG_CPU == JZ4732 || CONFIG_CPU == JZ4760B
__cpm_idle_mode();
#endif
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