mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 13:15:18 -05:00
Bulk convert all DOS line endings to UNIX.
For the git migration we want a nice clean repository with UNIX line endings. git does not use svn:eol-style, we just need the file contents to be sane. Sorry everybody. I know this messes up blame. Scumbag *NIX developer says migrating to git will make line ending issues go away; commits giant change to svn which changes line endings anyway. :) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30924 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
d9b7d58fa6
commit
569285794b
59 changed files with 24428 additions and 24428 deletions
|
|
@ -1,166 +1,166 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: debug-s5l8700.c 28719 2010-12-01 18:35:01Z Buschel $
|
||||
*
|
||||
* Copyright © 2008 Rafaël Carré
|
||||
*
|
||||
* 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 <stdbool.h>
|
||||
#include "config.h"
|
||||
#include "kernel.h"
|
||||
#include "debug-target.h"
|
||||
#include "button.h"
|
||||
#include "lcd.h"
|
||||
#include "font.h"
|
||||
#include "storage.h"
|
||||
#include "power.h"
|
||||
#include "pmu-target.h"
|
||||
#include "pcm-target.h"
|
||||
|
||||
/* Skeleton for adding target specific debug info to the debug menu
|
||||
*/
|
||||
|
||||
#define _DEBUG_PRINTF(a, varargs...) lcd_putsf(0, line++, (a), ##varargs);
|
||||
|
||||
extern int lcd_type;
|
||||
bool dbg_hw_info(void)
|
||||
{
|
||||
int line;
|
||||
int i;
|
||||
unsigned int state = 0;
|
||||
const unsigned int max_states=3;
|
||||
|
||||
lcd_clear_display();
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
state=0;
|
||||
while(1)
|
||||
{
|
||||
lcd_clear_display();
|
||||
line = 0;
|
||||
|
||||
if(state == 0)
|
||||
{
|
||||
_DEBUG_PRINTF("CPU:");
|
||||
_DEBUG_PRINTF("current_tick: %d", (unsigned int)current_tick);
|
||||
line++;
|
||||
|
||||
_DEBUG_PRINTF("LCD type: %d", lcd_type);
|
||||
line++;
|
||||
}
|
||||
else if(state==1)
|
||||
{
|
||||
_DEBUG_PRINTF("PMU:");
|
||||
for(i=0;i<7;i++)
|
||||
{
|
||||
char *device[] = {"(unknown)",
|
||||
"(unknown)",
|
||||
"(unknown)",
|
||||
"(unknown)",
|
||||
"(unknown)",
|
||||
"(unknown)",
|
||||
"(unknown)"};
|
||||
_DEBUG_PRINTF("ldo%d %s: %dmV %s",i,
|
||||
pmu_read(0x2e + (i << 1))?" on":"off",
|
||||
900 + pmu_read(0x2d + (i << 1))*100,
|
||||
device[i]);
|
||||
}
|
||||
_DEBUG_PRINTF("cpu voltage: %dmV",625 + pmu_read(0x1e)*25);
|
||||
_DEBUG_PRINTF("memory voltage: %dmV",625 + pmu_read(0x22)*25);
|
||||
line++;
|
||||
_DEBUG_PRINTF("charging: %s", charging_state() ? "true" : "false");
|
||||
_DEBUG_PRINTF("backlight: %s", pmu_read(0x29) ? "on" : "off");
|
||||
_DEBUG_PRINTF("brightness value: %d", pmu_read(0x28));
|
||||
}
|
||||
else if(state==2)
|
||||
{
|
||||
_DEBUG_PRINTF("Audio DMA:");
|
||||
_DEBUG_PRINTF(">%08X %08X %08X %08X %08X", DMAC0C0CONFIG, DMAC0C0SRCADDR,
|
||||
DMAC0C0DESTADDR, DMAC0C0NEXTLLI, DMAC0C0CONTROL);
|
||||
for(i = 0; i < PCM_LLICOUNT; i++)
|
||||
_DEBUG_PRINTF("%08X: %08X %08X %08X %08X", &pcm_lli[i], pcm_lli[i].srcaddr,
|
||||
pcm_lli[i].dstaddr, pcm_lli[i].nextlli, pcm_lli[i].control);
|
||||
_DEBUG_PRINTF("chunk: %08X %08X", pcm_chunksize, pcm_remaining);
|
||||
}
|
||||
else
|
||||
{
|
||||
state=0;
|
||||
}
|
||||
|
||||
|
||||
lcd_update();
|
||||
switch(button_get_w_tmo(HZ/20))
|
||||
{
|
||||
case BUTTON_SCROLL_BACK:
|
||||
if(state!=0) state--;
|
||||
break;
|
||||
|
||||
case BUTTON_SCROLL_FWD:
|
||||
if(state!=max_states-1)
|
||||
{
|
||||
state++;
|
||||
}
|
||||
break;
|
||||
|
||||
case DEBUG_CANCEL:
|
||||
case BUTTON_REL:
|
||||
lcd_setfont(FONT_UI);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
lcd_setfont(FONT_UI);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dbg_ports(void)
|
||||
{
|
||||
int line;
|
||||
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
while(1)
|
||||
{
|
||||
lcd_clear_display();
|
||||
line = 0;
|
||||
|
||||
_DEBUG_PRINTF("GPIO 0: %08x",(unsigned int)PDAT(0));
|
||||
_DEBUG_PRINTF("GPIO 1: %08x",(unsigned int)PDAT(1));
|
||||
_DEBUG_PRINTF("GPIO 2: %08x",(unsigned int)PDAT(2));
|
||||
_DEBUG_PRINTF("GPIO 3: %08x",(unsigned int)PDAT(3));
|
||||
_DEBUG_PRINTF("GPIO 4: %08x",(unsigned int)PDAT(4));
|
||||
_DEBUG_PRINTF("GPIO 5: %08x",(unsigned int)PDAT(5));
|
||||
_DEBUG_PRINTF("GPIO 6: %08x",(unsigned int)PDAT(6));
|
||||
_DEBUG_PRINTF("GPIO 7: %08x",(unsigned int)PDAT(7));
|
||||
_DEBUG_PRINTF("GPIO 8: %08x",(unsigned int)PDAT(8));
|
||||
_DEBUG_PRINTF("GPIO 9: %08x",(unsigned int)PDAT(9));
|
||||
_DEBUG_PRINTF("GPIO 10: %08x",(unsigned int)PDAT(10));
|
||||
_DEBUG_PRINTF("GPIO 11: %08x",(unsigned int)PDAT(11));
|
||||
_DEBUG_PRINTF("GPIO 12: %08x",(unsigned int)PDAT(12));
|
||||
_DEBUG_PRINTF("GPIO 13: %08x",(unsigned int)PDAT(13));
|
||||
_DEBUG_PRINTF("GPIO 14: %08x",(unsigned int)PDAT(14));
|
||||
_DEBUG_PRINTF("GPIO 15: %08x",(unsigned int)PDAT(15));
|
||||
_DEBUG_PRINTF("USEC : %08x",(unsigned int)USEC_TIMER);
|
||||
|
||||
lcd_update();
|
||||
if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
|
||||
break;
|
||||
}
|
||||
lcd_setfont(FONT_UI);
|
||||
return false;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: debug-s5l8700.c 28719 2010-12-01 18:35:01Z Buschel $
|
||||
*
|
||||
* Copyright © 2008 Rafaël Carré
|
||||
*
|
||||
* 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 <stdbool.h>
|
||||
#include "config.h"
|
||||
#include "kernel.h"
|
||||
#include "debug-target.h"
|
||||
#include "button.h"
|
||||
#include "lcd.h"
|
||||
#include "font.h"
|
||||
#include "storage.h"
|
||||
#include "power.h"
|
||||
#include "pmu-target.h"
|
||||
#include "pcm-target.h"
|
||||
|
||||
/* Skeleton for adding target specific debug info to the debug menu
|
||||
*/
|
||||
|
||||
#define _DEBUG_PRINTF(a, varargs...) lcd_putsf(0, line++, (a), ##varargs);
|
||||
|
||||
extern int lcd_type;
|
||||
bool dbg_hw_info(void)
|
||||
{
|
||||
int line;
|
||||
int i;
|
||||
unsigned int state = 0;
|
||||
const unsigned int max_states=3;
|
||||
|
||||
lcd_clear_display();
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
state=0;
|
||||
while(1)
|
||||
{
|
||||
lcd_clear_display();
|
||||
line = 0;
|
||||
|
||||
if(state == 0)
|
||||
{
|
||||
_DEBUG_PRINTF("CPU:");
|
||||
_DEBUG_PRINTF("current_tick: %d", (unsigned int)current_tick);
|
||||
line++;
|
||||
|
||||
_DEBUG_PRINTF("LCD type: %d", lcd_type);
|
||||
line++;
|
||||
}
|
||||
else if(state==1)
|
||||
{
|
||||
_DEBUG_PRINTF("PMU:");
|
||||
for(i=0;i<7;i++)
|
||||
{
|
||||
char *device[] = {"(unknown)",
|
||||
"(unknown)",
|
||||
"(unknown)",
|
||||
"(unknown)",
|
||||
"(unknown)",
|
||||
"(unknown)",
|
||||
"(unknown)"};
|
||||
_DEBUG_PRINTF("ldo%d %s: %dmV %s",i,
|
||||
pmu_read(0x2e + (i << 1))?" on":"off",
|
||||
900 + pmu_read(0x2d + (i << 1))*100,
|
||||
device[i]);
|
||||
}
|
||||
_DEBUG_PRINTF("cpu voltage: %dmV",625 + pmu_read(0x1e)*25);
|
||||
_DEBUG_PRINTF("memory voltage: %dmV",625 + pmu_read(0x22)*25);
|
||||
line++;
|
||||
_DEBUG_PRINTF("charging: %s", charging_state() ? "true" : "false");
|
||||
_DEBUG_PRINTF("backlight: %s", pmu_read(0x29) ? "on" : "off");
|
||||
_DEBUG_PRINTF("brightness value: %d", pmu_read(0x28));
|
||||
}
|
||||
else if(state==2)
|
||||
{
|
||||
_DEBUG_PRINTF("Audio DMA:");
|
||||
_DEBUG_PRINTF(">%08X %08X %08X %08X %08X", DMAC0C0CONFIG, DMAC0C0SRCADDR,
|
||||
DMAC0C0DESTADDR, DMAC0C0NEXTLLI, DMAC0C0CONTROL);
|
||||
for(i = 0; i < PCM_LLICOUNT; i++)
|
||||
_DEBUG_PRINTF("%08X: %08X %08X %08X %08X", &pcm_lli[i], pcm_lli[i].srcaddr,
|
||||
pcm_lli[i].dstaddr, pcm_lli[i].nextlli, pcm_lli[i].control);
|
||||
_DEBUG_PRINTF("chunk: %08X %08X", pcm_chunksize, pcm_remaining);
|
||||
}
|
||||
else
|
||||
{
|
||||
state=0;
|
||||
}
|
||||
|
||||
|
||||
lcd_update();
|
||||
switch(button_get_w_tmo(HZ/20))
|
||||
{
|
||||
case BUTTON_SCROLL_BACK:
|
||||
if(state!=0) state--;
|
||||
break;
|
||||
|
||||
case BUTTON_SCROLL_FWD:
|
||||
if(state!=max_states-1)
|
||||
{
|
||||
state++;
|
||||
}
|
||||
break;
|
||||
|
||||
case DEBUG_CANCEL:
|
||||
case BUTTON_REL:
|
||||
lcd_setfont(FONT_UI);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
lcd_setfont(FONT_UI);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dbg_ports(void)
|
||||
{
|
||||
int line;
|
||||
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
while(1)
|
||||
{
|
||||
lcd_clear_display();
|
||||
line = 0;
|
||||
|
||||
_DEBUG_PRINTF("GPIO 0: %08x",(unsigned int)PDAT(0));
|
||||
_DEBUG_PRINTF("GPIO 1: %08x",(unsigned int)PDAT(1));
|
||||
_DEBUG_PRINTF("GPIO 2: %08x",(unsigned int)PDAT(2));
|
||||
_DEBUG_PRINTF("GPIO 3: %08x",(unsigned int)PDAT(3));
|
||||
_DEBUG_PRINTF("GPIO 4: %08x",(unsigned int)PDAT(4));
|
||||
_DEBUG_PRINTF("GPIO 5: %08x",(unsigned int)PDAT(5));
|
||||
_DEBUG_PRINTF("GPIO 6: %08x",(unsigned int)PDAT(6));
|
||||
_DEBUG_PRINTF("GPIO 7: %08x",(unsigned int)PDAT(7));
|
||||
_DEBUG_PRINTF("GPIO 8: %08x",(unsigned int)PDAT(8));
|
||||
_DEBUG_PRINTF("GPIO 9: %08x",(unsigned int)PDAT(9));
|
||||
_DEBUG_PRINTF("GPIO 10: %08x",(unsigned int)PDAT(10));
|
||||
_DEBUG_PRINTF("GPIO 11: %08x",(unsigned int)PDAT(11));
|
||||
_DEBUG_PRINTF("GPIO 12: %08x",(unsigned int)PDAT(12));
|
||||
_DEBUG_PRINTF("GPIO 13: %08x",(unsigned int)PDAT(13));
|
||||
_DEBUG_PRINTF("GPIO 14: %08x",(unsigned int)PDAT(14));
|
||||
_DEBUG_PRINTF("GPIO 15: %08x",(unsigned int)PDAT(15));
|
||||
_DEBUG_PRINTF("USEC : %08x",(unsigned int)USEC_TIMER);
|
||||
|
||||
lcd_update();
|
||||
if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
|
||||
break;
|
||||
}
|
||||
lcd_setfont(FONT_UI);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,33 +1,33 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: debug-target.h 28522 2010-11-06 14:24:25Z wodz $
|
||||
*
|
||||
* Copyright (C) 2007 by Karl Kurbjun
|
||||
*
|
||||
* 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_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define DEBUG_CANCEL BUTTON_MENU
|
||||
|
||||
bool dbg_hw_info(void);
|
||||
bool dbg_ports(void);
|
||||
|
||||
#endif /* _DEBUG_TARGET_H_ */
|
||||
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: debug-target.h 28522 2010-11-06 14:24:25Z wodz $
|
||||
*
|
||||
* Copyright (C) 2007 by Karl Kurbjun
|
||||
*
|
||||
* 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_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define DEBUG_CANCEL BUTTON_MENU
|
||||
|
||||
bool dbg_hw_info(void);
|
||||
bool dbg_ports(void);
|
||||
|
||||
#endif /* _DEBUG_TARGET_H_ */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,196 +1,196 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: i2c-s5l8700.c 28589 2010-11-14 15:19:30Z theseven $
|
||||
*
|
||||
* Copyright (C) 2009 by Bertrik Sikken
|
||||
*
|
||||
* 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 "i2c-s5l8702.h"
|
||||
|
||||
/* Driver for the s5l8700 built-in I2C controller in master mode
|
||||
|
||||
Both the i2c_read and i2c_write function take the following arguments:
|
||||
* slave, the address of the i2c slave device to read from / write to
|
||||
* address, optional sub-address in the i2c slave (unused if -1)
|
||||
* len, number of bytes to be transfered
|
||||
* data, pointer to data to be transfered
|
||||
A return value < 0 indicates an error.
|
||||
|
||||
Note:
|
||||
* blocks the calling thread for the entire duraton of the i2c transfer but
|
||||
uses wakeup_wait/wakeup_signal to allow other threads to run.
|
||||
* ACK from slave is not checked, so functions never return an error
|
||||
*/
|
||||
|
||||
static struct mutex i2c_mtx[2];
|
||||
|
||||
static void i2c_on(int bus)
|
||||
{
|
||||
/* enable I2C clock */
|
||||
PWRCON(1) &= ~(1 << 4);
|
||||
|
||||
IICCON(bus) = (1 << 7) | /* ACK_GEN */
|
||||
(0 << 6) | /* CLKSEL = PCLK/16 */
|
||||
(1 << 5) | /* INT_EN */
|
||||
(1 << 4) | /* IRQ clear */
|
||||
(7 << 0); /* CK_REG */
|
||||
|
||||
/* serial output on */
|
||||
IICSTAT(bus) = (1 << 4);
|
||||
}
|
||||
|
||||
static void i2c_off(int bus)
|
||||
{
|
||||
/* serial output off */
|
||||
IICSTAT(bus) = 0;
|
||||
|
||||
/* disable I2C clock */
|
||||
PWRCON(1) |= (1 << 4);
|
||||
}
|
||||
|
||||
void i2c_init()
|
||||
{
|
||||
mutex_init(&i2c_mtx[0]);
|
||||
mutex_init(&i2c_mtx[1]);
|
||||
}
|
||||
|
||||
int i2c_write(int bus, unsigned char slave, int address, int len, const unsigned char *data)
|
||||
{
|
||||
mutex_lock(&i2c_mtx[bus]);
|
||||
i2c_on(bus);
|
||||
long timeout = current_tick + HZ / 50;
|
||||
|
||||
/* START */
|
||||
IICDS(bus) = slave & ~1;
|
||||
IICSTAT(bus) = 0xF0;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICCON(bus) & 0x10) == 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (address >= 0) {
|
||||
/* write address */
|
||||
IICDS(bus) = address;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICCON(bus) & 0x10) == 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* write data */
|
||||
while (len--) {
|
||||
IICDS(bus) = *data++;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICCON(bus) & 0x10) == 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* STOP */
|
||||
IICSTAT(bus) = 0xD0;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICSTAT(bus) & (1 << 5)) != 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 5;
|
||||
}
|
||||
|
||||
i2c_off(bus);
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_read(int bus, unsigned char slave, int address, int len, unsigned char *data)
|
||||
{
|
||||
mutex_lock(&i2c_mtx[bus]);
|
||||
i2c_on(bus);
|
||||
long timeout = current_tick + HZ / 50;
|
||||
|
||||
if (address >= 0) {
|
||||
/* START */
|
||||
IICDS(bus) = slave & ~1;
|
||||
IICSTAT(bus) = 0xF0;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICCON(bus) & 0x10) == 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write address */
|
||||
IICDS(bus) = address;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICCON(bus) & 0x10) == 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* (repeated) START */
|
||||
IICDS(bus) = slave | 1;
|
||||
IICSTAT(bus) = 0xB0;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICCON(bus) & 0x10) == 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
while (len--) {
|
||||
IICCON(bus) = (len == 0) ? 0x33 : 0xB3; /* NAK or ACK */
|
||||
while ((IICCON(bus) & 0x10) == 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 4;
|
||||
}
|
||||
*data++ = IICDS(bus);
|
||||
}
|
||||
|
||||
/* STOP */
|
||||
IICSTAT(bus) = 0x90;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICSTAT(bus) & (1 << 5)) != 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 5;
|
||||
}
|
||||
|
||||
i2c_off(bus);
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: i2c-s5l8700.c 28589 2010-11-14 15:19:30Z theseven $
|
||||
*
|
||||
* Copyright (C) 2009 by Bertrik Sikken
|
||||
*
|
||||
* 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 "i2c-s5l8702.h"
|
||||
|
||||
/* Driver for the s5l8700 built-in I2C controller in master mode
|
||||
|
||||
Both the i2c_read and i2c_write function take the following arguments:
|
||||
* slave, the address of the i2c slave device to read from / write to
|
||||
* address, optional sub-address in the i2c slave (unused if -1)
|
||||
* len, number of bytes to be transfered
|
||||
* data, pointer to data to be transfered
|
||||
A return value < 0 indicates an error.
|
||||
|
||||
Note:
|
||||
* blocks the calling thread for the entire duraton of the i2c transfer but
|
||||
uses wakeup_wait/wakeup_signal to allow other threads to run.
|
||||
* ACK from slave is not checked, so functions never return an error
|
||||
*/
|
||||
|
||||
static struct mutex i2c_mtx[2];
|
||||
|
||||
static void i2c_on(int bus)
|
||||
{
|
||||
/* enable I2C clock */
|
||||
PWRCON(1) &= ~(1 << 4);
|
||||
|
||||
IICCON(bus) = (1 << 7) | /* ACK_GEN */
|
||||
(0 << 6) | /* CLKSEL = PCLK/16 */
|
||||
(1 << 5) | /* INT_EN */
|
||||
(1 << 4) | /* IRQ clear */
|
||||
(7 << 0); /* CK_REG */
|
||||
|
||||
/* serial output on */
|
||||
IICSTAT(bus) = (1 << 4);
|
||||
}
|
||||
|
||||
static void i2c_off(int bus)
|
||||
{
|
||||
/* serial output off */
|
||||
IICSTAT(bus) = 0;
|
||||
|
||||
/* disable I2C clock */
|
||||
PWRCON(1) |= (1 << 4);
|
||||
}
|
||||
|
||||
void i2c_init()
|
||||
{
|
||||
mutex_init(&i2c_mtx[0]);
|
||||
mutex_init(&i2c_mtx[1]);
|
||||
}
|
||||
|
||||
int i2c_write(int bus, unsigned char slave, int address, int len, const unsigned char *data)
|
||||
{
|
||||
mutex_lock(&i2c_mtx[bus]);
|
||||
i2c_on(bus);
|
||||
long timeout = current_tick + HZ / 50;
|
||||
|
||||
/* START */
|
||||
IICDS(bus) = slave & ~1;
|
||||
IICSTAT(bus) = 0xF0;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICCON(bus) & 0x10) == 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (address >= 0) {
|
||||
/* write address */
|
||||
IICDS(bus) = address;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICCON(bus) & 0x10) == 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* write data */
|
||||
while (len--) {
|
||||
IICDS(bus) = *data++;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICCON(bus) & 0x10) == 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* STOP */
|
||||
IICSTAT(bus) = 0xD0;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICSTAT(bus) & (1 << 5)) != 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 5;
|
||||
}
|
||||
|
||||
i2c_off(bus);
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_read(int bus, unsigned char slave, int address, int len, unsigned char *data)
|
||||
{
|
||||
mutex_lock(&i2c_mtx[bus]);
|
||||
i2c_on(bus);
|
||||
long timeout = current_tick + HZ / 50;
|
||||
|
||||
if (address >= 0) {
|
||||
/* START */
|
||||
IICDS(bus) = slave & ~1;
|
||||
IICSTAT(bus) = 0xF0;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICCON(bus) & 0x10) == 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write address */
|
||||
IICDS(bus) = address;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICCON(bus) & 0x10) == 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* (repeated) START */
|
||||
IICDS(bus) = slave | 1;
|
||||
IICSTAT(bus) = 0xB0;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICCON(bus) & 0x10) == 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
while (len--) {
|
||||
IICCON(bus) = (len == 0) ? 0x33 : 0xB3; /* NAK or ACK */
|
||||
while ((IICCON(bus) & 0x10) == 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 4;
|
||||
}
|
||||
*data++ = IICDS(bus);
|
||||
}
|
||||
|
||||
/* STOP */
|
||||
IICSTAT(bus) = 0x90;
|
||||
IICCON(bus) = 0xB3;
|
||||
while ((IICSTAT(bus) & (1 << 5)) != 0)
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 5;
|
||||
}
|
||||
|
||||
i2c_off(bus);
|
||||
mutex_unlock(&i2c_mtx[bus]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,56 +1,56 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: kernel-s5l8700.c 28795 2010-12-11 17:52:52Z Buschel $
|
||||
*
|
||||
* Copyright © 2009 Bertrik Sikken
|
||||
*
|
||||
* 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"
|
||||
|
||||
/* S5L8702 driver for the kernel timer
|
||||
|
||||
Timer B is configured as a 10 kHz timer
|
||||
*/
|
||||
|
||||
void INT_TIMERB(void)
|
||||
{
|
||||
/* clear interrupt */
|
||||
TBCON = TBCON;
|
||||
|
||||
call_tick_tasks(); /* Run through the list of tick tasks */
|
||||
}
|
||||
|
||||
void tick_start(unsigned int interval_in_ms)
|
||||
{
|
||||
int cycles = 10 * interval_in_ms;
|
||||
|
||||
/* configure timer for 10 kHz */
|
||||
TBCMD = (1 << 1); /* TB_CLR */
|
||||
TBPRE = 337 - 1; /* prescaler */
|
||||
TBCON = (0 << 13) | /* TB_INT1_EN */
|
||||
(1 << 12) | /* TB_INT0_EN */
|
||||
(0 << 11) | /* TB_START */
|
||||
(2 << 8) | /* TB_CS = PCLK / 16 */
|
||||
(0 << 4); /* TB_MODE_SEL = interval mode */
|
||||
TBDATA0 = cycles; /* set interval period */
|
||||
TBCMD = (1 << 0); /* TB_EN */
|
||||
|
||||
/* enable timer interrupt */
|
||||
VIC0INTENABLE = 1 << IRQ_TIMER;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: kernel-s5l8700.c 28795 2010-12-11 17:52:52Z Buschel $
|
||||
*
|
||||
* Copyright © 2009 Bertrik Sikken
|
||||
*
|
||||
* 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"
|
||||
|
||||
/* S5L8702 driver for the kernel timer
|
||||
|
||||
Timer B is configured as a 10 kHz timer
|
||||
*/
|
||||
|
||||
void INT_TIMERB(void)
|
||||
{
|
||||
/* clear interrupt */
|
||||
TBCON = TBCON;
|
||||
|
||||
call_tick_tasks(); /* Run through the list of tick tasks */
|
||||
}
|
||||
|
||||
void tick_start(unsigned int interval_in_ms)
|
||||
{
|
||||
int cycles = 10 * interval_in_ms;
|
||||
|
||||
/* configure timer for 10 kHz */
|
||||
TBCMD = (1 << 1); /* TB_CLR */
|
||||
TBPRE = 337 - 1; /* prescaler */
|
||||
TBCON = (0 << 13) | /* TB_INT1_EN */
|
||||
(1 << 12) | /* TB_INT0_EN */
|
||||
(0 << 11) | /* TB_START */
|
||||
(2 << 8) | /* TB_CS = PCLK / 16 */
|
||||
(0 << 4); /* TB_MODE_SEL = interval mode */
|
||||
TBDATA0 = cycles; /* set interval period */
|
||||
TBCMD = (1 << 0); /* TB_EN */
|
||||
|
||||
/* enable timer interrupt */
|
||||
VIC0INTENABLE = 1 << IRQ_TIMER;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,228 +1,228 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: pcm-s5l8700.c 28600 2010-11-14 19:49:20Z Buschel $
|
||||
*
|
||||
* Copyright © 2011 Michael Sparmann
|
||||
*
|
||||
* 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 <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "audio.h"
|
||||
#include "s5l8702.h"
|
||||
#include "panic.h"
|
||||
#include "audiohw.h"
|
||||
#include "pcm.h"
|
||||
#include "pcm-internal.h"
|
||||
#include "pcm_sampr.h"
|
||||
#include "mmu-arm.h"
|
||||
#include "pcm-target.h"
|
||||
|
||||
static volatile int locked = 0;
|
||||
static const int zerosample = 0;
|
||||
static unsigned char dblbuf[2][PCM_WATERMARK * 4];
|
||||
static int active_dblbuf;
|
||||
struct dma_lli pcm_lli[PCM_LLICOUNT] __attribute__((aligned(16)));
|
||||
static struct dma_lli* lastlli;
|
||||
static const unsigned char* dataptr;
|
||||
size_t pcm_remaining;
|
||||
size_t pcm_chunksize;
|
||||
|
||||
/* Mask the DMA interrupt */
|
||||
void pcm_play_lock(void)
|
||||
{
|
||||
if (locked++ == 0) {
|
||||
//TODO: Urgh, I don't like that at all...
|
||||
VIC0INTENCLEAR = 1 << IRQ_DMAC0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unmask the DMA interrupt if enabled */
|
||||
void pcm_play_unlock(void)
|
||||
{
|
||||
if (--locked == 0) {
|
||||
VIC0INTENABLE = 1 << IRQ_DMAC0;
|
||||
}
|
||||
}
|
||||
|
||||
void INT_DMAC0C0(void) ICODE_ATTR;
|
||||
void INT_DMAC0C0(void)
|
||||
{
|
||||
DMAC0INTTCCLR = 1;
|
||||
if (!pcm_remaining)
|
||||
{
|
||||
pcm_play_get_more_callback((void**)&dataptr, &pcm_remaining);
|
||||
pcm_chunksize = pcm_remaining;
|
||||
}
|
||||
if (!pcm_remaining)
|
||||
{
|
||||
pcm_lli->nextlli = NULL;
|
||||
pcm_lli->control = 0x75249000;
|
||||
clean_dcache();
|
||||
return;
|
||||
}
|
||||
uint32_t lastsize = MIN(PCM_WATERMARK * 4, pcm_remaining / 2 + 1) & ~1;
|
||||
pcm_remaining -= lastsize;
|
||||
if (pcm_remaining) lastlli = &pcm_lli[ARRAYLEN(pcm_lli) - 1];
|
||||
else lastlli = pcm_lli;
|
||||
uint32_t chunksize = MIN(PCM_CHUNKSIZE * 4 - lastsize, pcm_remaining);
|
||||
if (pcm_remaining > chunksize && chunksize > pcm_remaining - PCM_WATERMARK * 8)
|
||||
chunksize = pcm_remaining - PCM_WATERMARK * 8;
|
||||
pcm_remaining -= chunksize;
|
||||
bool last = !chunksize;
|
||||
int i = 0;
|
||||
while (chunksize)
|
||||
{
|
||||
uint32_t thislli = MIN(PCM_LLIMAX * 4, chunksize);
|
||||
chunksize -= thislli;
|
||||
pcm_lli[i].srcaddr = (void*)dataptr;
|
||||
pcm_lli[i].dstaddr = (void*)((int)&I2STXDB0);
|
||||
pcm_lli[i].nextlli = chunksize ? &pcm_lli[i + 1] : lastlli;
|
||||
pcm_lli[i].control = (chunksize ? 0x75249000 : 0xf5249000) | (thislli / 2);
|
||||
dataptr += thislli;
|
||||
i++;
|
||||
}
|
||||
if (!pcm_remaining)
|
||||
{
|
||||
memcpy(dblbuf[active_dblbuf], dataptr, lastsize);
|
||||
lastlli->srcaddr = dblbuf[active_dblbuf];
|
||||
active_dblbuf ^= 1;
|
||||
}
|
||||
else lastlli->srcaddr = dataptr;
|
||||
lastlli->dstaddr = (void*)((int)&I2STXDB0);
|
||||
lastlli->nextlli = last ? NULL : pcm_lli;
|
||||
lastlli->control = (last ? 0xf5249000 : 0x75249000) | (lastsize / 2);
|
||||
dataptr += lastsize;
|
||||
clean_dcache();
|
||||
if (!(DMAC0C0CONFIG & 1) && (pcm_lli[0].control & 0xfff))
|
||||
{
|
||||
DMAC0C0LLI = pcm_lli[0];
|
||||
DMAC0C0CONFIG = 0x8a81;
|
||||
}
|
||||
else DMAC0C0NEXTLLI = pcm_lli;
|
||||
|
||||
pcm_play_dma_started_callback();
|
||||
}
|
||||
|
||||
void pcm_play_dma_start(const void* addr, size_t size)
|
||||
{
|
||||
dataptr = (const unsigned char*)addr;
|
||||
pcm_remaining = size;
|
||||
I2STXCOM = 0xe;
|
||||
DMAC0CONFIG |= 4;
|
||||
INT_DMAC0C0();
|
||||
}
|
||||
|
||||
void pcm_play_dma_stop(void)
|
||||
{
|
||||
DMAC0C0CONFIG = 0x8a80;
|
||||
I2STXCOM = 0xa;
|
||||
}
|
||||
|
||||
/* pause playback by disabling LRCK */
|
||||
void pcm_play_dma_pause(bool pause)
|
||||
{
|
||||
if (pause) I2STXCOM |= 1;
|
||||
else I2STXCOM &= ~1;
|
||||
}
|
||||
|
||||
void pcm_play_dma_init(void)
|
||||
{
|
||||
PWRCON(0) &= ~(1 << 4);
|
||||
PWRCON(1) &= ~(1 << 7);
|
||||
I2S40 = 0x110;
|
||||
I2STXCON = 0xb100059;
|
||||
I2SCLKCON = 1;
|
||||
VIC0INTENABLE = 1 << IRQ_DMAC0;
|
||||
|
||||
audiohw_preinit();
|
||||
}
|
||||
|
||||
void pcm_play_dma_postinit(void)
|
||||
{
|
||||
audiohw_postinit();
|
||||
}
|
||||
|
||||
void pcm_dma_apply_settings(void)
|
||||
{
|
||||
}
|
||||
|
||||
size_t pcm_get_bytes_waiting(void)
|
||||
{
|
||||
int bytes = pcm_remaining;
|
||||
const struct dma_lli* lli = (const struct dma_lli*)((int)&DMAC0C0LLI);
|
||||
while (lli)
|
||||
{
|
||||
bytes += (lli->control & 0xfff) * 2;
|
||||
if (lli == lastlli) break;
|
||||
lli = lli->nextlli;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
const void* pcm_play_dma_get_peak_buffer(int *count)
|
||||
{
|
||||
*count = (DMAC0C0LLI.control & 0xfff) * 2;
|
||||
return (void*)(((uint32_t)DMAC0C0LLI.srcaddr) & ~3);
|
||||
}
|
||||
|
||||
#ifdef HAVE_PCM_DMA_ADDRESS
|
||||
void * pcm_dma_addr(void *addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Recording DMA transfer
|
||||
**/
|
||||
#ifdef HAVE_RECORDING
|
||||
void pcm_rec_lock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void pcm_rec_unlock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void pcm_rec_dma_stop(void)
|
||||
{
|
||||
}
|
||||
|
||||
void pcm_rec_dma_start(void *addr, size_t size)
|
||||
{
|
||||
(void)addr;
|
||||
(void)size;
|
||||
}
|
||||
|
||||
void pcm_rec_dma_close(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void pcm_rec_dma_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const void * pcm_rec_dma_get_peak_buffer(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* HAVE_RECORDING */
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: pcm-s5l8700.c 28600 2010-11-14 19:49:20Z Buschel $
|
||||
*
|
||||
* Copyright © 2011 Michael Sparmann
|
||||
*
|
||||
* 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 <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "audio.h"
|
||||
#include "s5l8702.h"
|
||||
#include "panic.h"
|
||||
#include "audiohw.h"
|
||||
#include "pcm.h"
|
||||
#include "pcm-internal.h"
|
||||
#include "pcm_sampr.h"
|
||||
#include "mmu-arm.h"
|
||||
#include "pcm-target.h"
|
||||
|
||||
static volatile int locked = 0;
|
||||
static const int zerosample = 0;
|
||||
static unsigned char dblbuf[2][PCM_WATERMARK * 4];
|
||||
static int active_dblbuf;
|
||||
struct dma_lli pcm_lli[PCM_LLICOUNT] __attribute__((aligned(16)));
|
||||
static struct dma_lli* lastlli;
|
||||
static const unsigned char* dataptr;
|
||||
size_t pcm_remaining;
|
||||
size_t pcm_chunksize;
|
||||
|
||||
/* Mask the DMA interrupt */
|
||||
void pcm_play_lock(void)
|
||||
{
|
||||
if (locked++ == 0) {
|
||||
//TODO: Urgh, I don't like that at all...
|
||||
VIC0INTENCLEAR = 1 << IRQ_DMAC0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unmask the DMA interrupt if enabled */
|
||||
void pcm_play_unlock(void)
|
||||
{
|
||||
if (--locked == 0) {
|
||||
VIC0INTENABLE = 1 << IRQ_DMAC0;
|
||||
}
|
||||
}
|
||||
|
||||
void INT_DMAC0C0(void) ICODE_ATTR;
|
||||
void INT_DMAC0C0(void)
|
||||
{
|
||||
DMAC0INTTCCLR = 1;
|
||||
if (!pcm_remaining)
|
||||
{
|
||||
pcm_play_get_more_callback((void**)&dataptr, &pcm_remaining);
|
||||
pcm_chunksize = pcm_remaining;
|
||||
}
|
||||
if (!pcm_remaining)
|
||||
{
|
||||
pcm_lli->nextlli = NULL;
|
||||
pcm_lli->control = 0x75249000;
|
||||
clean_dcache();
|
||||
return;
|
||||
}
|
||||
uint32_t lastsize = MIN(PCM_WATERMARK * 4, pcm_remaining / 2 + 1) & ~1;
|
||||
pcm_remaining -= lastsize;
|
||||
if (pcm_remaining) lastlli = &pcm_lli[ARRAYLEN(pcm_lli) - 1];
|
||||
else lastlli = pcm_lli;
|
||||
uint32_t chunksize = MIN(PCM_CHUNKSIZE * 4 - lastsize, pcm_remaining);
|
||||
if (pcm_remaining > chunksize && chunksize > pcm_remaining - PCM_WATERMARK * 8)
|
||||
chunksize = pcm_remaining - PCM_WATERMARK * 8;
|
||||
pcm_remaining -= chunksize;
|
||||
bool last = !chunksize;
|
||||
int i = 0;
|
||||
while (chunksize)
|
||||
{
|
||||
uint32_t thislli = MIN(PCM_LLIMAX * 4, chunksize);
|
||||
chunksize -= thislli;
|
||||
pcm_lli[i].srcaddr = (void*)dataptr;
|
||||
pcm_lli[i].dstaddr = (void*)((int)&I2STXDB0);
|
||||
pcm_lli[i].nextlli = chunksize ? &pcm_lli[i + 1] : lastlli;
|
||||
pcm_lli[i].control = (chunksize ? 0x75249000 : 0xf5249000) | (thislli / 2);
|
||||
dataptr += thislli;
|
||||
i++;
|
||||
}
|
||||
if (!pcm_remaining)
|
||||
{
|
||||
memcpy(dblbuf[active_dblbuf], dataptr, lastsize);
|
||||
lastlli->srcaddr = dblbuf[active_dblbuf];
|
||||
active_dblbuf ^= 1;
|
||||
}
|
||||
else lastlli->srcaddr = dataptr;
|
||||
lastlli->dstaddr = (void*)((int)&I2STXDB0);
|
||||
lastlli->nextlli = last ? NULL : pcm_lli;
|
||||
lastlli->control = (last ? 0xf5249000 : 0x75249000) | (lastsize / 2);
|
||||
dataptr += lastsize;
|
||||
clean_dcache();
|
||||
if (!(DMAC0C0CONFIG & 1) && (pcm_lli[0].control & 0xfff))
|
||||
{
|
||||
DMAC0C0LLI = pcm_lli[0];
|
||||
DMAC0C0CONFIG = 0x8a81;
|
||||
}
|
||||
else DMAC0C0NEXTLLI = pcm_lli;
|
||||
|
||||
pcm_play_dma_started_callback();
|
||||
}
|
||||
|
||||
void pcm_play_dma_start(const void* addr, size_t size)
|
||||
{
|
||||
dataptr = (const unsigned char*)addr;
|
||||
pcm_remaining = size;
|
||||
I2STXCOM = 0xe;
|
||||
DMAC0CONFIG |= 4;
|
||||
INT_DMAC0C0();
|
||||
}
|
||||
|
||||
void pcm_play_dma_stop(void)
|
||||
{
|
||||
DMAC0C0CONFIG = 0x8a80;
|
||||
I2STXCOM = 0xa;
|
||||
}
|
||||
|
||||
/* pause playback by disabling LRCK */
|
||||
void pcm_play_dma_pause(bool pause)
|
||||
{
|
||||
if (pause) I2STXCOM |= 1;
|
||||
else I2STXCOM &= ~1;
|
||||
}
|
||||
|
||||
void pcm_play_dma_init(void)
|
||||
{
|
||||
PWRCON(0) &= ~(1 << 4);
|
||||
PWRCON(1) &= ~(1 << 7);
|
||||
I2S40 = 0x110;
|
||||
I2STXCON = 0xb100059;
|
||||
I2SCLKCON = 1;
|
||||
VIC0INTENABLE = 1 << IRQ_DMAC0;
|
||||
|
||||
audiohw_preinit();
|
||||
}
|
||||
|
||||
void pcm_play_dma_postinit(void)
|
||||
{
|
||||
audiohw_postinit();
|
||||
}
|
||||
|
||||
void pcm_dma_apply_settings(void)
|
||||
{
|
||||
}
|
||||
|
||||
size_t pcm_get_bytes_waiting(void)
|
||||
{
|
||||
int bytes = pcm_remaining;
|
||||
const struct dma_lli* lli = (const struct dma_lli*)((int)&DMAC0C0LLI);
|
||||
while (lli)
|
||||
{
|
||||
bytes += (lli->control & 0xfff) * 2;
|
||||
if (lli == lastlli) break;
|
||||
lli = lli->nextlli;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
const void* pcm_play_dma_get_peak_buffer(int *count)
|
||||
{
|
||||
*count = (DMAC0C0LLI.control & 0xfff) * 2;
|
||||
return (void*)(((uint32_t)DMAC0C0LLI.srcaddr) & ~3);
|
||||
}
|
||||
|
||||
#ifdef HAVE_PCM_DMA_ADDRESS
|
||||
void * pcm_dma_addr(void *addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Recording DMA transfer
|
||||
**/
|
||||
#ifdef HAVE_RECORDING
|
||||
void pcm_rec_lock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void pcm_rec_unlock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void pcm_rec_dma_stop(void)
|
||||
{
|
||||
}
|
||||
|
||||
void pcm_rec_dma_start(void *addr, size_t size)
|
||||
{
|
||||
(void)addr;
|
||||
(void)size;
|
||||
}
|
||||
|
||||
void pcm_rec_dma_close(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void pcm_rec_dma_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const void * pcm_rec_dma_get_peak_buffer(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* HAVE_RECORDING */
|
||||
|
|
|
|||
|
|
@ -1,40 +1,40 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: system-target.h 28791 2010-12-11 09:39:33Z Buschel $
|
||||
*
|
||||
* Copyright (C) 2010 by Michael Sparmann
|
||||
*
|
||||
* 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 __PCM_TARGET_H__
|
||||
#define __PCM_TARGET_H__
|
||||
|
||||
|
||||
/* S5L8702 PCM driver tunables: */
|
||||
#define PCM_LLIMAX (2047) /* Maximum number of samples per LLI */
|
||||
#define PCM_CHUNKSIZE (10747) /* Maximum number of samples to handle with one IRQ */
|
||||
/* (bigger chunks will be segmented internally) */
|
||||
#define PCM_WATERMARK (512) /* Number of remaining samples to schedule IRQ at */
|
||||
|
||||
|
||||
#define PCM_LLICOUNT ((PCM_CHUNKSIZE - PCM_WATERMARK + PCM_LLIMAX - 1) / PCM_LLIMAX + 1)
|
||||
|
||||
|
||||
extern struct dma_lli pcm_lli[PCM_LLICOUNT];
|
||||
extern size_t pcm_remaining;
|
||||
extern size_t pcm_chunksize;
|
||||
|
||||
|
||||
#endif /* __PCM_TARGET_H__ */
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: system-target.h 28791 2010-12-11 09:39:33Z Buschel $
|
||||
*
|
||||
* Copyright (C) 2010 by Michael Sparmann
|
||||
*
|
||||
* 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 __PCM_TARGET_H__
|
||||
#define __PCM_TARGET_H__
|
||||
|
||||
|
||||
/* S5L8702 PCM driver tunables: */
|
||||
#define PCM_LLIMAX (2047) /* Maximum number of samples per LLI */
|
||||
#define PCM_CHUNKSIZE (10747) /* Maximum number of samples to handle with one IRQ */
|
||||
/* (bigger chunks will be segmented internally) */
|
||||
#define PCM_WATERMARK (512) /* Number of remaining samples to schedule IRQ at */
|
||||
|
||||
|
||||
#define PCM_LLICOUNT ((PCM_CHUNKSIZE - PCM_WATERMARK + PCM_LLIMAX - 1) / PCM_LLIMAX + 1)
|
||||
|
||||
|
||||
extern struct dma_lli pcm_lli[PCM_LLICOUNT];
|
||||
extern size_t pcm_remaining;
|
||||
extern size_t pcm_chunksize;
|
||||
|
||||
|
||||
#endif /* __PCM_TARGET_H__ */
|
||||
|
|
|
|||
|
|
@ -1,47 +1,47 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: system-target.h 28791 2010-12-11 09:39:33Z Buschel $
|
||||
*
|
||||
* Copyright (C) 2007 by Dave Chapman
|
||||
*
|
||||
* 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 SYSTEM_TARGET_H
|
||||
#define SYSTEM_TARGET_H
|
||||
|
||||
#include "system-arm.h"
|
||||
#include "mmu-arm.h"
|
||||
|
||||
#define CPUFREQ_SLEEP 32768
|
||||
#define CPUFREQ_MAX 216000000
|
||||
#define CPUFREQ_DEFAULT 108000000
|
||||
#define CPUFREQ_NORMAL 108000000
|
||||
|
||||
#define STORAGE_WANTS_ALIGN
|
||||
|
||||
#define inl(a) (*(volatile unsigned long *) (a))
|
||||
#define outl(a,b) (*(volatile unsigned long *) (b) = (a))
|
||||
#define inb(a) (*(volatile unsigned char *) (a))
|
||||
#define outb(a,b) (*(volatile unsigned char *) (b) = (a))
|
||||
#define inw(a) (*(volatile unsigned short*) (a))
|
||||
#define outw(a,b) (*(volatile unsigned short*) (b) = (a))
|
||||
|
||||
static inline void udelay(unsigned usecs)
|
||||
{
|
||||
unsigned stop = USEC_TIMER + usecs;
|
||||
while (TIME_BEFORE(USEC_TIMER, stop));
|
||||
}
|
||||
|
||||
#endif /* SYSTEM_TARGET_H */
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: system-target.h 28791 2010-12-11 09:39:33Z Buschel $
|
||||
*
|
||||
* Copyright (C) 2007 by Dave Chapman
|
||||
*
|
||||
* 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 SYSTEM_TARGET_H
|
||||
#define SYSTEM_TARGET_H
|
||||
|
||||
#include "system-arm.h"
|
||||
#include "mmu-arm.h"
|
||||
|
||||
#define CPUFREQ_SLEEP 32768
|
||||
#define CPUFREQ_MAX 216000000
|
||||
#define CPUFREQ_DEFAULT 108000000
|
||||
#define CPUFREQ_NORMAL 108000000
|
||||
|
||||
#define STORAGE_WANTS_ALIGN
|
||||
|
||||
#define inl(a) (*(volatile unsigned long *) (a))
|
||||
#define outl(a,b) (*(volatile unsigned long *) (b) = (a))
|
||||
#define inb(a) (*(volatile unsigned char *) (a))
|
||||
#define outb(a,b) (*(volatile unsigned char *) (b) = (a))
|
||||
#define inw(a) (*(volatile unsigned short*) (a))
|
||||
#define outw(a,b) (*(volatile unsigned short*) (b) = (a))
|
||||
|
||||
static inline void udelay(unsigned usecs)
|
||||
{
|
||||
unsigned stop = USEC_TIMER + usecs;
|
||||
while (TIME_BEFORE(USEC_TIMER, stop));
|
||||
}
|
||||
|
||||
#endif /* SYSTEM_TARGET_H */
|
||||
|
|
|
|||
|
|
@ -1,94 +1,94 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: timer-s5l8700.c 23103 2009-10-11 11:35:14Z theseven $
|
||||
*
|
||||
* Copyright (C) 2009 Bertrik Sikken
|
||||
*
|
||||
* 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 "inttypes.h"
|
||||
#include "s5l8702.h"
|
||||
#include "system.h"
|
||||
#include "timer.h"
|
||||
|
||||
//TODO: This needs calibration once we figure out the clocking
|
||||
|
||||
void INT_TIMERC(void)
|
||||
{
|
||||
/* clear interrupt */
|
||||
TCCON = TCCON;
|
||||
|
||||
if (pfn_timer != NULL) {
|
||||
pfn_timer();
|
||||
}
|
||||
}
|
||||
|
||||
bool timer_set(long cycles, bool start)
|
||||
{
|
||||
static const int cs_table[] = {1, 2, 4, 6};
|
||||
int prescale, cs;
|
||||
long count;
|
||||
|
||||
/* stop and clear timer */
|
||||
TCCMD = (1 << 1); /* TD_CLR */
|
||||
|
||||
/* optionally unregister any previously registered timer user */
|
||||
if (start) {
|
||||
if (pfn_unregister != NULL) {
|
||||
pfn_unregister();
|
||||
pfn_unregister = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* scale the count down with the clock select */
|
||||
for (cs = 0; cs < 4; cs++) {
|
||||
count = cycles >> cs_table[cs];
|
||||
if ((count < 65536) || (cs == 3)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* scale the count down with the prescaler */
|
||||
prescale = 1;
|
||||
while (count >= 65536) {
|
||||
count >>= 1;
|
||||
prescale <<= 1;
|
||||
}
|
||||
|
||||
/* configure timer */
|
||||
TCCON = (1 << 12) | /* TD_INT0_EN */
|
||||
(cs << 8) | /* TS_CS */
|
||||
(0 << 4); /* TD_MODE_SEL, 0 = interval mode */
|
||||
TCPRE = prescale - 1;
|
||||
TCDATA0 = count;
|
||||
TCCMD = (1 << 0); /* TD_ENABLE */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool timer_start(void)
|
||||
{
|
||||
TCCMD = (1 << 0); /* TD_ENABLE */
|
||||
return true;
|
||||
}
|
||||
|
||||
void timer_stop(void)
|
||||
{
|
||||
TCCMD = (0 << 0); /* TD_ENABLE */
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: timer-s5l8700.c 23103 2009-10-11 11:35:14Z theseven $
|
||||
*
|
||||
* Copyright (C) 2009 Bertrik Sikken
|
||||
*
|
||||
* 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 "inttypes.h"
|
||||
#include "s5l8702.h"
|
||||
#include "system.h"
|
||||
#include "timer.h"
|
||||
|
||||
//TODO: This needs calibration once we figure out the clocking
|
||||
|
||||
void INT_TIMERC(void)
|
||||
{
|
||||
/* clear interrupt */
|
||||
TCCON = TCCON;
|
||||
|
||||
if (pfn_timer != NULL) {
|
||||
pfn_timer();
|
||||
}
|
||||
}
|
||||
|
||||
bool timer_set(long cycles, bool start)
|
||||
{
|
||||
static const int cs_table[] = {1, 2, 4, 6};
|
||||
int prescale, cs;
|
||||
long count;
|
||||
|
||||
/* stop and clear timer */
|
||||
TCCMD = (1 << 1); /* TD_CLR */
|
||||
|
||||
/* optionally unregister any previously registered timer user */
|
||||
if (start) {
|
||||
if (pfn_unregister != NULL) {
|
||||
pfn_unregister();
|
||||
pfn_unregister = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* scale the count down with the clock select */
|
||||
for (cs = 0; cs < 4; cs++) {
|
||||
count = cycles >> cs_table[cs];
|
||||
if ((count < 65536) || (cs == 3)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* scale the count down with the prescaler */
|
||||
prescale = 1;
|
||||
while (count >= 65536) {
|
||||
count >>= 1;
|
||||
prescale <<= 1;
|
||||
}
|
||||
|
||||
/* configure timer */
|
||||
TCCON = (1 << 12) | /* TD_INT0_EN */
|
||||
(cs << 8) | /* TS_CS */
|
||||
(0 << 4); /* TD_MODE_SEL, 0 = interval mode */
|
||||
TCPRE = prescale - 1;
|
||||
TCDATA0 = count;
|
||||
TCCMD = (1 << 0); /* TD_ENABLE */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool timer_start(void)
|
||||
{
|
||||
TCCMD = (1 << 0); /* TD_ENABLE */
|
||||
return true;
|
||||
}
|
||||
|
||||
void timer_stop(void)
|
||||
{
|
||||
TCCMD = (0 << 0); /* TD_ENABLE */
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue