From e8a8a1be43afe63079ae48ce1a9eb3052df3b1a4 Mon Sep 17 00:00:00 2001 From: Tomasz Moń Date: Wed, 16 Nov 2011 14:08:01 +0000 Subject: Sandisk Sansa Connect port (FS #12363) Included are drivers for buttons, backlight, lcd, audio and storage. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31000 a1c6a512-1295-4272-9138-f99709370657 --- apps/SOURCES | 2 + apps/keymaps/keymap-sansa-connect.c | 93 ++ apps/plugins/battery_bench.c | 6 + apps/plugins/blackjack.c | 6 +- apps/plugins/bounce.c | 3 +- apps/plugins/brickmania.c | 3 +- apps/plugins/calculator.c | 13 + apps/plugins/calendar.c | 10 + apps/plugins/chessbox/chessbox_pgn.h | 16 + apps/plugins/chessclock.c | 10 + apps/plugins/chip8.c | 13 + apps/plugins/chopper.c | 3 +- apps/plugins/clix.c | 3 +- apps/plugins/cube.c | 10 + apps/plugins/doom/i_video.c | 10 + apps/plugins/fft/fft.c | 9 + apps/plugins/fireworks.c | 3 +- apps/plugins/flipit.c | 18 + apps/plugins/fractals/fractal.h | 12 + apps/plugins/goban/goban.h | 13 + apps/plugins/imageviewer/imageviewer_button.h | 15 + apps/plugins/invadrox.c | 3 +- apps/plugins/jewels.c | 3 +- apps/plugins/lamp.c | 3 +- apps/plugins/lib/pluginlib_actions.c | 6 +- apps/plugins/logo.c | 3 +- apps/plugins/matrix.c | 3 +- apps/plugins/midi/midiplay.c | 8 + apps/plugins/minesweeper.c | 14 + apps/plugins/mosaique.c | 5 + apps/plugins/mp3_encoder.c | 6 + apps/plugins/mpegplayer/mpeg_settings.c | 8 + apps/plugins/mpegplayer/mpegplayer.c | 9 + apps/plugins/oscilloscope.c | 11 + apps/plugins/pacbox/pacbox.h | 11 + apps/plugins/pegbox.c | 19 + apps/plugins/plugin.lds | 2 +- apps/plugins/pong.c | 3 +- apps/plugins/reversi/reversi-gui.h | 3 +- apps/plugins/rockblox.c | 10 + apps/plugins/rockblox1d.c | 3 +- apps/plugins/rockboy/rockboy.c | 12 + apps/plugins/rockpaint.c | 11 + apps/plugins/sliding_puzzle.c | 9 + apps/plugins/snake.c | 3 +- apps/plugins/snake2.c | 3 +- apps/plugins/snow.c | 3 +- apps/plugins/sokoban.c | 22 + apps/plugins/solitaire.c | 18 + apps/plugins/spacerocks.c | 10 + apps/plugins/star.c | 17 + apps/plugins/starfield.c | 3 +- apps/plugins/stats.c | 3 +- apps/plugins/stopwatch.c | 8 + apps/plugins/sudoku/sudoku.h | 11 + apps/plugins/superdom.c | 8 + apps/plugins/text_viewer/tv_button.h | 12 + apps/plugins/vu_meter.c | 11 + apps/plugins/wormlet.c | 10 + apps/plugins/xobox.c | 9 + apps/plugins/zxbox/keymaps.h | 3 +- apps/plugins/zxbox/zxbox_keyb.c | 3 +- bootloader/SOURCES | 3 + bootloader/sansaconnect.c | 135 +++ firmware/SOURCES | 23 + firmware/drivers/audio/aic3x.c | 247 ++++++ firmware/export/aic3x.h | 77 ++ firmware/export/audiohw.h | 2 + firmware/export/config.h | 6 + firmware/export/config/sansaconnect.h | 201 +++++ firmware/export/dm320.h | 51 ++ firmware/sound.c | 2 +- firmware/target/arm/tms320dm320/app.lds | 2 +- firmware/target/arm/tms320dm320/boot.lds | 19 +- firmware/target/arm/tms320dm320/debug-dm320.c | 2 + firmware/target/arm/tms320dm320/dma-dm320.c | 78 ++ firmware/target/arm/tms320dm320/dma-target.h | 44 + firmware/target/arm/tms320dm320/i2c-dm320.c | 138 ++- firmware/target/arm/tms320dm320/kernel-dm320.c | 9 +- .../tms320dm320/sansa-connect/adc-sansaconnect.c | 35 + .../arm/tms320dm320/sansa-connect/adc-target.h | 25 + .../tms320dm320/sansa-connect/avr-sansaconnect.c | 461 ++++++++++ .../tms320dm320/sansa-connect/avr-sansaconnect.h | 38 + .../sansa-connect/backlight-sansaconnect.c | 93 ++ .../tms320dm320/sansa-connect/backlight-target.h | 33 + .../arm/tms320dm320/sansa-connect/button-target.h | 64 ++ .../arm/tms320dm320/sansa-connect/crt0-board.S | 238 ++++++ .../tms320dm320/sansa-connect/lcd-sansaconnect.c | 273 ++++++ .../arm/tms320dm320/sansa-connect/lcd-target.h | 25 + .../tms320dm320/sansa-connect/pcm-sansaconnect.c | 207 +++++ .../tms320dm320/sansa-connect/power-sansaconnect.c | 59 ++ .../sansa-connect/powermgmt-sansaconnect.c | 56 ++ .../tms320dm320/sansa-connect/usb-sansaconnect.c | 53 ++ .../arm/tms320dm320/sansa-connect/usb-target.h | 32 + firmware/target/arm/tms320dm320/sdmmc-dm320.c | 949 +++++++++++++++++++++ firmware/target/arm/tms320dm320/system-dm320.c | 33 +- firmware/target/arm/tms320dm320/system-target.h | 5 + tools/configure | 35 +- tools/scramble.c | 2 + 99 files changed, 4302 insertions(+), 46 deletions(-) create mode 100644 apps/keymaps/keymap-sansa-connect.c create mode 100644 bootloader/sansaconnect.c create mode 100644 firmware/drivers/audio/aic3x.c create mode 100644 firmware/export/aic3x.h create mode 100644 firmware/export/config/sansaconnect.h create mode 100644 firmware/target/arm/tms320dm320/dma-dm320.c create mode 100644 firmware/target/arm/tms320dm320/dma-target.h create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/adc-sansaconnect.c create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/adc-target.h create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.h create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/backlight-sansaconnect.c create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/backlight-target.h create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/button-target.h create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/crt0-board.S create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/lcd-target.h create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/pcm-sansaconnect.c create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/power-sansaconnect.c create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/powermgmt-sansaconnect.c create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/usb-sansaconnect.c create mode 100644 firmware/target/arm/tms320dm320/sansa-connect/usb-target.h create mode 100644 firmware/target/arm/tms320dm320/sdmmc-dm320.c diff --git a/apps/SOURCES b/apps/SOURCES index 7ef81a10ee..34dc202345 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -330,5 +330,7 @@ keymaps/keymap-rk27xx-generic.c keymaps/keymap-hm60x.c #elif CONFIG_KEYPAD == HM801_PAD keymaps/keymap-hm801.c +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +keymaps/keymap-sansa-connect.c #endif diff --git a/apps/keymaps/keymap-sansa-connect.c b/apps/keymaps/keymap-sansa-connect.c new file mode 100644 index 0000000000..6f8a58496b --- /dev/null +++ b/apps/keymaps/keymap-sansa-connect.c @@ -0,0 +1,93 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 Sandisk Sansa Connect target */ + +#include "config.h" +#include "action.h" +#include "button.h" + +/* + * 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_SCROLL_BACK, BUTTON_NONE}, + {ACTION_STD_PREVREPEAT, BUTTON_SCROLL_BACK|BUTTON_REPEAT, BUTTON_NONE}, + {ACTION_STD_NEXT, BUTTON_SCROLL_FWD, BUTTON_NONE}, + {ACTION_STD_NEXTREPEAT, BUTTON_SCROLL_FWD|BUTTON_REPEAT, BUTTON_NONE}, + {ACTION_STD_OK, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT}, + {ACTION_STD_OK, BUTTON_RIGHT, BUTTON_NONE}, + {ACTION_STD_CANCEL, BUTTON_LEFT, BUTTON_NONE}, + {ACTION_STD_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE}, + {ACTION_STD_MENU, BUTTON_DOWN|BUTTON_REL, BUTTON_DOWN}, + {ACTION_STD_QUICKSCREEN,BUTTON_DOWN|BUTTON_REL, BUTTON_DOWN}, + {ACTION_STD_HOTKEY, BUTTON_UP|BUTTON_REL, BUTTON_UP}, + LAST_ITEM_IN_LIST +}; /* button_context_standard */ + +static const struct button_mapping button_context_wps[] = { + {ACTION_WPS_PLAY, BUTTON_DOWN|BUTTON_REL, BUTTON_DOWN}, + {ACTION_WPS_SEEKBACK, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, + {ACTION_WPS_SEEKFWD, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, + {ACTION_WPS_STOPSEEK, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT|BUTTON_REPEAT}, + {ACTION_WPS_SKIPNEXT, BUTTON_NEXT, BUTTON_NONE}, + {ACTION_WPS_SKIPPREV, BUTTON_PREV, BUTTON_NONE}, + {ACTION_WPS_STOP, BUTTON_POWER, BUTTON_NONE}, + {ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE}, + {ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE}, + {ACTION_WPS_VOLUP, BUTTON_VOL_UP, BUTTON_NONE}, + {ACTION_WPS_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE}, + {ACTION_WPS_BROWSE, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT}, + {ACTION_WPS_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT}, + {ACTION_WPS_MENU, BUTTON_DOWN|BUTTON_REL, BUTTON_DOWN}, + {ACTION_WPS_ABSETA_PREVDIR, BUTTON_POWER|BUTTON_RIGHT, BUTTON_POWER}, + {ACTION_WPS_ABSETB_NEXTDIR, BUTTON_POWER|BUTTON_LEFT, BUTTON_POWER}, + {ACTION_WPS_ABRESET, BUTTON_POWER|BUTTON_UP, BUTTON_POWER}, + {ACTION_WPS_HOTKEY, BUTTON_UP|BUTTON_REL, BUTTON_UP}, + LAST_ITEM_IN_LIST +}; /* button_context_wps */ + + + +/* 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_STD: + return button_context_standard; + case CONTEXT_WPS: + return button_context_wps; + + case CONTEXT_TREE: + case CONTEXT_LIST: + case CONTEXT_MAINMENU: + + case CONTEXT_SETTINGS: + case CONTEXT_SETTINGS|CONTEXT_REMOTE: + default: + return button_context_standard; + } + return button_context_standard; +} diff --git a/apps/plugins/battery_bench.c b/apps/plugins/battery_bench.c index 1adc30278a..b88c4dc46a 100644 --- a/apps/plugins/battery_bench.c +++ b/apps/plugins/battery_bench.c @@ -235,6 +235,12 @@ #define BATTERY_ON_TXT "PLAYPAUSE - start" #define BATTERY_OFF_TXT "POWER" +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define BATTERY_ON BUTTON_SELECT +#define BATTERY_OFF BUTTON_POWER +#define BATTERY_ON_TXT "SELECT - start" +#define BATTERY_OFF_TXT "POWER" + #else #error No keymap defined! #endif diff --git a/apps/plugins/blackjack.c b/apps/plugins/blackjack.c index 578136802c..0c35306cfc 100644 --- a/apps/plugins/blackjack.c +++ b/apps/plugins/blackjack.c @@ -166,7 +166,8 @@ enum { #define BJACK_RIGHT BUTTON_RIGHT #define BJACK_LEFT BUTTON_LEFT -#elif CONFIG_KEYPAD == SANSA_E200_PAD +#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ + (CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define BJACK_SELECT_NAME "SELECT" #define BJACK_STAY_NAME "RIGHT" #define BJACK_QUIT_NAME "POWER" @@ -1032,7 +1033,8 @@ static signed int blackjack_get_amount(char message[20], signed int lower_limit, (CONFIG_KEYPAD == IPOD_3G_PAD) || \ (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \ (CONFIG_KEYPAD == SANSA_E200_PAD) || \ - (CONFIG_KEYPAD == SANSA_FUZE_PAD) + (CONFIG_KEYPAD == SANSA_FUZE_PAD) || \ + (CONFIG_KEYPAD == SANSA_CONNECT_PAD) rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, " >>|: +1"); rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, " |<<: -1"); rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "SCROLL+: +10"); diff --git a/apps/plugins/bounce.c b/apps/plugins/bounce.c index c3a0dc9657..6880e269e2 100644 --- a/apps/plugins/bounce.c +++ b/apps/plugins/bounce.c @@ -110,7 +110,8 @@ #elif CONFIG_KEYPAD == SANSA_C200_PAD || \ CONFIG_KEYPAD == SANSA_CLIP_PAD || \ - CONFIG_KEYPAD == SANSA_M200_PAD + CONFIG_KEYPAD == SANSA_M200_PAD || \ + CONFIG_KEYPAD == SANSA_CONNECT_PAD #define BOUNCE_LEFT BUTTON_LEFT #define BOUNCE_RIGHT BUTTON_RIGHT #define BOUNCE_UP BUTTON_UP diff --git a/apps/plugins/brickmania.c b/apps/plugins/brickmania.c index 993a3c488b..c362ffe702 100644 --- a/apps/plugins/brickmania.c +++ b/apps/plugins/brickmania.c @@ -139,7 +139,8 @@ #elif CONFIG_KEYPAD == SANSA_C200_PAD || \ CONFIG_KEYPAD == SANSA_CLIP_PAD || \ -CONFIG_KEYPAD == SANSA_M200_PAD +CONFIG_KEYPAD == SANSA_M200_PAD || \ +CONFIG_KEYPAD == SANSA_CONNECT_PAD #define QUIT BUTTON_POWER #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT diff --git a/apps/plugins/calculator.c b/apps/plugins/calculator.c index 994b066e7b..8288f34c28 100644 --- a/apps/plugins/calculator.c +++ b/apps/plugins/calculator.c @@ -418,6 +418,19 @@ F3: equal to "=" #define CALCULATOR_CALC BUTTON_PLAYPAUSE #define CALCULATOR_CLEAR BUTTON_BACK +#elif (CONFIG_KEYPAD == SANSA_CONNECT_PAD) +#define CALCULATOR_LEFT BUTTON_LEFT +#define CALCULATOR_RIGHT BUTTON_RIGHT +#define CALCULATOR_UP BUTTON_UP +#define CALCULATOR_DOWN BUTTON_DOWN +#define CALCULATOR_UP_W_SHIFT BUTTON_SCROLL_BACK +#define CALCULATOR_DOWN_W_SHIFT BUTTON_SCROLL_FWD +#define CALCULATOR_QUIT BUTTON_POWER +#define CALCULATOR_INPUT_CALC_PRE BUTTON_SELECT +#define CALCULATOR_INPUT (BUTTON_SELECT|BUTTON_REL) +#define CALCULATOR_CALC BUTTON_NEXT +#define CALCULATOR_CLEAR BUTTON_PREV + #else #error No keymap defined! #endif diff --git a/apps/plugins/calendar.c b/apps/plugins/calendar.c index 0a94dfcffc..d8d8f1ad12 100644 --- a/apps/plugins/calendar.c +++ b/apps/plugins/calendar.c @@ -298,6 +298,16 @@ #define CALENDAR_NEXT_MONTH BUTTON_PLAYPAUSE #define CALENDAR_PREV_MONTH BUTTON_BACK +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define CALENDAR_QUIT BUTTON_POWER +#define CALENDAR_SELECT BUTTON_SELECT +#define CALENDAR_NEXT_WEEK BUTTON_RIGHT +#define CALENDAR_PREV_WEEK BUTTON_LEFT +#define CALENDAR_NEXT_DAY BUTTON_UP +#define CALENDAR_PREV_DAY BUTTON_DOWN +#define CALENDAR_NEXT_MONTH BUTTON_NEXT +#define CALENDAR_PREV_MONTH BUTTON_PREV + #else #error "No keypad setting." #endif diff --git a/apps/plugins/chessbox/chessbox_pgn.h b/apps/plugins/chessbox/chessbox_pgn.h index 9f25eb97aa..1627426cef 100644 --- a/apps/plugins/chessbox/chessbox_pgn.h +++ b/apps/plugins/chessbox/chessbox_pgn.h @@ -406,6 +406,22 @@ #define CB_LEVEL BUTTON_BACK #define CB_MENU (BUTTON_PLAYPAUSE | BUTTON_REPEAT) +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define CB_SELECT BUTTON_SELECT +#define CB_UP BUTTON_UP +#define CB_DOWN BUTTON_DOWN +#define CB_LEFT BUTTON_LEFT +#define CB_RIGHT BUTTON_RIGHT +#define CB_PLAY BUTTON_NEXT +#define CB_LEVEL BUTTON_VOL_DOWN +#define CB_RESTART BUTTON_PREV +#define CB_MENU BUTTON_POWER + +#define CB_SCROLL_UP (BUTTON_SCROLL_UP|BUTTON_REPEAT) +#define CB_SCROLL_DOWN (BUTTON_SCROLL_DOWN|BUTTON_REPEAT) +#define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT) +#define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT) + #else #error No keymap defined! #endif diff --git a/apps/plugins/chessclock.c b/apps/plugins/chessclock.c index b05e849e83..dca5c4040e 100644 --- a/apps/plugins/chessclock.c +++ b/apps/plugins/chessclock.c @@ -316,6 +316,16 @@ #define CHC_SETTINGS_OK BUTTON_SELECT #define CHC_SETTINGS_CANCEL BUTTON_BACK +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define CHC_QUIT BUTTON_POWER +#define CHC_STARTSTOP BUTTON_NEXT +#define CHC_RESET BUTTON_PREV +#define CHC_MENU BUTTON_SELECT +#define CHC_SETTINGS_INC BUTTON_VOL_UP +#define CHC_SETTINGS_DEC BUTTON_VOL_DOWN +#define CHC_SETTINGS_OK BUTTON_SELECT +#define CHC_SETTINGS_CANCEL BUTTON_LEFT + #else #error No keymap defined! #endif diff --git a/apps/plugins/chip8.c b/apps/plugins/chip8.c index 71024b27a2..97d8351fe9 100644 --- a/apps/plugins/chip8.c +++ b/apps/plugins/chip8.c @@ -1180,6 +1180,19 @@ CONFIG_KEYPAD == MROBE500_PAD #define CHIP8_KEY8 BUTTON_VOL_DOWN #define CHIP8_KEY9 BUTTON_VOL_UP +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD + +#define CHIP8_OFF BUTTON_POWER +#define CHIP8_KEY1 BUTTON_LEFT +#define CHIP8_KEY2 BUTTON_UP +#define CHIP8_KEY3 BUTTON_RIGHT +#define CHIP8_KEY4 BUTTON_DOWN +#define CHIP8_KEY5 BUTTON_NEXT +#define CHIP8_KEY6 BUTTON_PREV +#define CHIP8_KEY7 BUTTON_SELECT +#define CHIP8_KEY8 BUTTON_VOL_DOWN +#define CHIP8_KEY9 BUTTON_VOL_UP + #else #error No keymap defined! #endif diff --git a/apps/plugins/chopper.c b/apps/plugins/chopper.c index ef1f8aacf3..71ea8f835f 100644 --- a/apps/plugins/chopper.c +++ b/apps/plugins/chopper.c @@ -70,7 +70,8 @@ Still To do: #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ (CONFIG_KEYPAD == SANSA_C200_PAD) || \ (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ - (CONFIG_KEYPAD == SANSA_M200_PAD) + (CONFIG_KEYPAD == SANSA_M200_PAD) || \ + (CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define QUIT BUTTON_POWER #define ACTION BUTTON_SELECT #define ACTIONTEXT "SELECT" diff --git a/apps/plugins/clix.c b/apps/plugins/clix.c index 14a758f1a6..378e9813e6 100644 --- a/apps/plugins/clix.c +++ b/apps/plugins/clix.c @@ -24,7 +24,8 @@ -#if (CONFIG_KEYPAD == SANSA_E200_PAD) +#if (CONFIG_KEYPAD == SANSA_E200_PAD) || \ + (CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define CLIX_BUTTON_QUIT BUTTON_POWER #define CLIX_BUTTON_UP BUTTON_UP #define CLIX_BUTTON_DOWN BUTTON_DOWN diff --git a/apps/plugins/cube.c b/apps/plugins/cube.c index 5f4a0f6a69..7e97eaf569 100644 --- a/apps/plugins/cube.c +++ b/apps/plugins/cube.c @@ -319,6 +319,16 @@ #define CUBE_PAUSE BUTTON_PLAYPAUSE #define CUBE_HIGHSPEED BUTTON_BACK +#elif CONFIG_KEYPAD == SANSA_CONNECT_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_SELECT +#define CUBE_PAUSE BUTTON_DOWN +#define CUBE_HIGHSPEED BUTTON_LEFT + #else #error No keymap defined! #endif diff --git a/apps/plugins/doom/i_video.c b/apps/plugins/doom/i_video.c index 473ce49f8c..d12799cac4 100644 --- a/apps/plugins/doom/i_video.c +++ b/apps/plugins/doom/i_video.c @@ -413,6 +413,16 @@ void I_ShutdownGraphics(void) #define DOOMBUTTON_ESC BUTTON_BACK #define DOOMBUTTON_ENTER (BUTTON_PLAYPAUSE|BUTTON_REPEAT) #define DOOMBUTTON_WEAPON (BUTTON_SELECT|BUTTON_REPEAT) +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define DOOMBUTTON_UP BUTTON_UP +#define DOOMBUTTON_DOWN BUTTON_DOWN +#define DOOMBUTTON_LEFT BUTTON_LEFT +#define DOOMBUTTON_RIGHT BUTTON_RIGHT +#define DOOMBUTTON_SHOOT BUTTON_SELECT +#define DOOMBUTTON_OPEN BUTTON_VOL_DOWN +#define DOOMBUTTON_ESC BUTTON_VOL_UP +#define DOOMBUTTON_ENTER BUTTON_NEXT +#define DOOMBUTTON_WEAPON BUTTON_PREV #else #error Keymap not defined! diff --git a/apps/plugins/fft/fft.c b/apps/plugins/fft/fft.c index fa08848f03..11bdfc8e74 100644 --- a/apps/plugins/fft/fft.c +++ b/apps/plugins/fft/fft.c @@ -248,6 +248,15 @@ GREY_INFO_STRUCT # define FFT_AMP_SCALE BUTTON_PLAYPAUSE # define FFT_QUIT BUTTON_POWER +#elif (CONFIG_KEYPAD == SANSA_CONNECT_PAD) +# define FFT_PREV_GRAPH BUTTON_LEFT +# define FFT_NEXT_GRAPH BUTTON_RIGHT +# define FFT_ORIENTATION BUTTON_SELECT +# define FFT_WINDOW BUTTON_VOL_DOWN +# define FFT_AMP_SCALE BUTTON_UP +# define FFT_FREQ_SCALE BUTTON_DOWN +# define FFT_QUIT BUTTON_POWER + #else #error No keymap defined! #endif diff --git a/apps/plugins/fireworks.c b/apps/plugins/fireworks.c index 69c7be0bc4..e3a391035a 100644 --- a/apps/plugins/fireworks.c +++ b/apps/plugins/fireworks.c @@ -68,7 +68,8 @@ #define BTN_FIRE BUTTON_SELECT #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ - (CONFIG_KEYPAD == SANSA_C200_PAD) + (CONFIG_KEYPAD == SANSA_C200_PAD) || \ + (CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define BTN_MENU BUTTON_POWER #define BTN_FIRE BUTTON_SELECT diff --git a/apps/plugins/flipit.c b/apps/plugins/flipit.c index 70d35ec100..ffc691c720 100644 --- a/apps/plugins/flipit.c +++ b/apps/plugins/flipit.c @@ -368,6 +368,18 @@ #define FLIPIT_STEP_BY_STEP (BUTTON_BACK|BUTTON_PLAYPAUSE) #define FLIPIT_TOGGLE BUTTON_SELECT +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD + +#define FLIPIT_LEFT BUTTON_LEFT +#define FLIPIT_RIGHT BUTTON_RIGHT +#define FLIPIT_UP BUTTON_UP +#define FLIPIT_DOWN BUTTON_DOWN +#define FLIPIT_QUIT BUTTON_POWER +#define FLIPIT_SHUFFLE BUTTON_VOL_UP +#define FLIPIT_SOLVE BUTTON_PREV +#define FLIPIT_STEP_BY_STEP BUTTON_NEXT +#define FLIPIT_TOGGLE BUTTON_SELECT + #else #error No keymap defined! #endif @@ -838,6 +850,12 @@ enum plugin_status plugin_start(const void* parameter) rb->lcd_putsxy(2, 28, "[MODE] shuffle"); rb->lcd_putsxy(2, 38, "[MENU..] solution"); rb->lcd_putsxy(2, 48, "[MENU] step by step"); +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD + rb->lcd_putsxy(2, 8, "[POWER] to stop"); + rb->lcd_putsxy(2, 18, "[SELECT] toggle"); + rb->lcd_putsxy(2, 28, "[VOL+] shuffle"); + rb->lcd_putsxy(2, 38, "[PREV] solution"); + rb->lcd_putsxy(2, 48, "[NEXT] step by step"); #endif #ifdef HAVE_TOUCHSCREEN diff --git a/apps/plugins/fractals/fractal.h b/apps/plugins/fractals/fractal.h index b0fa93752c..76f3229399 100644 --- a/apps/plugins/fractals/fractal.h +++ b/apps/plugins/fractals/fractal.h @@ -366,6 +366,18 @@ #define FRACTAL_PRECISION_DEC (BUTTON_PLAYPAUSE|BUTTON_RIGHT) #define FRACTAL_RESET BUTTON_BACK +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define FRACTAL_QUIT BUTTON_POWER +#define FRACTAL_UP BUTTON_UP +#define FRACTAL_DOWN BUTTON_DOWN +#define FRACTAL_LEFT BUTTON_LEFT +#define FRACTAL_RIGHT BUTTON_RIGHT +#define FRACTAL_ZOOM_IN BUTTON_SCROLL_FWD +#define FRACTAL_ZOOM_OUT BUTTON_SCROLL_BACK +#define FRACTAL_PRECISION_INC BUTTON_VOL_UP +#define FRACTAL_PRECISION_DEC BUTTON_VOL_DOWN +#define FRACTAL_RESET BUTTON_PREV + #else #error No keymap defined! #endif diff --git a/apps/plugins/goban/goban.h b/apps/plugins/goban/goban.h index 1931311d2d..d03bc82474 100644 --- a/apps/plugins/goban/goban.h +++ b/apps/plugins/goban/goban.h @@ -138,6 +138,19 @@ #define GBN_BUTTON_CONTEXT BUTTON_SELECT | BUTTON_REPEAT /* No next var */ +#elif (CONFIG_KEYPAD == SANSA_CONNECT_PAD) +#define GBN_BUTTON_UP BUTTON_UP +#define GBN_BUTTON_DOWN BUTTON_DOWN +#define GBN_BUTTON_LEFT BUTTON_LEFT +#define GBN_BUTTON_RIGHT BUTTON_RIGHT +#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_SELECT | BUTTON_REL +#define GBN_BUTTON_CONTEXT BUTTON_SELECT | BUTTON_REPEAT +#define GBN_BUTTON_NEXT_VAR BUTTON_NEXT + + #elif (CONFIG_KEYPAD == CREATIVEZVM_PAD) \ || (CONFIG_KEYPAD == CREATIVEZV_PAD) #define GBN_BUTTON_UP BUTTON_UP diff --git a/apps/plugins/imageviewer/imageviewer_button.h b/apps/plugins/imageviewer/imageviewer_button.h index 198b35c14c..9f345d83f3 100644 --- a/apps/plugins/imageviewer/imageviewer_button.h +++ b/apps/plugins/imageviewer/imageviewer_button.h @@ -364,6 +364,21 @@ #define IMGVIEW_MENU BUTTON_SELECT #define IMGVIEW_QUIT BUTTON_POWER +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define IMGVIEW_ZOOM_PRE BUTTON_SELECT +#define IMGVIEW_ZOOM_IN BUTTON_VOL_UP +#define IMGVIEW_ZOOM_OUT BUTTON_VOL_DOWN +#define IMGVIEW_UP BUTTON_UP +#define IMGVIEW_DOWN BUTTON_DOWN +#define IMGVIEW_LEFT BUTTON_LEFT +#define IMGVIEW_RIGHT BUTTON_RIGHT +#define IMGVIEW_NEXT BUTTON_SCROLL_FWD +#define IMGVIEW_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT) +#define IMGVIEW_PREVIOUS BUTTON_SCROLL_BACK +#define IMGVIEW_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT) +#define IMGVIEW_MENU BUTTON_POWER +#define IMGVIEW_SLIDE_SHOW BUTTON_NEXT + #else #error No keymap defined! #endif diff --git a/apps/plugins/invadrox.c b/apps/plugins/invadrox.c index 94d079f2b4..96e04a976f 100644 --- a/apps/plugins/invadrox.c +++ b/apps/plugins/invadrox.c @@ -129,7 +129,8 @@ #define RIGHT BUTTON_RIGHT #define FIRE BUTTON_SELECT -#elif CONFIG_KEYPAD == SANSA_E200_PAD +#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ + (CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define QUIT BUTTON_POWER #define LEFT BUTTON_LEFT diff --git a/apps/plugins/jewels.c b/apps/plugins/jewels.c index ae6105bcb0..4d5a5b6ce9 100644 --- a/apps/plugins/jewels.c +++ b/apps/plugins/jewels.c @@ -123,7 +123,8 @@ #define HK_SELECT "SELECT" #define HK_CANCEL "POWER" -#elif CONFIG_KEYPAD == SANSA_E200_PAD +#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ + (CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define JEWELS_SCROLLWHEEL #define JEWELS_UP BUTTON_UP #define JEWELS_DOWN BUTTON_DOWN diff --git a/apps/plugins/lamp.c b/apps/plugins/lamp.c index 7389811a59..d9ad70b946 100644 --- a/apps/plugins/lamp.c +++ b/apps/plugins/lamp.c @@ -64,7 +64,8 @@ # define LAMP_DOWN BUTTON_DOWN #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ - (CONFIG_KEYPAD == SANSA_FUZE_PAD) + (CONFIG_KEYPAD == SANSA_FUZE_PAD) || \ + (CONFIG_KEYPAD == SANSA_CONNECT_PAD) # define LAMP_LEFT BUTTON_LEFT # define LAMP_RIGHT BUTTON_RIGHT # define LAMP_UP BUTTON_SCROLL_FWD diff --git a/apps/plugins/lib/pluginlib_actions.c b/apps/plugins/lib/pluginlib_actions.c index 4b0f3a6945..0a2f12da50 100644 --- a/apps/plugins/lib/pluginlib_actions.c +++ b/apps/plugins/lib/pluginlib_actions.c @@ -115,7 +115,8 @@ const struct button_mapping pla_main_ctx[] = || (CONFIG_KEYPAD == SANSA_E200_PAD) \ || (CONFIG_KEYPAD == SANSA_FUZE_PAD) \ || (CONFIG_KEYPAD == SAMSUNG_YH_PAD) \ - || (CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD)) + || (CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD) \ + || (CONFIG_KEYPAD == SANSA_CONNECT_PAD)) { PLA_UP, BUTTON_UP, BUTTON_NONE }, { PLA_DOWN, BUTTON_DOWN, BUTTON_NONE }, { PLA_LEFT, BUTTON_LEFT, BUTTON_NONE }, @@ -270,7 +271,8 @@ const struct button_mapping pla_main_ctx[] = || CONFIG_KEYPAD == SANSA_CLIP_PAD \ || CONFIG_KEYPAD == SANSA_M200_PAD \ || CONFIG_KEYPAD == MROBE100_PAD \ - || CONFIG_KEYPAD == PHILIPS_HDD1630_PAD) + || CONFIG_KEYPAD == PHILIPS_HDD1630_PAD \ + || CONFIG_KEYPAD == SANSA_CONNECT_PAD) {PLA_CANCEL, BUTTON_POWER|BUTTON_REL, BUTTON_POWER}, {PLA_EXIT, BUTTON_POWER|BUTTON_REPEAT, BUTTON_NONE}, {PLA_SELECT, BUTTON_SELECT, BUTTON_NONE}, diff --git a/apps/plugins/logo.c b/apps/plugins/logo.c index dc0db8e95a..d651c2f634 100644 --- a/apps/plugins/logo.c +++ b/apps/plugins/logo.c @@ -98,7 +98,8 @@ const unsigned char rockbox16x7[] = { #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ (CONFIG_KEYPAD == SANSA_C200_PAD) || \ (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ - (CONFIG_KEYPAD == SANSA_M200_PAD) + (CONFIG_KEYPAD == SANSA_M200_PAD) || \ + (CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define LP_QUIT BUTTON_POWER #define LP_DEC_X BUTTON_LEFT #define LP_INC_X BUTTON_RIGHT diff --git a/apps/plugins/matrix.c b/apps/plugins/matrix.c index d1a672cd96..1a1008073c 100644 --- a/apps/plugins/matrix.c +++ b/apps/plugins/matrix.c @@ -82,7 +82,8 @@ #define MATRIX_SLEEP_LESS BUTTON_DOWN #define MATRIX_PAUSE BUTTON_SELECT -#elif CONFIG_KEYPAD == SANSA_E200_PAD +#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ + (CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define MATRIX_EXIT BUTTON_POWER #define MATRIX_SLEEP_MORE BUTTON_SCROLL_BACK|BUTTON_REPEAT #define MATRIX_SLEEP_LESS BUTTON_SCROLL_FWD|BUTTON_REPEAT diff --git a/apps/plugins/midi/midiplay.c b/apps/plugins/midi/midiplay.c index 3066502dda..1b5d18465b 100644 --- a/apps/plugins/midi/midiplay.c +++ b/apps/plugins/midi/midiplay.c @@ -225,6 +225,14 @@ #define BTN_DOWN BUTTON_DOWN #define BTN_PLAY BUTTON_PLAYPAUSE +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define BTN_QUIT BUTTON_POWER +#define BTN_RIGHT BUTTON_RIGHT +#define BTN_LEFT BUTTON_LEFT +#define BTN_UP BUTTON_UP +#define BTN_DOWN BUTTON_DOWN +#define BTN_PLAY BUTTON_SELECT + #else #error No keymap defined! #endif diff --git a/apps/plugins/minesweeper.c b/apps/plugins/minesweeper.c index d8313fb741..ad67b1dd67 100644 --- a/apps/plugins/minesweeper.c +++ b/apps/plugins/minesweeper.c @@ -297,6 +297,20 @@ CONFIG_KEYPAD == MROBE500_PAD # define MINESWP_DISCOVER BUTTON_PLAYPAUSE # define MINESWP_INFO BUTTON_BACK +#elif (CONFIG_KEYPAD == SANSA_CONNECT_PAD) + +# define MINESWP_SCROLLWHEEL +# define MINESWP_LEFT BUTTON_LEFT +# define MINESWP_RIGHT BUTTON_RIGHT +# define MINESWP_UP BUTTON_UP +# define MINESWP_DOWN BUTTON_DOWN +# define MINESWP_QUIT BUTTON_POWER +# define MINESWP_NEXT BUTTON_SCROLL_FWD +# define MINESWP_PREV BUTTON_SCROLL_BACK +# define MINESWP_TOGGLE BUTTON_NEXT +# define MINESWP_DISCOVER BUTTON_SELECT +# define MINESWP_INFO BUTTON_PREV + #else #error No keymap defined! #endif diff --git a/apps/plugins/mosaique.c b/apps/plugins/mosaique.c index f0f260fc13..ec41c8c02b 100644 --- a/apps/plugins/mosaique.c +++ b/apps/plugins/mosaique.c @@ -188,6 +188,11 @@ #define MOSAIQUE_SPEED BUTTON_PLAYPAUSE #define MOSAIQUE_RESTART BUTTON_BACK +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define MOSAIQUE_QUIT BUTTON_POWER +#define MOSAIQUE_SPEED BUTTON_SELECT +#define MOSAIQUE_RESTART BUTTON_DOWN + #else #error No keymap defined! #endif diff --git a/apps/plugins/mp3_encoder.c b/apps/plugins/mp3_encoder.c index ac6a0baf73..a70e316f06 100644 --- a/apps/plugins/mp3_encoder.c +++ b/apps/plugins/mp3_encoder.c @@ -2507,6 +2507,12 @@ CONFIG_KEYPAD == MROBE500_PAD #define MP3ENC_DONE BUTTON_PLAYPAUSE #define MP3ENC_SELECT BUTTON_SELECT +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define MP3ENC_PREV BUTTON_PREV +#define MP3ENC_NEXT BUTTON_NEXT +#define MP3ENC_DONE BUTTON_DOWN +#define MP3ENC_SELECT BUTTON_SELECT + #else #error No keymap defined! #endif diff --git a/apps/plugins/mpegplayer/mpeg_settings.c b/apps/plugins/mpegplayer/mpeg_settings.c index 093d8ec2c0..90b547893e 100644 --- a/apps/plugins/mpegplayer/mpeg_settings.c +++ b/apps/plugins/mpegplayer/mpeg_settings.c @@ -240,6 +240,14 @@ struct mpeg_settings settings; #define MPEG_START_TIME_DOWN BUTTON_DOWN #define MPEG_START_TIME_EXIT BUTTON_POWER +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define MPEG_START_TIME_SELECT BUTTON_SELECT +#define MPEG_START_TIME_LEFT BUTTON_LEFT +#define MPEG_START_TIME_RIGHT BUTTON_RIGHT +#define MPEG_START_TIME_UP BUTTON_UP +#define MPEG_START_TIME_DOWN BUTTON_DOWN +#define MPEG_START_TIME_EXIT BUTTON_POWER + #else #error No keymap defined! #endif diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c index 2491bb1aec..e3d9865e12 100644 --- a/apps/plugins/mpegplayer/mpegplayer.c +++ b/apps/plugins/mpegplayer/mpegplayer.c @@ -353,6 +353,15 @@ CONFIG_KEYPAD == SANSA_M200_PAD #define MPEG_RW BUTTON_LEFT #define MPEG_FF BUTTON_RIGHT +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define MPEG_MENU BUTTON_POWER +#define MPEG_PAUSE (BUTTON_SELECT | BUTTON_REL) +#define MPEG_STOP (BUTTON_SELECT | BUTTON_REPEAT) +#define MPEG_VOLDOWN BUTTON_VOL_DOWN +#define MPEG_VOLUP BUTTON_VOL_UP +#define MPEG_RW BUTTON_LEFT +#define MPEG_FF BUTTON_RIGHT + #else #error No keymap defined! #endif diff --git a/apps/plugins/oscilloscope.c b/apps/plugins/oscilloscope.c index 52cef65d64..4469a92e12 100644 --- a/apps/plugins/oscilloscope.c +++ b/apps/plugins/oscilloscope.c @@ -331,6 +331,17 @@ #define OSCILLOSCOPE_VOL_UP BUTTON_VOL_UP #define OSCILLOSCOPE_VOL_DOWN BUTTON_VOL_DOWN +#elif (CONFIG_KEYPAD == SANSA_CONNECT_PAD) +#define OSCILLOSCOPE_QUIT BUTTON_POWER +#define OSCILLOSCOPE_DRAWMODE BUTTON_SELECT +#define OSCILLOSCOPE_ADVMODE BUTTON_DOWN +#define OSCILLOSCOPE_ORIENTATION BUTTON_UP +#define OSCILLOSCOPE_PAUSE BUTTON_NEXT +#define OSCILLOSCOPE_SPEED_UP BUTTON_RIGHT +#define OSCILLOSCOPE_SPEED_DOWN BUTTON_LEFT +#define OSCILLOSCOPE_VOL_UP BUTTON_VOL_UP +#define OSCILLOSCOPE_VOL_DOWN BUTTON_VOL_DOWN + #else #error No keymap defined! #endif diff --git a/apps/plugins/pacbox/pacbox.h b/apps/plugins/pacbox/pacbox.h index d9b8ec7460..3c906ac0aa 100644 --- a/apps/plugins/pacbox/pacbox.h +++ b/apps/plugins/pacbox/pacbox.h @@ -254,6 +254,17 @@ #define PACMAN_COIN BUTTON_PLAYPAUSE #define PACMAN_MENU BUTTON_POWER +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD + +#define PACMAN_UP BUTTON_UP +#define PACMAN_DOWN BUTTON_DOWN +#define PACMAN_LEFT BUTTON_LEFT +#define PACMAN_RIGHT BUTTON_RIGHT +#define PACMAN_1UP BUTTON_SELECT +#define PACMAN_2UP BUTTON_NEXT +#define PACMAN_COIN BUTTON_VOL_DOWN +#define PACMAN_MENU BUTTON_POWER + #else #error Keymap not defined! diff --git a/apps/plugins/pegbox.c b/apps/plugins/pegbox.c index babe653e93..3eb6008f76 100644 --- a/apps/plugins/pegbox.c +++ b/apps/plugins/pegbox.c @@ -491,6 +491,25 @@ CONFIG_KEYPAD == MROBE500_PAD #define LVL_DOWN_TEXT "Vol-" #define SELECT_TEXT "SELECT" +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define PEGBOX_SELECT BUTTON_SELECT +#define PEGBOX_QUIT BUTTON_POWER +#define PEGBOX_SAVE BUTTON_VOL_UP +#define PEGBOX_RESTART BUTTON_VOL_DOWN +#define PEGBOX_LVL_UP BUTTON_NEXT +#define PEGBOX_LVL_DOWN BUTTON_PREV +#define PEGBOX_UP BUTTON_UP +#define PEGBOX_DOWN BUTTON_DOWN +#define PEGBOX_RIGHT BUTTON_RIGHT +#define PEGBOX_LEFT BUTTON_LEFT + +#define SAVE_TEXT "Vol+" +#define QUIT_TEXT "POWER" +#define RESTART_TEXT "Vol-" +#define LVL_UP_TEXT "NEXT" +#define LVL_DOWN_TEXT "PREV" +#define SELECT_TEXT "SELECT" + #else #error Unsupported keymap! #endif diff --git a/apps/plugins/plugin.lds b/apps/plugins/plugin.lds index 7a20ddd219..1da9065760 100644 --- a/apps/plugins/plugin.lds +++ b/apps/plugins/plugin.lds @@ -120,7 +120,7 @@ OUTPUT_FORMAT(elf32-littlemips) #define IRAMSIZE 0 #elif CONFIG_CPU==DM320 -#define DRAMORIG 0x00900000 + STUBOFFSET +#define DRAMORIG CONFIG_SDRAM_START + STUBOFFSET #define IRAM DRAM /* The bit of IRAM that is available is used in the core */ #define IRAMSIZE 0 diff --git a/apps/plugins/pong.c b/apps/plugins/pong.c index 37d71155ee..d3875f39e4 100644 --- a/apps/plugins/pong.c +++ b/apps/plugins/pong.c @@ -105,7 +105,8 @@ #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ - (CONFIG_KEYPAD == SANSA_M200_PAD) + (CONFIG_KEYPAD == SANSA_M200_PAD) || \ + (CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define PONG_QUIT BUTTON_POWER #define PONG_PAUSE BUTTON_SELECT #define PONG_LEFT_UP BUTTON_LEFT diff --git a/apps/plugins/reversi/reversi-gui.h b/apps/plugins/reversi/reversi-gui.h index baeb343005..a36efe51cb 100644 --- a/apps/plugins/reversi/reversi-gui.h +++ b/apps/plugins/reversi/reversi-gui.h @@ -108,7 +108,8 @@ #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ (CONFIG_KEYPAD == SANSA_C200_PAD) || \ (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ -(CONFIG_KEYPAD == SANSA_M200_PAD) +(CONFIG_KEYPAD == SANSA_M200_PAD) || \ +(CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define REVERSI_BUTTON_QUIT BUTTON_POWER #define REVERSI_BUTTON_UP BUTTON_UP #define REVERSI_BUTTON_DOWN BUTTON_DOWN diff --git a/apps/plugins/rockblox.c b/apps/plugins/rockblox.c index 07e9c16b79..9354d10f5a 100644 --- a/apps/plugins/rockblox.c +++ b/apps/plugins/rockblox.c @@ -369,6 +369,16 @@ #define ROCKBLOX_DROP BUTTON_PLAYPAUSE #define ROCKBLOX_RESTART BUTTON_BACK +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define ROCKBLOX_OFF BUTTON_POWER +#define ROCKBLOX_ROTATE_CW BUTTON_NEXT +#define ROCKBLOX_ROTATE_CCW BUTTON_PREV +#define ROCKBLOX_DOWN BUTTON_DOWN +#define ROCKBLOX_LEFT BUTTON_LEFT +#define ROCKBLOX_RIGHT BUTTON_RIGHT +#define ROCKBLOX_DROP BUTTON_SELECT +#define ROCKBLOX_RESTART BUTTON_VOL_DOWN + #else #error No keymap defined! #endif diff --git a/apps/plugins/rockblox1d.c b/apps/plugins/rockblox1d.c index 073bc30f06..49219c2eba 100644 --- a/apps/plugins/rockblox1d.c +++ b/apps/plugins/rockblox1d.c @@ -56,7 +56,8 @@ #elif CONFIG_KEYPAD == SANSA_E200_PAD || \ CONFIG_KEYPAD == SANSA_C200_PAD || \ CONFIG_KEYPAD == SANSA_CLIP_PAD || \ - CONFIG_KEYPAD == SANSA_M200_PAD + CONFIG_KEYPAD == SANSA_M200_PAD || \ + CONFIG_KEYPAD == SANSA_CONNECT_PAD #define ONEDROCKBLOX_DOWN BUTTON_SELECT #define ONEDROCKBLOX_QUIT BUTTON_POWER diff --git a/apps/plugins/rockboy/rockboy.c b/apps/plugins/rockboy/rockboy.c index f3ca002e5d..37f0566b21 100644 --- a/apps/plugins/rockboy/rockboy.c +++ b/apps/plugins/rockboy/rockboy.c @@ -330,6 +330,18 @@ static void setoptions (void) options.SELECT = (BUTTON_PLAYPAUSE | BUTTON_REPEAT); options.MENU = (BUTTON_SELECT | BUTTON_REPEAT); +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD + options.UP = BUTTON_UP; + options.DOWN = BUTTON_DOWN; + options.LEFT = BUTTON_LEFT; + options.RIGHT = BUTTON_RIGHT; + + options.A = BUTTON_VOL_UP; + options.B = BUTTON_VOL_DOWN; + options.START = BUTTON_PREV; + options.SELECT = BUTTON_NEXT; + options.MENU = BUTTON_SELECT; + #else #error No Keymap Defined! #endif diff --git a/apps/plugins/rockpaint.c b/apps/plugins/rockpaint.c index 9ec289fce4..7f16bf2763 100644 --- a/apps/plugins/rockpaint.c +++ b/apps/plugins/rockpaint.c @@ -232,6 +232,17 @@ #define ROCKPAINT_LEFT BUTTON_LEFT #define ROCKPAINT_RIGHT BUTTON_RIGHT +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define ROCKPAINT_QUIT BUTTON_POWER +#define ROCKPAINT_DRAW BUTTON_SELECT +#define ROCKPAINT_MENU BUTTON_VOL_DOWN +#define ROCKPAINT_TOOLBAR BUTTON_PREV +#define ROCKPAINT_TOOLBAR2 BUTTON_NEXT +#define ROCKPAINT_UP BUTTON_UP +#define ROCKPAINT_DOWN BUTTON_DOWN +#define ROCKPAINT_LEFT BUTTON_LEFT +#define ROCKPAINT_RIGHT BUTTON_RIGHT + #else #error "Please define keys for this keypad" #endif diff --git a/apps/plugins/sliding_puzzle.c b/apps/plugins/sliding_puzzle.c index 1d857c0198..653099a547 100644 --- a/apps/plugins/sliding_puzzle.c +++ b/apps/plugins/sliding_puzzle.c @@ -254,6 +254,15 @@ CONFIG_KEYPAD == MROBE500_PAD #define PUZZLE_SHUFFLE BUTTON_PLAYPAUSE #define PUZZLE_PICTURE BUTTON_SELECT +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define PUZZLE_QUIT BUTTON_POWER +#define PUZZLE_LEFT BUTTON_LEFT +#define PUZZLE_RIGHT BUTTON_RIGHT +#define PUZZLE_UP BUTTON_UP +#define PUZZLE_DOWN BUTTON_DOWN +#define PUZZLE_SHUFFLE BUTTON_VOL_DOWN +#define PUZZLE_PICTURE BUTTON_SELECT + #else #error No keymap defined! #endif diff --git a/apps/plugins/snake.c b/apps/plugins/snake.c index 2223887f94..09e72a5fff 100644 --- a/apps/plugins/snake.c +++ b/apps/plugins/snake.c @@ -105,7 +105,8 @@ dir is the current direction of the snake - 0=up, 1=right, 2=down, 3=left; #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ (CONFIG_KEYPAD == SANSA_C200_PAD) || \ (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ - (CONFIG_KEYPAD == SANSA_M200_PAD) + (CONFIG_KEYPAD == SANSA_M200_PAD) || \ + (CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define SNAKE_QUIT BUTTON_POWER #define SNAKE_LEFT BUTTON_LEFT #define SNAKE_RIGHT BUTTON_RIGHT diff --git a/apps/plugins/snake2.c b/apps/plugins/snake2.c index c23772ab1c..0e7b499271 100644 --- a/apps/plugins/snake2.c +++ b/apps/plugins/snake2.c @@ -200,7 +200,8 @@ Head and Tail are stored #define SNAKE2_PLAYPAUSE_TEXT "Select" #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ -(CONFIG_KEYPAD == SANSA_C200_PAD) +(CONFIG_KEYPAD == SANSA_C200_PAD) || \ +(CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define SNAKE2_LEFT BUTTON_LEFT #define SNAKE2_RIGHT BUTTON_RIGHT #define SNAKE2_UP BUTTON_UP diff --git a/apps/plugins/snow.c b/apps/plugins/snow.c index 2a3ba17fcc..8a2de39707 100644 --- a/apps/plugins/snow.c +++ b/apps/plugins/snow.c @@ -59,7 +59,8 @@ (CONFIG_KEYPAD == ONDAVX747_PAD) || \ (CONFIG_KEYPAD == ONDAVX777_PAD) || \ (CONFIG_KEYPAD == GIGABEAT_PAD) || \ -(CONFIG_KEYPAD == IAUDIO_X5M5_PAD) +(CONFIG_KEYPAD == IAUDIO_X5M5_PAD) || \ +(CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define SNOW_QUIT BUTTON_POWER #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD) diff --git a/apps/plugins/sokoban.c b/apps/plugins/sokoban.c index c5ba706047..ddc95290da 100644 --- a/apps/plugins/sokoban.c +++ b/apps/plugins/sokoban.c @@ -511,6 +511,21 @@ #define BUTTON_SAVE (BUTTON_SELECT|BUTTON_REPEAT) #define BUTTON_SAVE_NAME "SELECT LONG" +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define SOKOBAN_LEFT BUTTON_LEFT +#define SOKOBAN_RIGHT BUTTON_RIGHT +#define SOKOBAN_UP BUTTON_UP +#define SOKOBAN_DOWN BUTTON_DOWN +#define SOKOBAN_MENU BUTTON_POWER +#define SOKOBAN_UNDO BUTTON_PREV +#define SOKOBAN_REDO BUTTON_NEXT +#define SOKOBAN_LEVEL_DOWN BUTTON_VOL_DOWN +#define SOKOBAN_LEVEL_REPEAT (BUTTON_NEXT|BUTTON_PREV) +#define SOKOBAN_LEVEL_UP BUTTON_VOL_UP +#define SOKOBAN_PAUSE BUTTON_SELECT +#define BUTTON_SAVE (BUTTON_SELECT|BUTTON_REPEAT) +#define BUTTON_SAVE_NAME "SELECT LONG" + #else #error No keymap defined! #endif @@ -1487,6 +1502,13 @@ static int sokoban_menu(void) rb->lcd_putsxy(3, 36, "[PREV] Previous Level"); rb->lcd_putsxy(3, 46, "[PLAY] Restart Level"); rb->lcd_putsxy(3, 56, "[NEXT] Next Level"); +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD + rb->lcd_putsxy(3, 6, "[POWER] Menu"); + rb->lcd_putsxy(3, 16, "[PREV] Undo"); + rb->lcd_putsxy(3, 26, "[NEXT] Redo"); + rb->lcd_putsxy(3, 36, "[VOL-] Previous Level"); + rb->lcd_putsxy(3, 46, "[NEXT+PREV] Restart Level"); + rb->lcd_putsxy(3, 56, "[VOL+] Next Level"); #endif #ifdef HAVE_TOUCHSCREEN diff --git a/apps/plugins/solitaire.c b/apps/plugins/solitaire.c index b011d1d248..91ef346221 100644 --- a/apps/plugins/solitaire.c +++ b/apps/plugins/solitaire.c @@ -526,6 +526,24 @@ CONFIG_KEYPAD == MROBE500_PAD # define HK_CUR2STACK "DOUBLE SELECT" # define HK_REM2STACK "LEFT" +#elif (CONFIG_KEYPAD == SANSA_CONNECT_PAD) +# define SOL_QUIT BUTTON_POWER +# define SOL_UP BUTTON_UP +# define SOL_DOWN BUTTON_DOWN +# define SOL_LEFT BUTTON_SCROLL_BACK +# define SOL_RIGHT BUTTON_SCROLL_FWD +# define SOL_MOVE BUTTON_SELECT +# define SOL_DRAW BUTTON_VOL_UP +# define SOL_REM2CUR BUTTON_LEFT +# define SOL_CUR2STACK_PRE BUTTON_VOL_DOWN +# define SOL_CUR2STACK BUTTON_NEXT +# define SOL_REM2STACK BUTTON_PREV +# define HK_MOVE "SELECT" +# define HK_DRAW "Vol+" +# define HK_REM2CUR "LEFT" +# define HK_CUR2STACK "NEXT" +# define HK_REM2STACK "PREV" + #else #error No keymap defined! #endif diff --git a/apps/plugins/spacerocks.c b/apps/plugins/spacerocks.c index d0826408e0..0c03a3183b 100644 --- a/apps/plugins/spacerocks.c +++ b/apps/plugins/spacerocks.c @@ -268,6 +268,16 @@ #define AST_RIGHT BUTTON_RIGHT #define AST_FIRE BUTTON_SELECT +#elif (CONFIG_KEYPAD == SANSA_CONNECT_PAD) + +#define ALT_PAUSE BUTTON_VOL_DOWN +#define AST_QUIT BUTTON_POWER +#define AST_THRUST BUTTON_UP +#define AST_HYPERSPACE BUTTON_DOWN +#define AST_LEFT BUTTON_LEFT +#define AST_RIGHT BUTTON_RIGHT +#define AST_FIRE BUTTON_SELECT + #else #error No keymap defined! #endif diff --git a/apps/plugins/star.c b/apps/plugins/star.c index ebdaca58c3..620cddf77e 100644 --- a/apps/plugins/star.c +++ b/apps/plugins/star.c @@ -463,6 +463,23 @@ #define STAR_LEVEL_DOWN_NAME "Vol-" #define STAR_LEVEL_REPEAT_NAME "BACK LONG" +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD + +#define STAR_QUIT BUTTON_POWER +#define STAR_LEFT BUTTON_LEFT +#define STAR_RIGHT BUTTON_RIGHT +#define STAR_UP BUTTON_UP +#define STAR_DOWN BUTTON_DOWN +#define STAR_TOGGLE_CONTROL BUTTON_SELECT +#define STAR_LEVEL_UP BUTTON_VOL_UP +#define STAR_LEVEL_DOWN BUTTON_VOL_DOWN +#define STAR_LEVEL_REPEAT (BUTTON_PREV | BUTTON_REPEAT) +#define STAR_TOGGLE_CONTROL_NAME "SELECT" +#define STAR_QUIT_NAME "POWER" +#define STAR_LEVEL_UP_NAME "Vol+" +#define STAR_LEVEL_DOWN_NAME "Vol-" +#define STAR_LEVEL_REPEAT_NAME "PREV LONG" + #else #error No keymap defined! #endif diff --git a/apps/plugins/starfield.c b/apps/plugins/starfield.c index 6ead68fb3a..e3b5634978 100644 --- a/apps/plugins/starfield.c +++ b/apps/plugins/starfield.c @@ -61,7 +61,8 @@ #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ (CONFIG_KEYPAD == SANSA_C200_PAD) || \ (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ - (CONFIG_KEYPAD == SANSA_M200_PAD) + (CONFIG_KEYPAD == SANSA_M200_PAD) || \ + (CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define STARFIELD_QUIT BUTTON_POWER #define STARFIELD_INCREASE_ZMOVE BUTTON_UP #define STARFIELD_DECREASE_ZMOVE BUTTON_DOWN diff --git a/apps/plugins/stats.c b/apps/plugins/stats.c index 1bfd10788a..c5ff31e2bd 100644 --- a/apps/plugins/stats.c +++ b/apps/plugins/stats.c @@ -58,7 +58,8 @@ static bool cancel; #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ (CONFIG_KEYPAD == SANSA_C200_PAD) || \ (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ -(CONFIG_KEYPAD == SANSA_M200_PAD) +(CONFIG_KEYPAD == SANSA_M200_PAD) || \ +(CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define STATS_STOP BUTTON_POWER #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD) diff --git a/apps/plugins/stopwatch.c b/apps/plugins/stopwatch.c index 03f183e916..94785dc352 100644 --- a/apps/plugins/stopwatch.c +++ b/apps/plugins/stopwatch.c @@ -255,6 +255,14 @@ #define STOPWATCH_SCROLL_UP BUTTON_UP #define STOPWATCH_SCROLL_DOWN BUTTON_DOWN +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define STOPWATCH_QUIT BUTTON_POWER +#define STOPWATCH_START_STOP BUTTON_SELECT +#define STOPWATCH_RESET_TIMER BUTTON_LEFT +#define STOPWATCH_LAP_TIMER BUTTON_RIGHT +#define STOPWATCH_SCROLL_UP BUTTON_UP +#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN + #else #error No keymap defined! #endif diff --git a/apps/plugins/sudoku/sudoku.h b/apps/plugins/sudoku/sudoku.h index 86a8b33a35..456e4fd9ee 100644 --- a/apps/plugins/sudoku/sudoku.h +++ b/apps/plugins/sudoku/sudoku.h @@ -318,6 +318,17 @@ #define SUDOKU_BUTTON_TOGGLEBACK BUTTON_DOWN #define SUDOKU_BUTTON_POSSIBLE BUTTON_PLAYPAUSE +#elif (CONFIG_KEYPAD == SANSA_CONNECT_PAD) +#define SUDOKU_BUTTON_QUIT BUTTON_POWER +#define SUDOKU_BUTTON_UP BUTTON_UP +#define SUDOKU_BUTTON_DOWN BUTTON_DOWN +#define SUDOKU_BUTTON_LEFT BUTTON_LEFT +#define SUDOKU_BUTTON_RIGHT BUTTON_RIGHT +#define SUDOKU_BUTTON_TOGGLEBACK BUTTON_PREV +#define SUDOKU_BUTTON_TOGGLE BUTTON_NEXT +#define SUDOKU_BUTTON_MENU BUTTON_SELECT +#define SUDOKU_BUTTON_POSSIBLE BUTTON_VOL_DOWN + #else #error No keymap defined! #endif diff --git a/apps/plugins/superdom.c b/apps/plugins/superdom.c index 2dfd142bde..b4e25afdb1 100644 --- a/apps/plugins/superdom.c +++ b/apps/plugins/superdom.c @@ -190,6 +190,14 @@ char buf[255]; #define SUPERDOM_RIGHT BUTTON_RIGHT #define SUPERDOM_CANCEL BUTTON_BACK +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define SUPERDOM_OK BUTTON_SELECT +#define SUPERDOM_UP BUTTON_UP +#define SUPERDOM_DOWN BUTTON_DOWN +#define SUPERDOM_LEFT BUTTON_LEFT +#define SUPERDOM_RIGHT BUTTON_RIGHT +#define SUPERDOM_CANCEL BUTTON_POWER + #endif #ifdef HAVE_TOUCHSCREEN diff --git a/apps/plugins/text_viewer/tv_button.h b/apps/plugins/text_viewer/tv_button.h index 3de276228c..697076e643 100644 --- a/apps/plugins/text_viewer/tv_button.h +++ b/apps/plugins/text_viewer/tv_button.h @@ -424,6 +424,18 @@ #define TV_AUTOSCROLL BUTTON_BACK #define TV_BOOKMARK BUTTON_PLAYPAUSE +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define TV_QUIT BUTTON_POWER +#define TV_SCROLL_UP BUTTON_UP +#define TV_SCROLL_DOWN BUTTON_DOWN +#define TV_SCREEN_LEFT BUTTON_LEFT +#define TV_SCREEN_RIGHT BUTTON_RIGHT +#define TV_MENU BUTTON_SELECT +#define TV_AUTOSCROLL BUTTON_VOL_DOWN +#define TV_LINE_UP BUTTON_SCROLL_BACK +#define TV_LINE_DOWN BUTTON_SCROLL_FWD +#define TV_BOOKMARK (BUTTON_DOWN|BUTTON_SELECT) + #else #error No keymap defined! #endif diff --git a/apps/plugins/vu_meter.c b/apps/plugins/vu_meter.c index 27f9fe06df..cf66070c6b 100644 --- a/apps/plugins/vu_meter.c +++ b/apps/plugins/vu_meter.c @@ -327,6 +327,17 @@ #define LABEL_MENU "BACK" #define LABEL_VOLUME "UP/DOWN" +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define VUMETER_QUIT BUTTON_POWER +#define VUMETER_HELP BUTTON_NEXT +#define VUMETER_MENU BUTTON_PREV +#define VUMETER_UP BUTTON_UP +#define VUMETER_DOWN BUTTON_DOWN +#define LABEL_HELP "NEXT" +#define LABEL_QUIT "POWER" +#define LABEL_MENU "PREV" +#define LABEL_VOLUME "VOL+/VOL-" + #else #error No keymap defined! #endif diff --git a/apps/plugins/wormlet.c b/apps/plugins/wormlet.c index bb3526991d..016c4ad31b 100644 --- a/apps/plugins/wormlet.c +++ b/apps/plugins/wormlet.c @@ -310,6 +310,16 @@ CONFIG_KEYPAD == MROBE500_PAD #define BTN_QUIT BUTTON_POWER #define BTN_STOPRESET BUTTON_BACK +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD + +#define BTN_DIR_UP BUTTON_UP +#define BTN_DIR_DOWN BUTTON_DOWN +#define BTN_DIR_LEFT BUTTON_LEFT +#define BTN_DIR_RIGHT BUTTON_RIGHT +#define BTN_STARTPAUSE BUTTON_SELECT +#define BTN_QUIT BUTTON_POWER +#define BTN_STOPRESET BUTTON_VOL_DOWN + #else #error No keymap defined! #endif diff --git a/apps/plugins/xobox.c b/apps/plugins/xobox.c index 33cf823c4d..8de0c8fe16 100644 --- a/apps/plugins/xobox.c +++ b/apps/plugins/xobox.c @@ -268,6 +268,15 @@ CONFIG_KEYPAD == MROBE500_PAD #define DOWN BUTTON_DOWN #define PAUSE BUTTON_PLAYPAUSE +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD + +#define QUIT BUTTON_POWER +#define LEFT BUTTON_LEFT +#define RIGHT BUTTON_RIGHT +#define UP BUTTON_UP +#define DOWN BUTTON_DOWN +#define PAUSE BUTTON_SELECT + #else #error No keymap defined! #endif diff --git a/apps/plugins/zxbox/keymaps.h b/apps/plugins/zxbox/keymaps.h index 5f216fda14..4e5d73a343 100644 --- a/apps/plugins/zxbox/keymaps.h +++ b/apps/plugins/zxbox/keymaps.h @@ -89,7 +89,8 @@ #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ (CONFIG_KEYPAD == SANSA_C200_PAD) || \ (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ - (CONFIG_KEYPAD == SANSA_M200_PAD) + (CONFIG_KEYPAD == SANSA_M200_PAD) || \ + (CONFIG_KEYPAD == SANSA_CONNECT_PAD) #define ZX_SELECT BUTTON_SELECT #define ZX_MENU BUTTON_POWER #define ZX_LEFT BUTTON_LEFT diff --git a/apps/plugins/zxbox/zxbox_keyb.c b/apps/plugins/zxbox/zxbox_keyb.c index 92a56a8a4d..fc5ed41169 100644 --- a/apps/plugins/zxbox/zxbox_keyb.c +++ b/apps/plugins/zxbox/zxbox_keyb.c @@ -117,7 +117,8 @@ (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ (CONFIG_KEYPAD == SANSA_M200_PAD) || \ (CONFIG_KEYPAD == SANSA_FUZE_PAD) || \ -(CONFIG_KEYPAD == MROBE100_PAD) +(CONFIG_KEYPAD == MROBE100_PAD) || \ +(CONFIG_KEYPAD == SANSA_CONNECT_PAD) /* TODO: Check keyboard mappings */ diff --git a/bootloader/SOURCES b/bootloader/SOURCES index 1725939fa3..4678175bb6 100644 --- a/bootloader/SOURCES +++ b/bootloader/SOURCES @@ -70,4 +70,7 @@ mpio_hd200_hd300.c #elif defined(RK27_GENERIC) || defined(HM60X) || defined(HM801) rk27xx.c show_logo.c +#elif defined(SANSA_CONNECT) +sansaconnect.c +show_logo.c #endif diff --git a/bootloader/sansaconnect.c b/bootloader/sansaconnect.c new file mode 100644 index 0000000000..9ef831f0b3 --- /dev/null +++ b/bootloader/sansaconnect.c @@ -0,0 +1,135 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id: $ +* +* Copyright (C) 2011 by Tomasz Moń +* +* All files in this archive are subject to the GNU General Public License. +* See the file COPYING in the source tree root for full license agreement. +* +* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +* KIND, either express or implied. +* +****************************************************************************/ + +#include "system.h" +#include "lcd.h" +#include "kernel.h" +#include "thread.h" +#include "storage.h" +#include "ata-target.h" +#include "disk.h" +#include "font.h" +#include "backlight.h" +#include "button.h" +#include "common.h" +#include "version.h" +#include "uart-target.h" +#include "power.h" + +extern void show_logo(void); + +void main(void) +{ + unsigned char* loadbuffer; + int buffer_size; + int(*kernel_entry)(void); + int ret; + int btn; + + /* Make sure interrupts are disabled */ + set_irq_level(IRQ_DISABLED); + set_fiq_status(FIQ_DISABLED); + system_init(); + kernel_init(); + + /* Now enable interrupts */ + set_irq_level(IRQ_ENABLED); + set_fiq_status(FIQ_ENABLED); + backlight_init(); + lcd_init(); + font_init(); + button_init(); + +#ifdef HAVE_LCD_ENABLE + lcd_enable(true); +#endif + lcd_setfont(FONT_SYSFIXED); + reset_screen(); + show_logo(); + + btn = button_read_device(); + + printf("Rockbox boot loader"); + printf("Version " RBVERSION); + + ret = storage_init(); + if(ret) + printf("SD error: %d", ret); + + disk_init(IF_MD(0)); + + ret = disk_mount_all(); + if (ret <= 0) + error(EDISK, ret, true); + + if (btn & BUTTON_PREV) + { + printf("Loading OF firmware..."); + printf("Loading vmlinux.bin..."); + loadbuffer = (unsigned char*)0x01008000; + buffer_size = 0x200000; + + ret = load_raw_firmware(loadbuffer, "/vmlinux.bin", buffer_size); + + if (ret < 0) + { + printf("Unable to load vmlinux.bin"); + } + else + { + printf("Loading initrd.bin..."); + loadbuffer = (unsigned char*)0x04400020; + buffer_size = 0x200000; + ret = load_raw_firmware(loadbuffer, "/initrd.bin", buffer_size); + } + + if (ret > 0) + { + system_prepare_fw_start(); + + kernel_entry = (void*)0x01008000; + ret = kernel_entry(); + printf("FAILED to boot OF"); + } + } + + printf("Loading Rockbox firmware..."); + + loadbuffer = (unsigned char*)CONFIG_SDRAM_START; + buffer_size = 0x1000000; + + ret = load_firmware(loadbuffer, BOOTFILE, buffer_size); + + if(ret < 0) + { + error(EBOOTFILE, ret, true); + } + else if(ret == EOK) + { + system_prepare_fw_start(); + + kernel_entry = (void*) loadbuffer; + ret = kernel_entry(); + printf("FAILED!"); + } + + storage_sleepnow(); + + while(1); +} diff --git a/firmware/SOURCES b/firmware/SOURCES index 6a84b5fc11..b918a19418 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -355,6 +355,8 @@ drivers/audio/uda1341.c drivers/audio/cs42l55.c #elif defined (HAVE_RK27XX_CODEC) drivers/audio/rk27xx_codec.c +#elif defined(HAVE_AIC3X) +drivers/audio/aic3x.c #elif defined (HAVE_DUMMY_CODEC) drivers/audio/dummy_codec.c #endif /* defined(HAVE_*) */ @@ -1064,6 +1066,9 @@ target/arm/bits-armv4.S target/arm/tms320dm320/debug-dm320.c target/arm/tms320dm320/dsp-dm320.c target/arm/tms320dm320/i2c-dm320.c +#ifdef HAVE_SOFTWARE_I2C +drivers/generic_i2c.c +#endif target/arm/tms320dm320/kernel-dm320.c target/arm/tms320dm320/spi-dm320.c target/arm/tms320dm320/system-dm320.c @@ -1112,6 +1117,24 @@ target/arm/tms320dm320/creative-zvm/usb-creativezvm.c #endif /* SIMULATOR */ #endif /* CREATIVE_ZVx */ +#ifdef SANSA_CONNECT +#ifndef SIMULATOR +target/arm/mmu-arm.S +target/arm/lcd-as-memframe.S +target/arm/tms320dm320/sdmmc-dm320.c +target/arm/tms320dm320/sansa-connect/crt0-board.S +target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c +target/arm/tms320dm320/sansa-connect/adc-sansaconnect.c +target/arm/tms320dm320/sansa-connect/power-sansaconnect.c +target/arm/tms320dm320/sansa-connect/powermgmt-sansaconnect.c +target/arm/tms320dm320/sansa-connect/usb-sansaconnect.c +target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c +target/arm/tms320dm320/sansa-connect/backlight-sansaconnect.c +target/arm/tms320dm320/sansa-connect/pcm-sansaconnect.c +target/arm/tms320dm320/dma-dm320.c +#endif /* SIMULATOR */ +#endif /* SANSA_CONNECT */ + #ifdef MROBE_100 #ifndef SIMULATOR #ifndef BOOTLOADER diff --git a/firmware/drivers/audio/aic3x.c b/firmware/drivers/audio/aic3x.c new file mode 100644 index 0000000000..3284326565 --- /dev/null +++ b/firmware/drivers/audio/aic3x.c @@ -0,0 +1,247 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 "logf.h" +#include "system.h" +#include "string.h" +#include "audio.h" + +#ifdef SANSA_CONNECT +#include "avr-sansaconnect.h" +#endif + +#if CONFIG_I2C == I2C_DM320 +#include "i2c-dm320.h" +#endif +#include "audiohw.h" + +/* (7-bit) address is 0x18, the LSB is read/write flag */ +#define AIC3X_ADDR (0x18 << 1) + +static char volume_left = 0, volume_right = 0; + +const struct sound_settings_info audiohw_settings[] = { + [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN/10, VOLUME_MAX/10, -25}, + /* HAVE_SW_TONE_CONTROLS */ + [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, + [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, + [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, + [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, + [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, +}; + +/* convert tenth of dB volume to master volume register value */ +int tenthdb2master(int db) +{ + /* 0 to -63.0dB in 1dB steps, aic3x can goto -63.5 in 0.5dB steps */ + if (db < VOLUME_MIN) + { + return 0x7E; + } + else if (db >= VOLUME_MAX) + { + return 0x00; + } + else + { + return (-((db)/5)); /* VOLUME_MIN is negative */ + } +} + +static void aic3x_write_reg(unsigned reg, unsigned value) +{ + unsigned char data[2]; + + data[0] = reg; + data[1] = value; + +#if CONFIG_I2C == I2C_DM320 + if (i2c_write(AIC3X_ADDR, data, 2) != 0) +#else + #warning Implement aic3x_write_reg() +#endif + { + logf("AIC3X error reg=0x%x", reg); + return; + } +} + +static void aic3x_apply_volume(void) +{ + unsigned char data[3]; + +#if 0 /* handle page switching onve we use first page at all */ + aic3x_write_reg(0, 0); /* switch to page 0 */ +#endif + + data[0] = AIC3X_LEFT_VOL; + data[1] = volume_left; + data[2] = volume_right; + + /* use autoincrement write */ +#if CONFIG_I2C == I2C_DM320 + if (i2c_write(AIC3X_ADDR, data, 3) != 0) +#else + #warning Implement aic3x_apply_volume() +#endif + { + logf("AIC3X error in apply volume"); + return; + } +} + + +static void audiohw_mute(bool mute) +{ + if (mute) + { + volume_left |= 0x80; + volume_right |= 0x80; + } + else + { + volume_left &= 0x7F; + volume_right &= 0x7F; + } + + aic3x_apply_volume(); +} + +/* public functions */ + +/** + * Init our tlv with default values + */ +void audiohw_init(void) +{ + logf("AIC3X init"); + + /* Do software reset (self-clearing) */ + aic3x_write_reg(AIC3X_SOFT_RESET, 0x80); + + /* ADC fs = fs(ref)/5.5; DAC fs = fs(ref) */ + aic3x_write_reg(AIC3X_SMPL_RATE, 0x90); + + /* Enable PLL. Set Q=16, P=1 */ + aic3x_write_reg(AIC3X_PLL_REG_A, 0x81); + /* PLL J = 53 */ + aic3x_write_reg(AIC3X_PLL_REG_B, 0xD4); + /* PLL D = 5211 */ + aic3x_write_reg(AIC3X_PLL_REG_C, 0x51); + aic3x_write_reg(AIC3X_PLL_REG_D, 0x6C); /* PLL D = 5211 */ + + /* Left DAC plays left channel, Right DAC plays right channel */ + aic3x_write_reg(AIC3X_DATAPATH, 0xA); + + /* Audio data interface */ + /* BCLK and WCLK are outputs (master mode) */ + aic3x_write_reg(AIC3X_DATA_REG_A, 0xC0); + /* right-justified mode */ + aic3x_write_reg(AIC3X_DATA_REG_B, 0x80); + /* data offset = 0 clocks */ + aic3x_write_reg(AIC3X_DATA_REG_C, 0); + + /* GPIO1 used for audio serial data bus ADC word clock */ + aic3x_write_reg(AIC3X_GPIO1_CTRL, 0x10); + + /* power left and right DAC, HPLCOM constant VCM output */ + aic3x_write_reg(AIC3X_DAC_POWER, 0xD0); + /* HPRCOM as constant VCM output. Enable short-circuit protection + (limit current) */ + aic3x_write_reg(AIC3X_HIGH_POWER, 0xC); + + /* driver power-on time 200 ms, ramp-up step time 4 ms */ + aic3x_write_reg(AIC3X_POP_REDUCT, 0x7C); + + /* DAC_L1 routed to HPLOUT, volume analog gain 0xC (-6.0dB) */ + aic3x_write_reg(AIC3X_DAC_L1_VOL, 0x8C); + /* HPLOUT output level 0dB, not muted, fully powered up */ + aic3x_write_reg(AIC3X_HPLOUT_LVL, 0xB); + + /* HPLCOM is muted */ + aic3x_write_reg(AIC3X_HPLCOM_LVL, 0x7); + + /* DAC_R1 routed to HPROUT, volume analog gain 0xC (-6.0 dB) */ + aic3x_write_reg(AIC3X_DAC_R1_VOL, 0x8C); + /* HPROUT output level 0dB, not muted, fully powered up */ + aic3x_write_reg(AIC3X_HPROUT_LVL, 0xB); + + /* DAC_L1 routed to MONO_LOP/M, gain 0x2 (-1.0dB) */ + aic3x_write_reg(AIC3X_DAC_L1_MONO_LOP_M_VOL, 0x92); + /* DAC_R1 routed to MONO_LOP/M, gain 0x2 (-1.0dB) */ + aic3x_write_reg(AIC3X_DAC_R1_MONO_LOP_M_VOL, 0x92); + + /* MONO_LOP output level 6dB, not muted, fully powered up */ + aic3x_write_reg(AIC3X_MONO_LOP_M_LVL, 0x6b); + + /* DAC_L1 routed to LEFT_LOP/M */ + aic3x_write_reg(AIC3X_DAC_L1_LEFT_LOP_M_VOL, 0x80); + /* LEFT_LOP/M output level 0dB, not muted */ + aic3x_write_reg(AIC3X_LEFT_LOP_M_LVL, 0xB); + + /* DAC_R1 routed to RIGHT_LOP/M */ + aic3x_write_reg(AIC3X_DAC_R1_RIGHT_LOP_M_VOL, 0x80); + /* RIGHT_LOP/M output level 0dB, not muted */ + aic3x_write_reg(AIC3X_RIGHT_LOP_M_LVL, 0xB); +} + +void audiohw_postinit(void) +{ + audiohw_mute(false); + + /* Power up Left, Right DAC/LOP, HPLOUT and HPROUT */ + aic3x_write_reg(AIC3X_MOD_POWER, 0xFE); +} + +void audiohw_set_frequency(int fsel) +{ + (void)fsel; + /* TODO */ +} + +void audiohw_set_headphone_vol(int vol_l, int vol_r) +{ + if ((volume_left & 0x7F) == (vol_l & 0x7F) && + (volume_right & 0x7F) == (vol_r & 0x7F)) + { + /* Volume already set to this value */ + return; + } + + volume_left &= 0x80; /* preserve mute bit */ + volume_left |= (vol_l & 0x7F); /* set gain */ + + volume_right &= 0x80; /* preserve mute bit */ + volume_right |= (vol_r & 0x7F); /* set gain */ + + aic3x_apply_volume(); +} + +/* Nice shutdown of AIC3X codec */ +void audiohw_close(void) +{ + audiohw_mute(true); +#ifdef SANSA_CONNECT + avr_hid_reset_codec(); +#endif +} + + diff --git a/firmware/export/aic3x.h b/firmware/export/aic3x.h new file mode 100644 index 0000000000..17e5ea019a --- /dev/null +++ b/firmware/export/aic3x.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 _AIC3X_H_ +#define _AIC3X_H_ + +#define VOLUME_MIN -630 +#define VOLUME_MAX 0 + +extern int tenthdb2master(int db); + +/*** definitions ***/ +extern void audiohw_set_headphone_vol(int vol_l, int vol_r); + +/* Page 0 registers */ +#define AIC3X_PAGE_SELECT 0 +#define AIC3X_SOFT_RESET 1 +#define AIC3X_SMPL_RATE 2 +#define AIC3X_PLL_REG_A 3 +#define AIC3X_PLL_REG_B 4 +#define AIC3X_PLL_REG_C 5 +#define AIC3X_PLL_REG_D 6 +#define AIC3X_DATAPATH 7 +#define AIC3X_DATA_REG_A 8 +#define AIC3X_DATA_REG_B 9 +#define AIC3X_DATA_REG_C 10 + +#define AIC3X_DAC_POWER 37 +#define AIC3X_HIGH_POWER 38 + +#define AIC3X_POP_REDUCT 42 +#define AIC3X_LEFT_VOL 43 +#define AIC3X_RIGHT_VOL 44 + +#define AIC3X_DAC_L1_VOL 47 +#define AIC3X_HPLOUT_LVL 51 + +#define AIC3X_HPLCOM_LVL 58 + +#define AIC3X_DAC_R1_VOL 64 +#define AIC3X_HPROUT_LVL 65 + +#define AIC3X_DAC_L1_MONO_LOP_M_VOL 75 + +#define AIC3X_DAC_R1_MONO_LOP_M_VOL 76 + +#define AIC3X_MONO_LOP_M_LVL 79 + +#define AIC3X_DAC_L1_LEFT_LOP_M_VOL 82 + +#define AIC3X_LEFT_LOP_M_LVL 86 + +#define AIC3X_DAC_R1_RIGHT_LOP_M_VOL 92 +#define AIC3X_RIGHT_LOP_M_LVL 93 +#define AIC3X_MOD_POWER 94 + +#define AIC3X_GPIO1_CTRL 98 + +#endif /*_AIC3X_H_*/ diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h index 6bf4d71810..102d107d8a 100644 --- a/firmware/export/audiohw.h +++ b/firmware/export/audiohw.h @@ -70,6 +70,8 @@ #include "ak4537.h" #elif defined(HAVE_RK27XX_CODEC) #include "rk27xx_codec.h" +#elif defined(HAVE_AIC3X) +#include "aic3x.h" #elif defined(HAVE_CS42L55) #include "cs42l55.h" #elif defined(HAVE_IMX233_CODEC) diff --git a/firmware/export/config.h b/firmware/export/config.h index 55a194817d..2e7b4dc4d6 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -142,6 +142,7 @@ #define RK27XX_GENERIC_PAD 49 #define HM60X_PAD 50 #define HM801_PAD 51 +#define SANSA_CONNECT_PAD 52 /* CONFIG_REMOTE_KEYPAD */ #define H100_REMOTE 1 @@ -229,6 +230,7 @@ #define LCD_SPFD5420A 42 /* rk27xx */ #define LCD_CLIPZIP 43 /* as used by the Sandisk Sansa Clip Zip */ #define LCD_HX8340B 44 /* as used by the HiFiMAN HM-601/HM-602/HM-801 */ +#define LCD_CONNECT 45 /* as used by the Sandisk Sansa Connect */ /* LCD_PIXELFORMAT */ #define HORIZONTAL_PACKING 1 @@ -302,6 +304,7 @@ Lyre prototype 1 */ #define RTC_D2 18 /* Either PCF50606 or PCF50635 */ #define RTC_S35380A 19 #define RTC_IMX233 20 +#define RTC_STM41T62 21 /* ST M41T62 */ /* USB On-the-go */ #define USBOTG_M66591 6591 /* M:Robe 500 */ @@ -314,6 +317,7 @@ Lyre prototype 1 */ #define USBOTG_AS3525v2 3535 /* AMS AS3525v2 FIXME : same as S3C6400X */ #define USBOTG_S3C6400X 6400 /* Samsung S3C6400X, also used in the S5L8701/S5L8702/S5L8720 */ #define USBOTG_RK27XX 2700 /* Rockchip rk27xx */ +#define USBOTG_TNETV105 105 /* TI TNETV105 */ /* Multiple cores */ #define CPU 0 @@ -466,6 +470,8 @@ Lyre prototype 1 */ #include "config/hifimanhm60x.h" #elif defined(HM801) #include "config/hifimanhm801.h" +#elif defined(SANSA_CONNECT) +#include "config/sansaconnect.h" #elif defined(SDLAPP) #include "config/sdlapp.h" #elif defined(ANDROID) diff --git a/firmware/export/config/sansaconnect.h b/firmware/export/config/sansaconnect.h new file mode 100644 index 0000000000..714534d6ad --- /dev/null +++ b/firmware/export/config/sansaconnect.h @@ -0,0 +1,201 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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. + * + ****************************************************************************/ + +/* + * This config file is for the Sansa Connect + */ +#define TARGET_TREE /* this target is using the target tree system */ + +/* This is the absolute address on the bus set by OF bootloader */ +#define CONFIG_SDRAM_START 0x01000000 + +#define SANSA_CONNECT 1 +#define MODEL_NAME "Sandisk Sansa Connect" + +/* For Rolo and boot loader */ +#define MODEL_NUMBER 81 + +/* define this if you have a flash memory storage */ +#define HAVE_FLASH_STORAGE + +/* define this if you use an SD controller */ +#define CONFIG_STORAGE STORAGE_SD + +#define HAVE_MULTIDRIVE +#define NUM_DRIVES 2 +#define HAVE_HOTSWAP +#define HAVE_HOTSWAP_STORAGE_AS_MAIN + +/* define this if you have a bitmap LCD display */ +#define HAVE_LCD_BITMAP + +/* define this if you have a colour LCD */ +#define HAVE_LCD_COLOR + +/* define this if you want album art for this target */ +#define HAVE_ALBUMART + +/* define this to enable bitmap scaling */ +#define HAVE_BMP_SCALING + +/* define this to enable JPEG decoding */ +#define HAVE_JPEG + +/* define this if you have access to the quickscreen */ +#define HAVE_QUICKSCREEN + +/* define this if you have access to the pitchscreen */ +#define HAVE_PITCHSCREEN + +/* 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 + +/* define this if you want viewport clipping enabled for safe LCD functions */ +#define HAVE_VIEWPORT_CLIP + +/* LCD dimensions */ +#define CONFIG_LCD LCD_CONNECT + +#define LCD_WIDTH 240 +#define LCD_HEIGHT 320 + +#define LCD_DEPTH 16 /* 65k colours */ +#define LCD_PIXELFORMAT RGB565 /* rgb565 */ + +#define HAVE_LCD_ENABLE +#ifndef BOOTLOADER +#define HAVE_LCD_SLEEP +#endif + +#define LCD_SLEEP_TIMEOUT (2*HZ) + +#define MAX_ICON_HEIGHT 35 +#define MAX_ICON_WIDTH 35 + + +#define CONFIG_KEYPAD SANSA_CONNECT_PAD + +/* Define this to have CPU bootsted while scrolling in the UI */ +#define HAVE_GUI_BOOST + +/* define this if the target has volume keys which can be used in the lists */ +#define HAVE_VOLUME_IN_LIST + +#define HAVE_MORSE_INPUT + +/* Define this if you do software codec */ +#define CONFIG_CODEC SWCODEC + +//#define HAVE_HARDWARE_BEEP + +/* There is no hardware tone control */ +#define HAVE_SW_TONE_CONTROLS + +#define HAVE_AIC3X + +//#define HW_SAMPR_CAPS SAMPR_CAP_44 | SAMPR_CAP_22 | SAMPR_CAP_11 | SAMPR_CAP_8 + +/* define this if you have a real-time clock */ +//#define CONFIG_RTC RTC_STM41T62 + +/* define this if the unit uses a scrollwheel for navigation */ +#define HAVE_SCROLLWHEEL + +/* Define this for LCD backlight available */ +#define HAVE_BACKLIGHT + +#define HAVE_BACKLIGHT_BRIGHTNESS + +#define CONFIG_BACKLIGHT_FADING BACKLIGHT_FADING_SW_SETTING + +/* Main LCD backlight brightness range and defaults */ +#define MIN_BRIGHTNESS_SETTING 1 +#define MAX_BRIGHTNESS_SETTING 20 +#define DEFAULT_BRIGHTNESS_SETTING 16 /* OF default brightness (80%) */ +#define DEFAULT_DIMNESS_SETTING 6 /* OF default inactive (30%) */ + +/* 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 0x200000 + +#define BATTERY_CAPACITY_DEFAULT 800 /* default battery capacity */ +#define BATTERY_CAPACITY_MIN 700 /* min. capacity selectable */ +#define BATTERY_CAPACITY_MAX 1000 /* max. capacity selectable */ +#define BATTERY_CAPACITY_INC 100 /* capacity increment */ +#define BATTERY_TYPES_COUNT 1 /* only one type */ + +/* define current usage levels */ +#if 0 +/* TODO */ +#define CURRENT_NORMAL 85 +#define CURRENT_BACKLIGHT 200 +#endif + +/* Hardware controlled charging with monitoring */ +//#define CONFIG_CHARGING CHARGING_MONITOR + +#define CONFIG_CPU DM320 + +#define CONFIG_I2C I2C_DM320 +#define HAVE_SOFTWARE_I2C + +/* define this if the hardware can be powered off while charging */ +#define HAVE_POWEROFF_WHILE_CHARGING + +/* The size of the flash ROM */ +#define FLASH_SIZE 0x400000 + +/* Define this to the CPU frequency */ +#define CPU_FREQ 150000000 + +/* Define this if you have ATA power-off control */ +#define HAVE_ATA_POWER_OFF + +/* 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 + +#if 0 +#define HAVE_USBSTACK +#define USB_VENDOR_ID 0x0781 +#define USB_PRODUCT_ID 0x7480 +#endif + +#define INCLUDE_TIMEOUT_API + +/* Define this if you have adjustable CPU frequency */ +#define HAVE_ADJUSTABLE_CPU_FREQ + +#define BOOTFILE_EXT "sansa" +#define BOOTFILE "rockbox." BOOTFILE_EXT +#define BOOTDIR "/.rockbox" + +/* Define this if a programmable hotkey is mapped */ +#define HAVE_HOTKEY diff --git a/firmware/export/dm320.h b/firmware/export/dm320.h index a629586be8..def8508b0b 100644 --- a/firmware/export/dm320.h +++ b/firmware/export/dm320.h @@ -870,6 +870,8 @@ extern unsigned long _ttbstart; #define CLK_MOD2_TMR0 (1 << 1) #define CLK_MOD2_WDT (1 << 0) +#define CLK_SEL0_UART0 (1 << 5) + #define CLK_SEL1_OSD (1 << 12) #define CLK_SEL1_CCD (1 << 8) #define CLK_SEL1_VENCPLL (1 << 4) @@ -884,6 +886,55 @@ extern unsigned long _ttbstart; #define CLK_BYP_DSP (1 << 4) #define CLK_BYP_ARM (1 << 0) +#define CLK_INV_MMC (1 << 0) +#define CLK_INV_VENC (1 << 4) +#define CLK_INV_CCD (1 << 8) +#define CLK_INV_SIF0 (1 << 12) +#define CLK_INV_SIF1 (1 << 13) + +#define MMC_CTRL_DATRST (1 << 0) +#define MMC_CTRL_CMDRST (1 << 1) +#define MMC_CTRL_WIDTH (1 << 2) +#define MMC_CTRL_DMASZEN (1 << 4) +#define MMC_CTRL_TEST2 (1 << 8) +#define MMC_CTRL_PERMDR (1 << 9) +#define MMC_CTRL_PERMDX (1 << 10) + +#define MMC_CMD_CMD_MASK (0x3F) +#define MMC_CMD_PPLEN (1 << 7) +#define MMC_CMD_BSYEXP (1 << 8) +#define MMC_CMD_RSPFMT_SHIFT 9 +#define MMC_CMD_RSPFMT_MASK (3 << MMC_CMD_RSPFMT_SHIFT) +#define MMC_CMD_WRITE (1 << 11) +#define MMC_CMD_STREAM (1 << 12) +#define MMC_CMD_DATA (1 << 13) +#define MMC_CMD_INITCLK (1 << 14) +#define MMC_CMD_DCLR (1 << 15) + +#define MMC_ST0_DATDNE (1 << 0) +#define MMC_ST0_BSYDNE (1 << 1) +#define MMC_ST0_RSPDNE (1 << 2) +#define MMC_ST0_DATA_TIMEOUT (1 << 3) +#define MMC_ST0_CMD_TIMEOUT (1 << 4) +#define MMC_ST0_WR_CRCERR (1 << 5) +#define MMC_ST0_RD_CRCERR (1 << 6) +#define MMC_ST0_RESP_CRCERR (1 << 7) +#define MMC_ST0_DMADNE (1 << 8) +#define MMC_ST0_DXRDY (1 << 9) +#define MMC_ST0_DRRDY (1 << 10) +#define MMC_ST0_DAT3_EDGE (1 << 11) + +#define MMC_ST1_BUSY (1 << 0) +#define MMC_ST1_CLKSTP (1 << 1) +#define MMC_ST1_DXEMPTY (1 << 2) +#define MMC_ST1_DXFULL (1 << 3) +#define MMC_ST1_DAT3ST (1 << 4) + +#define MMC_DMAMODE_RD_WORDSWAP (1 << 10) +#define MMC_DMAMODE_WR_WORDSWAP (1 << 11) +#define MMC_DMAMODE_WRITE (1 << 12) +#define MMC_DMAMODE_ENABLE (1 << 13) +#define MMC_DMAMODE_TIMEOUTIRQ_EN (1 << 14) /* * IO_EINTx bits */ diff --git a/firmware/sound.c b/firmware/sound.c index ec577d6a10..c97ccc243f 100644 --- a/firmware/sound.c +++ b/firmware/sound.c @@ -250,7 +250,7 @@ static void set_prescaled_volume(void) audiohw_set_lineout_vol(tenthdb2master(0), tenthdb2master(0)); #endif -#elif defined(HAVE_TLV320) || defined(HAVE_WM8978) || defined(HAVE_WM8985) || defined(HAVE_IMX233_CODEC) +#elif defined(HAVE_TLV320) || defined(HAVE_WM8978) || defined(HAVE_WM8985) || defined(HAVE_IMX233_CODEC) || defined(HAVE_AIC3X) audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r)); #elif defined(HAVE_JZ4740_CODEC) || defined(HAVE_SDL_AUDIO) || defined(ANDROID) audiohw_set_volume(current_volume); diff --git a/firmware/target/arm/tms320dm320/app.lds b/firmware/target/arm/tms320dm320/app.lds index 1e0d1839c0..4ea22a7902 100644 --- a/firmware/target/arm/tms320dm320/app.lds +++ b/firmware/target/arm/tms320dm320/app.lds @@ -29,7 +29,7 @@ STARTUP(target/arm/tms320dm320/crt0.o) #define DRAMSIZE (MEMORYSIZE * 0x100000) -#define DRAMORIG 0x00900000 +#define DRAMORIG CONFIG_SDRAM_START #define FLASHORIG 0x00100000 #define FLASHSIZE 0x00800000 diff --git a/firmware/target/arm/tms320dm320/boot.lds b/firmware/target/arm/tms320dm320/boot.lds index 2b9f345a23..65649d7268 100644 --- a/firmware/target/arm/tms320dm320/boot.lds +++ b/firmware/target/arm/tms320dm320/boot.lds @@ -28,14 +28,27 @@ STARTUP(target/arm/tms320dm320/crt0.o) #define LCD_TTB_AREA 0x100000*((LCD_BUFFER_SIZE>>19)+1) /* Bootloader only uses/knows about the upper 32 M */ -#define DRAMORIG 0x02900000 +#define DRAMORIG CONFIG_SDRAM_START+0x02000000 #define DRAMSIZE (MEMORYSIZE * 0x80000) #define IRAMORIG 0x00000000 #define IRAMSIZE 0x4000 +#ifdef SANSA_CONNECT +/* Offset in flash from beginning, we don't want overwrite OF bootloader + due to recovery mode and more importantly - hardware block protection. + This offset makes Rockbox bootloader a replacement for OF vmlinux. + In .srr file header add any valid memory address from following + <0x1000000; 0x1300180) u (0x131EAF4; 0x1420000) u (0x1440000; 0x5000000> + ensuring that complete bootloader fits in. + Entry point in .srr file should be 0x120010. */ +#define FLASHOFFSET 0x20010 +#else +#define FLASHOFFSET 0 +#endif + #define FLASHORIG 0x00100000 -#define FLASHSIZE 0x00800000 +#define FLASHSIZE 0x00800000-FLASHOFFSET PRO_STACK_SIZE = 0x2000; IRQ_STACK_SIZE = 0x400; @@ -48,7 +61,7 @@ MEMORY { DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE - FLASH : ORIGIN = FLASHORIG, LENGTH = FLASHSIZE + FLASH : ORIGIN = FLASHORIG+FLASHOFFSET, LENGTH = FLASHSIZE } SECTIONS diff --git a/firmware/target/arm/tms320dm320/debug-dm320.c b/firmware/target/arm/tms320dm320/debug-dm320.c index de17d54843..262d843bfc 100644 --- a/firmware/target/arm/tms320dm320/debug-dm320.c +++ b/firmware/target/arm/tms320dm320/debug-dm320.c @@ -212,6 +212,7 @@ bool dbg_hw_info(void) button = button_get(false); if(button & BUTTON_POWER) done = true; +#if defined(CREATIVE_ZVx) else if(button & BUTTON_LEFT) lcd_set_direct_fb(false); else if(button & BUTTON_RIGHT) @@ -221,6 +222,7 @@ bool dbg_hw_info(void) lcd_putsf(0, line++, " LCD direct FB access? %s", (lcd_get_direct_fb() ? "yes" : "no")); line++; +#endif #endif lcd_puts(0, line++, "[Rockbox info]"); lcd_putsf(0, line++, "current tick: %08x Seconds running: %08d", diff --git a/firmware/target/arm/tms320dm320/dma-dm320.c b/firmware/target/arm/tms320dm320/dma-dm320.c new file mode 100644 index 0000000000..e60102b6fb --- /dev/null +++ b/firmware/target/arm/tms320dm320/dma-dm320.c @@ -0,0 +1,78 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 "kernel.h" +#include "thread.h" +#include "system.h" +#include "dma-target.h" +#include "dm320.h" +#include + +void dma_init(void) +{ + /* TODO */ +} + +/* + Requests channel for peripheral. + Returns channel assigned for caller which must be released after + transfer complete using dma_release_channel(). +*/ +int dma_request_channel(int peripheral, int mode) +{ + /* TODO: proper checking if channel is already taken + currently only SDMMC and DSP uses DMA on this target */ + int channel = -1; + + if (peripheral == DMA_PERIPHERAL_MMCSD) + { + /* Set first DMA channel */ + IO_SDRAM_SDDMASEL = (IO_SDRAM_SDDMASEL & 0xFFE0) | peripheral | + (mode << 3); + channel = 1; + } + else if (peripheral == DMA_PERIPHERAL_DSP) + { + /* Set second DMA channel */ + IO_SDRAM_SDDMASEL = (IO_SDRAM_SDDMASEL & 0xFC1F) | + (peripheral << 5) | + (mode << 8); + channel = 2; + } + else if (peripheral == DMA_PERIPHERAL_SIF) + { + IO_SDRAM_SDDMASEL = (IO_SDRAM_SDDMASEL & 0x83FF) | + (peripheral << 10) | + (mode << 13); + channel = 3; + } + + return channel; +} + +void dma_release_channel(int channel) +{ + (void)channel; + /* TODO */ +} + + diff --git a/firmware/target/arm/tms320dm320/dma-target.h b/firmware/target/arm/tms320dm320/dma-target.h new file mode 100644 index 0000000000..37053b319b --- /dev/null +++ b/firmware/target/arm/tms320dm320/dma-target.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 + +/* These defines match DMA Select bits */ +#define DMA_PERIPHERAL_MTC 0 +#define DMA_PERIPHERAL_SIF 1 +#define DMA_PERIPHERAL_MS 2 +#define DMA_PERIPHERAL_MMCSD 3 +#define DMA_PERIPHERAL_DSP 4 + +/* These defines match DMA Burst bits */ +/* 1 burst DMA - address must be 4 byte aligned */ +#define DMA_MODE_1_BURST 0 +/* 4 burst DMA - address must be 16 byte aligned */ +#define DMA_MODE_4_BURST 1 +/* 8 burst DMA - address must be 32 byte aligned */ +#define DMA_MODE_8_BURST 2 + +void dma_init(void); +int dma_request_channel(int peripheral, int mode); +void dma_release_channel(int channel); + +#endif diff --git a/firmware/target/arm/tms320dm320/i2c-dm320.c b/firmware/target/arm/tms320dm320/i2c-dm320.c index 8bcc84dd8f..990dad0721 100644 --- a/firmware/target/arm/tms320dm320/i2c-dm320.c +++ b/firmware/target/arm/tms320dm320/i2c-dm320.c @@ -7,6 +7,7 @@ * \/ \/ \/ \/ \/ * $Id$ * + * Copyright (C) 2011 by Tomasz Moń * Copyright (C) 2008 by Maurus Cuelenaere * * DM320 I²C driver @@ -24,11 +25,11 @@ #include "thread.h" #include "i2c-dm320.h" -#define I2C_SCS_COND_START 0x0001 -#define I2C_SCS_COND_STOP 0x0002 -#define I2C_SCS_XMIT 0x0004 +#ifdef HAVE_SOFTWARE_I2C +#include "generic_i2c.h" +#endif -#define I2C_TX_ACK (1 << 8) +#ifndef HAVE_SOFTWARE_I2C static struct mutex i2c_mtx; @@ -42,6 +43,12 @@ static inline void i2c_end(void) mutex_unlock(&i2c_mtx); } +#define I2C_SCS_COND_START 0x0001 +#define I2C_SCS_COND_STOP 0x0002 +#define I2C_SCS_XMIT 0x0004 + +#define I2C_TX_ACK (1 << 8) + static inline bool i2c_getack(void) { return (IO_I2C_RXDATA >> 8) & 1; @@ -158,3 +165,126 @@ void i2c_init(void) IO_I2C_SCS &= ~0x8; //set clock to 100 kHz IO_INTC_EINT2 &= ~INTR_EINT2_I2C; // disable I²C interrupt } + +#else /* Software I2C implementation */ + +#ifdef SANSA_CONNECT + /* SDA - GIO35 */ + #define SDA_SET_REG IO_GIO_BITSET2 + #define SDA_CLR_REG IO_GIO_BITCLR2 + #define SOFTI2C_SDA (1 << 3) + /* SCL - GIO36 */ + #define SCL_SET_REG IO_GIO_BITSET2 + #define SCL_CLR_REG IO_GIO_BITCLR2 + #define SOFTI2C_SCL (1 << 4) +#else + #error Configure SDA and SCL lines +#endif + +static int dm320_i2c_bus; + +static void dm320_scl_dir(bool out) +{ + if (out) + { + IO_GIO_DIR2 &= ~(SOFTI2C_SCL); + } + else + { + IO_GIO_DIR2 |= SOFTI2C_SCL; + } +} + +static void dm320_sda_dir(bool out) +{ + if (out) + { + IO_GIO_DIR2 &= ~(SOFTI2C_SDA); + } + else + { + IO_GIO_DIR2 |= SOFTI2C_SDA; + } +} + +static void dm320_scl_out(bool high) +{ + if (high) + { + SCL_SET_REG = SOFTI2C_SCL; + } + else + { + SCL_CLR_REG = SOFTI2C_SCL; + } +} + +static void dm320_sda_out(bool high) +{ + if (high) + { + SDA_SET_REG = SOFTI2C_SDA; + } + else + { + SDA_CLR_REG = SOFTI2C_SDA; + } +} + +static bool dm320_scl_in(void) +{ + return (SCL_SET_REG & SOFTI2C_SCL); +} + +static bool dm320_sda_in(void) +{ + return (SDA_SET_REG & SOFTI2C_SDA); +} + +/* simple delay */ +static void dm320_i2c_delay(int delay) +{ + udelay(delay); +} + +/* interface towards the generic i2c driver */ +static const struct i2c_interface dm320_i2c_interface = { + .scl_dir = dm320_scl_dir, + .sda_dir = dm320_sda_dir, + .scl_out = dm320_scl_out, + .sda_out = dm320_sda_out, + .scl_in = dm320_scl_in, + .sda_in = dm320_sda_in, + .delay = dm320_i2c_delay, + + /* uncalibrated */ + .delay_hd_sta = 1, + .delay_hd_dat = 1, + .delay_su_dat = 1, + .delay_su_sto = 1, + .delay_su_sta = 1, + .delay_thigh = 1 +}; + +void i2c_init(void) +{ +#ifdef SANSA_CONNECT + IO_GIO_FSEL3 &= 0xFF0F; /* GIO35, GIO36 as normal GIO */ + IO_GIO_INV2 &= ~(SOFTI2C_SDA | SOFTI2C_SCL); /* not inverted */ +#endif + + /* generic_i2c takes care of setting direction */ + dm320_i2c_bus = i2c_add_node(&dm320_i2c_interface); +} + +int i2c_write(unsigned short address, const unsigned char* buf, int count) +{ + return i2c_write_data(dm320_i2c_bus, address, -1, buf, count); +} + +int i2c_read(unsigned short address, unsigned char* buf, int count) +{ + return i2c_read_data(dm320_i2c_bus, address, -1, buf, count); +} + +#endif diff --git a/firmware/target/arm/tms320dm320/kernel-dm320.c b/firmware/target/arm/tms320dm320/kernel-dm320.c index 08c50432e4..79206c3413 100644 --- a/firmware/target/arm/tms320dm320/kernel-dm320.c +++ b/firmware/target/arm/tms320dm320/kernel-dm320.c @@ -37,7 +37,7 @@ void tick_start(unsigned int interval_in_ms) /* Setup the Divisor */ IO_TIMER1_TMDIV = (TIMER_FREQ / (10*1000))*interval_in_ms - 1; - + /* Turn Timer1 to Free Run mode */ IO_TIMER1_TMMD = CONFIG_TIMER1_TMMD_FREE_RUN; @@ -45,6 +45,13 @@ void tick_start(unsigned int interval_in_ms) bitset16(&IO_INTC_EINT0, INTR_EINT0_TMR1); } +#ifdef BOOTLOADER +void tick_stop(void) +{ + bitclr16(&IO_CLK_MOD2, CLK_MOD2_TMR1); /* disable TIMER1 clock */ +} +#endif + void TIMER1(void) __attribute__ ((section(".icode"))); void TIMER1(void) { diff --git a/firmware/target/arm/tms320dm320/sansa-connect/adc-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/adc-sansaconnect.c new file mode 100644 index 0000000000..b3e427b9a5 --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/adc-sansaconnect.c @@ -0,0 +1,35 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 "cpu.h" +#include "adc.h" +#include "adc-target.h" +#include "kernel.h" + +void adc_init(void) +{ +} + +/* Called to get the recent ADC reading */ +inline unsigned short adc_read(int channel) +{ + return (short)channel; +} diff --git a/firmware/target/arm/tms320dm320/sansa-connect/adc-target.h b/firmware/target/arm/tms320dm320/sansa-connect/adc-target.h new file mode 100644 index 0000000000..49244b4c3b --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/adc-target.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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_ + +#endif diff --git a/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c new file mode 100644 index 0000000000..3a6a748621 --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c @@ -0,0 +1,461 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id: $ +* +* Copyright (C) 2011 by Tomasz Moń +* +* 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 +#include "config.h" +#include "system.h" +#include "kernel.h" +#include "logf.h" +#include "avr-sansaconnect.h" +#include "uart-target.h" +#include "button.h" +#include "backlight.h" +#include "powermgmt.h" + +//#define BUTTON_DEBUG + +#ifdef BUTTON_DEBUG +#include "lcd-target.h" +#include "lcd.h" +#include "font.h" +#include "common.h" +#endif + +#ifdef BUTTON_DEBUG +#define dbgprintf DEBUGF +#else +#define dbgprintf(...) +#endif + +#define CMD_SYNC 0xAA +#define CMD_CLOSE 0xCC +#define CMD_LCM_POWER 0xC9 +#define LCM_POWER_OFF 0x00 +#define LCM_POWER_ON 0x01 +#define LCM_POWER_SLEEP 0x02 +#define LCM_POWER_WAKE 0x03 +#define LCM_REPOWER_ON 0x04 + +#define CMD_STATE 0xBB +#define CMD_VER 0xBC +#define CMD_WHEEL_EN 0xD0 +#define CMD_SET_INTCHRG 0xD1 +#define CMD_CODEC_RESET 0xD7 +#define CMD_FILL 0xFF + +#define CMD_SYS_CTRL 0xDA +#define SYS_CTRL_POWEROFF 0x00 + +/* protects spi avr commands from concurrent access */ +static struct mutex avr_mtx; + +/* buttons thread */ +#define BTN_INTERRUPT 1 +static int btn = 0; +static bool hold_switch; +#ifndef BOOTLOADER +static long btn_stack[DEFAULT_STACK_SIZE/sizeof(long)]; +static const char btn_thread_name[] = "buttons"; +static struct event_queue btn_queue; +#endif + +static inline unsigned short be2short(unsigned char* buf) +{ + return (unsigned short)((buf[0] << 8) | buf[1]); +} + +#define BUTTON_DIRECT_MASK (BUTTON_LEFT | BUTTON_UP | BUTTON_RIGHT | BUTTON_DOWN | BUTTON_SELECT | BUTTON_VOL_UP | BUTTON_VOL_DOWN | BUTTON_NEXT | BUTTON_PREV) + +#ifndef BOOTLOADER +static void handle_wheel(unsigned char wheel) +{ + static int key = 0; + static unsigned char velocity = 0; + static unsigned long wheel_delta = 1ul << 24; + static unsigned char wheel_prev = 0; + static long next_backlight_on = 0; + static int prev_key = -1; + static int prev_key_post = 0; + + if (TIME_AFTER(current_tick, next_backlight_on)) + { + backlight_on(); + reset_poweroff_timer(); + next_backlight_on = current_tick + HZ/4; + } + + if (wheel_prev < wheel) + { + key = BUTTON_SCROLL_FWD; + velocity = wheel - wheel_prev; + } + else if (wheel_prev > wheel) + { + key = BUTTON_SCROLL_BACK; + velocity = wheel_prev - wheel; + } + + if (prev_key != key && velocity < 2 /* filter "rewinds" */) + { + /* direction reversal */ + prev_key = key; + wheel_delta = 1ul << 24; + return; + } + + /* TODO: take velocity into account */ + if (queue_empty(&button_queue)) + { + if (prev_key_post == key) + { + key |= BUTTON_REPEAT; + } + + /* Post directly, don't update btn as avr doesn't give + interrupt on scroll stop */ + queue_post(&button_queue, key, wheel_delta); + + wheel_delta = 1ul << 24; + + prev_key_post = key; + } + else + { + /* skipped post - increment delta and limit to 7 bits */ + wheel_delta += 1ul << 24; + + if (wheel_delta > (0x7ful << 24)) + wheel_delta = 0x7ful << 24; + } + + wheel_prev = wheel; + + prev_key = key; +} +#endif + +/* buf must be 11-byte array of byte (reply from avr_hid_get_state() */ +static void parse_button_state(unsigned char *buf) +{ + unsigned short main_btns_state = be2short(&buf[4]); +#ifdef BUTTON_DEBUG + unsigned short main_btns_changed = be2short(&buf[6]); +#endif + + /* make sure other bits doesn't conflict with our "free bits" buttons */ + main_btns_state &= BUTTON_DIRECT_MASK; + + if (buf[3] & 0x01) /* is power button pressed? */ + { + main_btns_state |= BUTTON_POWER; + } + + btn = main_btns_state; + +#ifndef BOOTLOADER + /* check if stored hold_switch state changed (prevents lost changes) */ + if ((buf[3] & 0x20) /* hold change notification */ || + (hold_switch != ((buf[3] & 0x02) >> 1))) + { +#endif + hold_switch = (buf[3] & 0x02) >> 1; +#ifdef BUTTON_DEBUG + dbgprintf("HOLD changed (%d)", hold_switch); +#endif +#ifndef BOOTLOADER + backlight_hold_changed(hold_switch); + } +#endif +#ifndef BOOTLOADER + if ((hold_switch == false) && (buf[3] & 0x80)) /* scrollwheel change */ + { + handle_wheel(buf[2]); + } +#endif + +#ifdef BUTTON_DEBUG + if (buf[3] & 0x10) /* power button change */ + { + /* power button state has changed */ + main_btns_changed |= BUTTON_POWER; + } + + if (btn & BUTTON_LEFT) dbgprintf("LEFT"); + if (btn & BUTTON_UP) dbgprintf("UP"); + if (btn & BUTTON_RIGHT) dbgprintf("RIGHT"); + if (btn & BUTTON_DOWN) dbgprintf("DOWN"); + if (btn & BUTTON_SELECT) dbgprintf("SELECT"); + if (btn & BUTTON_VOL_UP) dbgprintf("VOL UP"); + if (btn & BUTTON_VOL_DOWN) dbgprintf("VOL DOWN"); + if (btn & BUTTON_NEXT) dbgprintf("NEXT"); + if (btn & BUTTON_PREV) dbgprintf("PREV"); + if (btn & BUTTON_POWER) dbgprintf("POWER"); + if (btn & BUTTON_HOLD) dbgprintf("HOLD"); + if (btn & BUTTON_SCROLL_FWD) dbgprintf("SCROLL FWD"); + if (btn & BUTTON_SCROLL_BACK) dbgprintf("SCROLL BACK"); +#endif +} + +/* HID Slave Select - GIO14 */ +#define HID_SS (1<<14) + +static inline void select_hid(bool on) +{ + if (on == true) + { + /* SS is active low */ + IO_GIO_BITCLR0 = HID_SS; + } + else + { + IO_GIO_BITSET0 = HID_SS; + } +} + +static void spi_txrx(unsigned char *buf_tx, unsigned char *buf_rx, int n) +{ + int i; + unsigned short rxdata; + + mutex_lock(&avr_mtx); + + bitset16(&IO_CLK_MOD2, CLK_MOD2_SIF1); + IO_SERIAL1_TX_ENABLE = 0x0001; + select_hid(true); + + for (i = 0; i 200 kHz */ + IO_SERIAL1_MODE = 0x6DB; + + mutex_init(&avr_mtx); + + avr_hid_sync(); +} + + +static void avr_hid_get_state(void) +{ + static unsigned char cmd[11] = {CMD_SYNC, CMD_STATE, + CMD_FILL, CMD_FILL, CMD_FILL, CMD_FILL, CMD_FILL, CMD_FILL, CMD_FILL, CMD_FILL, + CMD_CLOSE}; + + static unsigned char buf[11]; + static unsigned char cmd_empty[1] = {0xCC}; + + spi_txrx(cmd, buf, sizeof(cmd)); + + spi_txrx(cmd_empty, NULL, 1); /* request interrupt on button press */ + + parse_button_state(buf); +} + +static void avr_hid_enable_wheel(void) +{ + unsigned char wheel_en[4] = {CMD_SYNC, CMD_WHEEL_EN, 0x01, CMD_CLOSE}; + + spi_txrx(wheel_en, NULL, sizeof(wheel_en)); +} + +/* command that is sent by "hidtool -J 1" issued on every OF boot */ +void avr_hid_enable_charger(void) +{ + unsigned char charger_en[4] = {CMD_SYNC, CMD_SET_INTCHRG, 0x01, CMD_CLOSE}; + + spi_txrx(charger_en, NULL, sizeof(charger_en)); +} + +void avr_hid_lcm_sleep(void) +{ + unsigned char lcm_sleep[4] = {CMD_SYNC, CMD_LCM_POWER, LCM_POWER_SLEEP, CMD_CLOSE}; + + spi_txrx(lcm_sleep, NULL, sizeof(lcm_sleep)); +} + + +void avr_hid_lcm_wake(void) +{ + unsigned char lcm_wake[4] = {CMD_SYNC, CMD_LCM_POWER, LCM_POWER_WAKE, CMD_CLOSE}; + + spi_txrx(lcm_wake, NULL, sizeof(lcm_wake)); +} + +void avr_hid_lcm_power_on(void) +{ + unsigned char lcm_power_on[4] = {CMD_SYNC, CMD_LCM_POWER, LCM_POWER_ON, CMD_CLOSE}; + + spi_txrx(lcm_power_on, NULL, sizeof(lcm_power_on)); +} + +void avr_hid_lcm_power_off(void) +{ + unsigned char lcm_power_off[4] = {CMD_SYNC, CMD_LCM_POWER, LCM_POWER_OFF, CMD_CLOSE}; + + spi_txrx(lcm_power_off, NULL, sizeof(lcm_power_off)); +} + +void avr_hid_reset_codec(void) +{ + unsigned char codec_reset[4] = {CMD_SYNC, CMD_CODEC_RESET, CMD_CLOSE, CMD_FILL}; + + spi_txrx(codec_reset, NULL, sizeof(codec_reset)); +} + +void avr_hid_power_off(void) +{ + unsigned char prg[4] = {CMD_SYNC, CMD_SYS_CTRL, SYS_CTRL_POWEROFF, CMD_CLOSE}; + + spi_txrx(prg, NULL, sizeof(prg)); +} + +#ifndef BOOTLOADER +void btn_thread(void) +{ + struct queue_event ev; + + while (1) + { + queue_wait(&btn_queue, &ev); + + /* Ignore all messages except BTN_INTERRUPT */ + if (ev.id != BTN_INTERRUPT) + continue; + + /* Enable back button interrupt */ + IO_INTC_EINT1 |= INTR_EINT1_EXT0; + + /* Read buttons state */ + avr_hid_get_state(); + + yield(); + + if (queue_empty(&btn_queue) && ((IO_GIO_BITSET0 & 0x1) == 0)) + { + /* for some reason we have lost next interrupt */ + queue_post(&btn_queue, BTN_INTERRUPT, 0); + } + } +} + +void GIO0(void) __attribute__ ((section(".icode"))); +void GIO0(void) +{ + /* Clear interrupt */ + IO_INTC_IRQ1 = (1 << 5); + /* Disable interrupt */ + IO_INTC_EINT1 &= ~INTR_EINT1_EXT0; + + /* interrupt will be enabled back after button read */ + queue_post(&btn_queue, BTN_INTERRUPT, 0); +} +#endif + +void button_init_device(void) +{ + btn = 0; + hold_switch = false; +#ifndef BOOTLOADER + queue_init(&btn_queue, true); + create_thread(btn_thread, btn_stack, sizeof(btn_stack), 0, + btn_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) + IF_COP(, CPU)); +#endif + IO_GIO_DIR0 |= 0x01; /* Set GIO0 as input */ + + /* Enable wheel */ + avr_hid_enable_wheel(); + /* Read button status and tell avr we want interrupt on next change */ + avr_hid_get_state(); + +#ifndef BOOTLOADER + IO_GIO_IRQPORT |= 0x01; /* Enable GIO0 external interrupt */ + IO_GIO_INV0 &= ~0x01; /* Clear INV for GIO0 (falling edge detection) */ + IO_GIO_IRQEDGE &= ~0x01; /* Set edge detection (falling) */ + + /* Enable GIO0 interrupt */ + IO_INTC_EINT1 |= INTR_EINT1_EXT0; +#endif +} + +int button_read_device(void) +{ + if(hold_switch) + return 0; + else + return btn; +} + +bool button_hold(void) +{ + return hold_switch; +} + +void lcd_enable(bool on) +{ + (void)on; +} + diff --git a/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.h b/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.h new file mode 100644 index 0000000000..64b44675f7 --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.h @@ -0,0 +1,38 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id: $ +* +* Copyright (C) 2011 by Tomasz Moń +* +* 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 _AVR_SANSACONNECT_H_ +#define _AVR_SANSACONNECT_H_ + +#include "config.h" + +void avr_hid_init(void); + +void avr_hid_enable_charger(void); + +void avr_hid_lcm_sleep(void); +void avr_hid_lcm_wake(void); +void avr_hid_lcm_power_on(void); +void avr_hid_lcm_power_off(void); +void avr_hid_reset_codec(void); +void avr_hid_power_off(void); + +#endif /* _AVR_SANSACONNECT_H_ */ diff --git a/firmware/target/arm/tms320dm320/sansa-connect/backlight-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/backlight-sansaconnect.c new file mode 100644 index 0000000000..b7989849d7 --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/backlight-sansaconnect.c @@ -0,0 +1,93 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 "backlight-target.h" +#include "backlight.h" +#include "lcd.h" +#include "power.h" +#include "spi-target.h" +#include "lcd-target.h" + +static void _backlight_write_brightness(int brightness) +{ + /* + Maps brightness int to percentage value found in OF + + OF PWM1H + 5% 14 + 10% 140 + 15% 210 + 20% 280 + ... + 95% 1330 + 100% 1400 + */ + if (brightness > 20) + brightness = 20; + else if (brightness < 0) + brightness = 0; + + IO_CLK_PWM1H = brightness*70; +} + +void _backlight_on(void) +{ + /* set GIO34 as PWM1 */ + IO_GIO_FSEL3 = (IO_GIO_FSEL3 & 0xFFF3) | (1 << 2); + +#if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_NO_FADING) + _backlight_write_brightness(backlight_brightness); +#endif +} + +void _backlight_off(void) +{ + _backlight_write_brightness(0); + + bitclr16(&IO_GIO_FSEL3, 0xC); /* set GIO34 to normal GIO */ + bitclr16(&IO_GIO_INV2, (1 << 2)); /* make sure GIO34 is not inverted */ + IO_GIO_BITCLR2 = (1 << 2); /* drive GIO34 low */ +} + +/* Assumes that the backlight has been initialized */ +void _backlight_set_brightness(int brightness) +{ + _backlight_write_brightness(brightness); +} + +void __backlight_dim(bool dim_now) +{ + _backlight_set_brightness(dim_now ? + DEFAULT_BRIGHTNESS_SETTING : + DEFAULT_DIMNESS_SETTING); +} + +bool _backlight_init(void) +{ + IO_CLK_PWM1C = 0x58D; /* as found in OF */ + + _backlight_set_brightness(backlight_brightness); + return true; +} + diff --git a/firmware/target/arm/tms320dm320/sansa-connect/backlight-target.h b/firmware/target/arm/tms320dm320/sansa-connect/backlight-target.h new file mode 100644 index 0000000000..89bd837cee --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/backlight-target.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef BACKLIGHT_TARGET_H +#define BACKLIGHT_TARGET_H + +bool _backlight_init(void); +void _backlight_on(void); +void _backlight_off(void); +void _backlight_set_brightness(int brightness); + +/* true: backlight fades off - false: backlight fades on */ +void __backlight_dim(bool dim); + +#endif diff --git a/firmware/target/arm/tms320dm320/sansa-connect/button-target.h b/firmware/target/arm/tms320dm320/sansa-connect/button-target.h new file mode 100644 index 0000000000..2eb571ae68 --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/button-target.h @@ -0,0 +1,64 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id: $ +* +* Copyright (C) 2011 by Tomasz Moń +* +* 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_ + +#include "config.h" + +#define BUTTON_REMOTE 0 + +/* these definitions match the avr hid reply */ +#define BUTTON_LEFT (1 << 2) +#define BUTTON_UP (1 << 3) +#define BUTTON_RIGHT (1 << 4) +#define BUTTON_DOWN (1 << 5) +#define BUTTON_SELECT (1 << 6) +#define BUTTON_VOL_UP (1 << 10) +#define BUTTON_VOL_DOWN (1 << 11) +#define BUTTON_NEXT (1 << 13) +#define BUTTON_PREV (1 << 14) + +/* following definitions use "free bits" from avr hid reply */ +#define BUTTON_POWER (1 << 0) +#define BUTTON_HOLD (1 << 1) +#define BUTTON_SCROLL_FWD (1 << 7) +#define BUTTON_SCROLL_BACK (1 << 8) + + +#define BUTTON_REMOTE 0 +#define BUTTON_MAIN (BUTTON_LEFT | BUTTON_UP | BUTTON_RIGHT | BUTTON_DOWN |\ + BUTTON_SELECT | BUTTON_VOL_UP | BUTTON_VOL_DOWN |\ + BUTTON_NEXT | BUTTON_PREV | BUTTON_POWER |\ + BUTTON_SCROLL_FWD | BUTTON_SCROLL_BACK) + +#define POWEROFF_BUTTON BUTTON_POWER +#define POWEROFF_COUNT 5 + +#define HAS_BUTTON_HOLD + +void button_init_device(void); +int button_read_device(void); +bool button_hold(void); + +int get_debug_info(int choice); + +#endif /* _BUTTON_TARGET_H_ */ diff --git a/firmware/target/arm/tms320dm320/sansa-connect/crt0-board.S b/firmware/target/arm/tms320dm320/sansa-connect/crt0-board.S new file mode 100644 index 0000000000..debd2cd2be --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/crt0-board.S @@ -0,0 +1,238 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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" + +/* Macro for reading a register */ +.macro mrh register + ldr r1, =\register + ldrh r0, [r1] +.endm + +/* Macro for writing a register */ +.macro mwh register, value + ldr r0, =\value + ldr r1, =\register + strh r0, [r1] +.endm + +/* This version uses a mov to save on the literal pool size. Otherwise it is + * functionally equivalent. + */ +.macro mwhm register, value + mov r0, #\value + ldr r1, =\register + strh r0, [r1] +.endm + + /* + * _init_board: + * This function initializes the specific board this SoC is on. + */ +.section .init, "ax" +.code 32 +.align 0x04 +.global _init_board +.type _init_board, %function + +_init_board: + + /* Setup the EMIF interface timings */ + + /* FLASH interface: + * These are based on the OF setup + */ + /* IO_EMIF_CS0CTRL1 and + * IO_EMIF_CS0CTRL2 + */ + mwh 0x30A00, 0x889A + mwh 0x30A02, 0x1110 + + mwhm 0x30A04, 0 + mwh 0x30A06, 0x1415 + mwh 0x30A08, 0x1109 + + mwh 0x30A0A, 0x1220 + mwh 0x30A0C, 0x1104 + mwh 0x30A0E, 0x0222 + + /* IO_EMIF_CS3CTRL1 and + * IO_EMIF_CS3CTRL2 + */ + mwh 0x30A10, 0x8899 + mwh 0x30A12, 0x5110 + + /* USB interface */ + /* IO_EMIF_CS4CTRL1 and + * IO_EMIF_CS4CTRL2 + */ + mwh 0x30A14, 0x77DF + mwh 0x30A16, 0x7740 + + /* IO_EMIF_BUSCTRL */ + mwhm 0x30A18, 0 + mwhm 0x30A1A, 0 + mwhm 0x30A1C, 0 + mwhm 0x30A1E, 0 + +_clock_setup: + /* Clock initialization */ + + /* IO_CLK_BYP: Bypass the PLLs for the following changes */ + mwh 0x30894, 0x1111 + + /* + * IO_CLK_PLLA + * IO_CLK_PLLB + */ + mwhm 0x30880, 0x00A0 + mwhm 0x30882, 0x1000 + + /* IO_CLK_SEL0 */ + mwh 0x30884, 0x0066 + + /* IO_CLK_SEL1 */ + mwhm 0x30886, 0x0003 + + # IO_CLK_SEL2: ARM, AXL, SDRAM and DSP are from PLLA */ + mwh 0x30888, 0 + + /* IO_CLK_DIV0: Set the slow clock speed for the ARM/AHB */ + mwh 0x3088A, 0x0101 + + /* IO_CLK_DIV1: Accelerator, SDRAM */ + mwh 0x3088C, 0x0102 + + /* IO_CLK_DIV2: DSP, MS Clock */ + mwhm 0x3088E, 0x0200 + + # PLLA &= ~0x1000 (BIC #0x1000) + mrh 0x30880 + bic r0, r0, #0x1000 + strh r0, [r1] + + /* Wait for PLLs to lock before feeding them to the downstream devices */ +_plla_wait: + mrh 0x30880 + bic r0, r0, #0x7F + tst r0, r0 + beq _plla_wait + + /* IO_CLK_BYP: Enable PLL feeds */ + mwhm 0x30894, 0x0 + + /* IO_CLK_MOD0 */ + mwh 0x30898, 0x01A7 + + /* IO_CLK_MOD1 */ + mwhm 0x3089A, 0x18 + + /* IO_CLK_MOD2 */ + mwhm 0x3089C, 0x4A0 + + /* Setup the SDRAM range on the AHB bus */ + /* SDRAMSA */ + mov r0, #0x60000 + mov r1, #0x1000000 + str r1, [r0, #0xF00] + + /* SDRAMEA: 64MB */ + mov r1, #0x5000000 + str r1, [r0, #0xF04] + + /* SDRC_REFCTL */ + mwh 0x309A8, 0 + + ldr r0, =0x309A6 + mov r2, #0x1380 + orr r1, r2, #2 + strh r1, [r0] + orr r1, r2, #4 + strh r1, [r0] + strh r1, [r0] + strh r1, [r0] + strh r1, [r0] + strh r1, [r0] + strh r1, [r0] + strh r1, [r0] + strh r1, [r0] + orr r1, r2, #1 + strh r1, [r0] + strh r2, [r0] + strh r2, [r0] + + mwhm 0x309A8, 0x0140 + + mwhm 0x309BE, 0x4 + mwhm 0x309BC, 0x2 + ldr r0, =0x309C4 + ldr r1, [r0] + orr r1, r1, #1 + strh r1, [r0] + + ldr r0, =0x309A6 + mov r1, #0x1380 + strh r1, [r0] + bic r1, r1, #0x80 + strh r1, [r0] + orr r1, r1, #0x40 + strh r1, [r0] + + mwhm 0x309A8, 0x0140 + + /* Go through the GPIO initialization */ + /* Warning: setting some of the functions wrong will make OF unable + to boot (freeze during startup) */ + /* IO_GIO_FSEL0: Set up the GPIO pin functions 0-16 */ + mwhm 0x305A4, 0xC000 + + /* IO_GIO_FSEL1: 17-24 */ + mwh 0x305A6, 0xAAAA + + /* IO_GIO_FSEL2: 18-32 */ + mwh 0x305A8, 0xA80A + + /* IO_GIO_FSEL3: 33-40 */ + mwh 0x305AA, 0x1007 + + /* IO_GIO_DIR0 */ + mwh 0x30580, 0xFF77 + + /* IO_GIO_DIR1 */ + mwh 0x30582, 0xEFFE + + /* IO_GIO_DIR2 */ + mwh 0x30584, 0x01FD + + /* IO_GIO_INV0 */ + mwh 0x30586, 0x0000 + + /* IO_GIO_INV1 */ + mwh 0x30588, 0x0000 + + /* IO_GIO_INV2 */ + mwh 0x3058A, 0x0000 + + bx lr + +.ltorg +.size _init_board, .-_init_board + diff --git a/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c new file mode 100644 index 0000000000..fcfc82e876 --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c @@ -0,0 +1,273 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 +#include "config.h" +#include "cpu.h" +#include "string.h" +#include "kernel.h" +#include "system.h" +#include "system-target.h" +#include "lcd.h" +#include "lcd-target.h" +#include "avr-sansaconnect.h" + +/* Copies a rectangle from one framebuffer to another. Can be used in + single transfer mode with width = num pixels, and height = 1 which + allows a full-width rectangle to be copied more efficiently. */ +extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, + int width, int height); + +static bool lcd_on = true; + +bool lcd_active(void) +{ + return lcd_on; +} + +#if defined(HAVE_LCD_SLEEP) +void lcd_sleep(void) +{ + if (lcd_on) + { + lcd_on = false; + avr_hid_lcm_sleep(); + sleep(HZ/20); + + /* disable video encoder */ + bitclr16(&IO_VID_ENC_VMOD, 0x01); + + sleep(HZ/20); + + /* disable video encoder clock */ + bitclr16(&IO_CLK_MOD1, CLK_MOD1_VENC); + } +} + +void lcd_awake(void) +{ + if (!lcd_on) + { + lcd_on = true; + /* enable video encoder clock */ + bitset16(&IO_CLK_MOD1, CLK_MOD1_VENC); + + /* enable video encoder */ + bitset16(&IO_VID_ENC_VMOD, 0x01); + + avr_hid_lcm_wake(); + + send_event(LCD_EVENT_ACTIVATION, NULL); + + lcd_update(); + } +} +#endif + +void lcd_init_device(void) +{ + unsigned int addr; + + /* Disable Video Encoder clock */ + bitclr16(&IO_CLK_MOD1, CLK_MOD1_VENC); + + /* configure GIO39, GIO34 and GIO33 as outputs */ + IO_GIO_DIR2 &= ~((1 << 7) /* GIO39 */ | (1 << 2) /* GIO34 */ | + (1 << 1) /* GIO33 */); + + IO_GIO_FSEL3 = (IO_GIO_FSEL3 & ~(0x300F)) | + (0x1000) /* GIO39 - FIELD_VENC */ | + (0x3) /* GIO33 - CLKOUT1B (bootloader does this) */ | + (0x4); /* GIO34 - PWM1 (brightness control) */ + + /* OSD Clock = VENC Clock /2, + CCD clock PCLK, + VENC Clock from PLLA */ + IO_CLK_SEL1 = 0x3; + + /* Set VENC Clock Division to 11 + OF bootloader sets division to 8, vmlinux sets it to 11 */ + IO_CLK_DIV3 = (IO_CLK_DIV3 & ~(0x1F00)) | 0xB00; + + /* Enable DAC and OSD clocks */ + bitset16(&IO_CLK_MOD1, CLK_MOD1_DAC | CLK_MOD1_OSD); + + /* magic values based on OF bootloader initialization */ + IO_VID_ENC_VMOD = 0x2010; + IO_VID_ENC_VDPRO = 0x80; + IO_VID_ENC_HSPLS = 0x4; + IO_VID_ENC_HINT = 0x4B0; + IO_VID_ENC_HSTART = 0x88; + IO_VID_ENC_HVALID = 0x3C0; + IO_VID_ENC_HSDLY = 0; + IO_VID_ENC_VSPLS = 0x2; + IO_VID_ENC_VINT = 0x152; + IO_VID_ENC_VSTART = 0x6; + IO_VID_ENC_VVALID = 0x140; + IO_VID_ENC_VSDLY = 0; + IO_VID_ENC_DCLKCTL = 0x3; + IO_VID_ENC_DCLKPTN0 = 0xC; + IO_VID_ENC_VDCTL = 0x6000; + IO_VID_ENC_SYNCTL = 0x2; + IO_VID_ENC_LCDOUT = 0x101; + IO_VID_ENC_VMOD = 0x2011; + + /* Copy Rockbox frame buffer to the second framebuffer */ + lcd_update(); + + avr_hid_lcm_power_on(); + + /* set framebuffer address - OF sets RAM start address to 0x1000000 */ + addr = ((int)FRAME-CONFIG_SDRAM_START)/32; + + IO_OSD_OSDWINADH = addr >> 16; + IO_OSD_OSDWIN0ADL = addr & 0xFFFF; + + IO_OSD_BASEPX = 0x44; + IO_OSD_BASEPY = 0x6; + IO_OSD_OSDWIN0XP = 0; + IO_OSD_OSDWIN0YP = 0; + IO_OSD_OSDWIN0XL = LCD_WIDTH*2; /* OF bootloader sets 480 */ + IO_OSD_OSDWIN0YL = LCD_HEIGHT; /* OF bootloader sets 320 */ + IO_OSD_OSDWIN0OFST = 0xF; + IO_OSD_OSDWINMD0 = 0x25FB;/* OF bootloader sets 25C3, + vmlinux changes this to 0x25FB */ + IO_OSD_VIDWINMD = 0; /* disable video windows (OF sets 0x03) */ + + IO_OSD_OSDWINMD1 = 0; /* disable OSD window 1 */ + + /* Enable DAC, Video Encoder and OSD clocks */ + bitset16(&IO_CLK_MOD1, CLK_MOD1_DAC | CLK_MOD1_VENC | CLK_MOD1_OSD); + + /* Enable Video Encoder - RGB666, custom timing */ + IO_VID_ENC_VMOD = 0x2011; + avr_hid_lcm_wake(); +} + +/* Update a fraction of the display. */ +void lcd_update_rect(int x, int y, int width, int height) + __attribute__ ((section(".icode"))); +void lcd_update_rect(int x, int y, int width, int height) +{ + register fb_data *dst, *src; + + if (!lcd_on) + return; + + if ((width | height) < 0) + return; /* Nothing left to do */ + + if (x + width > LCD_WIDTH) + width = LCD_WIDTH - x; /* Clip right */ + if (x < 0) + width += x, x = 0; /* Clip left */ + + if (y + height > LCD_HEIGHT) + height = LCD_HEIGHT - y; /* Clip bottom */ + if (y < 0) + height += y, y = 0; /* Clip top */ + + dst = FRAME + LCD_WIDTH*y + x; + src = &lcd_framebuffer[y][x]; + + /* Copy part of the Rockbox framebuffer to the second framebuffer */ + if (width < LCD_WIDTH) + { + /* Not full width - do line-by-line */ + lcd_copy_buffer_rect(dst, src, width, height); + } + else + { + /* Full width - copy as one line */ + lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); + } +} + +/* Update the display. + This must be called after all other LCD functions that change the display. */ +void lcd_update(void) __attribute__ ((section(".icode"))); +void lcd_update(void) +{ + if (!lcd_on) + return; + + lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); +} + +void lcd_set_contrast(int val) { + (void) val; + // TODO: +} + +void lcd_set_invert_display(bool yesno) { + (void) yesno; + // TODO: +} + +void lcd_set_flip(bool yesno) { + (void) yesno; + // TODO: +} + +/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ +extern void lcd_write_yuv420_lines(fb_data *dst, + unsigned char chroma_buf[LCD_HEIGHT/2*3], + unsigned char const * const src[3], + int width, int stride); + +/* Performance function to blit a YUV bitmap directly to the LCD */ +void lcd_blit_yuv(unsigned char * const src[3], + int src_x, int src_y, int stride, + int x, int y, int width, int height) +{ + /* Caches for chroma data so it only need be recalculated every other + line */ + unsigned char chroma_buf[LCD_HEIGHT/2*3]; /* 480 bytes */ + unsigned char const * yuv_src[3]; + off_t z; + + if (!lcd_on) + return; + + /* Sorry, but width and height must be >= 2 or else */ + width &= ~1; + height >>= 1; + + fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + (LCD_WIDTH - y) - 1; + + z = stride*src_y; + yuv_src[0] = src[0] + z + src_x; + yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); + yuv_src[2] = src[2] + (yuv_src[1] - src[1]); + + do + { + lcd_write_yuv420_lines(dst, chroma_buf, yuv_src, width, + stride); + + yuv_src[0] += stride << 1; /* Skip down two luma lines */ + yuv_src[1] += stride >> 1; /* Skip down one chroma line */ + yuv_src[2] += stride >> 1; + dst -= 2; + } + while (--height > 0); +} + diff --git a/firmware/target/arm/tms320dm320/sansa-connect/lcd-target.h b/firmware/target/arm/tms320dm320/sansa-connect/lcd-target.h new file mode 100644 index 0000000000..0c1ad0d5f5 --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/lcd-target.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 _LCD_TARGET_H_ +#define _LCD_TARGET_H_ + +#endif diff --git a/firmware/target/arm/tms320dm320/sansa-connect/pcm-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/pcm-sansaconnect.c new file mode 100644 index 0000000000..3f04838388 --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/pcm-sansaconnect.c @@ -0,0 +1,207 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 +#include "system.h" +#include "kernel.h" +#include "logf.h" +#include "audio.h" +#include "sound.h" +#include "file.h" +#include "dsp-target.h" +#include "dsp/ipc.h" +#include "mmu-arm.h" +#include "pcm-internal.h" +#include "dma-target.h" + +/* This is global to save some latency when pcm_play_dma_get_peak_buffer is + * called. + */ +static void *start; +static int dma_channel; + +void pcm_play_dma_postinit(void) +{ + audiohw_postinit(); +} + +/* Return the current location in the SDRAM to SARAM transfer along with the + * number of bytes read in the current buffer (count). There is latency with + * this method equivalent to ~ the size of the SARAM buffer since there is + * another buffer between your ears and this calculation, but this works for + * key clicks and an approximate peak meter. + */ +const void * pcm_play_dma_get_peak_buffer(int *count) +{ + int cnt = DSP_(_sdem_level); + + unsigned long addr = (unsigned long) start + cnt; + + *count = (cnt & 0xFFFFF) >> 1; + return (void *)((addr + 2) & ~3); +} + +void pcm_play_dma_init(void) +{ + /* GIO16 is DSP/AIC3X CLK */ + IO_GIO_FSEL0 &= 0x3FFF; + IO_CLK_OSEL = (IO_CLK_OSEL & 0xFFF0) | 4; /* PLLIN clock */ + IO_CLK_O0DIV = 7; + IO_GIO_DIR1 &= ~(1 << 0); /* GIO16 - output */ + IO_GIO_FSEL0 |= 0xC000; /* GIO16 - CLKOUT0 */ + + audiohw_init(); + audiohw_set_frequency(HW_FREQ_DEFAULT); + + IO_INTC_IRQ0 = INTR_IRQ0_IMGBUF; + bitset16(&IO_INTC_EINT0, INTR_EINT0_IMGBUF); + + /* Set this as a FIQ */ + bitset16(&IO_INTC_FISEL0, INTR_EINT0_IMGBUF); + + /* Enable the HPIB clock */ + bitset16(&IO_CLK_MOD0, (CLK_MOD0_HPIB | CLK_MOD0_DSP)); + + /* Enable IMGBUF clock */ + bitset16(&IO_CLK_MOD1, CLK_MOD1_IMGBUF); + + dma_channel = dma_request_channel(DMA_PERIPHERAL_DSP, + DMA_MODE_1_BURST); + + IO_DSPC_HPIB_CONTROL = 1 << 10 | 1 << 9 | 1 << 8 | 1 << 7 | 1 << 3 | 1 << 0; + + dsp_reset(); + dsp_load(dsp_image); + + DSP_(_dma0_stopped)=1; + dsp_wake(); +} + +void pcm_dma_apply_settings(void) +{ + audiohw_set_frequency(pcm_fsel); +} + +/* Note that size is actually limited to the size of a short right now due to + * the implementation on the DSP side (and the way that we access it) + */ +void pcm_play_dma_start(const void *addr, size_t size) +{ + unsigned long sdem_addr=(unsigned long)addr - CONFIG_SDRAM_START; + /* Initialize codec. */ + DSP_(_sdem_addrl) = sdem_addr & 0xffff; + DSP_(_sdem_addrh) = sdem_addr >> 16; + DSP_(_sdem_dsp_size) = size; + DSP_(_dma0_stopped)=0; + + dsp_wake(); +} + +void pcm_play_dma_stop(void) +{ + DSP_(_dma0_stopped)=1; + dsp_wake(); +} + +void pcm_play_lock(void) +{ + +} + +void pcm_play_unlock(void) +{ + +} + +void pcm_play_dma_pause(bool pause) +{ + if (pause) + { + DSP_(_dma0_stopped)=2; + dsp_wake(); + } + else + { + DSP_(_dma0_stopped)=0; + dsp_wake(); + } +} + +size_t pcm_get_bytes_waiting(void) +{ + return DSP_(_sdem_dsp_size)-DSP_(_sdem_level); +} + +/* Only used when debugging */ +static char buffer[80]; + +void DSPHINT(void) __attribute__ ((section(".icode"))); +void DSPHINT(void) +{ + unsigned int i; + size_t size; + + IO_INTC_FIQ0 = INTR_IRQ0_IMGBUF; + + switch (dsp_message.msg) + { + case MSG_DEBUGF: + /* DSP stores one character per word. */ + for (i = 0; i < sizeof(buffer); i++) + { + buffer[i] = dsp_message.payload.debugf.buffer[i]; + } + + DEBUGF("DSP: %s", buffer); + break; + + case MSG_REFILL: + /* Buffer empty. Try to get more. */ + pcm_play_get_more_callback(&start, &size); + + if (size != 0) + { + unsigned long sdem_addr=(unsigned long)start - CONFIG_SDRAM_START; + /* Flush any pending cache writes */ + clean_dcache_range(start, size); + + /* set the new DMA values */ + DSP_(_sdem_addrl) = sdem_addr & 0xffff; + DSP_(_sdem_addrh) = sdem_addr >> 16; + DSP_(_sdem_dsp_size) = size; + + DEBUGF("pcm_sdram at 0x%08lx, sdem_addr 0x%08lx", + (unsigned long)start, (unsigned long)sdem_addr); + + pcm_play_dma_started_callback(); + } + + break; + default: + DEBUGF("DSP: unknown msg 0x%04x", dsp_message.msg); + break; + } + + /* Re-Activate the channel */ + dsp_wake(); + + DEBUGF("DSP: %s", buffer); +} + diff --git a/firmware/target/arm/tms320dm320/sansa-connect/power-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/power-sansaconnect.c new file mode 100644 index 0000000000..52ea9be1d9 --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/power-sansaconnect.c @@ -0,0 +1,59 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 +#include "kernel.h" +#include "system.h" +#include "power.h" +#include "backlight.h" +#include "backlight-target.h" +#include "avr-sansaconnect.h" + +void power_init(void) +{ +} + +void power_off(void) +{ + avr_hid_reset_codec(); + avr_hid_power_off(); +} + +#if CONFIG_CHARGING +unsigned int power_input_status(void) +{ + return POWER_INPUT_NONE; +} + +/* Returns true if the unit is charging the batteries. */ +bool charging_state(void) +{ + return false; +} +#endif + +void ide_power_enable(bool on) +{ + (void)on; +} + diff --git a/firmware/target/arm/tms320dm320/sansa-connect/powermgmt-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/powermgmt-sansaconnect.c new file mode 100644 index 0000000000..bd90c51072 --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/powermgmt-sansaconnect.c @@ -0,0 +1,56 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 "adc.h" +#include "powermgmt.h" +#include "kernel.h" + +/* THIS CONTAINS CURRENTLY DUMMY CODE! */ + +static const unsigned short current_voltage = 3910; +const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = +{ + 0 +}; + +const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = +{ + 0 +}; + +/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ +const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = +{ + { 100, 300, 400, 500, 600, 700, 800, 900, 1000, 1200, 1320 }, +}; + +/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ +const unsigned short percent_to_volt_charge[11] = +{ + 100, 300, 400, 500, 600, 700, 800, 900, 1000, 1200, 1320, +}; + +/* Returns battery voltage from ADC [millivolts] */ +unsigned int battery_adc_voltage(void) +{ + return current_voltage; +} diff --git a/firmware/target/arm/tms320dm320/sansa-connect/usb-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/usb-sansaconnect.c new file mode 100644 index 0000000000..ab42beb2b4 --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/usb-sansaconnect.c @@ -0,0 +1,53 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 "usb.h" +#ifdef HAVE_USBSTACK +#include "usb_drv.h" +#include "usb_core.h" +#endif + +bool usb_drv_connected(void) +{ + return false; +} + +int usb_detect(void) +{ + return USB_EXTRACTED; +} + +void usb_init_device(void) +{ + return; +} + +void usb_enable(bool on) +{ + (void)on; +} + +void usb_attach(void) +{ +} diff --git a/firmware/target/arm/tms320dm320/sansa-connect/usb-target.h b/firmware/target/arm/tms320dm320/sansa-connect/usb-target.h new file mode 100644 index 0000000000..6142b09f0b --- /dev/null +++ b/firmware/target/arm/tms320dm320/sansa-connect/usb-target.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 USB_TARGET_H +#define USB_TARGET_H + +#include "dm320.h" + +#include +int usb_detect(void); +void usb_init_device(void); +bool usb_drv_connected(void); + +#endif diff --git a/firmware/target/arm/tms320dm320/sdmmc-dm320.c b/firmware/target/arm/tms320dm320/sdmmc-dm320.c new file mode 100644 index 0000000000..307b90ec3b --- /dev/null +++ b/firmware/target/arm/tms320dm320/sdmmc-dm320.c @@ -0,0 +1,949 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2011 by Tomasz Moń + * + * 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 "sd.h" +#include "system.h" +#include +#include "gcc_extensions.h" +#include "thread.h" +#include "panic.h" +#include "kernel.h" +#include "dma-target.h" + +//#define SD_DEBUG + +#ifdef SD_DEBUG +#include "lcd-target.h" +#include "lcd.h" +#include "font.h" +#ifdef BOOTLOADER +#include "common.h" +#else +#include "debug.h" +#endif +#endif +#include "sdmmc.h" +#include "disk.h" +#include "fat.h" +#include "system-target.h" + +/* The configuration method is not very flexible. */ +#define CARD_NUM_SLOT 1 +#define NUM_CARDS 2 + +#define EC_OK 0 +#define EC_FAILED 1 +#define EC_NOCARD 2 +#define EC_WAIT_STATE_FAILED 3 +#define EC_POWER_UP 4 +#define EC_FIFO_WR_EMPTY 5 +#define EC_FIFO_WR_DONE 6 +#define EC_TRAN_READ_ENTRY 7 +#define EC_TRAN_READ_EXIT 8 +#define EC_TRAN_WRITE_ENTRY 9 +#define EC_TRAN_WRITE_EXIT 10 +#define EC_COMMAND 11 +#define EC_WRITE_PROTECT 12 +#define EC_DATA_TIMEOUT 13 +#define EC_RESP_TIMEOUT 14 +#define EC_CRC_ERROR 15 +#define NUM_EC 16 + +#define MIN_YIELD_PERIOD 1000 +#define UNALIGNED_NUM_SECTORS 10 +#define MAX_TRANSFER_ERRORS 10 + +#define SECTOR_SIZE 512 +#define BLOCKS_PER_BANK 0x7A7800 + +/* command flags for send_cmd */ +#define SDHC_RESP_FMT_NONE 0x0000 +#define SDHC_RESP_FMT_1 0x0200 +#define SDHC_RESP_FMT_2 0x0400 +#define SDHC_RESP_FMT_3 0x0600 + +#define INITIAL_CLK 312500 /* Initial clock */ +#define SD_CLK 24000000 /* Clock for SD cards */ +#define MMC_CLK 15000000 /* Clock for MMC cards */ + +#ifdef SD_DEBUG +#ifdef BOOTLOADER +#define dbgprintf printf +#else +#define dbgprintf DEBUGF +#endif +#else +#define dbgprintf(...) +#endif + +struct sd_card_status +{ + int retry; + int retry_max; +}; + +/** static, private data **/ + +/* for compatibility */ +static long last_disk_activity = -1; + +static bool initialized = false; +static unsigned int sd_thread_id = 0; + +static bool sd_enabled = false; +static long next_yield = 0; + +static tCardInfo card_info [NUM_CARDS]; +static tCardInfo *currcard; + +static struct sd_card_status sd_status[NUM_CARDS] = +{ +#if NUM_CARDS > 1 + {0, 10}, +#endif + {0, 10} +}; + +/* Shoot for around 75% usage */ +static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)]; +static const char sd_thread_name[] = "sd"; +static struct mutex sd_mtx SHAREDBSS_ATTR; +static struct event_queue sd_queue; +static volatile unsigned int transfer_error[NUM_DRIVES]; +/* align on cache line size */ +static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] + __attribute__((aligned(32))); + +static void sd_card_mux(int card_no) +{ +#ifdef HAVE_MULTIDRIVE +#ifdef SANSA_CONNECT + /* GIO6 - select Card; GIO5 - select iNAND (both active low) */ + if (card_no == CARD_NUM_SLOT) + { + IO_GIO_BITSET0 = (1 << 5); /* deselect iNAND (GIO5) */ + IO_GIO_BITCLR0 = (1 << 6); /* select card (GIO6) */ + } + else + { + IO_GIO_BITSET0 = (1 << 6); /* deselect card (GIO6) */ + IO_GIO_BITCLR0 = (1 << 5); /* select iNAND (GIO5) */ + } +#else /* Different players */ + (void)card_no; +#endif +#else /* No multidrive */ + (void)card_no; +#endif +} + + +void sd_enable(bool on) +{ + if (sd_enabled == on) + return; /* nothing to do */ + + if (on) + { + sd_enabled = true; + } + else + { + sd_enabled = false; + } +} + +/* sets clock rate just like OF does */ +static void sd_set_clock_rate(unsigned long rate) +{ + unsigned char rate_val = 0; + + if (rate == INITIAL_CLK) + { + rate_val = 0x3B; + } + else if (rate > INITIAL_CLK) + { + rate_val = 0; + } + else + { + rate_val = 0xFF; + } + + IO_MMC_MEM_CLK_CONTROL = (IO_MMC_MEM_CLK_CONTROL & 0xFF00) | rate_val; +} + +static int sd_poll_status(int st_reg_num, volatile unsigned int flag) +{ + unsigned int status; + unsigned int status1; + bool done; + + do + { + long time = current_tick; + + if (TIME_AFTER(time, next_yield)) + { + long ty = current_tick; + yield(); + next_yield = ty + MIN_YIELD_PERIOD; + } + + status = IO_MMC_STATUS0; + status1 = IO_MMC_STATUS1; + + if (status & MMC_ST0_CMD_TIMEOUT) + { + dbgprintf("CMD timeout"); + return -EC_RESP_TIMEOUT; + } + if (status & MMC_ST0_DATA_TIMEOUT) + { + dbgprintf("DATA timeout"); + return -EC_DATA_TIMEOUT; + } + + if (status & + (MMC_ST0_WR_CRCERR | MMC_ST0_RD_CRCERR | MMC_ST0_RESP_CRCERR)) + { + dbgprintf("CRC error"); + return -EC_CRC_ERROR; + } + + if (st_reg_num == 0) + { + done = status & flag; + } + else + { + done = status1 & flag; + } + } while (!done); + + return EC_OK; +} + +static int dma_wait_for_completion(void) +{ + unsigned short dma_status; + + do + { + long time = current_tick; + + if (TIME_AFTER(time, next_yield)) + { + long ty = current_tick; + yield(); + next_yield = ty + MIN_YIELD_PERIOD; + } + + dma_status = IO_MMC_SD_DMA_STATUS1; + if (dma_status & (1 << 13)) + { + return -EC_DATA_TIMEOUT; + } + } while (dma_status & (1 << 12)); + + return EC_OK; +} + +static int sd_command(int cmd, unsigned long arg, + int cmdat, unsigned long *response) +{ + int ret; + + /* Clear response registers */ + IO_MMC_RESPONSE0 = 0; + IO_MMC_RESPONSE1 = 0; + IO_MMC_RESPONSE2 = 0; + IO_MMC_RESPONSE3 = 0; + IO_MMC_RESPONSE4 = 0; + IO_MMC_RESPONSE5 = 0; + IO_MMC_RESPONSE6 = 0; + IO_MMC_RESPONSE7 = 0; + IO_MMC_COMMAND_INDEX = 0; + IO_MMC_SPI_DATA = 0; + + IO_MMC_ARG_LOW = (unsigned int)((arg & 0xFFFF)); + IO_MMC_ARG_HI = (unsigned int)((arg & 0xFFFF0000) >> 16); + + /* SD is always in push-pull mode */ + cmdat |= MMC_CMD_PPLEN; + + cmdat |= (cmd & MMC_CMD_CMD_MASK); + + if (cmdat & MMC_CMD_DATA) + cmdat |= MMC_CMD_DCLR; + + IO_MMC_COMMAND = cmdat; + + if (cmdat & MMC_CMD_DATA) + { + /* Command requires data - do not wait for RSPDNE */ + ret = EC_OK; + } + else + { + ret = sd_poll_status(0, MMC_ST0_RSPDNE); + } + + if (ret != EC_OK) + { + dbgprintf("Command failed (ret %d)", ret); + return ret; + } + + if (response == NULL) + { + /* discard response */ + } + else if ((cmdat & SDHC_RESP_FMT_1) || (cmdat & SDHC_RESP_FMT_3)) + { + response[0] = (IO_MMC_RESPONSE7 << 16) | IO_MMC_RESPONSE6; + } + else if (cmdat & SDHC_RESP_FMT_2) + { + response[0] = (IO_MMC_RESPONSE7 << 16) | IO_MMC_RESPONSE6; + response[1] = (IO_MMC_RESPONSE5 << 16) | IO_MMC_RESPONSE4; + response[2] = (IO_MMC_RESPONSE3 << 16) | IO_MMC_RESPONSE2; + response[3] = (IO_MMC_RESPONSE1 << 16) | IO_MMC_RESPONSE0; + } + + return 0; +} + +static int sd_init_card(const int card_no) +{ + bool sdhc = false; + unsigned long response[4]; + int ret; + int i; + + memset(currcard, 0, sizeof(*currcard)); + sd_card_mux(card_no); + + /* Set data bus width to 1 bit */ + bitclr16(&IO_MMC_CONTROL, MMC_CTRL_WIDTH); + sd_set_clock_rate(INITIAL_CLK); + + ret = sd_command(SD_GO_IDLE_STATE, 0, MMC_CMD_INITCLK, NULL); + + if (ret < 0) + return -1; + + ret = sd_command(SD_SEND_IF_COND, 0x1AA, + SDHC_RESP_FMT_3, response); + if ((response[0] & 0xFFF) == 0x1AA) + { + sdhc = true; + dbgprintf("found sdhc card"); + } + + while ((currcard->ocr & (1 << 31)) == 0) /* until card is powered up */ + { + ret = sd_command(SD_APP_CMD, currcard->rca, + SDHC_RESP_FMT_1, NULL); + if (ret < 0) + { + dbgprintf("SD_APP_CMD failed"); + return -1; + } + + ret = sd_command(SD_APP_OP_COND, + (1 << 20) /* 3.2-3.3V */ | + (1 << 21) /* 3.3-3.4V */ | + (sdhc ? (1 << 30) : 0), + SDHC_RESP_FMT_3, &currcard->ocr); + + if (ret < 0) + { + dbgprintf("SD_APP_OP_COND failed"); + return -1; + } + } + + dbgprintf("Card powered up"); + + ret = sd_command(SD_ALL_SEND_CID, 0, + SDHC_RESP_FMT_2, response); + if (ret < 0) + { + dbgprintf("SD_ALL_SEND_CID failed"); + return -1; + } + + for (i = 0; i<4; i++) + { + currcard->cid[i] = response[i]; + } + + ret = sd_command(SD_SEND_RELATIVE_ADDR, 0, + SDHC_RESP_FMT_1, &currcard->rca); + if (ret < 0) + { + dbgprintf("SD_SEND_RELATIVE_ADDR failed"); + return -1; + } + + ret = sd_command(SD_SEND_CSD, currcard->rca, + SDHC_RESP_FMT_2, response); + if (ret < 0) + { + dbgprintf("SD_SEND_CSD failed"); + return -1; + } + + for (i = 0; i<4; i++) + { + currcard->csd[i] = response[i]; + } + + sd_parse_csd(currcard); + + sd_set_clock_rate(currcard->speed); + + ret = sd_command(SD_SELECT_CARD, currcard->rca, + SDHC_RESP_FMT_1, NULL); + if (ret < 0) + { + dbgprintf("SD_SELECT_CARD failed"); + return -1; + } + + ret = sd_command(SD_APP_CMD, currcard->rca, + SDHC_RESP_FMT_1, NULL); + if (ret < 0) + { + dbgprintf("SD_APP_CMD failed"); + return -1; + } + + ret = sd_command(SD_SET_BUS_WIDTH, currcard->rca | 2, + SDHC_RESP_FMT_1, NULL); /* 4 bit */ + if (ret < 0) + { + dbgprintf("SD_SET_BUS_WIDTH failed"); + return -1; + } + + /* Set data bus width to 4 bits */ + bitset16(&IO_MMC_CONTROL, MMC_CTRL_WIDTH); + + ret = sd_command(SD_SET_BLOCKLEN, currcard->blocksize, + SDHC_RESP_FMT_1, NULL); + if (ret < 0) + { + dbgprintf("SD_SET_BLOCKLEN failed"); + return -1; + } + + IO_MMC_BLOCK_LENGTH = currcard->blocksize; + + dbgprintf("Card initialized"); + currcard->initialized = 1; + + return EC_OK; +} + +/* lock must already by aquired */ +static void sd_select_device(int card_no) +{ + currcard = &card_info[card_no]; + + if (card_no == 0) + { + /* Main card always gets a chance */ + sd_status[0].retry = 0; + } + + if (currcard->initialized > 0) + { + /* This card is already initialized - switch to it */ + sd_card_mux(card_no); + return; + } + + if (currcard->initialized == 0) + { + /* Card needs (re)init */ + sd_init_card(card_no); + } +} + +static inline bool card_detect_target(void) +{ +#ifdef SANSA_CONNECT + bool removed; + + removed = IO_GIO_BITSET0 & (1 << 14); + + return !removed; +#else + return false; +#endif +} + + +#ifdef HAVE_HOTSWAP + +static int sd1_oneshot_callback(struct timeout *tmo) +{ + (void)tmo; + + /* This is called only if the state was stable for 300ms - check state + * and post appropriate event. */ + if (card_detect_target()) + { + queue_broadcast(SYS_HOTSWAP_INSERTED, 0); + } + else + queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0); + return 0; +} + +#ifdef SANSA_CONNECT +void GIO14(void) __attribute__ ((section(".icode"))); +void GIO14(void) +{ + static struct timeout sd1_oneshot; + + /* clear interrupt */ + IO_INTC_IRQ2 = (1<<3); + + timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); +} +#endif + +bool sd_removable(IF_MD_NONVOID(int card_no)) +{ +#ifndef HAVE_MULTIDRIVE + const int card_no = 0; +#endif + + return (card_no == CARD_NUM_SLOT); +} + +bool sd_present(IF_MD_NONVOID(int card_no)) +{ +#ifndef HAVE_MULTIDRIVE + const int card_no = 0; +#endif + + return (card_no == CARD_NUM_SLOT) ? card_detect_target() : +#ifdef SANSA_CONNECT + true; /* iNAND is always present */ +#else + false; +#endif +} + +#else /* no hotswap */ + +bool sd_removable(IF_MD_NONVOID(int card_no)) +{ +#ifdef HAVE_MULTIDRIVE + (void)card_no; +#endif + + /* not applicable */ + return false; +} + +#endif /* HAVE_HOTSWAP */ + +static void sd_thread(void) NORETURN_ATTR; +static void sd_thread(void) +{ + struct queue_event ev; + + /* TODO */ + while (1) + { + queue_wait_w_tmo(&sd_queue, &ev, HZ); + switch ( ev.id ) + { +#ifdef HAVE_HOTSWAP + case SYS_HOTSWAP_INSERTED: + case SYS_HOTSWAP_EXTRACTED: + { + int success = 1; + fat_lock(); /* lock-out FAT activity first - + prevent deadlocking via disk_mount that + would cause a reverse-order attempt with + another thread */ + mutex_lock(&sd_mtx); /* lock-out card activity - direct calls + into driver that bypass the fat cache */ + + /* We now have exclusive control of fat cache and ata */ + + disk_unmount(0); /* release "by force", ensure file + descriptors aren't leaked and any busy + ones are invalid if mounting */ + + /* Force card init for new card, re-init for re-inserted one or + * clear if the last attempt to init failed with an error. */ + card_info[0].initialized = 0; + + if (ev.id == SYS_HOTSWAP_INSERTED) + { + /* FIXME: once sd_enabled is implement properly, + * reinitializing the controllers might be needed */ + sd_enable(true); + if (success < 0) /* initialisation failed */ + panicf("SD init failed : %d", success); + success = disk_mount(0); /* 0 if fail */ + } + + /* notify the system about the changed filesystems + */ + if (success) + queue_broadcast(SYS_FS_CHANGED, 0); + + /* Access is now safe */ + mutex_unlock(&sd_mtx); + fat_unlock(); + sd_enable(false); + } + break; +#endif + } + } +} + +static int sd_wait_for_state(unsigned int state) +{ + unsigned long response = 0; + unsigned int timeout = HZ; /* ticks */ + long t = current_tick; + + while (1) + { + long tick; + int ret = sd_command(SD_SEND_STATUS, currcard->rca, + SDHC_RESP_FMT_1, &response); + if (ret < 0) + return ret; + + if ((SD_R1_CURRENT_STATE(response) == state)) + { + return EC_OK; + } + + if(TIME_AFTER(current_tick, t + timeout)) + return -2; + + if (TIME_AFTER((tick = current_tick), next_yield)) + { + yield(); + timeout += current_tick - tick; + next_yield = tick + MIN_YIELD_PERIOD; + } + } +} + +static int sd_transfer_sectors(int card_no, unsigned long start, + int count, void *buffer, bool write) +{ + int ret; + unsigned long start_addr; + int dma_channel = -1; + bool use_direct_dma; + int count_per_dma; + unsigned long rel_addr; + + dbgprintf("transfer %d %d %d", card_no, start, count); + mutex_lock(&sd_mtx); + sd_enable(true); + +sd_transfer_retry: + if (card_no == CARD_NUM_SLOT && !card_detect_target()) + { + /* no external sd-card inserted */ + ret = -EC_NOCARD; + goto sd_transfer_error; + } + + sd_select_device(card_no); + + if (currcard->initialized < 0) + { + ret = currcard->initialized; + goto sd_transfer_error; + } + + last_disk_activity = current_tick; + + ret = sd_wait_for_state(SD_TRAN); + if (ret < EC_OK) + { + goto sd_transfer_error; + } + + IO_MMC_BLOCK_LENGTH = currcard->blocksize; + + start_addr = start; + + do + { + count_per_dma = count; + + if (((unsigned long)buffer) & 0x1F) + { + /* MMC/SD interface requires 32-byte alignment of buffer */ + use_direct_dma = false; + if (count > UNALIGNED_NUM_SECTORS) + { + count_per_dma = UNALIGNED_NUM_SECTORS; + } + } + else + { + use_direct_dma = true; + } + + if (write == true) + { + if (use_direct_dma == false) + { + memcpy(aligned_buffer, buffer, count_per_dma*SD_BLOCK_SIZE); + } + commit_dcache_range(use_direct_dma ? buffer : aligned_buffer, + count_per_dma*SD_BLOCK_SIZE); + } + + IO_MMC_NR_BLOCKS = count_per_dma; + + /* Set start_addr to the correct unit (blocks or bytes) */ + if (!(card_info[card_no].ocr & SD_OCR_CARD_CAPACITY_STATUS)) + start_addr *= SD_BLOCK_SIZE; /* not SDHC */ + + ret = sd_command(write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK, + start_addr, MMC_CMD_DCLR | MMC_CMD_DATA | + SDHC_RESP_FMT_1 | (write ? MMC_CMD_WRITE : 0), + NULL); + + if (ret < 0) + goto sd_transfer_error; + + /* other burst modes are not supported for this peripheral */ + dma_channel = dma_request_channel(DMA_PERIPHERAL_MMCSD, + DMA_MODE_8_BURST); + + if (use_direct_dma == true) + { + rel_addr = ((unsigned long)buffer)-CONFIG_SDRAM_START; + } + else + { + rel_addr = ((unsigned long)aligned_buffer)-CONFIG_SDRAM_START; + } + + IO_MMC_SD_DMA_ADDR_LOW = rel_addr & 0xFFFF; + IO_MMC_SD_DMA_ADDR_HI = (rel_addr & 0xFFFF0000) >> 16; + + IO_MMC_SD_DMA_MODE |= MMC_DMAMODE_ENABLE; + if (write == true) + { + IO_MMC_SD_DMA_MODE |= MMC_DMAMODE_WRITE; + } + + IO_MMC_SD_DMA_TRIGGER = 1; + + dbgprintf("SD DMA transfer in progress"); + + ret = dma_wait_for_completion(); + dma_release_channel(dma_channel); + + dbgprintf("SD DMA transfer complete"); + + if (ret != EC_OK) + { + goto sd_transfer_error; + } + + count -= count_per_dma; + + if (write == false) + { + discard_dcache_range(use_direct_dma ? buffer : aligned_buffer, + count_per_dma*SD_BLOCK_SIZE); + + if (use_direct_dma == false) + { + memcpy(buffer, aligned_buffer, count_per_dma*SD_BLOCK_SIZE); + } + } + + buffer += count_per_dma*SD_BLOCK_SIZE; + start_addr += count_per_dma; + + last_disk_activity = current_tick; + + ret = sd_command(SD_STOP_TRANSMISSION, 0, SDHC_RESP_FMT_1, NULL); + if (ret < 0) + { + goto sd_transfer_error; + } + + ret = sd_wait_for_state(SD_TRAN); + if (ret < 0) + { + goto sd_transfer_error; + } + } while (count > 0); + + while (1) + { + sd_enable(false); + mutex_unlock(&sd_mtx); + + return ret; + +sd_transfer_error: + if (sd_status[card_no].retry < sd_status[card_no].retry_max + && ret != -EC_NOCARD) + { + sd_status[card_no].retry++; + currcard->initialized = 0; + goto sd_transfer_retry; + } + } +} + +int sd_read_sectors(IF_MD2(int card_no,) unsigned long start, int incount, + void* inbuf) +{ +#ifndef HAVE_MULTIDRIVE + const int card_no = 0; +#endif + return sd_transfer_sectors(card_no, start, incount, inbuf, false); +} + +int sd_write_sectors(IF_MD2(int card_no,) unsigned long start, int count, + const void* outbuf) +{ +#ifndef BOOTLOADER +#ifndef HAVE_MULTIDRIVE + const int card_no = 0; +#endif + return sd_transfer_sectors(card_no, start, count, (void*)outbuf, true); +#else /* we don't need write support in bootloader */ +#ifdef HAVE_MULTIDRIVE + (void)card_no; +#endif + (void)start; + (void)count; + (void)outbuf; + return 0; +#endif +} + +int sd_init(void) +{ + int ret = EC_OK; + +#ifndef BOOTLOADER + sd_enabled = true; + sd_enable(false); +#endif + mutex_init(&sd_mtx); + + mutex_lock(&sd_mtx); + initialized = true; + + /* based on linux/drivers/mmc/dm320mmc.c + Copyright (C) 2006 ZSI, All Rights Reserved. + Written by: Ben Bostwick */ + + bitclr16(&IO_CLK_MOD2, CLK_MOD2_MMC); + bitset16(&IO_CLK_INV, CLK_INV_MMC); + + /* mmc module clock: 75 Mhz (AHB) / 2 = ~37.5 Mhz */ + /* OF uses 1, but for some reason it freezes on us */ + IO_CLK_DIV3 = (IO_CLK_DIV3 & 0xFF00) | 0x02; + + bitset16(&IO_CLK_MOD2, CLK_MOD2_MMC); + + /* set mmc module into reset */ + bitset16(&IO_MMC_CONTROL, (MMC_CTRL_DATRST | MMC_CTRL_CMDRST)); + + /* set resp timeout to max */ + IO_MMC_RESPONSE_TIMEOUT |= 0x1FFF; + IO_MMC_READ_TIMEOUT = 0xFFFF; + + /* all done, take mmc module out of reset */ + bitclr16(&IO_MMC_CONTROL, (MMC_CTRL_DATRST | MMC_CTRL_CMDRST)); + +#ifdef SANSA_CONNECT + /* GIO37 - Power Card; GIO38 - Power iNAND (both active low) */ + IO_GIO_DIR2 &= ~((1 << 5) /* GIO37 */ | (1 << 6) /* GIO38 */); + IO_GIO_INV2 &= ~((1 << 5) /* GIO37 */ | (1 << 6) /* GIO38 */); + IO_GIO_BITCLR2 = (1 << 5) | (1 << 6); + + /* GIO6 - select Card; GIO5 - select iNAND (both active low) */ + IO_GIO_DIR0 &= ~((1 << 6) /* GIO6 */ | (1 << 5) /* GIO5 */); + IO_GIO_INV0 &= ~((1 << 6) /* GIO6 */ | (1 << 5) /* GIO5 */); + IO_GIO_BITSET0 = (1 << 6) | (1 << 5); + +#ifdef HAVE_HOTSWAP + /* GIO14 is card detect */ + IO_GIO_DIR0 |= (1 << 14); /* Set GIO14 as input */ + IO_GIO_INV0 &= ~(1 << 14); /* GIO14 not inverted */ + IO_GIO_IRQPORT |= (1 << 14); /* Enable GIO14 external interrupt */ + IO_GIO_IRQEDGE |= (1 << 14); /* Any edge detection */ + + /* Enable GIO14 interrupt */ + IO_INTC_EINT2 |= INTR_EINT2_EXT14; +#endif +#endif + + sd_select_device(1); + + /* Enable Memory Card CLK */ + bitset16(&IO_MMC_MEM_CLK_CONTROL, (1 << 8)); + + queue_init(&sd_queue, true); + sd_thread_id = create_thread(sd_thread, sd_stack, sizeof(sd_stack), + 0, sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) + IF_COP(, CPU)); + + mutex_unlock(&sd_mtx); + + return ret; +} + +long sd_last_disk_activity(void) +{ + return last_disk_activity; +} + +tCardInfo *card_get_info_target(int card_no) +{ + return &card_info[card_no]; +} + +void sd_sleepnow(void) +{ +} + diff --git a/firmware/target/arm/tms320dm320/system-dm320.c b/firmware/target/arm/tms320dm320/system-dm320.c index f2a4aacb68..528d442ce5 100644 --- a/firmware/target/arm/tms320dm320/system-dm320.c +++ b/firmware/target/arm/tms320dm320/system-dm320.c @@ -26,11 +26,16 @@ #include "uart-target.h" #include "system-arm.h" #include "spi.h" +#include "i2c.h" #ifdef CREATIVE_ZVx #include "dma-target.h" -#else +#endif +#ifdef MROBE_500 #include "usb-mr500.h" #endif +#ifdef SANSA_CONNECT +#include "avr-sansaconnect.h" +#endif static unsigned short clock_arm_slow = 0xFFFF; static unsigned short clock_arm_fast = 0xFFFF; @@ -182,7 +187,12 @@ void system_exception_wait(void) IO_INTC_EINT0 = 0; IO_INTC_EINT1 = 0; IO_INTC_EINT2 = 0; +#ifdef MROBE_500 while ((IO_GIO_BITSET0&0x01) != 0); /* Wait for power button */ +#endif +#ifdef SANSA_CONNECT + while (1); /* Holding power button for a while makes avr system reset */ +#endif } void system_init(void) @@ -311,7 +321,7 @@ void system_init(void) clock_arm_slow = (0 << 8) | 3; clock_arm_fast = (1 << 8) | 1; } - + /* M48XI disabled, USB buffer powerdown */ IO_CLK_LPCTL1 = 0x11; /* I2C wodn't work with this disabled */ @@ -337,14 +347,22 @@ void system_init(void) uart_init(); spi_init(); +#ifdef MROBE_500 /* Initialization is done so shut the front LED off so that the battery * can charge. */ IO_GIO_BITCLR2 = 0x0001; - +#endif + #ifdef CREATIVE_ZVx dma_init(); #endif + +#ifdef SANSA_CONNECT + i2c_init(); + avr_hid_init(); + avr_hid_enable_charger(); +#endif } int system_memory_guard(int newmode) @@ -388,4 +406,13 @@ void udelay(int usec) { } } +#ifdef BOOTLOADER +void system_prepare_fw_start(void) +{ + tick_stop(); + IO_INTC_EINT0 = 0; + IO_INTC_EINT1 = 0; + IO_INTC_EINT2 = 0; +} +#endif diff --git a/firmware/target/arm/tms320dm320/system-target.h b/firmware/target/arm/tms320dm320/system-target.h index 22cf5546b2..59ae61f8df 100644 --- a/firmware/target/arm/tms320dm320/system-target.h +++ b/firmware/target/arm/tms320dm320/system-target.h @@ -41,4 +41,9 @@ void udelay(int usec); true; }) /* handled here */ #endif +#ifdef BOOTLOADER +void tick_stop(void); +void system_prepare_fw_start(void); +#endif + #endif /* SYSTEM_TARGET_H */ diff --git a/tools/configure b/tools/configure index 222d1dcd1c..d715ef4100 100755 --- a/tools/configure +++ b/tools/configure @@ -1282,14 +1282,14 @@ cat <