imx233/fuze+: huge rework

- enable MMU
-rework lcd frame buffer
- add rtc/adc/power stubs (or not)
- fix a few MMC related defines (hopefully)
- implement cache handling for DMA
- more SD work
- add keymap (based on clip)
- add virtual buttons
- update linker scripts
- big step toward apps actually compiling

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30200 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Amaury Pouly 2011-07-23 11:45:22 +00:00
parent 06c94740e5
commit eb90d95693
29 changed files with 756 additions and 52 deletions

View file

@ -317,4 +317,6 @@ keymaps/keymap-mpio-hd300.c
keymaps/keymap-android.c keymaps/keymap-android.c
#elif CONFIG_KEYPAD == SDL_PAD #elif CONFIG_KEYPAD == SDL_PAD
keymaps/keymap-sdl.c keymaps/keymap-sdl.c
#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
keymaps/keymap-fuzeplus.c
#endif #endif

View file

@ -528,7 +528,7 @@ long default_event_handler_ex(long event, void (*callback)(void *), void *parame
case SYS_USB_CONNECTED: case SYS_USB_CONNECTED:
if (callback != NULL) if (callback != NULL)
callback(parameter); callback(parameter);
#if (CONFIG_STORAGE & STORAGE_MMC) #if (CONFIG_STORAGE & STORAGE_MMC) && (defined(ARCHOS_ONDIOSP) || defined(ARCHOS_ONDIOFM))
if (!mmc_touched() || if (!mmc_touched() ||
(mmc_remove_request() == SYS_HOTSWAP_EXTRACTED)) (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED))
#endif #endif

View file

@ -59,7 +59,7 @@
#include "dsp.h" #include "dsp.h"
#endif #endif
#if (CONFIG_STORAGE & STORAGE_MMC) #if (CONFIG_STORAGE & STORAGE_MMC) && (defined(ARCHOS_ONDIOSP) || defined(ARCHOS_ONDIOFM))
int mmc_remove_request(void) int mmc_remove_request(void)
{ {
struct queue_event ev; struct queue_event ev;

View file

@ -269,6 +269,8 @@ drivers/rtc/rtc_s35390a.c
drivers/rtc/rtc_s35380a.c drivers/rtc/rtc_s35380a.c
#elif (CONFIG_RTC == RTC_D2) #elif (CONFIG_RTC == RTC_D2)
drivers/rtc/rtc_d2.c drivers/rtc/rtc_d2.c
#elif (CONFIG_RTC == RTC_IMX233)
drivers/rtc/rtc_imx233.c
#endif /* (CONFIG_RTC == RTC_) */ #endif /* (CONFIG_RTC == RTC_) */
#endif /* PLATFORM_NATIVE */ #endif /* PLATFORM_NATIVE */
@ -490,6 +492,7 @@ target/arm/pnx0101/timer-pnx0101.c
#endif #endif
#if CONFIG_CPU == IMX233 #if CONFIG_CPU == IMX233
target/arm/mmu-arm.S
target/arm/imx233/lcdif-imx233.c target/arm/imx233/lcdif-imx233.c
target/arm/imx233/clkctrl-imx233.c target/arm/imx233/clkctrl-imx233.c
target/arm/imx233/system-imx233.c target/arm/imx233/system-imx233.c
@ -499,9 +502,15 @@ target/arm/imx233/kernel-imx233.c
target/arm/imx233/sd-imx233.c target/arm/imx233/sd-imx233.c
target/arm/imx233/mmc-imx233.c target/arm/imx233/mmc-imx233.c
target/arm/imx233/ssp-imx233.c target/arm/imx233/ssp-imx233.c
target/arm/imx233/usb-imx233.c
target/arm/imx233/dma-imx233.c target/arm/imx233/dma-imx233.c
target/arm/imx233/pinctrl-imx233.c target/arm/imx233/pinctrl-imx233.c
target/arm/imx233/power-imx233.c
target/arm/imx233/powermgmt-imx233.c
target/arm/imx233/adc-imx233.c
target/arm/imx233/debug-imx233.c
#if !defined(BOOTLOADER) || defined(HAVE_BOOTLOADER_USB_MODE)
target/arm/imx233/usb-imx233.c
#endif
#endif /* IMX233 */ #endif /* IMX233 */
#if CONFIG_CPU == AS3525 || CONFIG_CPU == AS3525v2 #if CONFIG_CPU == AS3525 || CONFIG_CPU == AS3525v2
@ -1456,10 +1465,13 @@ target/arm/as3525/lcd-as-e200v2-fuze-fuzev2.S
#ifndef SIMULATOR #ifndef SIMULATOR
drivers/synaptics-rmi.c drivers/synaptics-rmi.c
drivers/generic_i2c.c drivers/generic_i2c.c
target/arm/lcd-as-memframe.S
target/arm/imx233/sansa-fuzeplus/fmradio-i2c-fuzeplus.c target/arm/imx233/sansa-fuzeplus/fmradio-i2c-fuzeplus.c
target/arm/imx233/sansa-fuzeplus/backlight-fuzeplus.c target/arm/imx233/sansa-fuzeplus/backlight-fuzeplus.c
target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c
target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c
target/arm/imx233/sansa-fuzeplus/debug-fuzeplus.c
target/arm/imx233/sansa-fuzeplus/power-fuzeplus.c
#endif /* SIMULATOR */ #endif /* SIMULATOR */
#endif #endif

View file

@ -218,7 +218,7 @@ static struct mutex tempbuf_mutex;
static char fat_tempbuf[SECTOR_SIZE] CACHEALIGN_ATTR; static char fat_tempbuf[SECTOR_SIZE] CACHEALIGN_ATTR;
static bool tempbuf_locked; static bool tempbuf_locked;
#if defined(HAVE_HOTSWAP) && !(CONFIG_STORAGE & STORAGE_MMC) /* A better condition ?? */ #if defined(HAVE_HOTSWAP)
void fat_lock(void) void fat_lock(void)
{ {
mutex_lock(&cache_mutex); mutex_lock(&cache_mutex);

View file

@ -0,0 +1,68 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 by Amaury Pouly
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "system.h"
#include "rtc.h"
#include "timefuncs.h"
void rtc_init(void)
{
}
int rtc_read_datetime(struct tm *tm)
{
(void) tm;
return -1;
}
int rtc_write_datetime(const struct tm *tm)
{
(void) tm;
return -1;
}
void rtc_set_alarm(int h, int m)
{
(void) h;
(void) m;
}
void rtc_get_alarm(int *h, int *m)
{
(void) h;
(void) m;
}
void rtc_enable_alarm(bool enable)
{
(void) enable;
}
bool rtc_check_alarm_started(bool release_alarm)
{
(void) release_alarm;
return false;
}
bool rtc_check_alarm_flag(void)
{
return false;
}

View file

@ -70,6 +70,8 @@
#include "ak4537.h" #include "ak4537.h"
#elif defined(HAVE_CS42L55) #elif defined(HAVE_CS42L55)
#include "cs42l55.h" #include "cs42l55.h"
#elif defined(HAVE_IMX233_CODEC)
#include "imx233-codec.h"
#endif #endif
#if (CONFIG_PLATFORM & PLATFORM_HOSTED) #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
/* #include <SDL_audio.h> gives errors in other code areas, /* #include <SDL_audio.h> gives errors in other code areas,

View file

@ -869,7 +869,7 @@ Lyre prototype 1 */
#endif #endif
#if (defined(CPU_PP) || (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) || \ #if (defined(CPU_PP) || (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) || \
(CONFIG_CPU == IMX31L)) \ (CONFIG_CPU == IMX31L) || (CONFIG_CPU == IMX233)) \
&& (CONFIG_PLATFORM & PLATFORM_NATIVE) && !defined(BOOTLOADER) && (CONFIG_PLATFORM & PLATFORM_NATIVE) && !defined(BOOTLOADER)
/* Functions that have INIT_ATTR attached are NOT guaranteed to survive after /* Functions that have INIT_ATTR attached are NOT guaranteed to survive after
* root_menu() has been called. Their code may be overwritten by other data or * root_menu() has been called. Their code may be overwritten by other data or

View file

@ -28,7 +28,7 @@
/* define this if you have a colour LCD */ /* define this if you have a colour LCD */
#define HAVE_LCD_COLOR #define HAVE_LCD_COLOR
#ifndef BOOTLOADER/* define this if you want album art for this target */ #ifndef BOOTLOADER
#define HAVE_ALBUMART #define HAVE_ALBUMART
/* define this to enable bitmap scaling */ /* define this to enable bitmap scaling */
@ -37,9 +37,6 @@
/* define this to enable JPEG decoding */ /* define this to enable JPEG decoding */
#define HAVE_JPEG #define HAVE_JPEG
/* define this if you have a light associated with the buttons */
#define HAVE_BUTTON_LIGHT
/* define this if you have access to the quickscreen */ /* define this if you have access to the quickscreen */
#define HAVE_QUICKSCREEN #define HAVE_QUICKSCREEN
@ -69,13 +66,19 @@
/* define this if you have a real-time clock */ /* define this if you have a real-time clock */
#define CONFIG_RTC RTC_IMX233 #define CONFIG_RTC RTC_IMX233
/* define this if you have a real-time clock with alarm facilities */
#define HAVE_RTC_ALARM
#endif /* !BOOTLOADER */
/* define this if you have an i.MX23 codec */
#define HAVE_IMX233_CODEC
#define CONFIG_TUNER SI4700 #define CONFIG_TUNER SI4700
/* There is no hardware tone control */ /* There is no hardware tone control */
#define HAVE_SW_TONE_CONTROLS #define HAVE_SW_TONE_CONTROLS
#endif /* !BOOTLOADER */
#define CONFIG_KEYPAD SANSA_FUZEPLUS_PAD #define CONFIG_KEYPAD SANSA_FUZEPLUS_PAD
/* Define this to enable morse code input */ /* Define this to enable morse code input */
@ -84,7 +87,6 @@
/* Define this if you do software codec */ /* Define this if you do software codec */
#define CONFIG_CODEC SWCODEC #define CONFIG_CODEC SWCODEC
/* LCD dimensions */ /* LCD dimensions */
#define LCD_WIDTH 240 #define LCD_WIDTH 240
#define LCD_HEIGHT 320 #define LCD_HEIGHT 320

View file

@ -0,0 +1,29 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 by Amaury Pouly
*
* 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 __IMX233_CODEC_H_
#define __IMX233_CODEC_H_
#define VOLUME_MIN -1000
#define VOLUME_MAX -5
void audiohw_set_volume(int v);
#endif /* __IMX233_CODEC_H_ */

View file

@ -0,0 +1,34 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 by Amaury Pouly
*
* 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 "adc-target.h"
void adc_init(void)
{
}
unsigned short adc_read(int channel)
{
(void) channel;
return 0;
}

View file

@ -0,0 +1,119 @@
#include "config.h"
#include "cpu.h"
ENTRY(start)
OUTPUT_FORMAT(elf32-littlearm)
OUTPUT_ARCH(arm)
STARTUP(target/arm/imx233/crt0.o)
#define PLUGINSIZE PLUGIN_BUFFER_SIZE
#define CODECSIZE CODEC_SIZE
#define DRAMORIG DRAM_ORIG
#define IRAMORIG IRAM_ORIG
#define IRAMSIZE (IRAM_SIZE - TTB_SIZE)
#define DRAMSIZE (DRAM_SIZE - PLUGINSIZE - CODECSIZE - FRAME_SIZE)
/* End of the audio buffer, where the codec buffer starts */
#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE)
/* Where the codec buffer ends, and the plugin buffer starts */
#define ENDADDR (ENDAUDIOADDR + CODEC_SIZE)
/* INIT section is the codec buffer */
#define INITSIZE CODEC_SIZE
#define INITSTART ENDAUDIOADDR
MEMORY
{
IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
}
SECTIONS
{
.text :
{
loadaddress = .;
_loadaddress = .;
*(.text*)
} > DRAM
.data :
{
*(.data*)
*(.rodata*)
_dataend = . ;
} > DRAM
.iram :
{
_iramstart = .; // always 0
*(.vectors)
KEEP(*(.vectors));// otherwise there are no references to it and the linker strip it
*(.icode)
*(.irodata)
*(.idata)
. = ALIGN(0x4);
_iramend = .;
} > IRAM AT> DRAM
_iramcopy = LOADADDR(.iram);
.ibss (NOLOAD) :
{
_iedata = .;
*(.qharray)
*(.ibss)
. = ALIGN(0x4);
_iend = .;
} > IRAM
.init ENDAUDIOADDR :
{
. = ALIGN(4);
_initstart = .;
*(.init)
_initend = .;
} AT> DRAM
_initcopy = LOADADDR(.init);
.stack (NOLOAD) :
{
*(.stack)
stackbegin = .;
. += 0x2000;
stackend = .;
} > DRAM
.bss (NOLOAD) :
{
_edata = .;
*(.bss*);
_end = .;
} > DRAM
.audiobuf (NOLOAD) :
{
. = ALIGN(4);
_audiobuffer = .;
audiobuffer = .;
} > DRAM
.codec ENDAUDIOADDR (NOLOAD) :
{
audiobufend = .;
_audiobufend = .;
codecbuf = .;
_codecbuf = .;
} > DRAM
.plugin ENDADDR (NOLOAD) :
{
_pluginbuf = .;
pluginbuf = .;
}
}

View file

@ -39,6 +39,13 @@ start:
/* Save r0 */ /* Save r0 */
mov r6, r0 mov r6, r0
msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
/* Disable MMU, disable caching and buffering;
* use low exception range address (the core uses high range by default) */
mrc p15, 0, r0, c1, c0, 0
ldr r1, =0x3005
bic r0, r1
mcr p15, 0, r0, c1, c0, 0
/* Zero out IBSS */ /* Zero out IBSS */
ldr r2, =_iedata ldr r2, =_iedata
ldr r3, =_iend ldr r3, =_iend
@ -59,6 +66,22 @@ start:
strhi r5, [r3], #4 strhi r5, [r3], #4
bhi 1b bhi 1b
#ifdef HAVE_INIT_ATTR
/* copy init data to codec buffer */
/* must be done before bss is zeroed */
ldr r2, =_initcopy
ldr r3, =_initstart
ldr r4, =_initend
1:
cmp r4, r3
ldrhi r5, [r2], #4
strhi r5, [r3], #4
bhi 1b
mov r2, #0
mcr p15, 0, r2, c7, c5, 0 @ Invalidate ICache
#endif
/* Initialise bss section to zero */ /* Initialise bss section to zero */
ldr r2, =_edata ldr r2, =_edata
ldr r3, =_end ldr r3, =_end
@ -68,7 +91,6 @@ start:
strhi r4, [r2], #4 strhi r4, [r2], #4
bhi 1b bhi 1b
/* Set up some stack and munge it with 0xdeadbeef */ /* Set up some stack and munge it with 0xdeadbeef */
ldr sp, =stackend ldr sp, =stackend
ldr r2, =stackbegin ldr r2, =stackbegin
@ -92,16 +114,12 @@ start:
msr cpsr_c, #0xdb msr cpsr_c, #0xdb
ldr sp, =irq_stack ldr sp, =irq_stack
/* Enable MMU */
bl memory_init
/* Switch back to supervisor mode */ /* Switch back to supervisor mode */
msr cpsr_c, #0xd3 msr cpsr_c, #0xd3
/* Disable MMU, disable caching and buffering;
* use low exception range address (the core uses high range by default) */
mrc p15, 0, r0, c1, c0, 0
ldr r1, =0x3005
bic r0, r1
mcr p15, 0, r0, c1, c0, 0
/* Jump to main */ /* Jump to main */
mov r0, r6 mov r0, r6
bl main bl main

View file

@ -0,0 +1,33 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 by Amaury Pouly
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "system.h"
#include "debug-target.h"
bool dbg_hw_info(void)
{
return false;
}
bool dbg_ports(void)
{
return false;
}

View file

@ -0,0 +1,30 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 by Amaury Pouly
*
* 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 DEBUG_TARGET_H
#define DEBUG_TARGET_H
#define DEBUG_CANCEL BUTTON_BACK
bool dbg_hw_target_info(void);
bool dbg_hw_info(void);
bool dbg_ports(void);
#endif /* DEBUG_TARGET_H */

View file

@ -106,8 +106,54 @@ bool imx233_dma_is_channel_error_irq(unsigned chan)
HW_APBH_CTRL2__CHx_ERROR_IRQ(APB_GET_DMA_CHANNEL(chan))); HW_APBH_CTRL2__CHx_ERROR_IRQ(APB_GET_DMA_CHANNEL(chan)));
} }
/* Commit and/or discard all DMA descriptors and buffers pointed by them,
* handle circular lists */
static void imx233_dma_commit_and_discard(struct apb_dma_command_t *cmd)
{
/* We handle circular descriptors by using unused bits:
* bits 8-11 are not used by the hardware so we first go through the whole
* list and mark them all a special value at the same time we commit buffers
* and then we go through the list another time to clear the mark and
* commit the descriptors */
struct apb_dma_command_t *cur = cmd;
while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != HW_APB_CHx_CMD__UNUSED_MAGIC)
{
cur->cmd = (cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM) | HW_APB_CHx_CMD__UNUSED_MAGIC;
int op = cur->cmd & HW_APB_CHx_CMD__COMMAND_BM;
int sz = (cur->cmd & HW_APB_CHx_CMD__XFER_COUNT_BM) >> HW_APB_CHx_CMD__XFER_COUNT_BP;
/* device > host: discard */
if(op == HW_APB_CHx_CMD__COMMAND__WRITE)
discard_dcache_range(cur->buffer, sz);
/* host > device: commit and discard */
else if(op == HW_APB_CHx_CMD__COMMAND__READ)
commit_discard_dcache_range(cur->buffer, sz);
/* chain ? */
if(cur->cmd & HW_APB_CHx_CMD__CHAIN)
cur = cur->next;
else
break;
}
cur = cmd;
while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != 0)
{
cur->cmd = cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM;
int sz = (cur->cmd & HW_APB_CHx_CMD__CMDWORDS_BM) >> HW_APB_CHx_CMD__CMDWORDS_BP;
/* commit descriptor (don't discard since we access it after) */
commit_dcache_range(cur,
sizeof(struct apb_dma_command_t) + sizeof(uint32_t) * sz);
/* chain ? */
if(cur->cmd & HW_APB_CHx_CMD__CHAIN)
cur = cur->next;
else
break;
}
}
void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd) void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd)
{ {
imx233_dma_commit_and_discard(cmd);
if(APB_IS_APBX_CHANNEL(chan)) if(APB_IS_APBX_CHANNEL(chan))
{ {
HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd; HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd;
@ -129,5 +175,5 @@ void imx233_dma_wait_completion(unsigned chan)
sema = &HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)); sema = &HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan));
while(*sema & HW_APB_CHx_SEMA__PHORE_BM) while(*sema & HW_APB_CHx_SEMA__PHORE_BM)
; yield();
} }

