Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

userif.c File Reference

#include <cfg/lcd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dev/term.h>
#include <sys/thread.h>
#include <sys/timer.h>
#include <sys/event.h>
#include <arpa/inet.h>
#include "config.h"
#include "webradio.h"
#include "shoutcast.h"
#include "mp3player.h"
#include "tlv320dac.h"
#include "buttons.h"
#include "userif.h"

Include dependency graph for userif.c:

Go to the source code of this file.

Data Structures

struct  DISPLAYLINE
struct  DISPLAYINFO

Defines

#define LCD_VCOLS   80
 Number of virtual columns.
#define LCD_SCROLL_GAP   (LCD_COLS / 2)
#define UI_REFRESH_RATE   300
#define UI_THREAD_STACK   2048

Functions

static void DisplayRefresh (void)
 Refresh the LCD.
static void UserIfShowStationConf (STATIONCONF *scp)
 Displays configured information about a station.
static void UserIfShowStationInfo (STATIONINFO *sip)
 Displays station information.
void UserIfMainMenu (void)
 Main menu processing.
void UserIfThread (void *arg)
 Background thread for user interface.
void UserIfShowMessage (u_char row, u_char secs, CONST char *fmt,...)
 Display a specified text.
void UserIfShowStatus (u_char status)
 Display a specified status.
int UserIfInit (char *name)
 Start background thread for display updates.

Variables

static DISPLAYINFO display


Define Documentation

#define LCD_VCOLS   80
 

Number of virtual columns.

Contents will be scrolled, if it doesn't fit on a single LCD line.

Definition at line 76 of file userif.c.

#define LCD_SCROLL_GAP   (LCD_COLS / 2)
 

Definition at line 81 of file userif.c.

#define UI_REFRESH_RATE   300
 

Definition at line 85 of file userif.c.

#define UI_THREAD_STACK   2048
 

Definition at line 92 of file userif.c.


Function Documentation

static void DisplayRefresh void   )  [static]
 

Refresh the LCD.

Definition at line 117 of file userif.c.

00119 {
00120     u_int ln;
00121     u_int cn;
00122     DISPLAYLINE *dlp;
00123     char *line;
00124 
00125     for (ln = 0; ln < LCD_ROWS; ln++) {
00126         dlp = &display.dpi_line[ln];
00127 
00128         /*
00129          * Determine if we display a message or just the current status.
00130          */
00131         if (dlp->dln_msgticks) {
00132             /* Displaying a message. */
00133             line = dlp->dln_msg;
00134             dlp->dln_msgticks--;
00135         } else {
00136             /* Displaying the status. */
00137             line = dlp->dln_status;
00138         }
00139 
00140         /* 
00141          * Re-initialize scrolling, if the line length changed.
00142          */
00143         if (dlp->dln_len != strlen(line)) {
00144             dlp->dln_len = strlen(line);
00145             dlp->dln_step = 0;
00146         }
00147 
00148         /* Position the cursor. */
00149         fprintf(display.dpi_stream, ESC_POS "%c" "\x20", ln + 32);
00150 
00151         if (dlp->dln_len <= LCD_COLS) {
00152             /* No scrolling required. */
00153             fputs(line, display.dpi_stream);
00154             if (dlp->dln_len < LCD_COLS) {
00155                 fputs(ESC_CLREOL, display.dpi_stream);
00156             }
00157         }
00158         else {
00159             for (cn = 0; cn < LCD_COLS; cn++) {
00160                 if (dlp->dln_step + cn < dlp->dln_len) {
00161                     display.dpi_buff[cn] = line[dlp->dln_step + cn];
00162                 }
00163                 else if (dlp->dln_step + cn < dlp->dln_len + LCD_SCROLL_GAP) {
00164                     display.dpi_buff[cn] = ' ';
00165                 }
00166                 else {
00167                     display.dpi_buff[cn] = line[dlp->dln_step + cn - (dlp->dln_len + LCD_SCROLL_GAP)];
00168                 }
00169             }
00170             fputs(display.dpi_buff, display.dpi_stream);
00171 
00172             /* Update the scroll position counter. */
00173             dlp->dln_step++;
00174             if (dlp->dln_step >= dlp->dln_len + LCD_SCROLL_GAP) {
00175                 dlp->dln_step = 0;
00176             }
00177         }
00178     }

static void UserIfShowStationConf STATIONCONF scp  )  [static]
 

