From e28d56e67615ae3793b1e6e7334698f929d66837 Mon Sep 17 00:00:00 2001 From: asterix Date: Tue, 20 Sep 2011 15:44:12 +0000 Subject: [PATCH] Use events to start and stop playing. Clean up and reorder the code. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@5077 38d2e660-2303-0410-9eaa-f027e97ec537 --- .../sam3x-ek/examples/sam3x-ek_codec/main.c | 502 +++++++----------- 1 file changed, 179 insertions(+), 323 deletions(-) diff --git a/boards/sam3x-ek/examples/sam3x-ek_codec/main.c b/boards/sam3x-ek/examples/sam3x-ek_codec/main.c index 2a14cdbe..e7838a3f 100644 --- a/boards/sam3x-ek/examples/sam3x-ek_codec/main.c +++ b/boards/sam3x-ek/examples/sam3x-ek_codec/main.c @@ -47,7 +47,6 @@ #include -#include #include #include @@ -73,9 +72,12 @@ #include #include +#include #include +#include + #include #include @@ -86,344 +88,155 @@ // Keyboard #define KEY_MASK (K_LEFT | K_RIGHT) -// Kernel -#define PROC_STACK_SIZE KERN_MINSTACKSIZE * 2 - -static PROC_DEFINE_STACK(hp_stack, PROC_STACK_SIZE); -static PROC_DEFINE_STACK(lp_stack, PROC_STACK_SIZE); - /* * Codec has 7-bit address, the eighth is the R/W bit, so we * write the codec address with one bit shifted left */ #define CODEC_ADDR 0x36 +// Kernel +static PROC_DEFINE_STACK(play_proc_stack, 2048); +MsgPort proc_play_inPort; +#define PLAY_SIGNAL SIG_USER3 -typedef struct WavHdr -{ - char chunk_id[4]; - uint32_t chunk_size; - char format[4]; - - char subchunk1_id[4]; - uint32_t subchunk1_size; - uint16_t audio_format; - uint16_t num_channels; - uint32_t sample_rate; - uint32_t byte_rate; - uint16_t block_align; - uint16_t bits_per_sample; - - uint8_t subchunk2[8]; -} WavHdr; +#define MAX_ITEM_NODES 30 +#define MAX_ITEMS_ROW 15 +#define NEXT_ITEM_COL 10 +typedef struct FileItemNode +{ + Node n; + char file_name[13]; +} FileItemNode; -static uint8_t raster[RAST_SIZE(LCD_WIDTH, LCD_HEIGHT)]; -static Bitmap lcd_bitmap; -extern Font font_gohu; -static int lcd_brightness = LCD_BACKLIGHT_MAX; -static Process *hp_proc, *lp_proc; -static hptime_t start, end; +typedef struct PlayMsg +{ + Msg msg; + char file_name[13]; +} PlayMsg; +FileItemNode item_nodes[MAX_ITEM_NODES]; uint8_t tmp[4096]; // SD fat filesystem context FATFS fs; -FatFile log_file; -FatFile acq_file; +FatFile play_file; +FatFile rec_file; +static Sd sd; static I2c i2c; static I2s i2s; static Wm8731 wm8731_ctx; +static uint8_t raster[RAST_SIZE(LCD_WIDTH, LCD_HEIGHT)]; +static Bitmap lcd_bitmap; +extern Font font_gohu; +static int lcd_brightness = LCD_BACKLIGHT_MAX; +static uint16_t headphone_volume = 90; +static size_t played_size = 0; +static bool is_playing = false; -static void screen_saver(Bitmap *bm) -{ - int x1, y1, x2, y2; - int i; - - for (i = 0; ; i++) - { - x1 = i % LCD_WIDTH; - y1 = i % LCD_HEIGHT; - - x2 = LCD_WIDTH - i % LCD_WIDTH; - y2 = LCD_HEIGHT - i % LCD_HEIGHT; - - gfx_bitmapClear(bm); - gfx_rectDraw(bm, x1, y1, x2, y2); - lcd_hx8347_blitBitmap(bm); - if (kbd_peek() & KEY_MASK) - break; - } -} - - -INLINE hptime_t get_hp_ticks(void) -{ - return (timer_clock_unlocked() * TIMER_HW_CNT) + timer_hw_hpread(); -} - -static void NORETURN hp_process(void) +static void codec_play(struct I2s *i2s, void *_buf, size_t len) { - while (1) + played_size += kfile_read(&play_file.fd, _buf, len); + if (played_size >= play_file.fat_file.fsize - sizeof(WavHdr)) { - sig_wait(SIG_USER0); - end = get_hp_ticks(); - timer_delay(100); - sig_send(lp_proc, SIG_USER0); + kprintf("stop %d\n", played_size); + i2s_dmaTxStop(i2s); + is_playing = false; + played_size = 0; } } -static void NORETURN lp_process(void) +static void codec_rec(struct I2s *i2s, void *_buf, size_t len) { - while (1) + played_size += kfile_write(&rec_file.fd, _buf, len); + if (played_size >= 1024 * 1024) { - start = get_hp_ticks(); - sig_send(hp_proc, SIG_USER0); - sig_wait(SIG_USER0); + kprintf("stop %d\n", played_size); + i2s_dmaRxStop(i2s); + played_size = 0; } } -/* - * Lcd - */ -static void setBrightness(Bitmap *bm) +static void NORETURN play_proc(void) { while (1) { - gfx_bitmapClear(bm); - text_xprintf(bm, 1, 0, TEXT_FILL | TEXT_CENTER, "Brightness: %d", lcd_brightness); - text_xprintf(bm, 3, 0, TEXT_FILL | TEXT_CENTER, "RIGHT key: change"); - text_xprintf(bm, 4, 0, TEXT_FILL | TEXT_CENTER, "LEFT key: back "); - lcd_hx8347_blitBitmap(bm); - - keymask_t mask = kbd_get(); - - if (mask & K_LEFT) - break; - else if (mask & K_RIGHT) + event_wait(&proc_play_inPort.event); + PlayMsg *play; + play = (PlayMsg *)msg_get(&proc_play_inPort); + if (play && SD_CARD_PRESENT()) { - if (++lcd_brightness > LCD_BACKLIGHT_MAX) - lcd_brightness = 0; - lcd_setBacklight(lcd_brightness); - } - } -} - - -static void NORETURN soft_reset(Bitmap * bm) -{ - int i; - - gfx_bitmapClear(bm); - for (i = 5; i; --i) - { - text_xprintf(bm, 2, 0, TEXT_FILL | TEXT_CENTER, "%d", i); - lcd_hx8347_blitBitmap(bm); - timer_delay(1000); - } - text_xprintf(bm, 2, 0, TEXT_FILL | TEXT_CENTER, "REBOOT"); - lcd_hx8347_blitBitmap(bm); - timer_delay(1000); - - /* Perform a software reset request */ - HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ; - UNREACHABLE(); -} - -static void read_adc(Bitmap *bm) -{ - gfx_bitmapClear(bm); - text_xprintf(bm, 0, 0, TEXT_FILL | TEXT_CENTER, "ADC Value"); - while (1) - { - uint16_t value = ADC_RANGECONV(adc_read(1), 0, 3300); - uint16_t temp = hw_convertToDegree (adc_read(ADC_TEMPERATURE_CH)); - - text_xprintf(&lcd_bitmap, 2, 0, TEXT_FILL | TEXT_CENTER, - "Voltage on VR1: %d.%dV", value / 1000, value % 1000); - text_xprintf(&lcd_bitmap, 3, 0, TEXT_FILL | TEXT_CENTER, - "CPU temperature: %d.%dC", temp / 10, temp % 10); - lcd_hx8347_blitBitmap(bm); - timer_delay(400); - if (kbd_peek() & KEY_MASK) - break; - } -} -#define FILE_NAME "outfile.wav" -#define ACQ_FILE_NAME FILE_NAME - - -uint8_t tmp[4096]; - -// SD fat filesystem context -FATFS fs; -FatFile log_file; -FatFile acq_file; - - - -static int wav_check(KFile *fd) -{ - - WavHdr header; - - if (kfile_read(fd, &header, sizeof(header)) != sizeof(header)) - { - kputs("Error reading wave file header\n"); - return EOF; - } - - if (strncmp(header.chunk_id, "RIFF", 4)) - { - kputs("RIFF tag not found\n"); - goto error; - } - - if (strncmp(header.format, "WAVE", 4)) - { - kputs("WAVE tag not found\n"); - goto error; - } - - if (le16_to_cpu(header.audio_format) != 1) - { - kprintf("Audio format not valid, found [%d]\n", le16_to_cpu(header.audio_format)); - goto error; - } - - if (le16_to_cpu(header.num_channels) != 2) - { - kprintf("Channels number not valid, found [%d]\n", le16_to_cpu(header.num_channels)); - goto error; - } - - - if (le32_to_cpu(header.sample_rate) != 44100) - { - kprintf("Sample rate not valid, found [%ld]\n", le32_to_cpu(header.sample_rate)); - goto error; - } + timer_delay(10); - if (le16_to_cpu(header.bits_per_sample) != 16) - { - kprintf("Bits per sample not valid, found [%d]\n", le16_to_cpu(header.bits_per_sample)); - goto error; - } - return 0; - -error: - return 1; -} + bool sd_ok = sd_init(&sd, NULL, 0); + FRESULT result; + if (sd_ok) + { + kprintf("Mount FAT filesystem.\n"); -static int wav_writeHdr(KFile *fd, uint16_t rate, uint16_t channels, uint16_t bits) -{ - WavHdr header; + result = f_mount(0, &fs); + if (result != FR_OK) + { + kprintf("Mounting FAT volumes error[%d]\n", result); + sd_ok = false; + } - memcpy(&header.chunk_id, "RIFF", 4); - memcpy(&header.format, "WAVE", 4); - header.audio_format = cpu_to_le16((uint16_t)1); - header.num_channels = cpu_to_le16(channels); - header.sample_rate = cpu_to_le16(rate); - header.bits_per_sample = cpu_to_le16(bits); + if (sd_ok) + { + result = fatfile_open(&play_file, play->file_name, FA_OPEN_EXISTING | FA_READ); + if (result == FR_OK) + { + kprintf("Open file: %s size %ld\n", play->file_name, play_file.fat_file.fsize); + WavHdr wav; + kfile_read(&play_file.fd, &wav, sizeof(WavHdr)); + if (wav_checkHdr(&wav, 1, CONFIG_CHANNEL_NUM, CONFIG_SAMPLE_FREQ, CONFIG_WORD_BIT_SIZE) != -1) + { + kputs("Wav file play..\n"); - kfile_seek(fd, 0, KSM_SEEK_SET); - kfile_write(fd, &header, sizeof(header)); + wm8731_setVolume(&wm8731_ctx, WM8731_HEADPHONE, headphone_volume); + is_playing = true; + i2s_dmaStartTxStreaming(&i2s, tmp, sizeof(tmp), sizeof(tmp) / 4, codec_play); - return 0; -} + wm8731_setVolume(&wm8731_ctx, WM8731_HEADPHONE, 0); + } -size_t count = 0; -static void codec_play(struct I2s *i2s, void *_buf, size_t len) -{ - count += kfile_read(&log_file.fd, _buf, len); - if (count >= log_file.fat_file.fsize - sizeof(WavHdr)) - { - kprintf("stop %d\n", count); - i2s_dmaTxStop(i2s); - count = 0; + // Flush data and close the files. + kfile_flush(&play_file.fd); + kfile_close(&play_file.fd); + } + else + { + kprintf("Unable to open file: '%s' error[%d]\n", play->file_name, result); + } + } + f_mount(0, NULL); + } + } + kputs("no message\n"); } } -static void codec_rec(struct I2s *i2s, void *_buf, size_t len) +INLINE void start_play(char *file_name) { - count += kfile_write(&acq_file.fd, _buf, len); - if (count >= 1024 * 1024) - { - kprintf("stop %d\n", count); - i2s_dmaRxStop(i2s); - count = 0; - } + PlayMsg play_msg; + memcpy(play_msg.file_name, file_name, sizeof(play_msg.file_name)); + msg_put(&proc_play_inPort, &play_msg.msg); } - - -#define MAX_ITEM_NODES 30 -#define MAX_ITEMS_ROW 15 -#define NEXT_ITEM_COL 10 - -typedef struct FileItemNode +INLINE void stop_play(void) { - Node n; - char file_name[13]; -} FileItemNode; - -FileItemNode item_nodes[MAX_ITEM_NODES]; -static Sd sd; - -static void wav_play(Bitmap *bm, char *file_name) -{ - gfx_bitmapClear(bm); - - kprintf("Mount FAT filesystem.\n"); - FRESULT result = f_mount(0, &fs); - bool sd_ok = true; - if (result != FR_OK) - { - kprintf("Mounting FAT volumes error[%d]\n", result); - sd_ok = false; - } - - if (sd_ok) - { - result = fatfile_open(&log_file, file_name, FA_OPEN_EXISTING | FA_READ); - if (result == FR_OK) - { - text_xprintf(bm, 1, 0, TEXT_CENTER, "Play wav file: %s", file_name); - text_xprintf(bm, 2, 0, TEXT_CENTER, "File: %ld", log_file.fat_file.fsize); - text_xprintf(bm, 3, 0, TEXT_CENTER, "Volume level %ld", ADC_RANGECONV(adc_read(1), 0, 100)); - kprintf("Open file: %s\n", file_name); - wm8731_setVolume(&wm8731_ctx, WM8731_HEADPHONE, ADC_RANGECONV(adc_read(1), 0, 100)); - - lcd_hx8347_blitBitmap(bm); - if (wav_check(&log_file.fd) >= 0) - { - kputs("Wav file play..\n"); - i2s_dmaStartTxStreaming(&i2s, tmp, sizeof(tmp), sizeof(tmp) / 4, codec_play); - } - - wm8731_setVolume(&wm8731_ctx, WM8731_HEADPHONE, 0); - - // Flush data and close the files. - kfile_flush(&log_file.fd); - kfile_close(&log_file.fd); - } - else - { - kprintf("Unable to open file: '%s' error[%d]\n", FILE_NAME, result); - } - } - f_mount(0, NULL); - - lcd_hx8347_blitBitmap(bm); + i2s_dmaTxStop(&i2s); + played_size = 0; + is_playing = false; } -INLINE FileItemNode *refresh_cursor(Bitmap *bm, List *file_list, int select_idx) +INLINE FileItemNode *select_item(Bitmap *bm, List *file_list, int select_idx) { FileItemNode *item; FileItemNode *select_node; @@ -444,14 +257,18 @@ INLINE FileItemNode *refresh_cursor(Bitmap *bm, List *file_list, int select_idx) if (select_idx <= MAX_ITEMS_ROW) { if (row == select_idx && col == 0) + { text_style(bm, STYLEF_INVERT, STYLEF_INVERT); select_node = item; + } } else { if (row == (select_idx - MAX_ITEMS_ROW) && col == NEXT_ITEM_COL) + { text_style(bm, STYLEF_INVERT, STYLEF_INVERT); select_node = item; + } } text_xprintf(bm, row, col, TEXT_NORMAL, "%s", item->file_name); @@ -483,7 +300,6 @@ static void sd_explorer(Bitmap *bm) if (sd_ok) { kprintf("Mount FAT filesystem.\n"); - result = f_mount(0, &fs); if (result != FR_OK) { @@ -510,7 +326,6 @@ static void sd_explorer(Bitmap *bm) break; /* Break on error or end of dir */ if (fno.fname[0] == '.') continue; /* Ignore dot entry */ - if (fno.fattrib & AM_DIR) continue; else @@ -520,10 +335,11 @@ static void sd_explorer(Bitmap *bm) memcpy (&item_nodes[i].file_name, fno.fname, sizeof(item_nodes[i].file_name)); ADDTAIL(&file_list, &item_nodes[i].n); file_list_size++; + kprintf("%s\n", item_nodes[i].file_name); } else { - kputs("No enought spase to show file list..\n"); + kputs("No enought space to store items in list\n"); break; } } @@ -541,7 +357,8 @@ static void sd_explorer(Bitmap *bm) } int idx = 0; - FileItemNode *selected_node = refresh_cursor(bm, &file_list, idx); + FileItemNode *selected_node = NULL; + select_item(bm, &file_list, idx); while (1) { keymask_t key = kbd_peek(); @@ -551,50 +368,97 @@ static void sd_explorer(Bitmap *bm) if (idx > file_list_size) idx = 0; - selected_node = refresh_cursor(bm, &file_list, idx); - kprintf("lidx[%d]\n", idx); + selected_node = select_item(bm, &file_list, idx); + kprintf("lidx[%d] %s\n", idx, selected_node->file_name); } if (key & K_RIGHT) { - kprintf("ridx[%d]\n", idx); - wav_play(bm, selected_node->file_name); if (idx == 0) break; + + if (!is_playing) + start_play(selected_node->file_name); + else + stop_play(); } + + cpu_relax(); } } -static void test_draw(Bitmap *bm) +/* + * Lcd + */ +static void setBrightness(Bitmap *bm) +{ + while (1) + { + gfx_bitmapClear(bm); + text_xprintf(bm, 1, 0, TEXT_FILL | TEXT_CENTER, "Brightness: %d", lcd_brightness); + text_xprintf(bm, 3, 0, TEXT_FILL | TEXT_CENTER, "RIGHT key: change"); + text_xprintf(bm, 4, 0, TEXT_FILL | TEXT_CENTER, "LEFT key: back "); + lcd_hx8347_blitBitmap(bm); + + keymask_t mask = kbd_get(); + + if (mask & K_LEFT) + break; + else if (mask & K_RIGHT) + { + if (++lcd_brightness > LCD_BACKLIGHT_MAX) + lcd_brightness = 0; + lcd_setBacklight(lcd_brightness); + } + } +} + +static void setVolume(Bitmap *bm) { gfx_bitmapClear(bm); - text_xprintf(bm, 0, 0, TEXT_NORMAL, "%s\n", "12345678.123"); - text_xprintf(bm, 0, 10, TEXT_NORMAL, "%s\n", "12345678.123"); - text_xprintf(bm, 1, 0, TEXT_NORMAL, "%s\n", "12345678.123"); - text_xprintf(bm, 2, 0, TEXT_NORMAL, "%s\n", "12345678.123"); - text_xprintf(bm, 3, 0, TEXT_NORMAL, "%s\n", "12345678.123"); - lcd_hx8347_blitBitmap(bm); + text_style(bm, STYLEF_BOLD | STYLEF_UNDERLINE, STYLEF_BOLD | STYLEF_UNDERLINE); + text_xprintf(bm, 0, 0, TEXT_CENTER, "Headphone Volume"); + text_style(bm, 0, STYLEF_MASK); + text_xprintf(bm, 2, 0, TEXT_NORMAL, "Turn VR1 potentiometer to adjust it."); - timer_delay(400); while (1) + { + headphone_volume = ADC_RANGECONV(adc_read(1), 0, 100); + text_xprintf(bm, 5, 0, TEXT_FILL | TEXT_CENTER, "Volume %d%%", headphone_volume); + lcd_hx8347_blitBitmap(bm); + + timer_delay(400); if (kbd_peek() & KEY_MASK) break; + } } -static struct MenuItem sub_items[] = +static void NORETURN soft_reset(Bitmap * bm) { - { (const_iptr_t)"un", 0, (MenuHook)0, NULL }, - { (const_iptr_t)"du", 0, (MenuHook)0, NULL }, - { (const_iptr_t)"tr", 0, (MenuHook)0, NULL }, - { (const_iptr_t)0, 0, NULL, (iptr_t)0 } -}; -static struct Menu sub_menu = { sub_items, "BeRTOS", MF_SAVESEL, &lcd_bitmap, 0, lcd_hx8347_blitBitmap }; + int i; + + gfx_bitmapClear(bm); + for (i = 5; i; --i) + { + text_xprintf(bm, 2, 0, TEXT_FILL | TEXT_CENTER, "%d", i); + lcd_hx8347_blitBitmap(bm); + timer_delay(1000); + } + text_xprintf(bm, 2, 0, TEXT_FILL | TEXT_CENTER, "REBOOT"); + lcd_hx8347_blitBitmap(bm); + timer_delay(1000); + + /* Perform a software reset request */ + HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ; + UNREACHABLE(); +} + static struct MenuItem main_items[] = { - { (const_iptr_t)"Screen saver demo", 0, (MenuHook)screen_saver, &lcd_bitmap }, - { (const_iptr_t)"Display brightness", 0, (MenuHook)setBrightness, &lcd_bitmap }, - { (const_iptr_t)"SD dir", 0, (MenuHook)sd_explorer, (iptr_t)&lcd_bitmap }, - { (const_iptr_t)"Reboot", 0, (MenuHook)soft_reset, &lcd_bitmap }, + { (const_iptr_t)"Play SD file", 0, (MenuHook)sd_explorer, (iptr_t)&lcd_bitmap }, + { (const_iptr_t)"Set brightness", 0, (MenuHook)setBrightness, (iptr_t)&lcd_bitmap }, + { (const_iptr_t)"Set volume", 0, (MenuHook)setVolume, (iptr_t)&lcd_bitmap }, + { (const_iptr_t)"Reboot", 0, (MenuHook)soft_reset, (iptr_t)&lcd_bitmap }, { (const_iptr_t)0, 0, NULL, (iptr_t)0 } }; static struct Menu main_menu = { main_items, "BeRTOS", MF_STICKY | MF_SAVESEL, &lcd_bitmap, 0, lcd_hx8347_blitBitmap }; @@ -623,11 +487,6 @@ int main(void) kprintf("CPU Frequecy:%ld\n", CPU_FREQ); - - /* Enable the adc to read internal temperature sensor */ - hw_enableTempRead(); - - lcd_hx8347_init(); lcd_setBacklight(lcd_brightness); @@ -637,11 +496,8 @@ int main(void) kbd_init(); - hp_proc = proc_new(hp_process, NULL, PROC_STACK_SIZE, hp_stack); - lp_proc = proc_new(lp_process, NULL, PROC_STACK_SIZE, lp_stack); - - proc_setPri(hp_proc, 2); - proc_setPri(lp_proc, 1); + proc_new(play_proc, NULL, sizeof(play_proc_stack), play_proc_stack); + msg_initPort(&proc_play_inPort, event_createGeneric()); lcd_hx8347_blitBitmap24(10, 52, BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, bmp_logo); timer_delay(500); -- 2.25.1