View file

@ -138,11 +138,16 @@ struct apb_dma_command_t
#define HW_APBH_CHx_CMD__NANDWAIT4READY (1 << 5) #define HW_APBH_CHx_CMD__NANDWAIT4READY (1 << 5)
#define HW_APB_CHx_CMD__SEMAPHORE (1 << 6) #define HW_APB_CHx_CMD__SEMAPHORE (1 << 6)
#define HW_APB_CHx_CMD__WAIT4ENDCMD (1 << 7) #define HW_APB_CHx_CMD__WAIT4ENDCMD (1 << 7)
#define HW_APB_CHx_CMD__HALTONTERMINATE (1 << 8) /* An errata advise not to use it */
#define HW_APB_CHx_CMD__CMDWORDS_BM 0xf000 //#define HW_APB_CHx_CMD__HALTONTERMINATE (1 << 8)
#define HW_APB_CHx_CMD__CMDWORDS_BP 12 #define HW_APB_CHx_CMD__CMDWORDS_BM 0xf000
#define HW_APB_CHx_CMD__XFER_COUNT_BM 0xffff0000 #define HW_APB_CHx_CMD__CMDWORDS_BP 12
#define HW_APB_CHx_CMD__XFER_COUNT_BP 16 #define HW_APB_CHx_CMD__XFER_COUNT_BM 0xffff0000
#define HW_APB_CHx_CMD__XFER_COUNT_BP 16
/* For software use */
#define HW_APB_CHx_CMD__UNUSED_BP 8
#define HW_APB_CHx_CMD__UNUSED_BM (0xf << 8)
#define HW_APB_CHx_CMD__UNUSED_MAGIC (0xa << 8)
#define HW_APB_CHx_SEMA__PHORE_BM 0xff0000 #define HW_APB_CHx_SEMA__PHORE_BM 0xff0000
#define HW_APB_CHx_SEMA__PHORE_BP 16 #define HW_APB_CHx_SEMA__PHORE_BP 16