Displays configured information about a station.

Parameters:
scp Pointer to the configuration table entry.

Definition at line 185 of file userif.c.

00187 {
00188     if (scp->rs_port) {
00189         if (scp->rs_symbol && scp->rs_symbol[0]) {
00190             strncpy(display.dpi_line[0].dln_status, scp->rs_symbol, LCD_VCOLS);
00191         } else {
00192             strncpy(display.dpi_line[0].dln_status, inet_ntoa(scp->rs_ip), LCD_VCOLS);
00193         }
00194     } else {
00195         display.dpi_line[0].dln_status[0] = 0;
00196     }

static void UserIfShowStationInfo STATIONINFO sip  )  [static]
 

Displays station information.

Called during connect.

Parameters:
scp Pointer to the configuration table entry.

Definition at line 205 of file userif.c.

00207 {
00208     if (sip) {
00209         if (sip->si_name && sip->si_name[0]) {
00210             strncpy(display.dpi_line[0].dln_status, sip->si_name, LCD_VCOLS);
00211         } else {
00212             UserIfShowStationConf(sip->si_scp);
00213         }
00214     } else {
00215         display.dpi_line[0].dln_status[0] = 0;
00216     }

void UserIfMainMenu void   ) 
 

Main menu processing.

Definition at line 222 of file userif.c.

00224 {
00225     char key;
00226     u_int tmocnt = 0;
00227     u_char want = radio.rc_cstation;
00228 
00229     for (;;) {
00230         UserIfShowStationConf(&station[want]);
00231         strcpy(display.dpi_line[1].dln_status, "Prev Select Next");
00232         DisplayRefresh();
00233 
00234         /* Read the next button key code. Timeout after 5 seconds. */
00235         if ((key = ButtonRead(UI_REFRESH_RATE)) == 0) {
00236             /* Button timeout. Keep the current station and return from 
00237                main menu. */
00238             if (++tmocnt > 20) {
00239                 want = radio.rc_cstation;
00240                 break;
00241             }
00242         }
00243         else {
00244             tmocnt = 0;
00245             if (key == KEYCODE_DOWN) {
00246                 /* User pressed the DOWN button. Show the preceding list item. */
00247                 want = StationSelect(want, -1);
00248             }
00249             else if (key == KEYCODE_UP) {
00250                 /* User pressed the UP button. Show the next list item. */
00251                 want = StationSelect(want, 1);
00252             }
00253             else if (key == KEYCODE_SELECT) {
00254                 /* User pressed the SELECT key. */
00255                 break;
00256             }
00257         }
00258     }
00259     if (want != radio.rc_cstation) {
00260         UserIfShowMessage(1, 5, "Please wait");
00261         radio.rc_rstation = want;
00262     }

void UserIfThread void *  arg  ) 
 

Background thread for user interface.

Parameters:
arg Unused. Should be NULL.

Definition at line 269 of file userif.c.

