diff --git a/bsp/stm32_radio/board.h b/bsp/stm32_radio/board.h index 67e3efc9042b340685c439e16e28c2bfbca26287..73a85be5c4b2f64af6ce8423b4f8c891d320eb10 100644 --- a/bsp/stm32_radio/board.h +++ b/bsp/stm32_radio/board.h @@ -42,6 +42,10 @@ // Default: 1 #define STM32_CONSOLE_USART 1 +// Codec Version <1=>Version 1 <2=>Version 2 +// Default: 1 +#define CODEC_VERSION 1 + void rt_hw_board_led_on(int n); void rt_hw_board_led_off(int n); void rt_hw_board_init(void); diff --git a/bsp/stm32_radio/filelist.c b/bsp/stm32_radio/filelist.c index f0c7570137178f47fab129ad839ffdc3b527a22a..8c2aed8b5a8e6eddd8168bcd52dddbfa699682ee 100644 --- a/bsp/stm32_radio/filelist.c +++ b/bsp/stm32_radio/filelist.c @@ -224,9 +224,9 @@ static void _filelist_view_constructor(struct filelist_view *view) RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL; file_image = rtgui_image_create_from_mem("xpm", - (rt_uint8_t*)file_xpm, sizeof(file_xpm)); + (rt_uint8_t*)file_xpm, sizeof(file_xpm), RT_TRUE); folder_image = rtgui_image_create_from_mem("xpm", - (rt_uint8_t*)folder_xpm, sizeof(folder_xpm)); + (rt_uint8_t*)folder_xpm, sizeof(folder_xpm), RT_TRUE); } rtgui_type_t *filelist_view_type_get(void) diff --git a/bsp/stm32_radio/info.c b/bsp/stm32_radio/info.c index a32f656150309376fbdcbf5ea157ffa3a8a35bd6..8185f987050f6c498bcf1384bd6eadc72d415738 100644 --- a/bsp/stm32_radio/info.c +++ b/bsp/stm32_radio/info.c @@ -36,7 +36,7 @@ static rt_bool_t view_event_handler(struct rtgui_widget* widget, struct rtgui_ev rtt_image = RT_NULL; } - + if (network_image != RT_NULL) { rect.x1 = rect.x2 - (network_image->w + 2); @@ -61,7 +61,7 @@ static void info_entry(void* parameter) rtgui_thread_register(rt_thread_self(), mq); network_image = rtgui_image_create_from_mem("xpm", - (rt_uint8_t*)network_xpm, sizeof(network_xpm)); + (rt_uint8_t*)network_xpm, sizeof(network_xpm), RT_TRUE); workbench = rtgui_workbench_create("info", "workbench"); if (workbench == RT_NULL) return; diff --git a/bsp/stm32_radio/mp3.c b/bsp/stm32_radio/mp3.c index 2d5ad641f6c4e6743f16afdd1479d99dcae21172..535a56b9eb937044e20d783ce7a1d8badcd305ed 100644 --- a/bsp/stm32_radio/mp3.c +++ b/bsp/stm32_radio/mp3.c @@ -1,11 +1,17 @@ #include #include #include +#include #include "board.h" #include "netbuffer.h" +#include "player_ui.h" +#include "player_bg.h" #define MP3_AUDIO_BUF_SZ 4096 +#ifndef MIN +#define MIN(x, y) ((x) < (y)? (x) : (y)) +#endif rt_uint8_t mp3_fd_buffer[MP3_AUDIO_BUF_SZ]; @@ -21,9 +27,8 @@ struct mp3_decoder void* fetch_parameter; /* mp3 read session */ - rt_uint8_t *read_buffer; - rt_uint8_t* read_ptr; - rt_int32_t read_offset; + rt_uint8_t *read_buffer, *read_ptr; + rt_int32_t read_offset; rt_uint32_t bytes_left, bytes_left_before_decoding; /* audio device */ @@ -99,7 +104,6 @@ void mp3_decoder_delete(struct mp3_decoder* decoder) rt_free(decoder); } -rt_uint16_t is_first = 1; rt_uint32_t current_offset = 0; static rt_int32_t mp3_decoder_fill_buffer(struct mp3_decoder* decoder) { @@ -116,9 +120,6 @@ static rt_int32_t mp3_decoder_fill_buffer(struct mp3_decoder* decoder) bytes_to_read = (MP3_AUDIO_BUF_SZ - decoder->bytes_left) & ~(512 - 1); // rt_kprintf("read bytes: %d\n", bytes_to_read); - if (is_first) is_first = 0; - else current_offset += MP3_AUDIO_BUF_SZ - decoder->bytes_left; - bytes_read = decoder->fetch_data(decoder->fetch_parameter, (rt_uint8_t *)(decoder->read_buffer + decoder->bytes_left), bytes_to_read); @@ -141,9 +142,12 @@ int mp3_decoder_run(struct mp3_decoder* decoder) { int err; rt_uint16_t* buffer; + rt_uint32_t delta; RT_ASSERT(decoder != RT_NULL); + if (player_is_playing() != RT_TRUE) return -1; + if ((decoder->read_ptr == RT_NULL) || decoder->bytes_left < 2*MAINBUF_SIZE) { if(mp3_decoder_fill_buffer(decoder) != 0) @@ -162,6 +166,7 @@ int mp3_decoder_run(struct mp3_decoder* decoder) // rt_kprintf("sync position: %x\n", decoder->read_offset); decoder->read_ptr += decoder->read_offset; + delta = decoder->read_offset; decoder->bytes_left -= decoder->read_offset; decoder->bytes_left_before_decoding = decoder->bytes_left; @@ -196,6 +201,10 @@ int mp3_decoder_run(struct mp3_decoder* decoder) err = MP3Decode(decoder->decoder, &decoder->read_ptr, (int*)&decoder->bytes_left, (short*)buffer, 0); + delta += (decoder->bytes_left_before_decoding - decoder->bytes_left); + + current_offset += delta; + player_set_position(current_offset); // rt_kprintf("bytes left after decode: %d\n", decoder->bytes_left); @@ -277,26 +286,114 @@ int mp3_decoder_run(struct mp3_decoder* decoder) /* write to sound device */ rt_device_write(decoder->snd_device, 0, buffer, decoder->frame_info.outputSamps * 2); - // rt_mp_free(buffer); } return 0; } -/* audio information structure */ -struct audio_info +/* get mp3 information */ +void mp3_get_info(const char* filename, struct tag_info* info) { - char* title; - char* artist; + int fd; + char* id3buffer; + rt_size_t bytes_read; + int sync_word; + HMP3Decoder decoder; + MP3FrameInfo frame_info; - rt_uint32_t duration; - rt_uint32_t bit_rate; - rt_uint32_t sampling; -}; + id3buffer = (char*)&mp3_fd_buffer[0]; + if (filename == RT_NULL || info == RT_NULL) return; -/* get mp3 information */ -void mp3_get_info(char* filename, struct audio_info* info) -{ + fd = open(filename, O_RDONLY, 0); + if (fd < 0) return; /* can't read file */ + + /* init decoder */ + decoder = MP3InitDecoder(); + + /* read data */ + bytes_read = read(fd, id3buffer, sizeof(mp3_fd_buffer)); + + /* get frame information */ + sync_word = MP3FindSyncWord(id3buffer, bytes_read); + if (sync_word < 0) + { + /* can't get sync word */ + close(fd); + mp3_decoder_detach(decoder); + } + /* get frame information */ + MP3GetNextFrameInfo(decoder, &frame_info, &id3buffer[sync_word]); + info->bit_rate = frame_info.bitrate; + info->sampling = frame_info.samprate; + info->duration = lseek(fd, 0, SEEK_END)/ (info->bit_rate / 8); /* second */ + + if (strncmp("ID3", id3buffer, 4) == 0) + { + rt_uint32_t tag_size, frame_size, i; + rt_uint8_t version_major; + int frame_header_size; + + tag_size = ((rt_uint32_t)id3buffer[6] << 21)|((rt_uint32_t)id3buffer[7] << 14)|((rt_uint16_t)id3buffer[8] << 7)|id3buffer[9]; + info->data_start = tag_size; + version_major = id3buffer[3]; + if (version_major >= 3) + { + frame_header_size = 10; + } + else + { + frame_header_size = 6; + } + i = 10; + + // iterate through frames + while (i < MIN(tag_size, sizeof(id3buffer))) + { + if (version_major >= 3) + { + frame_size = ((rt_uint32_t)id3buffer[i + 4] << 24)|((rt_uint32_t)id3buffer[i + 5] << 16)|((rt_uint16_t)id3buffer[i + 6] << 8)|id3buffer[i + 7]; + } + else + { + frame_size = ((rt_uint32_t)id3buffer[i + 3] << 14)|((rt_uint16_t)id3buffer[i + 4] << 7)|id3buffer[i + 5]; + } + + if (strncmp("TT2", id3buffer + i, 3) == 0 || strncmp("TIT2", id3buffer + i, 4) == 0) + { + strncpy(info->title, id3buffer + i + frame_header_size + 1, MIN(frame_size - 1, sizeof(info->title) - 1)); + } + else if (strncmp("TP1", id3buffer + i, 3) == 0 || strncmp("TPE1", id3buffer + i, 4) == 0) + { + strncpy(info->artist, id3buffer + i + frame_header_size + 1, MIN(frame_size - 1, sizeof(info->artist) - 1)); + } + + i += frame_size + frame_header_size; + } + } + else + { + lseek(fd, -128, SEEK_END); + bytes_read = read(fd, id3buffer, 128); + + /* ID3v1 */ + if (strncmp("TAG", id3buffer, 3) == 0) + { + strncpy(info->title, id3buffer + 3, MIN(30, sizeof(info->title) - 1)); + strncpy(info->artist, id3buffer + 3 + 30, MIN(30, sizeof(info->artist) - 1)); + } + + /* set data start position */ + info->data_start = 0; + } + + /* set current position */ + info->position = 0; + + /* release mp3 decoder */ + MP3FreeDecoder(decoder); + + /* close file */ + close(fd); } #include @@ -309,7 +406,9 @@ void mp3(char* filename) { int fd; struct mp3_decoder* decoder; - + extern rt_bool_t is_playing; + + is_playing = RT_TRUE; fd = open(filename, O_RDONLY, 0); if (fd >= 0) { @@ -319,6 +418,7 @@ void mp3(char* filename) decoder->fetch_data = fd_fetch; decoder->fetch_parameter = (void*)fd; + current_offset = 0; while (mp3_decoder_run(decoder) != -1); close(fd); @@ -326,6 +426,7 @@ void mp3(char* filename) mp3_decoder_delete(decoder); } } + is_playing = RT_FALSE; } FINSH_FUNCTION_EXPORT(mp3, mp3 decode test); @@ -369,6 +470,7 @@ void http_mp3(char* url) decoder->fetch_data = http_data_fetch; decoder->fetch_parameter = RT_NULL; + current_offset = 0; while (mp3_decoder_run(decoder) != -1); /* delete decoder object */ diff --git a/bsp/stm32_radio/play_list.c b/bsp/stm32_radio/play_list.c new file mode 100644 index 0000000000000000000000000000000000000000..2484951f4746356fa78d536a773cf4d086d75366 --- /dev/null +++ b/bsp/stm32_radio/play_list.c @@ -0,0 +1,101 @@ +#include "play_list.h" +#include "player_ui.h" +#include + +static struct play_item **play_list = RT_NULL; +static rt_uint16_t play_list_size = 0; +static rt_int16_t play_list_current = 0; + +void play_list_clear() +{ + rt_uint32_t index; + + for (index = 0; index < play_list_size; index ++) + { + rt_free(play_list[index]->fn); + rt_free(play_list[index]); + + play_list[index] = RT_NULL; + } + + rt_free(play_list); + play_list = RT_NULL; + play_list_size = 0; +} + +char* play_list_start() +{ + play_list_current = 0; + return play_list[play_list_current]->fn; +} + +rt_bool_t play_list_is_end() +{ + if ((play_list_current == play_list_size - 1) || + play_list_size == 0) + return RT_TRUE; + + return RT_FALSE; +} + +rt_uint32_t play_list_items(void) +{ + return play_list_size; +} + +struct play_item* play_list_item(rt_uint32_t n) +{ + if (n > play_list_size) return RT_NULL; + return play_list[n]; +} + +void play_list_append(char* fn) +{ + play_list_size ++; + if (play_list == RT_NULL) + play_list = (struct play_item**) rt_malloc (play_list_size * sizeof(struct play_item*)); + else + play_list = (struct play_item**) rt_realloc(play_list, play_list_size * sizeof(struct play_item*)); + + play_list[play_list_size - 1] = (struct play_item*)rt_malloc(sizeof(struct play_item)); + if (strstr(fn, ".mp3") != RT_NULL || + strstr(fn, ".MP3") != RT_NULL) + { + struct tag_info info; + + memset(&info, 0, sizeof(info)); + mp3_get_info(fn, &info); + if (info.title[0] == '\0') + rt_snprintf(play_list[play_list_size - 1]->title, sizeof(play_list[play_list_size - 1]->title), + "<未知名音乐>"); + else + strcpy(play_list[play_list_size - 1]->title, info.title); + + play_list[play_list_size - 1]->fn = rt_strdup(fn); + play_list[play_list_size - 1]->duration = info.duration; + } + else + { + rt_snprintf(play_list[play_list_size - 1]->title, sizeof(play_list[play_list_size - 1]->title), + "<未知名音乐>"); + play_list[play_list_size - 1]->fn = rt_strdup(fn); + play_list[play_list_size - 1]->duration = 0; + } +} + +char* play_list_next() +{ + if (play_list_current < play_list_size - 1) play_list_current ++; + return play_list[play_list_current]->fn; +} + +char* play_list_prev() +{ + if (play_list_current > 0) play_list_current --; + return play_list[play_list_current]->fn; +} + +char* play_list_current_item() +{ + return play_list[play_list_current]->fn; +} diff --git a/bsp/stm32_radio/play_list.h b/bsp/stm32_radio/play_list.h new file mode 100644 index 0000000000000000000000000000000000000000..f7aa05382fdf134d74b7bdc14edd7365390dae0e --- /dev/null +++ b/bsp/stm32_radio/play_list.h @@ -0,0 +1,25 @@ +#ifndef __PLAY_LIST_H__ +#define __PLAY_LIST_H__ + +#include + +struct play_item +{ + char title[40]; + char *fn; + rt_uint32_t duration; +}; + +void play_list_clear(void); + +char* play_list_start(void); +rt_bool_t play_list_is_end(void); +rt_uint32_t play_list_items(void); +struct play_item* play_list_item(rt_uint32_t n); + +void play_list_append(char* fn); +char* play_list_next(void); +char* play_list_prev(void); +char* play_list_current_item(void); + +#endif diff --git a/bsp/stm32_radio/player.c b/bsp/stm32_radio/player.c deleted file mode 100644 index 23d97ecd238e698636b4e319deb61bda0e14d002..0000000000000000000000000000000000000000 --- a/bsp/stm32_radio/player.c +++ /dev/null @@ -1,673 +0,0 @@ -#include -#include -#include - -#include -#include -#include - -#include "listview.h" -#include "filelist.h" - -static const char * next_xpm[] = { -"24 24 149 2", -" c None", -". c #373737", -"+ c #383838", -"@ c #3A3A3A", -"# c #393939", -"$ c #434343", -"% c #676767", -"& c #9D9D9D", -"* c #C1C1C1", -"= c #D3D3D3", -"- c #404040", -"; c #707070", -"> c #EDEDED", -", c #F5F5F5", -"' c #4A4A4A", -") c #909090", -"! c #D9D9D9", -"~ c #4B4B4B", -"{ c #939393", -"] c #CECECE", -"^ c #E4E4E4", -"/ c #E5E5E5", -"( c #444444", -"_ c #8B8B8B", -": c #ABABAB", -"< c #DCDCDC", -"[ c #D4D4D4", -"} c #D2D2D2", -"| c #DDDDDD", -"1 c #DEDEDE", -"2 c #DFDFDF", -"3 c #414141", -"4 c #B8B8B8", -"5 c #BBBBBB", -"6 c #ADADAD", -"7 c #B7B7B7", -"8 c #CFCFCF", -"9 c #D8D8D8", -"0 c #D6D6D6", -"a c #B2B2B2", -"b c #AEAEAE", -"c c #B6B6B6", -"d c #4C4C4C", -"e c #989898", -"f c #9E9E9E", -"g c #CDCDCD", -"h c #C5C5C5", -"i c #C7C7C7", -"j c #A1A1A1", -"k c #B3B3B3", -"l c #9F9F9F", -"m c #A2A2A2", -"n c #CACACA", -"o c #696969", -"p c #A0A0A0", -"q c #B1B1B1", -"r c #F1F1F1", -"s c #E3E3E3", -"t c #CCCCCC", -"u c #C6C6C6", -"v c #D1D1D1", -"w c #C2C2C2", -"x c #464646", -"y c #848484", -"z c #A4A4A4", -"A c #A9A9A9", -"B c #BFBFBF", -"C c #959595", -"D c #EFEFEF", -"E c #EEEEEE", -"F c #929292", -"G c #808080", -"H c #CBCBCB", -"I c #858585", -"J c #B9B9B9", -"K c #A5A5A5", -"L c #494949", -"M c #A7A7A7", -"N c #B0B0B0", -"O c #888888", -"P c #EAEAEA", -"Q c #777777", -"R c #6C6C6C", -"S c #C4C4C4", -"T c #757575", -"U c #A8A8A8", -"V c #A3A3A3", -"W c #949494", -"X c #9C9C9C", -"Y c #EBEBEB", -"Z c #575757", -"` c #4D4D4D", -" . c #ACACAC", -".. c #6B6B6B", -"+. c #9A9A9A", -"@. c #E9E9E9", -"#. c #D7D7D7", -"$. c #BDBDBD", -"%. c #515151", -"&. c #E8E8E8", -"*. c #E2E2E2", -"=. c #9B9B9B", -"-. c #4E4E4E", -";. c #B4B4B4", -">. c #525252", -",. c #BEBEBE", -"'. c #8C8C8C", -"). c #AAAAAA", -"!. c #AFAFAF", -"~. c #E7E7E7", -"{. c #5D5D5D", -"]. c #7E7E7E", -"^. c #616161", -"/. c #C8C8C8", -"(. c #747474", -"_. c #B5B5B5", -":. c #6D6D6D", -"<. c #4F4F4F", -"[. c #5A5A5A", -"}. c #A6A6A6", -"|. c #919191", -"1. c #8D8D8D", -"2. c #DBDBDB", -"3. c #7F7F7F", -"4. c #E0E0E0", -"5. c #C0C0C0", -"6. c #828282", -"7. c #595959", -"8. c #C9C9C9", -"9. c #E1E1E1", -"0. c #E6E6E6", -"a. c #D5D5D5", -"b. c #626262", -"c. c #ECECEC", -"d. c #636363", -"e. c #646464", -"f. c #F0F0F0", -"g. c #F3F3F3", -"h. c #F4F4F4", -"i. c #F6F6F6", -"j. c #F7F7F7", -"k. c #5E5E5E", -"l. c #898989", -"m. c #F9F9F9", -"n. c #F8F8F8", -"o. c #8A8A8A", -"p. c #656565", -"q. c #5C5C5C", -"r. c #5F5F5F", -" . + @ @ + . ", -" # $ % & * = = * & % $ # ", -" - ; * > , , , , , , > * ; - ", -" ' ) ! > > > > > > > > > > ! ) ' ", -" ~ { ] ^ ^ / / / / / / / / / / ] { ~ ", -" ( _ : < [ } | 1 2 2 2 2 1 | < < < : _ ( ", -" 3 ; & 4 = 5 6 7 8 9 ! ! ! 0 a b c = 4 & ; 3 ", -" d e f 4 g b h i j k ] [ [ g l } m n 4 f e d ", -" o & p q i j * r s b { k t u ) v { w q j f o ", -"x y l z A B C 4 D D E v F _ : G H I J A K j y x ", -"L { m M : N O N > > > > P 4 Q R S T U : U V W L ", -"~ X K A b 6 ; K Y Y Y Y Y Y 2 k S Z K b : M & ~ ", -"` f M .N N ..+.@.@.@.@.@.@.#.f $.%.M a k q V ` ", -"` e U b a a R +.&.&.&.&.*.=.-.( ;.>.b ,.,.$.f ` ", -"-.'.).!.;.;.R +.&.&.~.7 {.Z ].L ;.^.B /./.i ) -.", -" (.).N _.;.:.+.&.] T <.G ).A %.h _ n } } i (. ", -" [.}.q _.;.:.|.) ` :.K B t /.1.= l [ 2.2.c [. ", -" >.G _.B B 3.[.o =.,.= 4./ 2.K 5.k | s #.6.>. ", -" 7.l S H 7 q 8.#.9.0.@.@./ g H a.&.0.M 7. ", -" b. .8 a.9 1 ^ &.Y c.E > c.c.E > 7 d. ", -" e.}.= s ~.Y > f.r g.h.i.j.@. .e. ", -" k.l.5.1 E g.i.j.m.n.Y /.o.k. ", -" [.p.6.m 5 H H ,.z 6.p.[. ", -" q.k.r.r.k.q. "}; - -static const char * prev_xpm[] = { -"24 24 153 2", -" c None", -". c #373737", -"+ c #383838", -"@ c #3A3A3A", -"# c #393939", -"$ c #434343", -"% c #676767", -"& c #9D9D9D", -"* c #C1C1C1", -"= c #D3D3D3", -"- c #404040", -"; c #707070", -"> c #EDEDED", -", c #F5F5F5", -"' c #4A4A4A", -") c #909090", -"! c #D9D9D9", -"~ c #4B4B4B", -"{ c #939393", -"] c #CECECE", -"^ c #E5E5E5", -"/ c #E4E4E4", -"( c #444444", -"_ c #8B8B8B", -": c #ABABAB", -"< c #DCDCDC", -"[ c #DDDDDD", -"} c #DEDEDE", -"| c #DFDFDF", -"1 c #D5D5D5", -"2 c #D2D2D2", -"3 c #DADADA", -"4 c #414141", -"5 c #B8B8B8", -"6 c #D4D4D4", -"7 c #BBBBBB", -"8 c #AEAEAE", -"9 c #AFAFAF", -"0 c #D0D0D0", -"a c #D8D8D8", -"b c #ADADAD", -"c c #B5B5B5", -"d c #B7B7B7", -"e c #4C4C4C", -"f c #989898", -"g c #9E9E9E", -"h c #AAAAAA", -"i c #CCCCCC", -"j c #A3A3A3", -"k c #D1D1D1", -"l c #A1A1A1", -"m c #CDCDCD", -"n c #A5A5A5", -"o c #C5C5C5", -"p c #696969", -"q c #A0A0A0", -"r c #B1B1B1", -"s c #C8C8C8", -"t c #C9C9C9", -"u c #949494", -"v c #CACACA", -"w c #B9B9B9", -"x c #959595", -"y c #A7A7A7", -"z c #F1F1F1", -"A c #969696", -"B c #BCBCBC", -"C c #464646", -"D c #848484", -"E c #9F9F9F", -"F c #A4A4A4", -"G c #A9A9A9", -"H c #C2C2C2", -"I c #868686", -"J c #8E8E8E", -"K c #8C8C8C", -"L c #EFEFEF", -"M c #C6C6C6", -"N c #888888", -"O c #B2B2B2", -"P c #494949", -"Q c #A2A2A2", -"R c #828282", -"S c #777777", -"T c #737373", -"U c #E7E7E7", -"V c #C0C0C0", -"W c #797979", -"X c #A8A8A8", -"Y c #9C9C9C", -"Z c #B0B0B0", -"` c #686868", -" . c #B6B6B6", -".. c #EBEBEB", -"+. c #5D5D5D", -"@. c #9A9A9A", -"#. c #4D4D4D", -"$. c #ACACAC", -"%. c #B3B3B3", -"&. c #636363", -"*. c #CFCFCF", -"=. c #E9E9E9", -"-. c #575757", -";. c #515151", -">. c #E8E8E8", -",. c #BEBEBE", -"'. c #BDBDBD", -"). c #4E4E4E", -"!. c #B4B4B4", -"~. c #646464", -"{. c #525252", -"]. c #5F5F5F", -"^. c #565656", -"/. c #666666", -"(. c #C7C7C7", -"_. c #747474", -":. c #929292", -"<. c #555555", -"[. c #6B6B6B", -"}. c #C3C3C3", -"|. c #5A5A5A", -"1. c #A6A6A6", -"2. c #C4C4C4", -"3. c #BABABA", -"4. c #838383", -"5. c #DBDBDB", -"6. c #808080", -"7. c #BFBFBF", -"8. c #858585", -"9. c #5E5E5E", -"0. c #E0E0E0", -"a. c #E2E2E2", -"b. c #D7D7D7", -"c. c #595959", -"d. c #E3E3E3", -"e. c #E6E6E6", -"f. c #626262", -"g. c #D6D6D6", -"h. c #ECECEC", -"i. c #EEEEEE", -"j. c #EAEAEA", -"k. c #F0F0F0", -"l. c #F3F3F3", -"m. c #F4F4F4", -"n. c #F6F6F6", -"o. c #F7F7F7", -"p. c #898989", -"q. c #F9F9F9", -"r. c #F8F8F8", -"s. c #8A8A8A", -"t. c #656565", -"u. c #CBCBCB", -"v. c #5C5C5C", -" . + @ @ + . ", -" # $ % & * = = * & % $ # ", -" - ; * > , , , , , , > * ; - ", -" ' ) ! > > > > > > > > > > ! ) ' ", -" ~ { ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ / / ] { ~ ", -" ( _ : < < < [ } } | | | } } 1 2 3 : _ ( ", -" 4 ; & 5 6 7 8 9 0 a ! ! ! = 7 b c 0 d & ; 4 ", -" e f g 5 ] h i j * k 6 k 5 l * m n o d g f e ", -" p & q r s & t u c v w x y } z m A B 9 l g p ", -"C D E F G * ) H I q J K v > L L M N O y n l D C ", -"P { Q y : O R 7 S T 9 U > > > > V W E X X j u P ", -"~ Y n G 8 Z ` . .3 ............ .+.@.: : y & ~ ", -"#.g y $.r %.&.b j *.=.=.=.=.=.=.8 -.& Z %.r j #.", -"#.f X 8 %.c &.X ;.' ) } >.>.>.>.8 -.j B ,.'.g #.", -").K h 9 !.d ~.X {.W ].^.$.^ >.>.8 /. .(.s (.) ).", -" _.h Z c 5 ~.X {.:.O :.<.[.o =.H J }.0 2 (._. ", -" |.1.r c 5 ~.X {.f 2.i 3.4.T !.s Q ] ! 5. .|. ", -" {.6.c 7.H S 8.9.n *.} 0.[ *.O X .! a.b.R {. ", -" c.E 2.m .j G m 0.U =.=.U d.b.b.e.e.y c. ", -" f.$.0 g.g.a | U ..h.i.i.L i.L h.d &. ", -" ~.1.= d.U j.> k.z l.m.n.o.=.$.~. ", -" 9.p.V } i.l.n.o.q.r...s s.9. ", -" |.t.R Q 7 u.u.,.F R t.|. ", -" v.9.].].9.v. "}; - -static rtgui_image_t *background = RT_NULL; -static rtgui_image_t *next = RT_NULL, *prev = RT_NULL; - -static struct rtgui_view* function_view; -static struct rtgui_view* home_view; -static struct rtgui_workbench* workbench; - -void player_play_list(const char** list); -void player_play_file(const char * fn); -void player_next(void); -void player_prev(void); - -void function_filelist(void* parameter) -{ - rtgui_rect_t rect; - filelist_view_t *view; - - rtgui_widget_get_rect(RTGUI_WIDGET(workbench), &rect); - view = filelist_view_create(workbench, "/", "*.*", &rect); - if (view != RT_NULL) - { - if (rtgui_view_show(RTGUI_VIEW(view), RT_TRUE) == RTGUI_MODAL_OK) - { - char fn[64]; - - /* get open file */ - rt_kprintf("dir %s\n", view->current_directory); - rt_kprintf("item %s\n", view->items[view->current_item].name); - - rt_snprintf(fn, 64, "%s/%s", view->current_directory, - view->items[view->current_item].name); - - rtgui_view_show(home_view, RT_FALSE); - - player_play_file(fn); - } - - /* destroy view */ - filelist_view_destroy(view); - } - - return; -} - -void function_device(void* parameter) -{ - rtgui_view_t *view; - extern rtgui_view_t* device_view_create(rtgui_workbench_t* workbench); - - view = device_view_create(workbench); - if (view != RT_NULL) - { - rtgui_view_show(view, RT_FALSE); - } - - return; -} - -void function_player(void* parameter) -{ - rtgui_view_show(home_view, RT_FALSE); - return; -} - -void function_action(void* parameter) -{ - rt_kprintf("item action!\n"); - return; -} - -struct list_item function_list[] = -{ - {"选择电台", RT_NULL, function_action, RT_NULL}, - {"更新电台", RT_NULL, function_action, RT_NULL}, - {"播放文件", RT_NULL, function_filelist, RT_NULL}, - {"设备信息", RT_NULL, function_device, RT_NULL}, - {"返回播放器", RT_NULL, function_player, RT_NULL}, -}; - -static rt_bool_t home_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) -{ - if (event->type == RTGUI_EVENT_PAINT) - { - struct rtgui_dc* dc; - struct rtgui_rect rect; - - dc = rtgui_dc_begin_drawing(widget); - if (dc == RT_NULL) return RT_FALSE; - rtgui_widget_get_rect(widget, &rect); - - /* draw background */ - background = rtgui_image_create_from_file("hdc", - "/resource/bg.hdc", RT_FALSE); - if (background != RT_NULL) - { - rtgui_image_blit(background, dc, &rect); - rtgui_image_destroy(background); - - background = RT_NULL; - } - else - { - rtgui_dc_fill_rect(dc, &rect); - } - - /* draw playing information */ - rect.x1 = 10; rect.y1 = 260; - rect.x2 = 25; rect.y2 = 285; - if (prev != RT_NULL) rtgui_image_blit(prev, dc, &rect); - if (next != RT_NULL) - { - rect.x2 = 230; rect.x1 = rect.x2 - 25; - rtgui_image_blit(next, dc, &rect); - } - - rect.x1 = 35; rect.y1 = 260; - rect.x2 = 205; rect.y2 = 285; - rtgui_dc_fill_rect(dc, &rect); - rtgui_dc_end_drawing(dc); - - return RT_FALSE; - } - else if (event->type == RTGUI_EVENT_KBD) - { - struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; - if (ekbd->type == RTGUI_KEYDOWN) - { - switch (ekbd->key) - { - case RTGUIK_RIGHT: - case RTGUIK_LEFT: - break; - - case RTGUIK_DOWN: - rtgui_view_show(function_view, RT_FALSE); - break; - } - } - return RT_FALSE; - } - - return rtgui_view_event_handler(widget, event); -} - -rt_bool_t today_workbench_event_handler(rtgui_widget_t *widget, rtgui_event_t *event) -{ - if (event->type == RTGUI_EVENT_KBD) - { - struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; - if ((ekbd->type == RTGUI_KEYUP) && ekbd->key == RTGUIK_HOME) - { - /* active home view */ - if (workbench->current_view != home_view) - { - rtgui_view_show(home_view, RT_FALSE); - return RT_FALSE; - } - } - } - - return rtgui_workbench_event_handler(widget, event); -} - -static void player_entry(void* parameter) -{ - rt_mq_t mq; - rtgui_rect_t rect; - - mq = rt_mq_create("qPlayer", 256, 4, RT_IPC_FLAG_FIFO); - rtgui_thread_register(rt_thread_self(), mq); - - next = rtgui_image_create_from_mem("xpm", (rt_uint8_t*)next_xpm, - sizeof(next_xpm)); - prev = rtgui_image_create_from_mem("xpm", (rt_uint8_t*)prev_xpm, - sizeof(prev_xpm)); - - workbench = rtgui_workbench_create("main", "workbench"); - if (workbench == RT_NULL) return; - rtgui_widget_set_event_handler(RTGUI_WIDGET(workbench), today_workbench_event_handler); - - /* add home view */ - home_view = rtgui_view_create("Home"); - rtgui_widget_set_event_handler(RTGUI_WIDGET(home_view), home_view_event_handler); - - rtgui_workbench_add_view(workbench, home_view); - /* this view can be focused */ - RTGUI_WIDGET(home_view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; - /* set widget focus */ - rtgui_widget_focus(RTGUI_WIDGET(home_view)); - - rtgui_view_show(home_view, RT_FALSE); - - /* add function view */ - rtgui_widget_get_rect(RTGUI_WIDGET(workbench), &rect); - function_view = (struct rtgui_view*)list_view_create(function_list, - sizeof(function_list)/sizeof(struct list_item), - &rect); - rtgui_workbench_add_view(workbench, function_view); - - rtgui_workbench_event_loop(workbench); - - rtgui_thread_deregister(rt_thread_self()); - rt_mq_delete(mq); -} - -enum PLAYER_MODE -{ - PLAYER_SINGLE, - PLAYER_FILE, - PLAYER_RADIO, -}; - -enum PLAYER_REQUEST_TYPE -{ - PLAYER_REQUEST_PLAY_SINGLE_FILE, - PLAYER_REQUEST_PLAY_LIST, - PLAYER_REQUEST_STOP, - PLAYER_REQUEST_NEXT, - PLAYER_REQUEST_PREV, -}; - -struct player_request -{ - enum PLAYER_REQUEST_TYPE type; - - char fn[64]; -}; -static rt_mq_t player_thread_mq; - -void player_play_list(const char** list) -{ -} - -void player_play_file(const char* fn) -{ - struct player_request request; - request.type = PLAYER_REQUEST_PLAY_SINGLE_FILE; - strncpy(request.fn, fn, sizeof(request.fn)); - - /* send to message queue */ - rt_mq_send(player_thread_mq, (void*)&request, sizeof(struct player_request)); -} - -void player_stop() -{ -} - -void player_next() -{ -} - -void player_prev() -{ -} - -void player_thread(void* parameter) -{ - rt_err_t result; - struct player_request request; - - while(1) - { - /* get request from message queue */ - result = rt_mq_recv(player_thread_mq, (void*)&request, - sizeof(struct player_request), RT_WAITING_FOREVER); - if (result == RT_EOK) - { - switch (request.type) - { - case PLAYER_REQUEST_PLAY_SINGLE_FILE: - if ((strstr(request.fn, ".mp3") != RT_NULL) || - (strstr(request.fn, ".MP3") != RT_NULL)) - { - mp3(request.fn); - } - else if ((strstr(request.fn, ".wav") != RT_NULL) || - (strstr(request.fn, ".WAV") != RT_NULL)) - { - wav(request.fn); - } - break; - } - } - } -} - -void player_init() -{ - rt_thread_t tid; - - tid = rt_thread_create("player", - player_entry, RT_NULL, - 2048, RTGUI_APP_THREAD_PRIORITY, RTGUI_APP_THREAD_TIMESLICE); - - if (tid != RT_NULL) rt_thread_startup(tid); - - /* create player thread */ - player_thread_mq = rt_mq_create("player", sizeof(struct player_request), - 8, RT_IPC_FLAG_FIFO); - RT_ASSERT(player_thread_mq != RT_NULL); - - tid = rt_thread_create("pthread", player_thread, RT_NULL, - 2048, RTGUI_APP_THREAD_PRIORITY, RTGUI_APP_THREAD_TIMESLICE); - if (tid != RT_NULL) rt_thread_startup(tid); -} - diff --git a/bsp/stm32_radio/player_bg.c b/bsp/stm32_radio/player_bg.c new file mode 100644 index 0000000000000000000000000000000000000000..e2553c26e76ce71793b6bbb59adee253ea91b19a --- /dev/null +++ b/bsp/stm32_radio/player_bg.c @@ -0,0 +1,83 @@ +#include "player_bg.h" +#include "player_ui.h" + +#include + +static rt_mq_t player_thread_mq; +rt_bool_t is_playing = RT_FALSE; + +rt_bool_t player_is_playing() +{ + return is_playing; +} + +void player_play_file(const char* fn) +{ + struct player_request request; + request.type = PLAYER_REQUEST_PLAY_SINGLE_FILE; + strncpy(request.fn, fn, sizeof(request.fn)); + + /* send to message queue */ + rt_mq_send(player_thread_mq, (void*)&request, sizeof(struct player_request)); +} + +void player_stop() +{ + is_playing = RT_FALSE; +} + +void player_thread(void* parameter) +{ + rt_err_t result; + struct player_request request; + + while(1) + { + /* get request from message queue */ + result = rt_mq_recv(player_thread_mq, (void*)&request, + sizeof(struct player_request), RT_WAITING_FOREVER); + if (result == RT_EOK) + { + switch (request.type) + { + case PLAYER_REQUEST_PLAY_SINGLE_FILE: + if ((strstr(request.fn, ".mp3") != RT_NULL) || + (strstr(request.fn, ".MP3") != RT_NULL)) + { + is_playing = RT_TRUE; + player_notify_play(); + + /* get music tag information */ + mp3(request.fn); + + player_notify_stop(); + is_playing = RT_FALSE; + } + else if ((strstr(request.fn, ".wav") != RT_NULL) || + (strstr(request.fn, ".WAV") != RT_NULL)) + { + is_playing = RT_TRUE; + wav(request.fn); + is_playing = RT_FALSE; + } + break; + } + } + } +} + +void player_init() +{ + rt_thread_t tid; + + /* create player thread */ + player_thread_mq = rt_mq_create("player", sizeof(struct player_request), + 8, RT_IPC_FLAG_FIFO); + RT_ASSERT(player_thread_mq != RT_NULL); + + tid = rt_thread_create("ply_bg", player_thread, RT_NULL, + 2048, 20, 5); + if (tid != RT_NULL) rt_thread_startup(tid); + + player_ui_init(); +} diff --git a/bsp/stm32_radio/player_bg.h b/bsp/stm32_radio/player_bg.h new file mode 100644 index 0000000000000000000000000000000000000000..c419e828e34d67f66688424312746bb5f28d3e86 --- /dev/null +++ b/bsp/stm32_radio/player_bg.h @@ -0,0 +1,28 @@ +#ifndef __PLAYER_BG_H__ +#define __PLAYER_BG_H__ + +#include + +enum PLAYER_REQUEST_TYPE +{ + PLAYER_REQUEST_PLAY_SINGLE_FILE, + PLAYER_REQUEST_PLAY_LIST, + PLAYER_REQUEST_STOP, + PLAYER_REQUEST_NEXT, + PLAYER_REQUEST_PREV, +}; + +struct player_request +{ + enum PLAYER_REQUEST_TYPE type; + + char fn[64]; +}; + +rt_bool_t player_is_playing(void); +void player_stop(void); + +void player_play_list(const char** list); +void player_play_file(const char* fn); + +#endif diff --git a/bsp/stm32_radio/player_ui.c b/bsp/stm32_radio/player_ui.c new file mode 100644 index 0000000000000000000000000000000000000000..f3d155f1d25c59883d967a95b3720490653c8867 --- /dev/null +++ b/bsp/stm32_radio/player_ui.c @@ -0,0 +1,652 @@ +#include +#include +#include + +#include +#include +#include + +#include + +#include "player_ui.h" +#include "player_bg.h" +#include "play_list.h" + +#include "listview.h" +#include "filelist.h" + +#include "play.hdh" +#include "stop.hdh" + +static rtgui_image_t *background = RT_NULL; + +static struct rtgui_view* function_view; +static struct rtgui_view* home_view; +static struct rtgui_workbench* workbench; +static rtgui_timer_t* info_timer; +static rt_thread_t player_ui_tid = RT_NULL; +static enum PLAYER_MODE player_mode = PLAYER_STOP; +static enum PLAYER_STEP next_step = PLAYER_STEP_STOP; +static struct tag_info tinfo; + +void player_set_position(rt_uint32_t position) +{ + tinfo.position = position / (tinfo.bit_rate / 8); +} + +void info_timer_timeout(rtgui_timer_t* timer, void* parameter) +{ + struct rtgui_dc* dc; + rtgui_color_t saved; + + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(home_view)); + if (dc == RT_NULL) return ; + + saved = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view)); + + RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view)) = RTGUI_RGB(206, 231, 255); + rtgui_dc_draw_hline(dc, 14, 14 + (tinfo.position * 212)/ tinfo.duration, + 75); + + RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view)) = saved; + rtgui_dc_end_drawing(dc); +} + +rt_uint32_t read_line(int fd, char* line, rt_uint32_t line_size) +{ + char *pos, *next; + rt_uint32_t length; + + length = read(fd, line, line_size); + if (length > 0) + { + pos = strstr(line, "\r\n"); + if (pos == RT_NULL) + { + pos = strstr(line, "\n"); + next = pos ++; + } + else next = pos + 2; + + if (pos != RT_NULL) + { + *pos = '\0'; + + /* move back */ + lseek(fd, -(length - (next - line)), SEEK_CUR); + + length = pos - line; + } + else length = 0; + } + + rt_kprintf("line %s\n", line); + return length; +} + +static void player_update_tag_info(struct rtgui_dc* dc) +{ + rtgui_rect_t rect; + char line[32]; + rtgui_color_t saved; + + saved = rtgui_dc_get_color(dc); + rtgui_dc_set_color(dc, black); + + rect.x1 = 0; rect.y1 = 0; + rect.x2 = 240; rect.y2 = 65; + /* draw background */ + background = rtgui_image_create_from_file("hdc", + "/resource/bg.hdc", RT_FALSE); + if (background != RT_NULL) + { + rtgui_image_blit(background, dc, &rect); + rtgui_image_destroy(background); + + background = RT_NULL; + } + else + { + rtgui_dc_fill_rect(dc, &rect); + } + + /* draw playing information */ + rect.x1 = 28; rect.y1 = 12; + rect.x2 = 220; rect.y2 = rect.y1 + 16; + if (player_mode == PLAYER_STOP) + { + rt_snprintf(line, sizeof(line), + "网络收音机"); + rtgui_dc_draw_text(dc, line, &rect); + } + else + rtgui_dc_draw_text(dc, tinfo.title, &rect); + + rect.x1 = 28; rect.y1 = 39; + rect.x2 = 220; rect.y2 = 59; + if (player_mode == PLAYER_STOP) + { + rt_snprintf(line, sizeof(line), + "radio.rt-thread.org"); + rtgui_dc_draw_text(dc, line, &rect); + } + else + rtgui_dc_draw_text(dc, tinfo.artist, &rect); + + if ((tinfo.duration != 0) && player_mode != PLAYER_STOP) + { + rect.x1 = rect.x2 - 64; + rt_snprintf(line, sizeof(line), "%02d:%02d:%02d", + tinfo.duration / 360, tinfo.duration / 60, tinfo.duration % 60); + rtgui_dc_draw_text(dc, line, &rect); + } + + rtgui_dc_set_color(dc, saved); +} + +void play_mp3_file(const char* fn) +{ + struct rtgui_dc* dc; + + /* get music tag information */ + mp3_get_info(fn, &tinfo); + if (tinfo.title[0] == '\0') + rt_snprintf(tinfo.title, sizeof(tinfo.title), "<未知名音乐>"); + + /* set player mode */ + player_mode = PLAYER_PLAY_FILE; + + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(home_view)); + if (dc != RT_NULL) + { + rtgui_rect_t play_rect; + rtgui_image_t *button; + + /* update tag information */ + player_update_tag_info(dc); + + /* update play button */ + button = rtgui_image_create_from_mem("hdc", + play_hdh, sizeof(play_hdh), RT_FALSE); + play_rect.x1 = 32; play_rect.y1 = 92; + play_rect.x2 = 61; play_rect.y2 = 114; + rtgui_image_blit(button, dc, &play_rect); + rtgui_image_destroy(button); + + rtgui_dc_end_drawing(dc); + } + + rtgui_view_show(home_view, RT_FALSE); + + rt_kprintf("play file: %s\n", fn); + player_play_file(fn); +} + +void function_filelist(void* parameter) +{ + rtgui_rect_t rect; + filelist_view_t *view; + + rtgui_widget_get_rect(RTGUI_WIDGET(workbench), &rect); + view = filelist_view_create(workbench, "/", "*.*", &rect); + if (view != RT_NULL) + { + if (rtgui_view_show(RTGUI_VIEW(view), RT_TRUE) == RTGUI_MODAL_OK) + { + char fn[64]; + + /* get open file */ + rt_snprintf(fn, 64, "%s/%s", view->current_directory, + view->items[view->current_item].name); + + if (strstr(view->items[view->current_item].name , ".mp3") != RT_NULL || + strstr(view->items[view->current_item].name , ".MP3") != RT_NULL) + { + /* clear old play list */ + play_list_clear(); + play_list_append(fn); + + player_mode = PLAYER_PLAY_FILE; + next_step = PLAYER_STEP_STOP; + play_mp3_file(play_list_start()); + } + else if (strstr(view->items[view->current_item].name , ".m3u") != RT_NULL || + strstr(view->items[view->current_item].name , ".M3U") != RT_NULL) + { + /* read all of music filename to a list */ + int fd; + char line[64]; + + fd = open(fn, O_RDONLY, 0); + if (fd >= 0) + { + rt_uint32_t length; + + length = read_line(fd, line, sizeof(line)); + if (strcmp(line, "#EXTM3U") == 0) + { + /* clear old play list */ + play_list_clear(); + + do + { + length = read_line(fd, line, sizeof(line)); + if (length > 0) + { + if (line[0] != '/') + { + rt_snprintf(fn, sizeof(fn), + "%s/%s", view->current_directory, line); + play_list_append(fn); + } + else play_list_append(line); + } + } while (length > 0); + } + + close(fd); + + if (play_list_items() > 0) + { + player_mode = PLAYER_PLAY_FILE; + next_step = PLAYER_STEP_NEXT; + play_mp3_file(play_list_start()); + } + } + } + else if (strstr(view->items[view->current_item].name , ".wav") != RT_NULL || + strstr(view->items[view->current_item].name , ".WAV") != RT_NULL) + { + } + } + + /* destroy view */ + filelist_view_destroy(view); + } + + return; +} + +void function_device(void* parameter) +{ + rtgui_view_t *view; + extern rtgui_view_t* device_view_create(rtgui_workbench_t* workbench); + + view = device_view_create(workbench); + if (view != RT_NULL) + { + rtgui_view_show(view, RT_FALSE); + } + + return; +} + +void function_player(void* parameter) +{ + rtgui_view_show(home_view, RT_FALSE); + return; +} + +void function_action(void* parameter) +{ + rt_kprintf("item action!\n"); + return; +} + +struct list_item function_list[] = +{ + {"选择电台", RT_NULL, function_action, RT_NULL}, + {"更新电台", RT_NULL, function_action, RT_NULL}, + {"播放文件", RT_NULL, function_filelist, RT_NULL}, + {"设备信息", RT_NULL, function_device, RT_NULL}, + {"选项设置", RT_NULL, function_action, RT_NULL}, + {"返回播放器", RT_NULL, function_player, RT_NULL}, +}; + +static rt_bool_t home_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) +{ + if (event->type == RTGUI_EVENT_PAINT) + { + struct rtgui_dc* dc; + struct rtgui_rect rect; + rtgui_color_t saved; + + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) return RT_FALSE; + rtgui_widget_get_rect(widget, &rect); + saved = RTGUI_WIDGET_FOREGROUND(widget); + + /* draw background */ + background = rtgui_image_create_from_file("hdc", + "/resource/bg.hdc", RT_FALSE); + if (background != RT_NULL) + { + rtgui_image_t *play; + rtgui_rect_t play_rect; + + rtgui_image_blit(background, dc, &rect); + rtgui_image_destroy(background); + + background = RT_NULL; + + if (player_mode == PLAYER_STOP) + play = rtgui_image_create_from_mem("hdc", + stop_hdh, sizeof(stop_hdh), RT_FALSE); + else + play = rtgui_image_create_from_mem("hdc", + play_hdh, sizeof(play_hdh), RT_FALSE); + play_rect.x1 = 32; play_rect.y1 = 92; + play_rect.x2 = 61; play_rect.y2 = 114; + rtgui_image_blit(play, dc, &play_rect); + rtgui_image_destroy(play); + } + else + { + rtgui_dc_fill_rect(dc, &rect); + } + + /* draw playing information */ + rtgui_dc_set_color(dc, black); + { + char line[32]; + + rect.x1 = 28; rect.y1 = 12; + rect.x2 = 220; rect.y2 = rect.y1 + 16; + if (player_mode == PLAYER_STOP) + { + rt_snprintf(line, sizeof(line), + "网络收音机"); + rtgui_dc_draw_text(dc, line, &rect); + } + else + rtgui_dc_draw_text(dc, tinfo.title, &rect); + + rect.x1 = 28; rect.y1 = 39; + rect.x2 = 220; rect.y2 = 59; + if (player_mode == PLAYER_STOP) + { + rt_snprintf(line, sizeof(line), + "radio.rt-thread.org"); + rtgui_dc_draw_text(dc, line, &rect); + } + else + rtgui_dc_draw_text(dc, tinfo.artist, &rect); + + if (tinfo.duration != 0) + { + rect.x1 = rect.x2 - 64; + rt_snprintf(line, sizeof(line), "%02d:%02d:%02d", + tinfo.duration / 360, tinfo.duration / 60, tinfo.duration % 60); + rtgui_dc_draw_text(dc, line, &rect); + } + } + + RTGUI_WIDGET_FOREGROUND(widget) = RTGUI_RGB(82, 199, 16); + rtgui_dc_draw_hline(dc, 14, 226, 75); + + RTGUI_WIDGET_FOREGROUND(widget) = saved; + + if (player_mode == PLAYER_PLAY_FILE) + { + char line[32]; + rt_uint32_t index; + struct play_item* item; + + rect.x1 = 20; rect.y1 = 150; + rect.x2 = 220; rect.y2 = 168; + for (index = 0; index < play_list_items() && index < 8; index ++) + { + item = play_list_item(index); + rtgui_dc_draw_text(dc, item->title, &rect); + + rect.x1 = rect.x2 - 64; + rt_snprintf(line, sizeof(line), "%02d:%02d:%02d", + item->duration / 360, + item->duration / 60, + item->duration % 60); + rtgui_dc_draw_text(dc, line, &rect); + + /* move to next item */ + rect.x1 = 20; + rect.y1 += 18; rect.y2 += 18; + } + } + rtgui_dc_end_drawing(dc); + + return RT_FALSE; + } + else if (event->type == RTGUI_EVENT_KBD) + { + struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; + if (ekbd->type == RTGUI_KEYDOWN) + { + switch (ekbd->key) + { + case RTGUIK_RIGHT: + if (player_mode == PLAYER_PLAY_FILE && play_list_items() > 0) + { + player_stop(); + next_step = PLAYER_STEP_NEXT; + } + break; + case RTGUIK_LEFT: + if (player_mode == PLAYER_PLAY_FILE && play_list_items() > 0) + { + player_stop(); + next_step = PLAYER_STEP_PREV; + } + break; + + case RTGUIK_RETURN: + if (player_is_playing() == RT_TRUE) + { + player_stop(); + next_step = PLAYER_STEP_STOP; + } + else + { + if ((player_mode == PLAYER_STOP) && (play_list_items() > 0)) + { + next_step = PLAYER_STEP_NEXT; + play_mp3_file(play_list_current_item()); + } + } + break; + + case RTGUIK_DOWN: + rtgui_view_show(function_view, RT_FALSE); + break; + } + } + return RT_FALSE; + } + else if (event->type == RTGUI_EVENT_COMMAND) + { + struct rtgui_event_command* ecmd = (struct rtgui_event_command*)event; + + switch (ecmd->command_id) + { + case PLAYER_REQUEST_PLAY_SINGLE_FILE: + case PLAYER_REQUEST_PLAY_LIST: + rtgui_timer_start(info_timer); + break; + case PLAYER_REQUEST_STOP: + { + rtgui_timer_stop(info_timer); + + switch (next_step) + { + case PLAYER_STEP_STOP: + { + struct rtgui_dc* dc; + rtgui_color_t saved; + rtgui_image_t *button; + rtgui_rect_t play_rect; + + player_mode = PLAYER_STOP; + + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) return RT_FALSE; + + player_update_tag_info(dc); + + RTGUI_WIDGET_FOREGROUND(widget) = RTGUI_RGB(82, 199, 16); + rtgui_dc_draw_hline(dc, 14, 226, 75); + + /* update play button */ + button = rtgui_image_create_from_mem("hdc", + stop_hdh, sizeof(stop_hdh), RT_FALSE); + play_rect.x1 = 32; play_rect.y1 = 92; + play_rect.x2 = 61; play_rect.y2 = 114; + rtgui_image_blit(button, dc, &play_rect); + rtgui_image_destroy(button); + + RTGUI_WIDGET_FOREGROUND(widget) = saved; + rtgui_dc_end_drawing(dc); + } + break; + case PLAYER_STEP_NEXT: + if (play_list_is_end() == RT_TRUE) + { + struct rtgui_dc* dc; + rtgui_color_t saved; + rtgui_image_t *button; + rtgui_rect_t play_rect; + + /* set stat */ + next_step = PLAYER_STEP_STOP; + player_mode = PLAYER_STOP; + + /* update UI */ + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) return RT_FALSE; + + player_update_tag_info(dc); + + RTGUI_WIDGET_FOREGROUND(widget) = RTGUI_RGB(82, 199, 16); + rtgui_dc_draw_hline(dc, 14, 226, 75); + + /* update play button */ + button = rtgui_image_create_from_mem("hdc", + stop_hdh, sizeof(stop_hdh), RT_FALSE); + play_rect.x1 = 32; play_rect.y1 = 92; + play_rect.x2 = 61; play_rect.y2 = 114; + rtgui_image_blit(button, dc, &play_rect); + rtgui_image_destroy(button); + + RTGUI_WIDGET_FOREGROUND(widget) = saved; + rtgui_dc_end_drawing(dc); + } + else + { + play_mp3_file(play_list_next()); + next_step = PLAYER_STEP_NEXT; + } + break; + + case PLAYER_STEP_PREV: + play_mp3_file(play_list_prev()); + next_step = PLAYER_STEP_NEXT; + break; + }; + } + break; + + default: + break; + } + + return RT_FALSE; + } + + return rtgui_view_event_handler(widget, event); +} + +rt_bool_t player_workbench_event_handler(rtgui_widget_t *widget, rtgui_event_t *event) +{ + if (event->type == RTGUI_EVENT_KBD) + { + struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; + if ((ekbd->type == RTGUI_KEYUP) && ekbd->key == RTGUIK_HOME) + { + /* active home view */ + if (workbench->current_view != home_view) + { + rtgui_view_show(home_view, RT_FALSE); + return RT_FALSE; + } + } + } + + return rtgui_workbench_event_handler(widget, event); +} + +static void player_entry(void* parameter) +{ + rt_mq_t mq; + rtgui_rect_t rect; + + mq = rt_mq_create("ply_ui", 256, 4, RT_IPC_FLAG_FIFO); + rtgui_thread_register(rt_thread_self(), mq); + + /* create information timer */ + info_timer = rtgui_timer_create(RT_TICK_PER_SECOND, + RT_TIMER_FLAG_PERIODIC, + info_timer_timeout, RT_NULL); + + workbench = rtgui_workbench_create("main", "workbench"); + if (workbench == RT_NULL) return; + rtgui_widget_set_event_handler(RTGUI_WIDGET(workbench), player_workbench_event_handler); + + /* add home view */ + home_view = rtgui_view_create("Home"); + rtgui_widget_set_event_handler(RTGUI_WIDGET(home_view), home_view_event_handler); + + rtgui_workbench_add_view(workbench, home_view); + /* this view can be focused */ + RTGUI_WIDGET(home_view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; + /* set widget focus */ + rtgui_widget_focus(RTGUI_WIDGET(home_view)); + + rtgui_view_show(home_view, RT_FALSE); + + /* add function view */ + rtgui_widget_get_rect(RTGUI_WIDGET(workbench), &rect); + function_view = (struct rtgui_view*)list_view_create(function_list, + sizeof(function_list)/sizeof(struct list_item), + &rect); + rtgui_workbench_add_view(workbench, function_view); + + rtgui_workbench_event_loop(workbench); + + rtgui_thread_deregister(rt_thread_self()); + rt_mq_delete(mq); +} + +void player_notify_play(void) +{ + struct rtgui_event_command ecmd; + RTGUI_EVENT_COMMAND_INIT(&ecmd); + ecmd.type = RTGUI_CMD_USER_INT; + ecmd.command_id = PLAYER_REQUEST_PLAY_SINGLE_FILE; + + rtgui_thread_send(player_ui_tid, &ecmd.parent, sizeof(ecmd)); +} + +void player_notify_stop() +{ + struct rtgui_event_command ecmd; + RTGUI_EVENT_COMMAND_INIT(&ecmd); + ecmd.type = RTGUI_CMD_USER_INT; + ecmd.command_id = PLAYER_REQUEST_STOP; + + rtgui_thread_send(player_ui_tid, &ecmd.parent, sizeof(ecmd)); +} + +void player_ui_init() +{ + player_ui_tid = rt_thread_create("ply_ui", player_entry, RT_NULL, + 4096, 25, 5); + if (player_ui_tid != RT_NULL) + rt_thread_startup(player_ui_tid); +} diff --git a/bsp/stm32_radio/player_ui.h b/bsp/stm32_radio/player_ui.h new file mode 100644 index 0000000000000000000000000000000000000000..50d4e0ce7df606d446dadf79c4923ae95874bcba --- /dev/null +++ b/bsp/stm32_radio/player_ui.h @@ -0,0 +1,47 @@ +#ifndef __PLAYER_H__ +#define __PLAYER_H__ + +#include + +/* music tag information structure */ +struct tag_info +{ + char title [40]; /* music title */ + char artist[40]; /* music artist */ + + rt_uint32_t duration; /* music total duration (second) */ + rt_uint32_t position; /* music current position (second) */ + + rt_uint32_t bit_rate; /* bit rate */ + rt_uint32_t sampling; /* sampling */ + rt_uint32_t data_start; /* start position of data */ +}; + +enum PLAYER_CMD +{ + PLAYER_CMD_START, + PLAYER_CMD_STOP +}; + +enum PLAYER_MODE +{ + PLAYER_STOP, + PLAYER_PLAY_FILE, + PLAYER_PLAY_RADIO, +}; + +enum PLAYER_STEP +{ + PLAYER_STEP_STOP, + PLAYER_STEP_PREV, + PLAYER_STEP_NEXT, +}; + +void player_ui_init(void); + +void player_notify_play(void); +void player_notify_stop(void); + +void player_set_position(rt_uint32_t position); + +#endif diff --git a/bsp/stm32_radio/project.Opt b/bsp/stm32_radio/project.Opt index 79329c24e4959d1b9b1c8eadd2a45210a3c1a282..70bc14f1574d1d63944064aa0fd548c0b07d669f 100644 --- a/bsp/stm32_radio/project.Opt +++ b/bsp/stm32_radio/project.Opt @@ -11,7 +11,7 @@ DaveTm { 0,0,0,0,0,0,0,0 } Target (RT-Thread STM32 Radio), 0x0004 // Tools: 'ARM-ADS' -GRPOPT 1,(Startup),0,0,0 +GRPOPT 1,(Startup),1,0,0 GRPOPT 2,(Kernel),0,0,0 GRPOPT 3,(STM32),0,0,0 GRPOPT 4,(StdPeriph_Driver),0,0,0 @@ -27,191 +27,195 @@ OPTFFF 1,2,5,0,0,0,0,0,<.\board.h> OPTFFF 1,3,5,0,0,0,0,0,<.\stm32f10x_conf.h> OPTFFF 1,4,1,0,0,0,0,0,<.\application.c> OPTFFF 1,5,1,0,0,0,0,0,<.\board.c> -OPTFFF 1,6,1,335544320,0,0,0,0,<.\startup.c> +OPTFFF 1,6,1,0,0,0,0,0,<.\startup.c> OPTFFF 1,7,1,0,0,0,0,0,<.\stm32f10x_it.c> OPTFFF 1,8,1,0,0,0,0,0,<.\usart.c> -OPTFFF 1,9,1,0,0,0,0,0,<.\sdcard.c> +OPTFFF 1,9,1,402653184,0,0,0,0,<.\sdcard.c> OPTFFF 1,10,1,0,0,0,0,0,<.\rtc.c> -OPTFFF 1,11,1,0,0,0,0,0,<.\wm8753.c> -OPTFFF 1,12,1,0,0,0,0,0,<.\dm9000.c> -OPTFFF 1,13,1,889192448,0,0,0,0,<.\fsmc_nand.c> -OPTFFF 1,14,1,0,0,0,0,0,<.\fsmc_sram.c> -OPTFFF 1,15,1,0,0,0,0,0,<.\fmt0371\fmt0371.c> -OPTFFF 1,16,1,0,0,0,0,0,<.\http.c> -OPTFFF 1,17,1,0,0,0,0,0,<.\lcd.c> -OPTFFF 1,18,1,620756992,0,0,0,0,<.\mp3.c> -OPTFFF 1,19,1,369098752,0,0,0,0,<.\wav.c> -OPTFFF 1,20,1,620756992,0,0,0,0,<.\netbuffer.c> -OPTFFF 1,21,1,0,0,0,0,0,<.\key.c> -OPTFFF 1,22,1,0,0,0,0,0,<.\info.c> -OPTFFF 1,23,1,0,0,0,0,0, -OPTFFF 1,24,1,0,0,0,0,0,<.\filelist.c> -OPTFFF 1,25,1,0,0,0,0,0,<.\device_info.c> -OPTFFF 1,26,1,0,0,0,0,0,<.\listview.c> -OPTFFF 2,27,1,0,0,0,0,0,<..\..\src\clock.c> -OPTFFF 2,28,1,0,0,0,0,0,<..\..\src\idle.c> -OPTFFF 2,29,1,671088640,0,0,0,0,<..\..\src\ipc.c> -OPTFFF 2,30,1,0,0,0,0,0,<..\..\src\mempool.c> -OPTFFF 2,31,1,0,0,0,0,0,<..\..\src\mem.c> -OPTFFF 2,32,1,0,0,0,0,0,<..\..\src\object.c> -OPTFFF 2,33,1,0,0,0,0,0,<..\..\src\scheduler.c> -OPTFFF 2,34,1,285212672,0,0,0,0,<..\..\src\thread.c> -OPTFFF 2,35,1,0,0,0,0,0,<..\..\src\timer.c> -OPTFFF 2,36,1,0,0,0,0,0,<..\..\src\irq.c> -OPTFFF 2,37,1,0,0,0,0,0,<..\..\src\kservice.c> -OPTFFF 2,38,1,0,0,0,0,0,<..\..\src\device.c> -OPTFFF 2,39,1,0,0,0,0,0,<..\..\src\slab.c> -OPTFFF 3,40,1,0,0,0,0,0,<..\..\libcpu\arm\stm32\stack.c> -OPTFFF 3,41,1,0,0,0,0,0,<..\..\libcpu\arm\stm32\interrupt.c> -OPTFFF 3,42,1,0,0,0,0,0,<..\..\libcpu\arm\stm32\cpu.c> -OPTFFF 3,43,1,0,0,0,0,0,<..\..\libcpu\arm\stm32\serial.c> -OPTFFF 3,44,2,0,0,0,0,0,<..\..\libcpu\arm\stm32\context_rvds.S> -OPTFFF 3,45,2,570425344,0,0,0,0,<..\..\libcpu\arm\stm32\start_rvds.s> -OPTFFF 3,46,1,0,0,0,0,0,<..\..\libcpu\arm\stm32\fault.c> -OPTFFF 3,47,2,0,0,0,0,0,<..\..\libcpu\arm\stm32\fault_rvds.S> -OPTFFF 4,48,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\misc.c> -OPTFFF 4,49,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_adc.c> -OPTFFF 4,50,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_bkp.c> -OPTFFF 4,51,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_can.c> -OPTFFF 4,52,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_crc.c> -OPTFFF 4,53,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dac.c> -OPTFFF 4,54,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dbgmcu.c> -OPTFFF 4,55,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dma.c> -OPTFFF 4,56,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_exti.c> -OPTFFF 4,57,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_flash.c> -OPTFFF 4,58,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_fsmc.c> -OPTFFF 4,59,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c> -OPTFFF 4,60,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_i2c.c> -OPTFFF 4,61,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_iwdg.c> -OPTFFF 4,62,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_pwr.c> -OPTFFF 4,63,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c> -OPTFFF 4,64,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_rtc.c> -OPTFFF 4,65,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_sdio.c> -OPTFFF 4,66,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_spi.c> -OPTFFF 4,67,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_tim.c> -OPTFFF 4,68,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_usart.c> -OPTFFF 4,69,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_wwdg.c> -OPTFFF 5,70,1,0,0,0,0,0,<.\Libraries\CMSIS\Core\CM3\core_cm3.c> -OPTFFF 5,71,1,0,0,0,0,0,<.\Libraries\CMSIS\Core\CM3\system_stm32f10x.c> -OPTFFF 6,72,1,0,0,0,0,0,<..\..\finsh\finsh_compiler.c> -OPTFFF 6,73,1,0,0,0,0,0,<..\..\finsh\finsh_error.c> -OPTFFF 6,74,1,0,0,0,0,0,<..\..\finsh\finsh_heap.c> -OPTFFF 6,75,1,0,0,0,0,0,<..\..\finsh\finsh_init.c> -OPTFFF 6,76,1,0,0,0,0,0,<..\..\finsh\finsh_node.c> -OPTFFF 6,77,1,0,0,0,0,0,<..\..\finsh\finsh_ops.c> -OPTFFF 6,78,1,0,0,0,0,0,<..\..\finsh\finsh_parser.c> -OPTFFF 6,79,1,0,0,0,0,0,<..\..\finsh\finsh_token.c> -OPTFFF 6,80,1,0,0,0,0,0,<..\..\finsh\finsh_var.c> -OPTFFF 6,81,1,0,0,0,0,0,<..\..\finsh\finsh_vm.c> -OPTFFF 6,82,1,0,0,0,0,0,<..\..\finsh\shell.c> -OPTFFF 6,83,1,0,0,0,0,0,<..\..\finsh\symbol.c> -OPTFFF 6,84,1,285212672,0,0,0,0,<..\..\finsh\cmd.c> -OPTFFF 7,85,1,0,0,0,0,0,<..\..\filesystem\dfs\src\dfs_init.c> -OPTFFF 7,86,1,503316480,0,0,0,0,<..\..\filesystem\dfs\src\dfs_fs.c> -OPTFFF 7,87,1,0,0,0,0,0,<..\..\filesystem\dfs\src\dfs_raw.c> -OPTFFF 7,88,1,0,0,0,0,0,<..\..\filesystem\dfs\src\dfs_util.c> -OPTFFF 7,89,1,0,0,0,0,0,<..\..\filesystem\dfs\src\dfs_posix.c> -OPTFFF 7,90,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\dir.c> -OPTFFF 7,91,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\fat.c> -OPTFFF 7,92,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\file.c> -OPTFFF 7,93,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\fs.c> -OPTFFF 7,94,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\ls.c> -OPTFFF 7,95,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\time.c> -OPTFFF 7,96,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\ui.c> -OPTFFF 7,97,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\base\plibc.c> -OPTFFF 7,98,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\base\efs.c> -OPTFFF 7,99,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\base\extract.c> -OPTFFF 7,100,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\base\partition.c> -OPTFFF 7,101,1,0,0,0,0,0,<..\..\filesystem\dfs\src\dfs_cache.c> -OPTFFF 8,102,1,0,0,0,0,0,<..\..\net\lwip\src\core\dhcp.c> -OPTFFF 8,103,1,0,0,0,0,0,<..\..\net\lwip\src\core\dns.c> -OPTFFF 8,104,1,0,0,0,0,0,<..\..\net\lwip\src\core\init.c> -OPTFFF 8,105,1,0,0,0,0,0,<..\..\net\lwip\src\core\netif.c> -OPTFFF 8,106,1,0,0,0,0,0,<..\..\net\lwip\src\core\pbuf.c> -OPTFFF 8,107,1,0,0,0,0,0,<..\..\net\lwip\src\core\raw.c> -OPTFFF 8,108,1,0,0,0,0,0,<..\..\net\lwip\src\core\stats.c> -OPTFFF 8,109,1,0,0,0,0,0,<..\..\net\lwip\src\core\sys.c> -OPTFFF 8,110,1,0,0,0,0,0,<..\..\net\lwip\src\core\tcp.c> -OPTFFF 8,111,1,0,0,0,0,0,<..\..\net\lwip\src\core\tcp_in.c> -OPTFFF 8,112,1,0,0,0,0,0,<..\..\net\lwip\src\core\tcp_out.c> -OPTFFF 8,113,1,0,0,0,0,0,<..\..\net\lwip\src\core\udp.c> -OPTFFF 8,114,1,0,0,0,0,0,<..\..\net\lwip\src\core\ipv4\autoip.c> -OPTFFF 8,115,1,0,0,0,0,0,<..\..\net\lwip\src\core\ipv4\icmp.c> -OPTFFF 8,116,1,0,0,0,0,0,<..\..\net\lwip\src\core\ipv4\igmp.c> -OPTFFF 8,117,1,0,0,0,0,0,<..\..\net\lwip\src\core\ipv4\inet.c> -OPTFFF 8,118,1,0,0,0,0,0,<..\..\net\lwip\src\core\ipv4\inet_chksum.c> -OPTFFF 8,119,1,0,0,0,0,0,<..\..\net\lwip\src\core\ipv4\ip.c> -OPTFFF 8,120,1,0,0,0,0,0,<..\..\net\lwip\src\core\ipv4\ip_addr.c> -OPTFFF 8,121,1,285212672,0,0,0,0,<..\..\net\lwip\src\core\ipv4\ip_frag.c> -OPTFFF 8,122,1,0,0,0,0,0,<..\..\net\lwip\src\core\snmp\msg_in.c> -OPTFFF 8,123,1,0,0,0,0,0,<..\..\net\lwip\src\core\snmp\msg_out.c> -OPTFFF 8,124,1,0,0,0,0,0,<..\..\net\lwip\src\api\api_lib.c> -OPTFFF 8,125,1,50331648,0,0,0,0,<..\..\net\lwip\src\api\api_msg.c> -OPTFFF 8,126,1,0,0,0,0,0,<..\..\net\lwip\src\api\err.c> -OPTFFF 8,127,1,0,0,0,0,0,<..\..\net\lwip\src\api\netbuf.c> -OPTFFF 8,128,1,0,0,0,0,0,<..\..\net\lwip\src\api\netdb.c> -OPTFFF 8,129,1,0,0,0,0,0,<..\..\net\lwip\src\api\netifapi.c> -OPTFFF 8,130,1,0,0,0,0,0,<..\..\net\lwip\src\api\tcpip.c> -OPTFFF 8,131,1,0,0,0,0,0,<..\..\net\lwip\src\netif\etharp.c> -OPTFFF 8,132,1,150994944,0,0,0,0,<..\..\net\lwip\src\netif\ethernetif.c> -OPTFFF 8,133,1,0,0,0,0,0,<..\..\net\lwip\src\netif\loopif.c> -OPTFFF 8,134,1,285212672,0,0,0,0,<..\..\net\lwip\src\arch\sys_arch_init.c> -OPTFFF 8,135,1,0,0,0,0,0,<..\..\net\lwip\src\arch\sys_arch.c> -OPTFFF 8,136,1,0,0,0,0,0,<..\..\net\lwip\src\api\sockets.c> -OPTFFF 8,137,1,0,0,0,0,0,<..\..\net\lwip\src\core\memp_tiny.c> -OPTFFF 9,138,1,268435456,0,0,0,0,<.\mp3\mp3dec.c> -OPTFFF 9,139,1,0,0,0,0,0,<.\mp3\mp3tabs.c> -OPTFFF 9,140,1,0,0,0,0,0,<.\mp3\real\bitstream.c> -OPTFFF 9,141,1,83886080,0,0,0,0,<.\mp3\real\buffers.c> -OPTFFF 9,142,1,0,0,0,0,0,<.\mp3\real\dct32.c> -OPTFFF 9,143,1,0,0,0,0,0,<.\mp3\real\dequant.c> -OPTFFF 9,144,1,0,0,0,0,0,<.\mp3\real\dqchan.c> -OPTFFF 9,145,1,0,0,0,0,0,<.\mp3\real\huffman.c> -OPTFFF 9,146,1,0,0,0,0,0,<.\mp3\real\hufftabs.c> -OPTFFF 9,147,1,0,0,0,0,0,<.\mp3\real\imdct.c> -OPTFFF 9,148,1,0,0,0,0,0,<.\mp3\real\scalfact.c> -OPTFFF 9,149,1,0,0,0,0,0,<.\mp3\real\stproc.c> -OPTFFF 9,150,1,0,0,0,0,0,<.\mp3\real\subband.c> -OPTFFF 9,151,1,0,0,0,0,0,<.\mp3\real\trigtabs.c> -OPTFFF 9,152,2,0,0,0,0,0,<.\mp3\real\arm\asmpoly_thumb2.s> -OPTFFF 9,153,2,0,0,0,0,0,<.\mp3\real\arm\asmmisc.s> -OPTFFF 10,154,1,0,0,0,0,0,<..\..\rtgui\common\rtgui_object.c> -OPTFFF 10,155,1,0,0,0,0,0,<..\..\rtgui\common\rtgui_system.c> -OPTFFF 10,156,1,620756992,0,0,0,0,<..\..\rtgui\common\rtgui_theme.c> -OPTFFF 10,157,1,0,0,0,0,0,<..\..\rtgui\common\asc12font.c> -OPTFFF 10,158,1,402653184,0,0,0,0,<..\..\rtgui\common\asc16font.c> -OPTFFF 10,159,1,0,0,0,0,0,<..\..\rtgui\common\color.c> -OPTFFF 10,160,1,0,0,0,0,0,<..\..\rtgui\common\dc.c> -OPTFFF 10,161,1,0,0,0,0,0,<..\..\rtgui\common\dc_buffer.c> -OPTFFF 10,162,1,0,0,0,0,0,<..\..\rtgui\common\dc_hw.c> -OPTFFF 10,163,1,16777216,0,0,0,0,<..\..\rtgui\common\filerw.c> -OPTFFF 10,164,1,0,0,0,0,0,<..\..\rtgui\common\font.c> -OPTFFF 10,165,1,469762048,0,0,0,0,<..\..\rtgui\common\image.c> -OPTFFF 10,166,1,0,0,0,0,0,<..\..\rtgui\common\image_xpm.c> -OPTFFF 10,167,1,0,0,0,0,0,<..\..\rtgui\common\image_hdc.c> -OPTFFF 10,168,1,0,0,0,0,0,<..\..\rtgui\common\region.c> -OPTFFF 10,169,1,100663296,0,0,0,0,<..\..\rtgui\server\server.c> -OPTFFF 10,170,1,0,0,0,0,0,<..\..\rtgui\server\driver.c> -OPTFFF 10,171,1,335544320,0,0,0,0,<..\..\rtgui\server\panel.c> -OPTFFF 10,172,1,0,0,0,0,0,<..\..\rtgui\widgets\widget.c> -OPTFFF 10,173,1,16777216,0,0,0,0,<..\..\rtgui\widgets\window.c> -OPTFFF 10,174,1,0,0,0,0,0,<..\..\rtgui\widgets\workbench.c> -OPTFFF 10,175,1,16777216,0,0,0,0,<..\..\rtgui\widgets\view.c> -OPTFFF 10,176,1,0,0,0,0,0,<..\..\rtgui\widgets\box.c> -OPTFFF 10,177,1,0,0,0,0,0,<..\..\rtgui\widgets\button.c> -OPTFFF 10,178,1,0,0,0,0,0,<..\..\rtgui\widgets\container.c> -OPTFFF 10,179,1,0,0,0,0,0,<..\..\rtgui\widgets\iconbox.c> -OPTFFF 10,180,1,0,0,0,0,0,<..\..\rtgui\widgets\label.c> -OPTFFF 10,181,1,0,0,0,0,0,<..\..\rtgui\widgets\textbox.c> -OPTFFF 10,182,1,0,0,0,0,0,<..\..\rtgui\widgets\title.c> -OPTFFF 10,183,1,67108864,0,0,0,0,<..\..\rtgui\widgets\toplevel.c> -OPTFFF 10,184,1,0,0,0,0,0,<..\..\rtgui\server\mouse.c> -OPTFFF 10,185,1,0,0,0,0,0,<..\..\rtgui\server\topwin.c> -OPTFFF 10,186,1,0,0,0,0,0,<..\..\rtgui\common\caret.c> -OPTFFF 10,187,1,0,0,0,0,0,<..\..\rtgui\common\font_hz_file.c> -OPTFFF 10,188,1,0,0,0,0,0,<..\..\rtgui\common\hz16font.c> -OPTFFF 10,189,1,0,0,0,0,0,<..\..\rtgui\common\hz12font.c> +OPTFFF 1,11,1,0,0,0,0,0,<.\dm9000.c> +OPTFFF 1,12,1,889192448,0,0,0,0,<.\fsmc_nand.c> +OPTFFF 1,13,1,0,0,0,0,0,<.\fsmc_sram.c> +OPTFFF 1,14,1,0,0,0,0,0,<.\fmt0371\fmt0371.c> +OPTFFF 1,15,1,0,0,0,0,0,<.\http.c> +OPTFFF 1,16,1,0,0,0,0,0,<.\lcd.c> +OPTFFF 1,17,1,16777216,0,401,410,0,<.\mp3.c> { 44,0,0,0,0,0,0,0,1,0,0,0,255,255,255,255,255,255,255,255,252,255,255,255,226,255,255,255,22,0,0,0,29,0,0,0,164,2,0,0,145,1,0,0 } +OPTFFF 1,18,1,369098752,0,0,0,0,<.\wav.c> +OPTFFF 1,19,1,0,0,0,0,0,<.\netbuffer.c> +OPTFFF 1,20,1,0,0,0,0,0,<.\key.c> +OPTFFF 1,21,1,553648128,0,0,0,0,<.\info.c> +OPTFFF 1,22,1,0,0,0,0,0,<.\filelist.c> +OPTFFF 1,23,1,0,0,0,0,0,<.\device_info.c> +OPTFFF 1,24,1,0,0,0,0,0,<.\listview.c> +OPTFFF 1,25,1,0,0,0,0,0,<.\wm8753.c> +OPTFFF 1,26,1,3,0,481,487,0,<.\player_ui.c> { 44,0,0,0,2,0,0,0,3,0,0,0,255,255,255,255,255,255,255,255,252,255,255,255,226,255,255,255,0,0,0,0,0,0,0,0,186,2,0,0,218,0,0,0 } +OPTFFF 1,27,1,268435456,0,1,1,0,<.\player_bg.c> { 44,0,0,0,0,0,0,0,1,0,0,0,255,255,255,255,255,255,255,255,252,255,255,255,226,255,255,255,66,0,0,0,87,0,0,0,252,2,0,0,49,1,0,0 } +OPTFFF 1,28,1,0,0,0,0,0,<.\wm8978.c> +OPTFFF 1,29,1,469762048,0,0,0,0,<.\play_list.c> +OPTFFF 2,30,1,0,0,0,0,0,<..\..\src\clock.c> +OPTFFF 2,31,1,0,0,0,0,0,<..\..\src\idle.c> +OPTFFF 2,32,1,0,0,0,0,0,<..\..\src\ipc.c> +OPTFFF 2,33,1,0,0,0,0,0,<..\..\src\mempool.c> +OPTFFF 2,34,1,0,0,0,0,0,<..\..\src\mem.c> +OPTFFF 2,35,1,0,0,0,0,0,<..\..\src\object.c> +OPTFFF 2,36,1,0,0,0,0,0,<..\..\src\scheduler.c> +OPTFFF 2,37,1,285212672,0,0,0,0,<..\..\src\thread.c> +OPTFFF 2,38,1,0,0,0,0,0,<..\..\src\timer.c> +OPTFFF 2,39,1,0,0,0,0,0,<..\..\src\irq.c> +OPTFFF 2,40,1,0,0,0,0,0,<..\..\src\kservice.c> +OPTFFF 2,41,1,0,0,0,0,0,<..\..\src\device.c> +OPTFFF 2,42,1,0,0,0,0,0,<..\..\src\slab.c> +OPTFFF 3,43,1,0,0,0,0,0,<..\..\libcpu\arm\stm32\stack.c> +OPTFFF 3,44,1,0,0,0,0,0,<..\..\libcpu\arm\stm32\interrupt.c> +OPTFFF 3,45,1,0,0,0,0,0,<..\..\libcpu\arm\stm32\cpu.c> +OPTFFF 3,46,1,0,0,0,0,0,<..\..\libcpu\arm\stm32\serial.c> +OPTFFF 3,47,2,0,0,0,0,0,<..\..\libcpu\arm\stm32\context_rvds.S> +OPTFFF 3,48,2,0,0,13,19,0,<..\..\libcpu\arm\stm32\start_rvds.s> { 44,0,0,0,0,0,0,0,1,0,0,0,255,255,255,255,255,255,255,255,252,255,255,255,226,255,255,255,88,0,0,0,116,0,0,0,1,3,0,0,232,1,0,0 } +OPTFFF 3,49,1,0,0,0,0,0,<..\..\libcpu\arm\stm32\fault.c> +OPTFFF 3,50,2,0,0,0,0,0,<..\..\libcpu\arm\stm32\fault_rvds.S> +OPTFFF 4,51,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\misc.c> +OPTFFF 4,52,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_adc.c> +OPTFFF 4,53,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_bkp.c> +OPTFFF 4,54,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_can.c> +OPTFFF 4,55,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_crc.c> +OPTFFF 4,56,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dac.c> +OPTFFF 4,57,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dbgmcu.c> +OPTFFF 4,58,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dma.c> +OPTFFF 4,59,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_exti.c> +OPTFFF 4,60,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_flash.c> +OPTFFF 4,61,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_fsmc.c> +OPTFFF 4,62,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c> +OPTFFF 4,63,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_i2c.c> +OPTFFF 4,64,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_iwdg.c> +OPTFFF 4,65,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_pwr.c> +OPTFFF 4,66,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c> +OPTFFF 4,67,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_rtc.c> +OPTFFF 4,68,1,16777216,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_sdio.c> +OPTFFF 4,69,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_spi.c> +OPTFFF 4,70,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_tim.c> +OPTFFF 4,71,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_usart.c> +OPTFFF 4,72,1,0,0,0,0,0,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_wwdg.c> +OPTFFF 5,73,1,0,0,0,0,0,<.\Libraries\CMSIS\Core\CM3\core_cm3.c> +OPTFFF 5,74,1,0,0,0,0,0,<.\Libraries\CMSIS\Core\CM3\system_stm32f10x.c> +OPTFFF 6,75,1,0,0,0,0,0,<..\..\finsh\finsh_compiler.c> +OPTFFF 6,76,1,0,0,0,0,0,<..\..\finsh\finsh_error.c> +OPTFFF 6,77,1,0,0,0,0,0,<..\..\finsh\finsh_heap.c> +OPTFFF 6,78,1,0,0,0,0,0,<..\..\finsh\finsh_init.c> +OPTFFF 6,79,1,0,0,0,0,0,<..\..\finsh\finsh_node.c> +OPTFFF 6,80,1,0,0,0,0,0,<..\..\finsh\finsh_ops.c> +OPTFFF 6,81,1,0,0,0,0,0,<..\..\finsh\finsh_parser.c> +OPTFFF 6,82,1,0,0,0,0,0,<..\..\finsh\finsh_token.c> +OPTFFF 6,83,1,0,0,0,0,0,<..\..\finsh\finsh_var.c> +OPTFFF 6,84,1,0,0,0,0,0,<..\..\finsh\finsh_vm.c> +OPTFFF 6,85,1,0,0,0,0,0,<..\..\finsh\shell.c> +OPTFFF 6,86,1,0,0,0,0,0,<..\..\finsh\symbol.c> +OPTFFF 6,87,1,285212672,0,0,0,0,<..\..\finsh\cmd.c> +OPTFFF 7,88,1,0,0,0,0,0,<..\..\filesystem\dfs\src\dfs_init.c> +OPTFFF 7,89,1,503316480,0,0,0,0,<..\..\filesystem\dfs\src\dfs_fs.c> +OPTFFF 7,90,1,0,0,0,0,0,<..\..\filesystem\dfs\src\dfs_raw.c> +OPTFFF 7,91,1,0,0,0,0,0,<..\..\filesystem\dfs\src\dfs_util.c> +OPTFFF 7,92,1,0,0,0,0,0,<..\..\filesystem\dfs\src\dfs_posix.c> +OPTFFF 7,93,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\dir.c> +OPTFFF 7,94,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\fat.c> +OPTFFF 7,95,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\file.c> +OPTFFF 7,96,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\fs.c> +OPTFFF 7,97,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\ls.c> +OPTFFF 7,98,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\time.c> +OPTFFF 7,99,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\ui.c> +OPTFFF 7,100,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\base\plibc.c> +OPTFFF 7,101,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\base\efs.c> +OPTFFF 7,102,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\base\extract.c> +OPTFFF 7,103,1,0,0,0,0,0,<..\..\filesystem\dfs\filesystems\efsl\src\base\partition.c> +OPTFFF 7,104,1,0,0,0,0,0,<..\..\filesystem\dfs\src\dfs_cache.c> +OPTFFF 8,105,1,0,0,0,0,0,<..\..\net\lwip\src\core\dhcp.c> +OPTFFF 8,106,1,0,0,0,0,0,<..\..\net\lwip\src\core\dns.c> +OPTFFF 8,107,1,0,0,0,0,0,<..\..\net\lwip\src\core\init.c> +OPTFFF 8,108,1,0,0,0,0,0,<..\..\net\lwip\src\core\netif.c> +OPTFFF 8,109,1,0,0,0,0,0,<..\..\net\lwip\src\core\pbuf.c> +OPTFFF 8,110,1,0,0,0,0,0,<..\..\net\lwip\src\core\raw.c> +OPTFFF 8,111,1,0,0,0,0,0,<..\..\net\lwip\src\core\stats.c> +OPTFFF 8,112,1,0,0,0,0,0,<..\..\net\lwip\src\core\sys.c> +OPTFFF 8,113,1,0,0,0,0,0,<..\..\net\lwip\src\core\tcp.c> +OPTFFF 8,114,1,0,0,0,0,0,<..\..\net\lwip\src\core\tcp_in.c> +OPTFFF 8,115,1,0,0,0,0,0,<..\..\net\lwip\src\core\tcp_out.c> +OPTFFF 8,116,1,0,0,0,0,0,<..\..\net\lwip\src\core\udp.c> +OPTFFF 8,117,1,0,0,0,0,0,<..\..\net\lwip\src\core\ipv4\autoip.c> +OPTFFF 8,118,1,0,0,0,0,0,<..\..\net\lwip\src\core\ipv4\icmp.c> +OPTFFF 8,119,1,0,0,0,0,0,<..\..\net\lwip\src\core\ipv4\igmp.c> +OPTFFF 8,120,1,0,0,0,0,0,<..\..\net\lwip\src\core\ipv4\inet.c> +OPTFFF 8,121,1,0,0,0,0,0,<..\..\net\lwip\src\core\ipv4\inet_chksum.c> +OPTFFF 8,122,1,0,0,0,0,0,<..\..\net\lwip\src\core\ipv4\ip.c> +OPTFFF 8,123,1,0,0,0,0,0,<..\..\net\lwip\src\core\ipv4\ip_addr.c> +OPTFFF 8,124,1,285212672,0,0,0,0,<..\..\net\lwip\src\core\ipv4\ip_frag.c> +OPTFFF 8,125,1,0,0,0,0,0,<..\..\net\lwip\src\core\snmp\msg_in.c> +OPTFFF 8,126,1,0,0,0,0,0,<..\..\net\lwip\src\core\snmp\msg_out.c> +OPTFFF 8,127,1,0,0,0,0,0,<..\..\net\lwip\src\api\api_lib.c> +OPTFFF 8,128,1,50331648,0,0,0,0,<..\..\net\lwip\src\api\api_msg.c> +OPTFFF 8,129,1,0,0,0,0,0,<..\..\net\lwip\src\api\err.c> +OPTFFF 8,130,1,0,0,0,0,0,<..\..\net\lwip\src\api\netbuf.c> +OPTFFF 8,131,1,0,0,0,0,0,<..\..\net\lwip\src\api\netdb.c> +OPTFFF 8,132,1,0,0,0,0,0,<..\..\net\lwip\src\api\netifapi.c> +OPTFFF 8,133,1,0,0,0,0,0,<..\..\net\lwip\src\api\tcpip.c> +OPTFFF 8,134,1,0,0,0,0,0,<..\..\net\lwip\src\netif\etharp.c> +OPTFFF 8,135,1,150994944,0,0,0,0,<..\..\net\lwip\src\netif\ethernetif.c> +OPTFFF 8,136,1,0,0,0,0,0,<..\..\net\lwip\src\netif\loopif.c> +OPTFFF 8,137,1,285212672,0,0,0,0,<..\..\net\lwip\src\arch\sys_arch_init.c> +OPTFFF 8,138,1,0,0,0,0,0,<..\..\net\lwip\src\arch\sys_arch.c> +OPTFFF 8,139,1,0,0,0,0,0,<..\..\net\lwip\src\api\sockets.c> +OPTFFF 8,140,1,0,0,0,0,0,<..\..\net\lwip\src\core\memp_tiny.c> +OPTFFF 9,141,1,402653184,0,0,0,0,<.\mp3\mp3dec.c> +OPTFFF 9,142,1,0,0,0,0,0,<.\mp3\mp3tabs.c> +OPTFFF 9,143,1,0,0,0,0,0,<.\mp3\real\bitstream.c> +OPTFFF 9,144,1,83886080,0,0,0,0,<.\mp3\real\buffers.c> +OPTFFF 9,145,1,0,0,0,0,0,<.\mp3\real\dct32.c> +OPTFFF 9,146,1,0,0,0,0,0,<.\mp3\real\dequant.c> +OPTFFF 9,147,1,0,0,0,0,0,<.\mp3\real\dqchan.c> +OPTFFF 9,148,1,0,0,0,0,0,<.\mp3\real\huffman.c> +OPTFFF 9,149,1,0,0,0,0,0,<.\mp3\real\hufftabs.c> +OPTFFF 9,150,1,0,0,0,0,0,<.\mp3\real\imdct.c> +OPTFFF 9,151,1,0,0,0,0,0,<.\mp3\real\scalfact.c> +OPTFFF 9,152,1,0,0,0,0,0,<.\mp3\real\stproc.c> +OPTFFF 9,153,1,0,0,0,0,0,<.\mp3\real\subband.c> +OPTFFF 9,154,1,0,0,0,0,0,<.\mp3\real\trigtabs.c> +OPTFFF 9,155,2,0,0,0,0,0,<.\mp3\real\arm\asmpoly_thumb2.s> +OPTFFF 9,156,2,0,0,0,0,0,<.\mp3\real\arm\asmmisc.s> +OPTFFF 10,157,1,0,0,0,0,0,<..\..\rtgui\common\rtgui_object.c> +OPTFFF 10,158,1,0,0,0,0,0,<..\..\rtgui\common\rtgui_system.c> +OPTFFF 10,159,1,318767104,0,0,0,0,<..\..\rtgui\common\rtgui_theme.c> +OPTFFF 10,160,1,0,0,0,0,0,<..\..\rtgui\common\asc12font.c> +OPTFFF 10,161,1,402653184,0,0,0,0,<..\..\rtgui\common\asc16font.c> +OPTFFF 10,162,1,0,0,0,0,0,<..\..\rtgui\common\color.c> +OPTFFF 10,163,1,603979776,0,0,0,0,<..\..\rtgui\common\dc.c> +OPTFFF 10,164,1,0,0,0,0,0,<..\..\rtgui\common\dc_buffer.c> +OPTFFF 10,165,1,0,0,0,0,0,<..\..\rtgui\common\dc_hw.c> +OPTFFF 10,166,1,16777216,0,0,0,0,<..\..\rtgui\common\filerw.c> +OPTFFF 10,167,1,0,0,0,0,0,<..\..\rtgui\common\font.c> +OPTFFF 10,168,1,0,0,0,0,0,<..\..\rtgui\common\image.c> +OPTFFF 10,169,1,0,0,0,0,0,<..\..\rtgui\common\image_xpm.c> +OPTFFF 10,170,1,0,0,0,0,0,<..\..\rtgui\common\image_hdc.c> +OPTFFF 10,171,1,0,0,0,0,0,<..\..\rtgui\common\region.c> +OPTFFF 10,172,1,100663296,0,0,0,0,<..\..\rtgui\server\server.c> +OPTFFF 10,173,1,0,0,0,0,0,<..\..\rtgui\server\driver.c> +OPTFFF 10,174,1,335544320,0,0,0,0,<..\..\rtgui\server\panel.c> +OPTFFF 10,175,1,0,0,0,0,0,<..\..\rtgui\widgets\widget.c> +OPTFFF 10,176,1,16777216,0,0,0,0,<..\..\rtgui\widgets\window.c> +OPTFFF 10,177,1,0,0,0,0,0,<..\..\rtgui\widgets\workbench.c> +OPTFFF 10,178,1,0,0,0,0,0,<..\..\rtgui\widgets\view.c> +OPTFFF 10,179,1,0,0,0,0,0,<..\..\rtgui\widgets\box.c> +OPTFFF 10,180,1,0,0,0,0,0,<..\..\rtgui\widgets\button.c> +OPTFFF 10,181,1,0,0,0,0,0,<..\..\rtgui\widgets\container.c> +OPTFFF 10,182,1,0,0,0,0,0,<..\..\rtgui\widgets\iconbox.c> +OPTFFF 10,183,1,0,0,0,0,0,<..\..\rtgui\widgets\label.c> +OPTFFF 10,184,1,0,0,0,0,0,<..\..\rtgui\widgets\textbox.c> +OPTFFF 10,185,1,0,0,0,0,0,<..\..\rtgui\widgets\title.c> +OPTFFF 10,186,1,67108864,0,0,0,0,<..\..\rtgui\widgets\toplevel.c> +OPTFFF 10,187,1,0,0,0,0,0,<..\..\rtgui\server\mouse.c> +OPTFFF 10,188,1,0,0,0,0,0,<..\..\rtgui\server\topwin.c> +OPTFFF 10,189,1,0,0,0,0,0,<..\..\rtgui\common\caret.c> +OPTFFF 10,190,1,0,0,0,0,0,<..\..\rtgui\common\font_hz_file.c> +OPTFFF 10,191,1,0,0,0,0,0,<..\..\rtgui\common\hz16font.c> +OPTFFF 10,192,1,0,0,0,0,0,<..\..\rtgui\common\hz12font.c> +ExtF 13,29,0,{ 44,0,0,0,0,0,0,0,1,0,0,0,255,255,255,255,255,255,255,255,252,255,255,255,226,255,255,255,66,0,0,0,87,0,0,0,208,2,0,0,203,1,0,0 } TARGOPT 1, (RT-Thread STM32 Radio) ADSCLK=8000000 @@ -225,15 +229,15 @@ TARGOPT 1, (RT-Thread STM32 Radio) OPTAX 255 OPTDL (SARMCM3.DLL)()(DARMSTM.DLL)(-pSTM32F103ZE)(SARMCM3.DLL)()(TARMSTM.DLL)(-pSTM32F103ZE) OPTDBG 48118,7,()()()()()()()()()() (Segger\JL2CM3.dll)()()() - OPTKEY 0,(DLGTARM)((1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(100=-1,-1,-1,-1,0)(110=-1,-1,-1,-1,0)(111=-1,-1,-1,-1,0)(1011=-1,-1,-1,-1,0)(180=-1,-1,-1,-1,0)(120=-1,-1,-1,-1,0)(121=-1,-1,-1,-1,0)(122=-1,-1,-1,-1,0)(123=-1,-1,-1,-1,0)(124=-1,-1,-1,-1,0)(125=-1,-1,-1,-1,0)(126=-1,-1,-1,-1,0)(140=-1,-1,-1,-1,0)(240=-1,-1,-1,-1,0)(190=-1,-1,-1,-1,0)(200=-1,-1,-1,-1,0)(170=-1,-1,-1,-1,0)(130=-1,-1,-1,-1,0)(131=-1,-1,-1,-1,0)(132=-1,-1,-1,-1,0)(133=-1,-1,-1,-1,0)(160=-1,-1,-1,-1,0)(161=-1,-1,-1,-1,0)(162=-1,-1,-1,-1,0)(210=-1,-1,-1,-1,0)(211=-1,-1,-1,-1,0)(220=-1,-1,-1,-1,0)(221=-1,-1,-1,-1,0)(230=-1,-1,-1,-1,0)(231=-1,-1,-1,-1,0)(232=-1,-1,-1,-1,0)(233=-1,-1,-1,-1,0)(150=-1,-1,-1,-1,0)(151=-1,-1,-1,-1,0)) + OPTKEY 0,(DLGTARM)((1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(100=-1,-1,-1,-1,0)(110=-1,-1,-1,-1,0)(111=-1,-1,-1,-1,0)(1011=60,91,584,445,0)(180=-1,-1,-1,-1,0)(120=-1,-1,-1,-1,0)(121=-1,-1,-1,-1,0)(122=-1,-1,-1,-1,0)(123=-1,-1,-1,-1,0)(124=-1,-1,-1,-1,0)(125=-1,-1,-1,-1,0)(126=-1,-1,-1,-1,0)(140=-1,-1,-1,-1,0)(240=-1,-1,-1,-1,0)(190=-1,-1,-1,-1,0)(200=-1,-1,-1,-1,0)(170=-1,-1,-1,-1,0)(130=-1,-1,-1,-1,0)(131=-1,-1,-1,-1,0)(132=-1,-1,-1,-1,0)(133=-1,-1,-1,-1,0)(160=-1,-1,-1,-1,0)(161=-1,-1,-1,-1,0)(162=-1,-1,-1,-1,0)(210=-1,-1,-1,-1,0)(211=-1,-1,-1,-1,0)(220=-1,-1,-1,-1,0)(221=-1,-1,-1,-1,0)(230=-1,-1,-1,-1,0)(231=-1,-1,-1,-1,0)(232=-1,-1,-1,-1,0)(233=-1,-1,-1,-1,0)(150=-1,-1,-1,-1,0)(151=-1,-1,-1,-1,0)) OPTKEY 0,(ARMDBGFLAGS)() - OPTKEY 0,(DLGUARM)((105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0)) + OPTKEY 0,(DLGUARM)((105=150,189,819,540,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0)) OPTKEY 0,(JL2CM3)(-U20090110 -O718 -S8 -C0 -JU1 -JI127.0.0.1 -JP0 -N00("ARM CoreSight SW-DP") -D00(00000000) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO27 -FD20000000 -FC800 -FN1 -FF0STM32F10x_512 -FS08000000 -FL080000) - OPTBB 0,0,590,1,134245962,0,0,0,0,1,()() - OPTBB 1,0,129,1,134325656,0,0,0,0,1,()() - OPTBB 2,0,41,1,134354810,0,0,0,0,1,()() - OPTBB 3,0,66,1,134343178,0,0,0,0,1,()() - OPTMM 1,8,(0x20005f34) + OPTBB 0,0,129,1,134329636,0,0,0,0,1,()() + OPTBB 1,0,3051,1,134335826,0,0,0,0,1,()() + OPTWA 0,1,(_mp) + OPTWA 1,1,(tinfo,0x0A) + OPTMM 1,8,(text) OPTMM 2,8,(mimeBuffer) OPTDF 0x82 OPTLE <> diff --git a/bsp/stm32_radio/project.Uv2 b/bsp/stm32_radio/project.Uv2 index 9c0f136df12da642cf8adc9509361bb29cf77344..66d99e3b69743b4cba61052d8e0b826db5700359 100644 --- a/bsp/stm32_radio/project.Uv2 +++ b/bsp/stm32_radio/project.Uv2 @@ -24,7 +24,6 @@ File 1,1,<.\stm32f10x_it.c> File 1,1,<.\usart.c> File 1,1,<.\sdcard.c> File 1,1,<.\rtc.c> -File 1,1,<.\wm8753.c> File 1,1,<.\dm9000.c> File 1,1,<.\fsmc_nand.c> File 1,1,<.\fsmc_sram.c> @@ -36,10 +35,14 @@ File 1,1,<.\wav.c> File 1,1,<.\netbuffer.c> File 1,1,<.\key.c> File 1,1,<.\info.c> -File 1,1,<.\player.c> File 1,1,<.\filelist.c> File 1,1,<.\device_info.c> File 1,1,<.\listview.c> +File 1,1,<.\wm8753.c> +File 1,1,<.\player_ui.c> +File 1,1,<.\player_bg.c> +File 1,1,<.\wm8978.c> +File 1,1,<.\play_list.c> File 2,1,<..\..\src\clock.c> File 2,1,<..\..\src\idle.c> File 2,1,<..\..\src\ipc.c> diff --git a/bsp/stm32_radio/sdcard.c b/bsp/stm32_radio/sdcard.c index fbbc42aab335aa878d3c699db101b24a23d374db..386db317936cd4b40b9ff48d027ada5acd7de371 100644 --- a/bsp/stm32_radio/sdcard.c +++ b/bsp/stm32_radio/sdcard.c @@ -21,7 +21,9 @@ /* Includes ------------------------------------------------------------------*/ #include "sdcard.h" #include -#include +#include + +#include /** @addtogroup STM32F10x_StdPeriph_Examples * @{ @@ -955,12 +957,30 @@ SD_Error SD_ReadBlock(uint32_t addr, uint32_t *readbuff, uint16_t BlockSize) } } else if (DeviceMode == SD_DMA_MODE) - { + { + int cnt = 0; SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE); SDIO_DMACmd(ENABLE); DMA_RxConfiguration(readbuff, BlockSize); while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET) - {} + { + cnt ++; + if (cnt > 10 * 50000) + { + rt_kprintf("DMA flag 0x%08x\n", DMA_GetFlagStatus(DMA2_FLAG_TC4)); + /* Clear all DPSM configuration */ + SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT; + SDIO_DataInitStructure.SDIO_DataLength = 0; + SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_1b; + SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard; + SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block; + SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Disable; + SDIO_DataConfig(&SDIO_DataInitStructure); + SDIO_DMACmd(DISABLE); + errorstatus = SD_ERROR; + break; + } + } } return(errorstatus); } @@ -2941,7 +2961,7 @@ static void DMA_RxConfiguration(uint32_t *BufferDST, uint32_t BufferSize) DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA2_Channel4, &DMA_InitStructure); - + /* DMA2 Channel4 enable */ DMA_Cmd(DMA2_Channel4, ENABLE); } @@ -2978,7 +2998,7 @@ static rt_err_t rt_sdcard_init(rt_device_t dev) NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); - + if (rt_sem_init(&sd_lock, "sdlock", 1, RT_IPC_FLAG_FIFO) != RT_EOK) { rt_kprintf("init sd lock semaphore failed\n"); @@ -3009,7 +3029,7 @@ static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_ rt_sem_take(&sd_lock, RT_WAITING_FOREVER); retry = 3; - /* read all sectors */ + /* read all sectors */ for (i = 0; i < size / SECTOR_SIZE; i ++) { __retry: @@ -3017,9 +3037,10 @@ __retry: (uint32_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE), SECTOR_SIZE); if (status != SD_OK) - { - if (--retry != 0) goto __retry; - break; + { + -- retry; + if (retry != 0) goto __retry; + else break; } } @@ -3130,4 +3151,3 @@ void rt_hw_sdcard_init() __return: rt_kprintf("sdcard init failed\n"); } - diff --git a/bsp/stm32_radio/startup.c b/bsp/stm32_radio/startup.c index af917f4a4a3d261c69766ebd26a2556570b3d71a..d5c16446c78c358ac5f112a591ae7d1595967a4d 100644 --- a/bsp/stm32_radio/startup.c +++ b/bsp/stm32_radio/startup.c @@ -44,7 +44,7 @@ extern void finsh_set_device(const char* device); #endif extern int rt_application_init(void); extern rt_err_t wm8753_hw_init(void); - +extern rt_err_t wm8978_hw_init(void); #ifdef DEBUG /******************************************************************************* * Function Name : assert_failed @@ -101,9 +101,13 @@ void rtthread_startup(void) #endif /* init scheduler system */ - rt_system_scheduler_init(); + rt_system_scheduler_init(); +#if CODEC_VERSION == 1 wm8753_hw_init(); +#elif CODEC_VERSION == 2 + wm8978_hw_init(); +#endif /* init hardware serial device */ rt_hw_usart_init(); diff --git a/bsp/stm32_radio/stm32f10x_it.c b/bsp/stm32_radio/stm32f10x_it.c index ac42f4ef59f56c629fd8ee51a20effc67e144fab..b0bb63278c65f99f4e1415776c53f5c63cf6f630 100644 --- a/bsp/stm32_radio/stm32f10x_it.c +++ b/bsp/stm32_radio/stm32f10x_it.c @@ -18,6 +18,7 @@ /* Includes ------------------------------------------------------------------*/ #include #include +#include "board.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ @@ -339,6 +340,7 @@ void DMA1_Channel4_IRQHandler(void) { } +#if CODEC_VERSION == 1 /******************************************************************************* * Function Name : DMA1_Channel5_IRQHandler * Description : This function handles DMA1 Channel 5 interrupt request. @@ -365,9 +367,8 @@ void DMA1_Channel5_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); - rt_hw_interrupt_thread_switch(); - } +#endif /******************************************************************************* * Function Name : DMA1_Channel6_IRQHandler @@ -394,74 +395,6 @@ void DMA1_Channel6_IRQHandler(void) #endif } -/******************************************************************************* -* Function Name : DMA1_Channel7_IRQHandler -* Description : This function handles DMA1 Channel 7 interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void DMA1_Channel7_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : ADC1_2_IRQHandler -* Description : This function handles ADC1 and ADC2 global interrupts requests. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void ADC1_2_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : USB_HP_CAN1_TX_IRQHandler -* Description : This function handles USB High Priority or CAN TX interrupts -* requests. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void USB_HP_CAN1_TX_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : USB_LP_CAN1_RX0_IRQHandler -* Description : This function handles USB Low Priority or CAN RX0 interrupts -* requests. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void USB_LP_CAN1_RX0_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : CAN1_RX1_IRQHandler -* Description : This function handles CAN RX1 interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void CAN1_RX1_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : CAN1_SCE_IRQHandler -* Description : This function handles CAN SCE interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void CAN1_SCE_IRQHandler(void) -{ -} - /******************************************************************************* * Function Name : EXTI9_5_IRQHandler * Description : This function handles External lines 9 to 5 interrupt request. @@ -488,140 +421,7 @@ void EXTI9_5_IRQHandler(void) #endif } -/******************************************************************************* -* Function Name : TIM1_BRK_IRQHandler -* Description : This function handles TIM1 Break interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void TIM1_BRK_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : TIM1_UP_IRQHandler -* Description : This function handles TIM1 overflow and update interrupt -* request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void TIM1_UP_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : TIM1_TRG_COM_IRQHandler -* Description : This function handles TIM1 Trigger and commutation interrupts -* requests. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void TIM1_TRG_COM_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : TIM1_CC_IRQHandler -* Description : This function handles TIM1 capture compare interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void TIM1_CC_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : TIM2_IRQHandler -* Description : This function handles TIM2 global interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void TIM2_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : TIM3_IRQHandler -* Description : This function handles TIM3 global interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void TIM3_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : TIM4_IRQHandler -* Description : This function handles TIM4 global interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void TIM4_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : I2C1_EV_IRQHandler -* Description : This function handles I2C1 Event interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void I2C1_EV_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : I2C1_ER_IRQHandler -* Description : This function handles I2C1 Error interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void I2C1_ER_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : I2C2_EV_IRQHandler -* Description : This function handles I2C2 Event interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void I2C2_EV_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : I2C2_ER_IRQHandler -* Description : This function handles I2C2 Error interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void I2C2_ER_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : SPI1_IRQHandler -* Description : This function handles SPI1 global interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void SPI1_IRQHandler(void) -{ -} - +#if CODEC_VERSION == 1 /******************************************************************************* * Function Name : SPI2_IRQHandler * Description : This function handles SPI2 global interrupt request. @@ -640,8 +440,8 @@ void SPI2_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); - rt_hw_interrupt_thread_switch(); } +#endif /******************************************************************************* * Function Name : USART1_IRQHandler @@ -836,17 +636,7 @@ void SDIO_IRQHandler(void) #endif } -/******************************************************************************* -* Function Name : TIM5_IRQHandler -* Description : This function handles TIM5 global interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void TIM5_IRQHandler(void) -{ -} - +#if CODEC_VERSION == 2 /******************************************************************************* * Function Name : SPI3_IRQHandler * Description : This function handles SPI3 global interrupt request. @@ -856,61 +646,15 @@ void TIM5_IRQHandler(void) *******************************************************************************/ void SPI3_IRQHandler(void) { -} - -/******************************************************************************* -* Function Name : UART4_IRQHandler -* Description : This function handles UART4 global interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void UART4_IRQHandler(void) -{ -} + extern void wm8978_isr(void); -/******************************************************************************* -* Function Name : UART5_IRQHandler -* Description : This function handles UART5 global interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void UART5_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : TIM6_IRQHandler -* Description : This function handles TIM6 global interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void TIM6_IRQHandler(void) -{ -} + /* enter interrupt */ + rt_interrupt_enter(); -/******************************************************************************* -* Function Name : TIM7_IRQHandler -* Description : This function handles TIM7 global interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void TIM7_IRQHandler(void) -{ -} + wm8978_isr(); -/******************************************************************************* -* Function Name : DMA2_Channel1_IRQHandler -* Description : This function handles DMA2 Channel 1 interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void DMA2_Channel1_IRQHandler(void) -{ + /* leave interrupt */ + rt_interrupt_leave(); } /******************************************************************************* @@ -922,61 +666,21 @@ void DMA2_Channel1_IRQHandler(void) *******************************************************************************/ void DMA2_Channel2_IRQHandler(void) { -} - -/******************************************************************************* -* Function Name : DMA2_Channel3_IRQHandler -* Description : This function handles DMA2 Channel 3 interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void DMA2_Channel3_IRQHandler(void) -{ -} - -/******************************************************************************* -* Function Name : DMA2_Channel4_5_IRQHandler -* Description : This function handles DMA2 Channel 4 and DMA2 Channel 5 -* interrupt request. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void DMA2_Channel4_5_IRQHandler(void) -{ -} - -void DMA2_Channel5_IRQHandler(void) -{ -} - -void ETH_IRQHandler(void) -{ -} - -void ETH_WKUP_IRQHandler(void) -{ -} - -void CAN2_TX_IRQHandler(void) -{ -} + extern void wm8978_dma_isr(void); -void CAN2_RX0_IRQHandler(void) -{ -} + /* enter interrupt */ + rt_interrupt_enter(); -void CAN2_RX1_IRQHandler(void) -{ -} + if (DMA_GetITStatus(DMA2_IT_TC2)) + { + /* clear DMA flag */ + DMA_ClearFlag(DMA2_FLAG_TC2 | DMA2_FLAG_TE2); -void CAN2_SCE_IRQHandler(void) -{ -} + /* transmission complete, invoke serial dma tx isr */ + wm8978_dma_isr(); + } -void OTG_FS_IRQHandler(void) -{ + /* leave interrupt */ + rt_interrupt_leave(); } - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +#endif diff --git a/bsp/stm32_radio/wm8978.c b/bsp/stm32_radio/wm8978.c new file mode 100644 index 0000000000000000000000000000000000000000..834bfdb6bf6bed165e278267be4cb07f98209451 --- /dev/null +++ b/bsp/stm32_radio/wm8978.c @@ -0,0 +1,446 @@ +#include +#include +#include "stm32f10x.h" + +/* + * WM8978 Driver + */ + +/* WM8978 register definitions */ +#define WM8978_DAC 0x01 +#define WM8978_ADC 0x02 +#define WM8978_PCM 0x03 +#define WM8978_HIFI 0x04 +#define WM8978_IOCTL 0x05 +#define WM8978_SRATE1 0x06 +#define WM8978_SRATE2 0x07 +#define WM8978_LDAC 0x08 +#define WM8978_RDAC 0x09 +#define WM8978_BASS 0x0a +#define WM8978_TREBLE 0x0b +#define WM8978_ALC1 0x0c +#define WM8978_ALC2 0x0d +#define WM8978_ALC3 0x0e +#define WM8978_NGATE 0x0f +#define WM8978_LADC 0x10 +#define WM8978_RADC 0x11 +#define WM8978_ADCTL1 0x12 +#define WM8978_3D 0x13 +#define WM8978_PWR1 0x14 +#define WM8978_PWR2 0x15 +#define WM8978_PWR3 0x16 +#define WM8978_PWR4 0x17 +#define WM8978_ID 0x18 +#define WM8978_INTPOL 0x19 +#define WM8978_INTEN 0x1a +#define WM8978_GPIO1 0x1b +#define WM8978_GPIO2 0x1c +#define WM8978_RESET 0x1f +#define WM8978_RECMIX1 0x20 +#define WM8978_RECMIX2 0x21 +#define WM8978_LOUTM1 0x22 +#define WM8978_LOUTM2 0x23 +#define WM8978_ROUTM1 0x24 +#define WM8978_ROUTM2 0x25 +#define WM8978_MOUTM1 0x26 +#define WM8978_MOUTM2 0x27 +#define WM8978_LOUT1V 0x28 +#define WM8978_ROUT1V 0x29 +#define WM8978_LOUT2V 0x2a +#define WM8978_ROUT2V 0x2b +#define WM8978_MOUTV 0x2c +#define WM8978_OUTCTL 0x2d +#define WM8978_ADCIN 0x2e +#define WM8978_INCTL1 0x2f +#define WM8978_INCTL2 0x30 +#define WM8978_LINVOL 0x31 +#define WM8978_RINVOL 0x32 +#define WM8978_MICBIAS 0x33 +#define WM8978_CLOCK 0x34 +#define WM8978_PLL1CTL1 0x35 +#define WM8978_PLL1CTL2 0x36 +#define WM8978_PLL1CTL3 0x37 +#define WM8978_PLL1CTL4 0x38 +#define WM8978_PLL2CTL1 0x39 +#define WM8978_PLL2CTL2 0x3a +#define WM8978_PLL2CTL3 0x3b +#define WM8978_PLL2CTL4 0x3c +#define WM8978_BIASCTL 0x3d +#define WM8978_ADCTL2 0x3f + +/* +SCLK PB7 +SDIN PB8 +CSB PB9 +*/ + +#define wm_sclk_0 GPIO_ResetBits(GPIOB,GPIO_Pin_7) +#define wm_sclk_1 GPIO_SetBits(GPIOB,GPIO_Pin_7) +#define wm_sdin_0 GPIO_ResetBits(GPIOB,GPIO_Pin_8) +#define wm_sdin_1 GPIO_SetBits(GPIOB,GPIO_Pin_8) +#define wm_csb_0 GPIO_ResetBits(GPIOB,GPIO_Pin_9) +#define wm_csb_1 GPIO_SetBits(GPIOB,GPIO_Pin_9) + +#define DATA_NODE_MAX 5 +/* data node for Tx Mode */ +struct wm8978_data_node +{ + rt_uint16_t *data_ptr; + rt_size_t data_size; +}; + +struct wm8978_device +{ + /* inherit from rt_device */ + struct rt_device parent; + + /* pcm data list */ + struct wm8978_data_node data_list[DATA_NODE_MAX]; + rt_uint16_t read_index, put_index; + + /* transmitted offset of current data node */ + rt_size_t offset; +}; +struct wm8978_device wm8978; + +static void NVIC_Configuration(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); + + /* SPI3 IRQ Channel configuration */ + NVIC_InitStructure.NVIC_IRQChannel = SPI3_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + /* DMA1 IRQ Channel configuration */ + NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel2_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +} + +static void GPIO_Configuration(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* configure GPIO B 7, 8, 9 */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIOB,&GPIO_InitStructure); + + /* configure GPIO B 3, 5 */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + /* configure GPIO A15 */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + /* Disable the JTAG interface and enable the SWJ interface */ + GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); +} + +#define SPI3_DR_Address 0x40003C0C +static void DMA_Configuration(rt_uint32_t addr, rt_size_t size) +{ + DMA_InitTypeDef DMA_InitStructure; + + /* DMA2 Channel2 configuration ----------------------------------------------*/ + DMA_Cmd(DMA2_Channel2, DISABLE); + DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SPI3_DR_Address; + DMA_InitStructure.DMA_MemoryBaseAddr = (u32)addr; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; + DMA_InitStructure.DMA_BufferSize = size; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; + DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; + DMA_Init(DMA2_Channel2, &DMA_InitStructure); + + /* Enable SPI3 DMA Tx request */ + SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Tx, ENABLE); + + DMA_ITConfig(DMA2_Channel2, DMA_IT_TC, ENABLE); + DMA_Cmd(DMA2_Channel2, ENABLE); +} + +static void I2S_Configuration(void) +{ + I2S_InitTypeDef I2S_InitStructure; + + /* I2S peripheral configuration */ + I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips; + I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b; + I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable; + I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_44k; + I2S_InitStructure.I2S_CPOL = I2S_CPOL_High;// I2S_CPOL_Low + + /* I2S2 Master Transmitter to I2S3 Slave Receiver communication -----------*/ + /* I2S2 configuration */ + I2S_InitStructure.I2S_Mode = I2S_Mode_SlaveTx; + I2S_Init(SPI3, &I2S_InitStructure); +} + +void wm_send(rt_uint16_t s_data) +{ + u8 i; + wm_csb_0; + wm_sclk_0; + + for (i=0;i<16;i++) + { + if (s_data & 0x8000) + { + wm_sdin_1; + } + else + { + wm_sdin_0; + } + wm_sclk_1; + s_data <<= 1; + wm_sclk_0; + } + + wm_csb_1; +} + +static rt_err_t wm8978_init (rt_device_t dev) +{ + wm_send(0<<9 | 0xFF); // reset + + /* POWER manager */ + wm_send(1<<9 | (0<<8) | (0<<7) | (0<<6) | (0<<5) | (1<<4) | (1<<3) | (1<<2) | 3 ); + wm_send(2<<9 | (1<<8) | (1<<7) | (1<<5) | (1<<4) ); + wm_send(3<<9 | (0<<8) | (0<<7) | (1<<6) | (1<<5) | (1<<3) | (1<<2) | (1<<1) | 1 ); + + /* IIS DAC test */ + wm_send(4<<9 | 0 | (2<<3) );//IIS 16BIT +#if 0 + wm_send(6<<9 | (3<<5) | (3<<2)| 1);//0: slave 1: master | (3<<5) | (3<<2) + wm_send(43<<9 | (1<<4) );//INVROUT2 +#else + // 12.288/3 = 4.096M 4.096M / 8 = 512K == (16K *2??)*16? + wm_send(6<<9 | (3<<5) | (3<<2)| 1); //16K MCLK/3/8 + wm_send(6<<9 | (0<<5) | (3<<2)| 1); //48K MCLK/1/8 +#endif + + return RT_EOK; +} + +#include +#if 0 +void vol(int v) +{ + wm_send(40<<9 | 0<<8 | 1<<7 | v); + wm_send(41<<9 | 1<<8 | 1<<7 | v); + + wm_send(42<<9 | 0<<8 | 1<<7 | v); + wm_send(43<<9 | 1<<8 | 1<<7 | v); +} +FINSH_FUNCTION_EXPORT(vol, set volume) +#endif + +static rt_err_t wm8978_open(rt_device_t dev, rt_uint16_t oflag) +{ + /* enable I2S */ + I2S_Cmd(SPI3, ENABLE); + + return RT_EOK; +} + +static rt_err_t wm8978_close(rt_device_t dev) +{ + /* interrupt mode */ + if (dev->flag & RT_DEVICE_FLAG_INT_TX) + { + /* Disable the I2S2 */ + I2S_Cmd(SPI3, DISABLE); + } + + /* remove all data node */ + + return RT_EOK; +} + +static rt_err_t wm8978_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + /* rate control */ + return RT_EOK; +} + +static rt_size_t wm8978_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +{ + struct wm8978_device* device; + struct wm8978_data_node* node; + rt_uint32_t level; + rt_uint16_t next_index; + + device = (struct wm8978_device*)dev; + RT_ASSERT(device != RT_NULL); + + next_index = device->put_index + 1; + if (next_index >= DATA_NODE_MAX) next_index = 0; + + /* check data_list full */ + if (next_index == device->read_index) + { + rt_set_errno(-RT_EFULL); + return 0; + } + + level = rt_hw_interrupt_disable(); + node = &device->data_list[device->put_index]; + device->put_index = next_index; + + // rt_kprintf("+\n"); + /* set node attribute */ + node->data_ptr = (rt_uint16_t*)buffer; + node->data_size = size >> 1; /* size is byte unit, convert to half word unit */ + + next_index = device->read_index + 1; + if (next_index >= DATA_NODE_MAX) next_index = 0; + + /* check data list whether is empty */ + if (next_index == device->put_index) + { + if (dev->flag & RT_DEVICE_FLAG_INT_TX) + { + device->offset = 0; + /* enable I2S interrupt */ + SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, ENABLE); + } + else if (dev->flag & RT_DEVICE_FLAG_DMA_TX) + { + DMA_Configuration((rt_uint32_t)node->data_ptr, node->data_size); + } + } + rt_hw_interrupt_enable(level); + + return size; +} + +rt_err_t wm8978_hw_init(void) +{ + rt_device_t dev; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); + + NVIC_Configuration(); + GPIO_Configuration(); + I2S_Configuration(); + + dev = (rt_device_t)&wm8978; + dev->type = RT_Device_Class_Unknown; + dev->rx_indicate = RT_NULL; + dev->tx_complete = RT_NULL; + dev->init = wm8978_init; + dev->open = wm8978_open; + dev->close = wm8978_close; + dev->read = RT_NULL; + dev->write = wm8978_write; + dev->control = wm8978_control; + dev->private = RT_NULL; + + /* set read_index and put index to 0 */ + wm8978.read_index = 0; + wm8978.put_index = 0; + + wm_sclk_0; + wm_sclk_1; + wm_sclk_0; + + wm_sdin_0; + wm_sdin_1; + wm_sdin_0; + + wm_csb_1; + wm_csb_0; + wm_csb_1; + + /* register the device */ + return rt_device_register(&wm8978.parent, "snd", + RT_DEVICE_FLAG_WRONLY | RT_DEVICE_FLAG_DMA_TX); +} + +void wm8978_isr() +{ + struct wm8978_data_node* node; + node = &wm8978.data_list[wm8978.read_index]; /* get current data node */ + + if (SPI_I2S_GetITStatus(SPI3, SPI_I2S_IT_TXE) == SET) + { + SPI_I2S_SendData(SPI3, node->data_ptr[wm8978.offset++]); + } + + if (wm8978.offset == node->data_size) + { + /* move to next node */ + rt_uint16_t next_index; + + next_index = wm8978.read_index + 1; + if (next_index >= DATA_NODE_MAX) next_index = 0; + + /* notify transmitted complete. */ + if (wm8978.parent.tx_complete != RT_NULL) + { + wm8978.parent.tx_complete (&wm8978.parent, wm8978.data_list[wm8978.read_index].data_ptr); + rt_kprintf("-\n"); + } + + wm8978.offset = 0; + wm8978.read_index = next_index; + if (next_index == wm8978.put_index) + { + /* no data on the list, disable I2S interrupt */ + SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, DISABLE); + + rt_kprintf("*\n"); + } + } +} + +void wm8978_dma_isr() +{ + /* switch to next buffer */ + rt_uint16_t next_index; + void* data_ptr; + + next_index = wm8978.read_index + 1; + if (next_index >= DATA_NODE_MAX) next_index = 0; + + /* save current data pointer */ + data_ptr = wm8978.data_list[wm8978.read_index].data_ptr; + + wm8978.read_index = next_index; + if (next_index != wm8978.put_index) + { + /* enable next dma request */ + DMA_Configuration((rt_uint32_t)wm8978.data_list[wm8978.read_index].data_ptr, + wm8978.data_list[wm8978.read_index].data_size); + } + else + { + rt_kprintf("*\n"); + } + + /* notify transmitted complete. */ + if (wm8978.parent.tx_complete != RT_NULL) + { + wm8978.parent.tx_complete (&wm8978.parent, data_ptr); + // rt_kprintf("-\n"); + } +} +