View file

@ -53,7 +53,7 @@ void INT_I2C_DMA(void)
semaphore_release(&i2c_sema); semaphore_release(&i2c_sema);
} }
void imx233_i2c_init(void) void i2c_init(void)
{ {
__REG_SET(HW_I2C_CTRL0) = __BLOCK_SFTRST | __BLOCK_CLKGATE; __REG_SET(HW_I2C_CTRL0) = __BLOCK_SFTRST | __BLOCK_CLKGATE;
/* setup pins (must be done when shutdown) */ /* setup pins (must be done when shutdown) */

View file

@ -126,7 +126,7 @@ enum imx233_i2c_error_t
I2C_SLAVE_NAK = -5 I2C_SLAVE_NAK = -5
}; };
void imx233_i2c_init(void); void i2c_init(void);
/* start building a transfer, will acquire an exclusive lock */ /* start building a transfer, will acquire an exclusive lock */
void imx233_i2c_begin(void); void imx233_i2c_begin(void);
/* add stage */ /* add stage */

View file

@ -0,0 +1,46 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 by Amaury Pouly
*
* 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 "power.h"
#include "system-target.h"
void power_init(void)
{
}
void power_off(void)
{
/* power down */
HW_POWER_RESET = HW_POWER_RESET__UNLOCK | HW_POWER_RESET__PWD;
while(1);
}
unsigned int power_input_status(void)
{
return POWER_INPUT_NONE;
}
bool charging_state(void)
{
return false;
}