00271 {
00272     char key;
00273 
00274     fputs(ESC_CURSOROFF, display.dpi_stream);
00275     NutThreadSetPriority(128);
00276     
00277     for (;;) {
00278         key = ButtonRead(UI_REFRESH_RATE);
00279         if (key == KEYCODE_SELECT) {
00280             UserIfMainMenu();
00281         }
00282         else {
00283             if (key) {
00284                 if (key == KEYCODE_DOWN) {
00285                     if (radio.rc_rvolume > DAC_MIN_VOLUME) {
00286                         radio.rc_rvolume--;
00287                     }
00288                 }
00289                 else if (key == KEYCODE_UP) {
00290                     if (radio.rc_rvolume < DAC_MAX_VOLUME) {
00291                         radio.rc_rvolume++;
00292                     }
00293                 }
00294                 UserIfShowMessage(1, 2, "Volume %d dB", radio.rc_rvolume);
00295             }
00296             DisplayRefresh();
00297         }
00298     }

void UserIfShowMessage u_char  row,
u_char  secs,
CONST char *  fmt,
  ...
 

Display a specified text.

Parameters:
row Row position of the message.
secs Number of seconds to display the message. Set to 0 for permanent display.
fmt Format string containing conversion specifications.

Definition at line 308 of file userif.c.

00310 {
00311     va_list ap;
00312 
00313     va_start(ap, fmt);
00314     if (secs) {
00315         vsprintf(display.dpi_line[row].dln_msg, fmt, ap);
00316         display.dpi_line[row].dln_msgticks = secs * (1000 / UI_REFRESH_RATE);
00317     } else
00318         vsprintf(display.dpi_line[row].dln_status, fmt, ap);
00319     va_end(ap);

void UserIfShowStatus u_char  status  ) 
 

Display a specified status.

Parameters:
status Status to be displayed.

Definition at line 326 of file userif.c.

00328 {
00329     if (radio.rc_cstatus != status) {
00330         if (status == DIST_FORCE)
00331             status = radio.rc_cstatus;
00332         else
00333             radio.rc_cstatus = status;
00334 
00335         if (status == DIST_NONE) {
00336             strcpy(display.dpi_line[0].dln_status, "Internet Radio");
00337             strcpy(display.dpi_line[1].dln_status, "Version ");
00338             strcat(display.dpi_line[1].dln_status, VERSION);
00339         } else if (status == DIST_DEAD) {
00340             UserIfShowStationConf(&station[radio.rc_cstation]);
00341             UserIfShowMessage(1, 2, "not available");
00342         } else if (status == DIST_CONNECTING) {
00343             UserIfShowStationConf(&station[radio.rc_cstation]);
00344             strcpy(display.dpi_line[1].dln_status, "Connecting...");
00345         } else if (status == DIST_CONNECTED) {
00346             UserIfShowStationInfo(radio.rc_sip);
00347             if (radio.rc_rip) {
00348                 SHOUTCASTINFO *sci = (SHOUTCASTINFO *) radio.rc_rip->ri_bcast;
00349                 if (sci) {
00350                     if (sci->sci_metatitle && sci->sci_metatitle[0]) {
00351                         strncpy(display.dpi_line[1].dln_status, sci->sci_metatitle, LCD_VCOLS);
00352                     }
00353                     else if (radio.rc_sip && radio.rc_sip->si_genre && radio.rc_sip->si_genre[0]) {
00354                         strncpy(display.dpi_line[1].dln_status, radio.rc_sip->si_genre, LCD_VCOLS);
00355                     }
00356                 }
00357             }
00358         }
00359     }

int UserIfInit char *  name  ) 
 

Start background thread for display updates.

Parameters:
name Display device name.
Returns:
0 on success or -1 in case of a failure.

Definition at line 368 of file userif.c.

00370 {
00371     /* Initialize button interface. */
00372     ButtonInit();
00373 
00374     if ((display.dpi_stream = fopen(name, "w")) == 0) {
00375         return -1;
00376     }
00377     display.dpi_scrolling = LCD_ROWS;
00378 
00379     if (NutThreadCreate("displ", UserIfThread, 0, UI_THREAD_STACK) == 0) {
00380         fclose(display.dpi_stream);
00381         display.dpi_stream = NULL;
00382         return -1;
00383     }
00384     radio.rc_cstatus = DIST_NONE;
00385     UserIfShowStatus(DIST_FORCE);
00386 
00387     return 0;


Variable Documentation

DISPLAYINFO display [static]
 

Definition at line 112 of file userif.c.


Generated on Fri Feb 23 17:29:00 2007 for SAM Internet Radio by  doxygen 1.4.4