Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
2e615814
U
U-Boot.Mirror
项目概览
OS
/
U-Boot.Mirror
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
U-Boot.Mirror
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
2e615814
编写于
1月 10, 2007
作者:
W
Wolfgang Denk
提交者:
Wolfgang Denk
1月 10, 2007
浏览文件
操作
浏览文件
下载
差异文件
Merge with /home/mk/11-cmb1920/u-boot#4upstream
上级
787fa158
67fea022
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
958 addition
and
25 deletion
+958
-25
board/spc1920/Makefile
board/spc1920/Makefile
+1
-1
board/spc1920/hpi.c
board/spc1920/hpi.c
+603
-0
board/spc1920/hpi.h
board/spc1920/hpi.h
+28
-0
board/spc1920/pld.h
board/spc1920/pld.h
+1
-1
board/spc1920/spc1920.c
board/spc1920/spc1920.c
+33
-5
cpu/mpc8xx/serial.c
cpu/mpc8xx/serial.c
+11
-2
include/configs/spc1920.h
include/configs/spc1920.h
+87
-15
rtc/Makefile
rtc/Makefile
+1
-1
rtc/ds3231.c
rtc/ds3231.c
+193
-0
未找到文件。
board/spc1920/Makefile
浏览文件 @
2e615814
...
...
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB
=
$(obj)
lib
$(BOARD)
.a
COBJS
=
$(BOARD)
.o
COBJS
=
$(BOARD)
.o
hpi.o
SRCS
:=
$(SOBJS:.o=.S)
$(COBJS:.o=.c)
OBJS
:=
$(
addprefix
$(obj)
,
$(COBJS)
)
...
...
board/spc1920/hpi.c
0 → 100644
浏览文件 @
2e615814
/*
* (C) Copyright 2006
* Markus Klotzbuecher, DENX Software Engineering, mk@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* Host Port Interface (HPI)
*/
/* debug levels:
* 0 : errors
* 1 : usefull info
* 2 : lots of info
* 3 : noisy
*/
#define DEBUG 0
#include <config.h>
#include <common.h>
#include <mpc8xx.h>
#include "pld.h"
#include "hpi.h"
#define _NOT_USED_ 0xFFFFFFFF
/* original table:
* - inserted loops to achieve long CS low and high Periods (~217ns)
* - move cs high 2/4 to the right
*/
const
uint
dsp_table_slow
[]
=
{
/* single read (offset 0x00 in upm ram) */
0x8fffdc04
,
0x0fffdc84
,
0x0fffdc84
,
0x0fffdc00
,
0x3fffdc04
,
0xffffdc84
,
0xffffdc84
,
0xffffdc05
,
/* burst read (offset 0x08 in upm ram) */
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
/* single write (offset 0x18 in upm ram) */
0x8fffd004
,
0x0fffd084
,
0x0fffd084
,
0x3fffd000
,
0xffffd084
,
0xffffd084
,
0xffffd005
,
_NOT_USED_
,
/* burst write (offset 0x20 in upm ram) */
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
/* refresh (offset 0x30 in upm ram) */
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
/* exception (offset 0x3C in upm ram) */
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
};
/* dsp hpi upm ram table
* works fine for noninc access, failes on incremental.
* - removed first word
*/
const
uint
dsp_table_fast
[]
=
{
/* single read (offset 0x00 in upm ram) */
0x8fffdc04
,
0x0fffdc04
,
0x0fffdc00
,
0x3fffdc04
,
0xffffdc05
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
/* burst read (offset 0x08 in upm ram) */
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
/* single write (offset 0x18 in upm ram) */
0x8fffd004
,
0x0fffd004
,
0x3fffd000
,
0xffffd005
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
/* burst write (offset 0x20 in upm ram) */
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
/* refresh (offset 0x30 in upm ram) */
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
/* exception (offset 0x3C in upm ram) */
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
_NOT_USED_
,
};
#ifdef CONFIG_SPC1920_HPI_TEST
#undef HPI_TEST_OSZI
#define HPI_TEST_CHUNKSIZE 0x1000
#define HPI_TEST_PATTERN 0x00000000
#define HPI_TEST_START 0x0
#define HPI_TEST_END 0x30000
#define TINY_AUTOINC_DATA_SIZE 16
/* 32bit words */
#define TINY_AUTOINC_BASE_ADDR 0x0
static
int
hpi_activate
(
void
);
static
void
hpi_inactivate
(
void
);
static
void
dsp_reset
(
void
);
static
int
hpi_write_inc
(
u32
addr
,
u32
*
data
,
u32
count
);
static
int
hpi_read_inc
(
u32
addr
,
u32
*
buf
,
u32
count
);
static
int
hpi_write_noinc
(
u32
addr
,
u32
data
);
static
u32
hpi_read_noinc
(
u32
addr
);
int
hpi_test
(
void
);
static
int
hpi_write_addr_test
(
u32
addr
);
static
int
hpi_read_write_test
(
u32
addr
,
u32
data
);
static
int
hpi_tiny_autoinc_test
(
void
);
#endif
/* CONFIG_SPC1920_HPI_TEST */
/* init the host port interface on UPMA */
int
hpi_init
(
void
)
{
volatile
immap_t
*
immr
=
(
immap_t
*
)
CFG_IMMR
;
volatile
memctl8xx_t
*
memctl
=
&
immr
->
im_memctl
;
volatile
spc1920_pld_t
*
pld
=
(
spc1920_pld_t
*
)
CFG_SPC1920_PLD_BASE
;
upmconfig
(
UPMA
,
(
uint
*
)
dsp_table_slow
,
sizeof
(
dsp_table_slow
)
/
sizeof
(
uint
));
udelay
(
100
);
memctl
->
memc_mamr
=
CFG_MAMR
;
memctl
->
memc_or3
=
CFG_OR3
;
memctl
->
memc_br3
=
CFG_BR3
;
/* reset dsp */
dsp_reset
();
/* activate hpi switch*/
pld
->
dsp_hpi_on
=
0x1
;
udelay
(
100
);
return
0
;
}
#ifdef CONFIG_SPC1920_HPI_TEST
/* activate the Host Port interface */
static
int
hpi_activate
(
void
)
{
volatile
spc1920_pld_t
*
pld
=
(
spc1920_pld_t
*
)
CFG_SPC1920_PLD_BASE
;
/* turn on hpi */
pld
->
dsp_hpi_on
=
0x1
;
udelay
(
5
);
/* turn on the power EN_DSP_POWER high*/
/* currently always on TBD */
/* setup hpi control register */
HPI_HPIC_1
=
(
u16
)
0x0008
;
HPI_HPIC_2
=
(
u16
)
0x0008
;
udelay
(
100
);
return
0
;
}
/* turn off the host port interface */
static
void
hpi_inactivate
(
void
)
{
volatile
spc1920_pld_t
*
pld
=
(
spc1920_pld_t
*
)
CFG_SPC1920_PLD_BASE
;
/* deactivate hpi */
pld
->
dsp_hpi_on
=
0x0
;
/* reset the dsp */
/* pld->dsp_reset = 0x0; */
/* turn off the power EN_DSP_POWER# high*/
/* currently always on TBD */
}
/* reset the DSP */
static
void
dsp_reset
(
void
)
{
volatile
spc1920_pld_t
*
pld
=
(
spc1920_pld_t
*
)
CFG_SPC1920_PLD_BASE
;
pld
->
dsp_reset
=
0x1
;
pld
->
dsp_hpi_on
=
0x0
;
udelay
(
300000
);
pld
->
dsp_reset
=
0x0
;
pld
->
dsp_hpi_on
=
0x1
;
}
/* write using autoinc (count is number of 32bit words) */
static
int
hpi_write_inc
(
u32
addr
,
u32
*
data
,
u32
count
)
{
int
i
;
u16
addr1
,
addr2
;
addr1
=
(
u16
)
((
addr
>>
16
)
&
0xffff
);
/* First HW is most significant */
addr2
=
(
u16
)
(
addr
&
0xffff
);
/* write address */
HPI_HPIA_1
=
addr1
;
HPI_HPIA_2
=
addr2
;
debugX
(
4
,
"writing from data=0x%x to 0x%x
\n
"
,
data
,
(
data
+
count
));
for
(
i
=
0
;
i
<
count
;
i
++
)
{
HPI_HPID_INC_1
=
(
u16
)
((
data
[
i
]
>>
16
)
&
0xffff
);
HPI_HPID_INC_2
=
(
u16
)
(
data
[
i
]
&
0xffff
);
debugX
(
4
,
"hpi_write_inc: data1=0x%x, data2=0x%x
\n
"
,
(
u16
)
((
data
[
i
]
>>
16
)
&
0xffff
),
(
u16
)
(
data
[
i
]
&
0xffff
));
}
#if 0
while(data_ptr < (u16*) (data + count)) {
HPI_HPID_INC_1 = *(data_ptr++);
HPI_HPID_INC_2 = *(data_ptr++);
}
#endif
/* return number of bytes written */
return
count
;
}
/*
* read using autoinc (count is number of 32bit words)
*/
static
int
hpi_read_inc
(
u32
addr
,
u32
*
buf
,
u32
count
)
{
int
i
;
u16
addr1
,
addr2
,
data1
,
data2
;
addr1
=
(
u16
)
((
addr
>>
16
)
&
0xffff
);
/* First HW is most significant */
addr2
=
(
u16
)
(
addr
&
0xffff
);
/* write address */
HPI_HPIA_1
=
addr1
;
HPI_HPIA_2
=
addr2
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
data1
=
HPI_HPID_INC_1
;
data2
=
HPI_HPID_INC_2
;
debugX
(
4
,
"hpi_read_inc: data1=0x%x, data2=0x%x
\n
"
,
data1
,
data2
);
buf
[
i
]
=
(((
u32
)
data1
)
<<
16
)
|
(
data2
&
0xffff
);
}
#if 0
while(buf_ptr < (u16*) (buf + count)) {
*(buf_ptr++) = HPI_HPID_INC_1;
*(buf_ptr++) = HPI_HPID_INC_2;
}
#endif
/* return number of bytes read */
return
count
;
}
/* write to non- auto inc regs */
static
int
hpi_write_noinc
(
u32
addr
,
u32
data
)
{
u16
addr1
,
addr2
,
data1
,
data2
;
addr1
=
(
u16
)
((
addr
>>
16
)
&
0xffff
);
/* First HW is most significant */
addr2
=
(
u16
)
(
addr
&
0xffff
);
/* printf("hpi_write_noinc: addr1=0x%x, addr2=0x%x\n", addr1, addr2); */
HPI_HPIA_1
=
addr1
;
HPI_HPIA_2
=
addr2
;
data1
=
(
u16
)
((
data
>>
16
)
&
0xffff
);
data2
=
(
u16
)
(
data
&
0xffff
);
/* printf("hpi_write_noinc: data1=0x%x, data2=0x%x\n", data1, data2); */
HPI_HPID_NOINC_1
=
data1
;
HPI_HPID_NOINC_2
=
data2
;
return
0
;
}
/* read from non- auto inc regs */
static
u32
hpi_read_noinc
(
u32
addr
)
{
u16
addr1
,
addr2
,
data1
,
data2
;
u32
ret
;
addr1
=
(
u16
)
((
addr
>>
16
)
&
0xffff
);
/* First HW is most significant */
addr2
=
(
u16
)
(
addr
&
0xffff
);
HPI_HPIA_1
=
addr1
;
HPI_HPIA_2
=
addr2
;
/* printf("hpi_read_noinc: addr1=0x%x, addr2=0x%x\n", addr1, addr2); */
data1
=
HPI_HPID_NOINC_1
;
data2
=
HPI_HPID_NOINC_2
;
/* printf("hpi_read_noinc: data1=0x%x, data2=0x%x\n", data1, data2); */
ret
=
(((
u32
)
data1
)
<<
16
)
|
(
data2
&
0xffff
);
return
ret
;
}
/*
* Host Port Interface Tests
*/
#ifndef HPI_TEST_OSZI
/* main test function */
int
hpi_test
(
void
)
{
int
err
=
0
;
u32
i
,
ii
,
pattern
,
tmp
;
pattern
=
HPI_TEST_PATTERN
;
u32
test_data
[
HPI_TEST_CHUNKSIZE
];
u32
read_data
[
HPI_TEST_CHUNKSIZE
];
debugX
(
2
,
"hpi_test: activating hpi..."
);
hpi_activate
();
debugX
(
2
,
"OK.
\n
"
);
#if 0
/* Dump the first 1024 bytes
*
*/
for(i=0; i<1024; i+=4) {
if(i%16==0)
printf("\n0x%08x: ", i);
printf("0x%08x ", hpi_read_noinc(i));
}
#endif
/* HPIA read-write test
*
*/
debugX
(
1
,
"hpi_test: starting HPIA read-write tests...
\n
"
);
err
|=
hpi_write_addr_test
(
0xdeadc0de
);
err
|=
hpi_write_addr_test
(
0xbeefd00d
);
err
|=
hpi_write_addr_test
(
0xabcd1234
);
err
|=
hpi_write_addr_test
(
0xaaaaaaaa
);
if
(
err
)
{
debugX
(
1
,
"hpi_test: HPIA read-write tests: *** FAILED ***
\n
"
);
return
-
1
;
}
debugX
(
1
,
"hpi_test: HPIA read-write tests: OK
\n
"
);
/* read write test using nonincremental data regs
*
*/
debugX
(
1
,
"hpi_test: starting nonincremental tests...
\n
"
);
for
(
i
=
HPI_TEST_START
;
i
<
HPI_TEST_END
;
i
+=
4
)
{
err
|=
hpi_read_write_test
(
i
,
pattern
);
/* stolen from cmd_mem.c */
if
(
pattern
&
0x80000000
)
{
pattern
=
-
pattern
;
/* complement & increment */
}
else
{
pattern
=
~
pattern
;
}
err
|=
hpi_read_write_test
(
i
,
pattern
);
if
(
err
)
{
debugX
(
1
,
"hpi_test: nonincremental tests *** FAILED ***
\n
"
);
return
-
1
;
}
}
debugX
(
1
,
"hpi_test: nonincremental test OK
\n
"
);
/* read write a chunk of data using nonincremental data regs
*
*/
debugX
(
1
,
"hpi_test: starting nonincremental chunk tests...
\n
"
);
pattern
=
HPI_TEST_PATTERN
;
for
(
i
=
HPI_TEST_START
;
i
<
HPI_TEST_END
;
i
+=
4
)
{
hpi_write_noinc
(
i
,
pattern
);
/* stolen from cmd_mem.c */
if
(
pattern
&
0x80000000
)
{
pattern
=
-
pattern
;
/* complement & increment */
}
else
{
pattern
=
~
pattern
;
}
}
pattern
=
HPI_TEST_PATTERN
;
for
(
i
=
HPI_TEST_START
;
i
<
HPI_TEST_END
;
i
+=
4
)
{
tmp
=
hpi_read_noinc
(
i
);
if
(
tmp
!=
pattern
)
{
debugX
(
1
,
"hpi_test: noninc chunk test *** FAILED *** @ 0x%x, written=0x%x, read=0x%x
\n
"
,
i
,
pattern
,
tmp
);
err
=
-
1
;
}
/* stolen from cmd_mem.c */
if
(
pattern
&
0x80000000
)
{
pattern
=
-
pattern
;
/* complement & increment */
}
else
{
pattern
=
~
pattern
;
}
}
if
(
err
)
return
-
1
;
debugX
(
1
,
"hpi_test: nonincremental chunk test OK
\n
"
);
#ifdef DO_TINY_TEST
/* small verbose test using autoinc and nonautoinc to compare
*
*/
debugX
(
1
,
"hpi_test: tiny_autoinc_test...
\n
"
);
hpi_tiny_autoinc_test
();
debugX
(
1
,
"hpi_test: tiny_autoinc_test done
\n
"
);
#endif
/* DO_TINY_TEST */
/* $%& write a chunk of data using the autoincremental regs
*
*/
debugX
(
1
,
"hpi_test: starting autoinc test %d chunks with 0x%x bytes...
\n
"
,
((
HPI_TEST_END
-
HPI_TEST_START
)
/
HPI_TEST_CHUNKSIZE
),
HPI_TEST_CHUNKSIZE
);
for
(
i
=
HPI_TEST_START
;
i
<
((
HPI_TEST_END
-
HPI_TEST_START
)
/
HPI_TEST_CHUNKSIZE
);
i
++
)
{
/* generate the pattern data */
debugX
(
3
,
"generating pattern data: "
);
for
(
ii
=
0
;
ii
<
HPI_TEST_CHUNKSIZE
;
ii
++
)
{
debugX
(
3
,
"0x%x "
,
pattern
);
test_data
[
ii
]
=
pattern
;
read_data
[
ii
]
=
0x0
;
/* zero to be sure */
/* stolen from cmd_mem.c */
if
(
pattern
&
0x80000000
)
{
pattern
=
-
pattern
;
/* complement & increment */
}
else
{
pattern
=
~
pattern
;
}
}
debugX
(
3
,
"done
\n
"
);
debugX
(
2
,
"Writing autoinc data @ 0x%x
\n
"
,
i
);
hpi_write_inc
(
i
,
test_data
,
HPI_TEST_CHUNKSIZE
);
debugX
(
2
,
"Reading autoinc data @ 0x%x
\n
"
,
i
);
hpi_read_inc
(
i
,
read_data
,
HPI_TEST_CHUNKSIZE
);
/* compare */
for
(
ii
=
0
;
ii
<
HPI_TEST_CHUNKSIZE
;
ii
++
)
{
debugX
(
3
,
"hpi_test_autoinc: @ 0x%x, written=0x%x, read=0x%x"
,
i
+
ii
,
test_data
[
ii
],
read_data
[
ii
]);
if
(
read_data
[
ii
]
!=
test_data
[
ii
])
{
debugX
(
0
,
"hpi_test: autoinc test @ 0x%x, written=0x%x, read=0x%x *** FAILED ***
\n
"
,
i
+
ii
,
test_data
[
ii
],
read_data
[
ii
]);
return
-
1
;
}
}
}
debugX
(
1
,
"hpi_test: autoinc test OK
\n
"
);
return
0
;
}
#else
/* HPI_TEST_OSZI */
int
hpi_test
(
void
)
{
int
i
;
u32
read_data
[
TINY_AUTOINC_DATA_SIZE
];
unsigned
int
dummy_data
[
TINY_AUTOINC_DATA_SIZE
]
=
{
0x11112222
,
0x33334444
,
0x55556666
,
0x77778888
,
0x9999aaaa
,
0xbbbbcccc
,
0xddddeeee
,
0xffff1111
,
0x00010002
,
0x00030004
,
0x00050006
,
0x00070008
,
0x0009000a
,
0x000b000c
,
0x000d000e
,
0x000f0001
};
debugX
(
0
,
"hpi_test: activating hpi..."
);
hpi_activate
();
debugX
(
0
,
"OK.
\n
"
);
while
(
1
)
{
led9
(
1
);
debugX
(
0
,
" writing to autoinc...
\n
"
);
hpi_write_inc
(
TINY_AUTOINC_BASE_ADDR
,
dummy_data
,
TINY_AUTOINC_DATA_SIZE
);
debugX
(
0
,
" reading from autoinc...
\n
"
);
hpi_read_inc
(
TINY_AUTOINC_BASE_ADDR
,
read_data
,
TINY_AUTOINC_DATA_SIZE
);
for
(
i
=
0
;
i
<
(
TINY_AUTOINC_DATA_SIZE
);
i
++
)
{
debugX
(
0
,
" written=0x%x, read(inc)=0x%x
\n
"
,
dummy_data
[
i
],
read_data
[
i
]);
}
led9
(
0
);
udelay
(
2000000
);
}
return
0
;
}
#endif
/* test if Host Port Address Register can be written correctly */
static
int
hpi_write_addr_test
(
u32
addr
)
{
u32
read_back
;
/* write address */
HPI_HPIA_1
=
((
u16
)
(
addr
>>
16
));
/* First HW is most significant */
HPI_HPIA_2
=
((
u16
)
addr
);
read_back
=
(((
u32
)
HPI_HPIA_1
)
<<
16
)
|
((
u32
)
HPI_HPIA_2
);
if
(
read_back
==
addr
)
{
debugX
(
2
,
" hpi_write_addr_test OK: written=0x%x, read=0x%x
\n
"
,
addr
,
read_back
);
return
0
;
}
else
{
debugX
(
0
,
" hpi_write_addr_test *** FAILED ***: written=0x%x, read=0x%x
\n
"
,
addr
,
read_back
);
return
-
1
;
}
return
0
;
}
/* test if a simple read/write sequence succeeds */
static
int
hpi_read_write_test
(
u32
addr
,
u32
data
)
{
u32
read_back
;
hpi_write_noinc
(
addr
,
data
);
read_back
=
hpi_read_noinc
(
addr
);
if
(
read_back
==
data
)
{
debugX
(
2
,
" hpi_read_write_test: OK, addr=0x%x written=0x%x, read=0x%x
\n
"
,
addr
,
data
,
read_back
);
return
0
;
}
else
{
debugX
(
0
,
" hpi_read_write_test: *** FAILED ***, addr=0x%x written=0x%x, read=0x%x
\n
"
,
addr
,
data
,
read_back
);
return
-
1
;
}
return
0
;
}
static
int
hpi_tiny_autoinc_test
(
void
)
{
int
i
;
u32
read_data
[
TINY_AUTOINC_DATA_SIZE
];
u32
read_data_noinc
[
TINY_AUTOINC_DATA_SIZE
];
unsigned
int
dummy_data
[
TINY_AUTOINC_DATA_SIZE
]
=
{
0x11112222
,
0x33334444
,
0x55556666
,
0x77778888
,
0x9999aaaa
,
0xbbbbcccc
,
0xddddeeee
,
0xffff1111
,
0x00010002
,
0x00030004
,
0x00050006
,
0x00070008
,
0x0009000a
,
0x000b000c
,
0x000d000e
,
0x000f0001
};
printf
(
" writing to autoinc...
\n
"
);
hpi_write_inc
(
TINY_AUTOINC_BASE_ADDR
,
dummy_data
,
TINY_AUTOINC_DATA_SIZE
);
printf
(
" reading from autoinc...
\n
"
);
hpi_read_inc
(
TINY_AUTOINC_BASE_ADDR
,
read_data
,
TINY_AUTOINC_DATA_SIZE
);
printf
(
" reading from noinc for comparison...
\n
"
);
for
(
i
=
0
;
i
<
(
TINY_AUTOINC_DATA_SIZE
);
i
++
)
read_data_noinc
[
i
]
=
hpi_read_noinc
(
TINY_AUTOINC_BASE_ADDR
+
i
*
4
);
for
(
i
=
0
;
i
<
(
TINY_AUTOINC_DATA_SIZE
);
i
++
)
{
printf
(
" written=0x%x, read(inc)=0x%x, read(noinc)=0x%x
\n
"
,
dummy_data
[
i
],
read_data
[
i
],
read_data_noinc
[
i
]);
}
return
0
;
}
#endif
/* CONFIG_SPC1920_HPI_TEST */
board/spc1920/hpi.h
0 → 100644
浏览文件 @
2e615814
/*
* (C) Copyright 2006
* Markus Klotzbuecher, DENX Software Engineering, mk@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
int
hpi_init
(
void
);
#ifdef CONFIG_SPC1920_HPI_TEST
int
hpi_test
(
void
);
#endif
board/spc1920/pld.h
浏览文件 @
2e615814
...
...
@@ -5,8 +5,8 @@ typedef struct spc1920_pld {
uchar
com1_en
;
uchar
dsp_reset
;
uchar
dsp_hpi_on
;
uchar
superv_mode
;
uchar
codec_dsp_power_en
;
uchar
clk2_en
;
uchar
clk3_select
;
uchar
clk4_select
;
}
spc1920_pld_t
;
...
...
board/spc1920/spc1920.c
浏览文件 @
2e615814
...
...
@@ -27,9 +27,9 @@
#include <common.h>
#include <mpc8xx.h>
#include "pld.h"
#include "hpi.h"
#define _NOT_USED_ 0xFFFFFFFF
/* #define debug(fmt,args...) printf (fmt ,##args) */
static
long
int
dram_size
(
long
int
,
long
int
*
,
long
int
);
...
...
@@ -172,10 +172,12 @@ long int initdram (int board_type)
memctl
->
memc_br1
=
(
CFG_SDRAM_BASE
&
BR_BA_MSK
)
|
BR_MS_UPMB
|
BR_V
;
udelay
(
1000
);
/* initalize the DSP Host Port Interface */
hpi_init
();
/*
PLD
Setup */
memctl
->
memc_or
5
=
CFG_OR5_PRELIM
;
memctl
->
memc_br
5
=
CFG_BR5_PRELIM
;
/*
FRAM
Setup */
memctl
->
memc_or
4
=
CFG_OR4
;
memctl
->
memc_br
4
=
CFG_BR4
;
udelay
(
1000
);
return
(
size_b0
);
...
...
@@ -207,13 +209,31 @@ int board_early_init_f(void)
{
volatile
immap_t
*
immap
=
(
immap_t
*
)
CFG_IMMR
;
/* Set Go/NoGo led (PA15) to color red */
immap
->
im_ioport
.
iop_papar
&=
~
0x1
;
immap
->
im_ioport
.
iop_paodr
&=
~
0x1
;
immap
->
im_ioport
.
iop_padir
|=
0x1
;
immap
->
im_ioport
.
iop_padat
|=
0x1
;
#if 0
/* Turn on LED PD9 */
immap->im_ioport.iop_pdpar &= ~(0x0040);
immap->im_ioport.iop_pddir |= 0x0040;
immap->im_ioport.iop_pddat |= 0x0040;
#endif
/*
* Enable console on SMC1. This requires turning on
* the com2_en signal and SMC1_DISABLE
*/
/* SMC1_DISABLE: PB17 */
immap
->
im_cpm
.
cp_pbodr
&=
~
0x4000
;
immap
->
im_cpm
.
cp_pbpar
&=
~
0x4000
;
immap
->
im_cpm
.
cp_pbdir
|=
0x4000
;
immap
->
im_cpm
.
cp_pbdat
&=
~
0x4000
;
/*
Enable PD10 (COM2_EN)
*/
/*
COM2_EN: PD10
*/
immap
->
im_ioport
.
iop_pdpar
&=
~
0x0020
;
immap
->
im_ioport
.
iop_pddir
&=
~
0x4000
;
immap
->
im_ioport
.
iop_pddir
|=
0x0020
;
...
...
@@ -228,6 +248,14 @@ int board_early_init_f(void)
return
0
;
}
int
last_stage_init
(
void
)
{
#ifdef CONFIG_SPC1920_HPI_TEST
printf
(
"CMB1920 Host Port Interface Test: %s
\n
"
,
hpi_test
()
?
"Failed!"
:
"OK"
);
#endif
return
0
;
}
int
checkboard
(
void
)
{
...
...
cpu/mpc8xx/serial.c
浏览文件 @
2e615814
...
...
@@ -227,8 +227,17 @@ static int smc_init (void)
sp
->
smc_smcm
=
0
;
sp
->
smc_smce
=
0xff
;
#ifdef CFG_SPC1920_SMC1_CLK4
/* clock source is PLD */
*
((
volatile
uchar
*
)
CFG_SPC1920_PLD_BASE
+
6
)
=
0xff
;
#ifdef CFG_SPC1920_SMC1_CLK4
/* clock source is PLD */
/* set freq to 19200 Baud */
*
((
volatile
uchar
*
)
CFG_SPC1920_PLD_BASE
+
6
)
=
0x3
;
/* configure clk4 as input */
im
->
im_ioport
.
iop_pdpar
|=
0x800
;
im
->
im_ioport
.
iop_pddir
&=
~
0x800
;
cp
->
cp_simode
=
0x0000
;
cp
->
cp_simode
|=
0x7000
;
#else
/* Set up the baud rate generator */
smc_setbrg
();
...
...
include/configs/spc1920.h
浏览文件 @
2e615814
...
...
@@ -44,19 +44,19 @@
#define CONFIG_BAUDRATE 19200
/* use PLD CLK4 instead of brg */
#
undef
CFG_SPC1920_SMC1_CLK4
#
define
CFG_SPC1920_SMC1_CLK4
#define CONFIG_8xx_OSCLK 10000000
/* 10 MHz oscillator on EXTCLK */
#define CONFIG_8xx_CPUCLK_DEFAULT 50000000
#define CFG_8xx_CPUCLK_MIN 40000000
#define CFG_8xx_CPUCLK_MAX 133000000
#define CFG_RESET_ADDRESS 0x
f8
000000
#define CFG_RESET_ADDRESS 0x
C0
000000
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_LAST_STAGE_INIT
#if 1
#if 0
#define CONFIG_BOOTDELAY -1 /* autoboot disabled */
#else
#define CONFIG_BOOTDELAY 5
/* autoboot after 5 seconds */
...
...
@@ -83,12 +83,13 @@
#ifndef CONFIG_COMMANDS
#define CONFIG_COMMANDS (CONFIG_CMD_DFL \
| CFG_CMD_ASKENV \
| CFG_CMD_DATE \
| CFG_CMD_ECHO \
| CFG_CMD_IMMAP \
| CFG_CMD_JFFS2 \
| CFG_CMD_PING \
| CFG_CMD_DHCP \
| CFG_CMD_I
MMAP
\
| CFG_CMD_I
2C
\
| CFG_CMD_MII)
/* & ~( CFG_CMD_NET)) */
...
...
@@ -193,13 +194,39 @@
#define CFG_CACHELINE_SIZE 16
/* For all MPC8xx CPUs */
#define CFG_CACHELINE_SHIFT 4
/* log base 2 of the above value */
#ifdef CFG_CMD_DATE
# define CONFIG_RTC_DS3231
# define CFG_I2C_RTC_ADDR 0x68
#endif
/*-----------------------------------------------------------------------
* I2C configuration
*/
#if (CONFIG_COMMANDS & CFG_CMD_I2C)
#define CONFIG_HARD_I2C 1
/* I2C with hardware support */
#define CFG_I2C_SPEED 400000
/* I2C speed and slave address defaults */
#define CFG_I2C_SLAVE 0x7F
/* enable I2C and select the hardware/software driver */
#undef CONFIG_HARD_I2C
/* I2C with hardware support */
#define CONFIG_SOFT_I2C 1
/* I2C bit-banged */
#define CFG_I2C_SPEED 93000
/* 93 kHz is supposed to work */
#define CFG_I2C_SLAVE 0xFE
#ifdef CONFIG_SOFT_I2C
/*
* Software (bit-bang) I2C driver configuration
*/
#define PB_SCL 0x00000020
/* PB 26 */
#define PB_SDA 0x00000010
/* PB 27 */
#define I2C_INIT (immr->im_cpm.cp_pbdir |= PB_SCL)
#define I2C_ACTIVE (immr->im_cpm.cp_pbdir |= PB_SDA)
#define I2C_TRISTATE (immr->im_cpm.cp_pbdir &= ~PB_SDA)
#define I2C_READ ((immr->im_cpm.cp_pbdat & PB_SDA) != 0)
#define I2C_SDA(bit) if(bit) immr->im_cpm.cp_pbdat |= PB_SDA; \
else immr->im_cpm.cp_pbdat &= ~PB_SDA
#define I2C_SCL(bit) if(bit) immr->im_cpm.cp_pbdat |= PB_SCL; \
else immr->im_cpm.cp_pbdat &= ~PB_SCL
#define I2C_DELAY udelay(2)
/* 1/4 I2C clock duration */
#endif
/* CONFIG_SOFT_I2C */
#endif
/*-----------------------------------------------------------------------
...
...
@@ -220,7 +247,7 @@
*-----------------------------------------------------------------------
* PCMCIA config., multi-function pin tri-state
*/
#define CFG_SIUMCR
(SIUMCR_DBGC00 | SIUMCR_DBPC00 | SIUMCR_MLRC01
)
#define CFG_SIUMCR
(SIUMCR_FRC
)
/*-----------------------------------------------------------------------
* TBSCR - Time Base Status and Control 11-26
...
...
@@ -283,7 +310,7 @@
* FLASH timing:
*/
#define CFG_OR_TIMING_FLASH (OR_ACS_DIV1 | OR_TRLX | OR_CSNT_SAM | \
OR_SCY_
3
_CLK | OR_EHTR | OR_BI)
OR_SCY_
6
_CLK | OR_EHTR | OR_BI)
#define CFG_OR0_REMAP (CFG_REMAP_OR_AM | CFG_OR_TIMING_FLASH)
#define CFG_OR0_PRELIM (CFG_PRELIM_OR_AM | CFG_OR_TIMING_FLASH)
...
...
@@ -330,7 +357,56 @@
MBMR_TLFB_4X)
/* 0x04804114 */
/* 0x10802114 */
/* PLD CS5 */
/*
* DSP Host Port Interface CS3
*/
#define CFG_SPC1920_HPI_BASE 0x90000000
#define CFG_PRELIM_OR3_AM 0xF8000000
#define CFG_OR3 (CFG_PRELIM_OR3_AM | \
OR_G5LS | \
OR_SCY_0_CLK | \
OR_BI)
#define CFG_BR3 ((CFG_SPC1920_HPI_BASE & BR_BA_MSK) | \
BR_MS_UPMA | \
BR_PS_16 | \
BR_V);
#define CFG_MAMR (MAMR_GPL_A4DIS | \
MAMR_RLFA_5X | \
MAMR_WLFA_5X)
#define CONFIG_SPC1920_HPI_TEST
#ifdef CONFIG_SPC1920_HPI_TEST
#define HPI_REG(x) (*((volatile u16 *) (CFG_SPC1920_HPI_BASE + x)))
#define HPI_HPIC_1 HPI_REG(0)
#define HPI_HPIC_2 HPI_REG(2)
#define HPI_HPIA_1 HPI_REG(0x2000008)
#define HPI_HPIA_2 HPI_REG(0x2000008 + 2)
#define HPI_HPID_INC_1 HPI_REG(0x1000004)
#define HPI_HPID_INC_2 HPI_REG(0x1000004 + 2)
#define HPI_HPID_NOINC_1 HPI_REG(0x300000c)
#define HPI_HPID_NOINC_2 HPI_REG(0x300000c + 2)
#endif
/* CONFIG_SPC1920_HPI_TEST */
/*
* Ramtron FM18L08 FRAM 32KB on CS4
*/
#define CFG_SPC1920_FRAM_BASE 0x80100000
#define CFG_PRELIM_OR4_AM 0xffff8000
#define CFG_OR4 (CFG_PRELIM_OR4_AM | \
OR_ACS_DIV2 | \
OR_BI | \
OR_SCY_4_CLK | \
OR_TRLX)
#define CFG_BR4 ((CFG_SPC1920_FRAM_BASE & BR_BA_MSK) | BR_PS_8 | BR_V);
/*
* PLD CS5
*/
#define CFG_SPC1920_PLD_BASE 0x80000000
#define CFG_PRELIM_OR5_AM 0xffff8000
...
...
@@ -343,10 +419,6 @@
#define CFG_BR5_PRELIM ((CFG_SPC1920_PLD_BASE & BR_BA_MSK) | BR_PS_8 | BR_V);
/* #define CFG_PLD_BASE 0x30000000 */
/* #define CFG_OR5_PRELIM 0xffff1110 */
/* #define CFG_BR5_PRELIM 0x30000401 */
/*
* Internal Definitions
*
...
...
rtc/Makefile
浏览文件 @
2e615814
...
...
@@ -29,7 +29,7 @@ LIB = $(obj)librtc.a
COBJS
=
date.o
\
bf533_rtc.o ds12887.o ds1302.o ds1306.o ds1307.o
\
ds1337.o ds1374.o ds1556.o ds164x.o ds174x.o
\
ds1337.o ds1374.o ds1556.o ds164x.o ds174x.o
ds3231.o
\
m41t11.o max6900.o m48t35ax.o mc146818.o mk48t59.o
\
mpc5xxx.o mpc8xx.o pcf8563.o s3c24x0_rtc.o rs5c372.o
...
...
rtc/ds3231.c
0 → 100644
浏览文件 @
2e615814
/*
* (C) Copyright 2006
* Markus Klotzbuecher, mk@denx.de
*
* See file CREDITS for list of people who contributed to this
* project.
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
* Extremly Accurate DS3231 Real Time Clock (RTC).
*
* copied from ds1337.c
*/
#include <common.h>
#include <command.h>
#include <rtc.h>
#include <i2c.h>
#if defined(CONFIG_RTC_DS3231) && (CONFIG_COMMANDS & CFG_CMD_DATE)
/*---------------------------------------------------------------------*/
#undef DEBUG_RTC
#ifdef DEBUG_RTC
#define DEBUGR(fmt,args...) printf(fmt ,##args)
#else
#define DEBUGR(fmt,args...)
#endif
/*---------------------------------------------------------------------*/
/*
* RTC register addresses
*/
#define RTC_SEC_REG_ADDR 0x0
#define RTC_MIN_REG_ADDR 0x1
#define RTC_HR_REG_ADDR 0x2
#define RTC_DAY_REG_ADDR 0x3
#define RTC_DATE_REG_ADDR 0x4
#define RTC_MON_REG_ADDR 0x5
#define RTC_YR_REG_ADDR 0x6
#define RTC_CTL_REG_ADDR 0x0e
#define RTC_STAT_REG_ADDR 0x0f
/*
* RTC control register bits
*/
#define RTC_CTL_BIT_A1IE 0x1
/* Alarm 1 interrupt enable */
#define RTC_CTL_BIT_A2IE 0x2
/* Alarm 2 interrupt enable */
#define RTC_CTL_BIT_INTCN 0x4
/* Interrupt control */
#define RTC_CTL_BIT_RS1 0x8
/* Rate select 1 */
#define RTC_CTL_BIT_RS2 0x10
/* Rate select 2 */
#define RTC_CTL_BIT_DOSC 0x80
/* Disable Oscillator */
/*
* RTC status register bits
*/
#define RTC_STAT_BIT_A1F 0x1
/* Alarm 1 flag */
#define RTC_STAT_BIT_A2F 0x2
/* Alarm 2 flag */
#define RTC_STAT_BIT_OSF 0x80
/* Oscillator stop flag */
static
uchar
rtc_read
(
uchar
reg
);
static
void
rtc_write
(
uchar
reg
,
uchar
val
);
static
uchar
bin2bcd
(
unsigned
int
n
);
static
unsigned
bcd2bin
(
uchar
c
);
/*
* Get the current time from the RTC
*/
void
rtc_get
(
struct
rtc_time
*
tmp
)
{
uchar
sec
,
min
,
hour
,
mday
,
wday
,
mon_cent
,
year
,
control
,
status
;
control
=
rtc_read
(
RTC_CTL_REG_ADDR
);
status
=
rtc_read
(
RTC_STAT_REG_ADDR
);
sec
=
rtc_read
(
RTC_SEC_REG_ADDR
);
min
=
rtc_read
(
RTC_MIN_REG_ADDR
);
hour
=
rtc_read
(
RTC_HR_REG_ADDR
);
wday
=
rtc_read
(
RTC_DAY_REG_ADDR
);
mday
=
rtc_read
(
RTC_DATE_REG_ADDR
);
mon_cent
=
rtc_read
(
RTC_MON_REG_ADDR
);
year
=
rtc_read
(
RTC_YR_REG_ADDR
);
DEBUGR
(
"Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
"hr: %02x min: %02x sec: %02x control: %02x status: %02x
\n
"
,
year
,
mon_cent
,
mday
,
wday
,
hour
,
min
,
sec
,
control
,
status
);
if
(
status
&
RTC_STAT_BIT_OSF
)
{
printf
(
"### Warning: RTC oscillator has stopped
\n
"
);
/* clear the OSF flag */
rtc_write
(
RTC_STAT_REG_ADDR
,
rtc_read
(
RTC_STAT_REG_ADDR
)
&
~
RTC_STAT_BIT_OSF
);
}
tmp
->
tm_sec
=
bcd2bin
(
sec
&
0x7F
);
tmp
->
tm_min
=
bcd2bin
(
min
&
0x7F
);
tmp
->
tm_hour
=
bcd2bin
(
hour
&
0x3F
);
tmp
->
tm_mday
=
bcd2bin
(
mday
&
0x3F
);
tmp
->
tm_mon
=
bcd2bin
(
mon_cent
&
0x1F
);
tmp
->
tm_year
=
bcd2bin
(
year
)
+
((
mon_cent
&
0x80
)
?
2000
:
1900
);
tmp
->
tm_wday
=
bcd2bin
((
wday
-
1
)
&
0x07
);
tmp
->
tm_yday
=
0
;
tmp
->
tm_isdst
=
0
;
DEBUGR
(
"Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d
\n
"
,
tmp
->
tm_year
,
tmp
->
tm_mon
,
tmp
->
tm_mday
,
tmp
->
tm_wday
,
tmp
->
tm_hour
,
tmp
->
tm_min
,
tmp
->
tm_sec
);
}
/*
* Set the RTC
*/
void
rtc_set
(
struct
rtc_time
*
tmp
)
{
uchar
century
;
DEBUGR
(
"Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d
\n
"
,
tmp
->
tm_year
,
tmp
->
tm_mon
,
tmp
->
tm_mday
,
tmp
->
tm_wday
,
tmp
->
tm_hour
,
tmp
->
tm_min
,
tmp
->
tm_sec
);
rtc_write
(
RTC_YR_REG_ADDR
,
bin2bcd
(
tmp
->
tm_year
%
100
));
century
=
(
tmp
->
tm_year
>=
2000
)
?
0x80
:
0
;
rtc_write
(
RTC_MON_REG_ADDR
,
bin2bcd
(
tmp
->
tm_mon
)
|
century
);
rtc_write
(
RTC_DAY_REG_ADDR
,
bin2bcd
(
tmp
->
tm_wday
+
1
));
rtc_write
(
RTC_DATE_REG_ADDR
,
bin2bcd
(
tmp
->
tm_mday
));
rtc_write
(
RTC_HR_REG_ADDR
,
bin2bcd
(
tmp
->
tm_hour
));
rtc_write
(
RTC_MIN_REG_ADDR
,
bin2bcd
(
tmp
->
tm_min
));
rtc_write
(
RTC_SEC_REG_ADDR
,
bin2bcd
(
tmp
->
tm_sec
));
}
/*
* Reset the RTC. We also enable the oscillator output on the
* SQW/INTB* pin and program it for 32,768 Hz output. Note that
* according to the datasheet, turning on the square wave output
* increases the current drain on the backup battery from about
* 600 nA to 2uA.
*/
void
rtc_reset
(
void
)
{
rtc_write
(
RTC_CTL_REG_ADDR
,
RTC_CTL_BIT_RS1
|
RTC_CTL_BIT_RS2
);
}
/*
* Helper functions
*/
static
uchar
rtc_read
(
uchar
reg
)
{
return
(
i2c_reg_read
(
CFG_I2C_RTC_ADDR
,
reg
));
}
static
void
rtc_write
(
uchar
reg
,
uchar
val
)
{
i2c_reg_write
(
CFG_I2C_RTC_ADDR
,
reg
,
val
);
}
static
unsigned
bcd2bin
(
uchar
n
)
{
return
((((
n
>>
4
)
&
0x0F
)
*
10
)
+
(
n
&
0x0F
));
}
static
unsigned
char
bin2bcd
(
unsigned
int
n
)
{
return
(((
n
/
10
)
<<
4
)
|
(
n
%
10
));
}
#endif
/* (CONFIG_RTC_DS3231) && (CONFIG_COMMANDS & CFG_CMD_DATE) */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录