View file

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

View file

@ -32,8 +32,18 @@ void button_debug_screen(void);
#define BUTTON_POWER 0x00000001 #define BUTTON_POWER 0x00000001
#define BUTTON_VOL_UP 0x00000002 #define BUTTON_VOL_UP 0x00000002
#define BUTTON_VOL_DOWN 0x00000004 #define BUTTON_VOL_DOWN 0x00000004
/* Virtual buttons */
#define BUTTON_LEFT 0x00000008
#define BUTTON_UP 0x00000010
#define BUTTON_RIGHT 0x00000020
#define BUTTON_DOWN 0x00000040
#define BUTTON_SELECT 0x00000080
#define BUTTON_PLAYPAUSE 0x00000100
#define BUTTON_BACK 0x00000200
#define BUTTON_MAIN (BUTTON_VOL_UP|BUTTON_VOL_DOWN|BUTTON_POWER) #define BUTTON_MAIN (BUTTON_VOL_UP|BUTTON_VOL_DOWN|BUTTON_POWER|BUTTON_LEFT| \
BUTTON_UP|BUTTON_RIGHT|BUTTON_DOWN|BUTTON_SELECT| \
BUTTON_PLAYPAUSE|BUTTON_BACK)
#define BUTTON_REMOTE 0 #define BUTTON_REMOTE 0

View file

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

View file

@ -85,22 +85,17 @@ struct i2c_interface fmradio_i2c =
.delay_thigh = 4 .delay_thigh = 4
}; };
void fmradio_i2c_init(void) void fmradio_i2c_enable(bool enable)
{ {
if(fmradio_i2c_bus == -1)
fmradio_i2c_bus = i2c_add_node(&fmradio_i2c);
imx233_set_pin_function(0, 29, PINCTRL_FUNCTION_GPIO); imx233_set_pin_function(0, 29, PINCTRL_FUNCTION_GPIO);
imx233_set_pin_function(1, 24, PINCTRL_FUNCTION_GPIO); imx233_set_pin_function(1, 24, PINCTRL_FUNCTION_GPIO);
imx233_set_pin_function(1, 22, PINCTRL_FUNCTION_GPIO); imx233_set_pin_function(1, 22, PINCTRL_FUNCTION_GPIO);
imx233_enable_gpio_output(1, 22, true); imx233_enable_gpio_output(1, 22, enable);
imx233_enable_gpio_output(1, 24, true); imx233_enable_gpio_output(1, 24, enable);
imx233_set_gpio_output(1, 22, true); imx233_set_gpio_output(1, 22, enable);
imx233_set_gpio_output(1, 24, true); imx233_set_gpio_output(1, 24, enable);
fmradio_i2c_bus = i2c_add_node(&fmradio_i2c);
}
void fmradio_i2c_enable(bool enable)
{
imx233_enable_gpio_output(0, 29, enable);
imx233_set_gpio_output(0, 29, enable);
} }
int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count) int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count)

View file

@ -29,6 +29,16 @@
#define logf(...) #define logf(...)
/* 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);
#ifdef HAVE_LCD_ENABLE
static bool lcd_on = false;
#endif
static enum lcd_kind_t static enum lcd_kind_t
{ {
LCD_KIND_7783 = 0x7783, LCD_KIND_7783 = 0x7783,
@ -375,7 +385,7 @@ void lcd_init_device(void)
} }
} }
#ifdef HAVE_LCD_ENABLE
static void lcd_enable_7783(bool enable) static void lcd_enable_7783(bool enable)
{ {
if(!enable) if(!enable)
@ -454,6 +464,10 @@ static void lcd_enable_9325(bool enable)
void lcd_enable(bool enable) void lcd_enable(bool enable)
{ {
if(lcd_on == enable)
return;
lcd_on = enable;
if(enable) if(enable)
common_lcd_enable(true); common_lcd_enable(true);
switch(lcd_kind) switch(lcd_kind)
@ -466,8 +480,19 @@ void lcd_enable(bool enable)
common_lcd_enable(false); common_lcd_enable(false);
} }
bool lcd_active(void)
{
return lcd_on;
}
#endif
void lcd_update(void) void lcd_update(void)
{ {
#ifdef HAVE_LCD_ENABLE
if(!lcd_on)
return;
#endif
imx233_lcdif_wait_ready();
lcd_write_reg(0x50, 0); lcd_write_reg(0x50, 0);
lcd_write_reg(0x51, LCD_WIDTH - 1); lcd_write_reg(0x51, LCD_WIDTH - 1);
lcd_write_reg(0x52, 0); lcd_write_reg(0x52, 0);
@ -479,8 +504,9 @@ void lcd_update(void)
imx233_lcdif_set_word_length(HW_LCDIF_CTRL__WORD_LENGTH_16_BIT); imx233_lcdif_set_word_length(HW_LCDIF_CTRL__WORD_LENGTH_16_BIT);
imx233_lcdif_set_byte_packing_format(0xf); /* two pixels per 32-bit word */ imx233_lcdif_set_byte_packing_format(0xf); /* two pixels per 32-bit word */
imx233_lcdif_set_data_format(false, false, false); /* RGB565, don't care, don't care */ imx233_lcdif_set_data_format(false, false, false); /* RGB565, don't care, don't care */
imx233_lcdif_dma_send(lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT); lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0],
imx233_lcdif_wait_ready(); LCD_WIDTH * LCD_HEIGHT, 1);
imx233_lcdif_dma_send(FRAME, LCD_WIDTH, LCD_HEIGHT);
} }
void lcd_update_rect(int x, int y, int width, int height) void lcd_update_rect(int x, int y, int width, int height)

View file

@ -0,0 +1,46 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 by Amaury Pouly
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "system.h"
#include "power.h"
#include "tuner.h"
#include "fmradio_i2c.h"
#include "pinctrl-imx233.h"
static bool tuner_enable = false;
bool tuner_power(bool enable)
{
if(enable != tuner_enable)
{
fmradio_i2c_enable(enable);
/* CE is B029 (active high) */
imx233_enable_gpio_output(0, 29, enable);
imx233_set_gpio_output(0, 29, enable);
tuner_enable = enable;
}
return tuner_enable;
}
bool tuner_powered(void)
{
return tuner_enable;
}

View file

@ -25,6 +25,10 @@
#include "ssp-imx233.h" #include "ssp-imx233.h"
#include "pinctrl-imx233.h" #include "pinctrl-imx233.h"
#include "button-target.h" #include "button-target.h"
#include "fat.h"
#include "disk.h"
#include "usb.h"
#include "debug.h"
/** /**
* This code assumes a single SD card slot * This code assumes a single SD card slot
@ -37,7 +41,13 @@
#endif #endif
static tCardInfo card_info; static tCardInfo card_info;
static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
static struct mutex sd_mutex; static struct mutex sd_mutex;
static const char sd_thread_name[] = "sd";
static struct event_queue sd_queue;
static int sd_first_drive;
static bool sd_initialized;
static int last_disk_activity;
static void sd_detect_callback(int ssp) static void sd_detect_callback(int ssp)
{ {
@ -53,22 +63,132 @@ static void sd_detect_callback(int ssp)
imx233_ssp_sdmmc_setup_detect(SD_SSP, true, sd_detect_callback); imx233_ssp_sdmmc_setup_detect(SD_SSP, true, sd_detect_callback);
} }
int sd_init(void) void sd_enable(bool on)
{ {
mutex_init(&sd_mutex); static bool sd_enable = false;
if(sd_enable == on)
return;
mutex_lock(&sd_mutex);
if(on)
imx233_ssp_start(SD_SSP);
else
imx233_ssp_stop(SD_SSP);
mutex_unlock(&sd_mutex);
sd_enable = on;
}
static int sd_init_card(void)
{
printf("sd_init_card");
imx233_ssp_start(SD_SSP); imx233_ssp_start(SD_SSP);
imx233_ssp_softreset(SD_SSP); imx233_ssp_softreset(SD_SSP);
imx233_ssp_set_mode(SD_SSP, HW_SSP_CTRL1__SSP_MODE__SD_MMC); imx233_ssp_set_mode(SD_SSP, HW_SSP_CTRL1__SSP_MODE__SD_MMC);
#ifdef SANSA_FUZEPLUS
imx233_ssp_setup_ssp1_sd_mmc_pins(true, 4, PINCTRL_DRIVE_8mA, false);
#endif
imx233_ssp_sdmmc_setup_detect(SD_SSP, true, sd_detect_callback);
/* SSPCLK @ 96MHz /* SSPCLK @ 96MHz
* gives bitrate of 96000 / 240 / 1 = 400kHz */ * gives bitrate of 96000 / 240 / 1 = 400kHz */
imx233_ssp_set_timings(SD_SSP, 240, 0, 0xffff); imx233_ssp_set_timings(SD_SSP, 240, 0, 0xffff);
imx233_ssp_set_bus_width(SD_SSP, 1); imx233_ssp_set_bus_width(SD_SSP, 1);
imx233_ssp_set_block_size(SD_SSP, 9); imx233_ssp_set_block_size(SD_SSP, 9);
card_info.rca = 0;
bool is_v2 = false;
uint32_t resp;
/* go to idle state */
int ret = imx233_ssp_sd_mmc_transfer(SD_SSP, SD_GO_IDLE_STATE, 0, SSP_NO_RESP, NULL, 0, false, false, NULL);
if(ret != 0)
return -1;
/* CMD8 Check for v2 sd card. Must be sent before using ACMD41
Non v2 cards will not respond to this command*/
ret = imx233_ssp_sd_mmc_transfer(SD_SSP, SD_SEND_IF_COND, 0x1AA, SSP_SHORT_RESP, NULL, 0, false, false, &resp);
if(ret == 0 && (resp & 0xFFF) == 0x1AA)
is_v2 = true;
return -10;
}
static void sd_thread(void) NORETURN_ATTR;
static void sd_thread(void)
{
struct queue_event ev;
while (1)
{
queue_wait_w_tmo(&sd_queue, &ev, HZ);
switch(ev.id)
{
case SYS_HOTSWAP_INSERTED:
case SYS_HOTSWAP_EXTRACTED:
{
int microsd_init = 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_mutex); /* lock-out card activity - direct calls
into driver that bypass the fat cache */
/* We now have exclusive control of fat cache and sd */
disk_unmount(sd_first_drive); /* 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.initialized = 0;
if(ev.id == SYS_HOTSWAP_INSERTED)
{
int ret = sd_init_card();
if(ret == 0)
{
ret = disk_mount(sd_first_drive); /* 0 if fail */
if(ret < 0)
DEBUGF("disk_mount failed: %d", ret);
}
else
DEBUGF("sd_init_card failed: %d", ret);
}
/*
* Mount succeeded, or this was an EXTRACTED event,
* in both cases notify the system about the changed filesystems
*/
if(card_info.initialized)
queue_broadcast(SYS_FS_CHANGED, 0);
/* Access is now safe */
mutex_unlock(&sd_mutex);
fat_unlock();
}
break;
case SYS_TIMEOUT:
if(!TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
sd_enable(false);
break;
case SYS_USB_CONNECTED:
usb_acknowledge(SYS_USB_CONNECTED_ACK);
/* Wait until the USB cable is extracted again */
usb_wait_for_disconnect(&sd_queue);
break;
}
}
}
int sd_init(void)
{
mutex_init(&sd_mutex);
queue_init(&sd_queue, true);
create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
#ifdef SANSA_FUZEPLUS
imx233_ssp_setup_ssp1_sd_mmc_pins(true, 4, PINCTRL_DRIVE_8mA, false);
#endif
imx233_ssp_sdmmc_setup_detect(SD_SSP, true, sd_detect_callback);
if(imx233_ssp_sdmmc_detect(SD_SSP))
queue_broadcast(SYS_HOTSWAP_INSERTED, 0);
return 0; return 0;
} }
@ -101,7 +221,7 @@ tCardInfo *card_get_info_target(int card_no)
int sd_num_drives(int first_drive) int sd_num_drives(int first_drive)
{ {
(void) first_drive; sd_first_drive = first_drive;
return 1; return 1;
} }

View file

@ -325,7 +325,6 @@ void imx233_ssp_sd_mmc_power_up_sequence(int ssp)
static int ssp_detect_oneshot_callback(int ssp) static int ssp_detect_oneshot_callback(int ssp)
{ {
printf("ssp_detect_oneshot_callback(%d)", ssp);
if(ssp_detect_cb[ssp - 1]) if(ssp_detect_cb[ssp - 1])
ssp_detect_cb[ssp - 1](ssp); ssp_detect_cb[ssp - 1](ssp);