00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00043 #include <cfg/clock.h>
00044
00045 #include <dev/board.h>
00046 #include <dev/at45db.h>
00047
00048 #include <sys/confos.h>
00049 #include <sys/confnet.h>
00050
00051 #include <string.h>
00052 #include <stdlib.h>
00053
00054 #include <arpa/inet.h>
00055
00056 #include "config.h"
00057 #include "logmsg.h"
00058 #include "favlist.h"
00059 #include "webradio.h"
00060
00061 #define CONFIG_MAGIC "ir1"
00062 #define CONFOS_SECTOR 0
00063 #define CONFNET_SECTOR 1
00064 #define CONFIG_SECTOR 2
00065
00066 static int at45db;
00067 static u_int page_size;
00068
00072 HTTP_PROXY proxy;
00073
00074 #define DF_WRITE_POLLS 1000
00075
00076 #define DFCMD_READ_STATUS 0xD7
00077 #define DFCMD_CONT_READ 0xE8
00078 #define DFCMD_BUF1_WRITE 0x84
00079 #define DFCMD_BUF1_FLASH 0x83
00080 #define DFCMD_PAGE_ERASE 0x81
00081
00082 #if defined(ELEKTOR_IR1)
00083
00084 #define VS10XX_XCS_BIT 31
00085 #define VS10XX_XCS_PIO_ID PIOA_ID
00086 #define VS10XX_XDCS_BIT 30
00087 #define VS10XX_XDCS_PIO_ID PIOB_ID
00088 #define VS10XX_DREQ_BIT 30
00089 #define VS10XX_DREQ_PIO_ID PIOA_ID
00090 #define VS10XX_SIGNAL sig_INTERRUPT1
00091 #define VS_XRESET_BIT 31
00092
00093
00094
00095
00096 int InitElektorHardware(void)
00097 {
00098 static int done;
00099
00100 if (!done) {
00101
00102 outr(PIOA_ASR, inr(PIOA_ASR)
00103 | _BV(PA12_SPI0_MISO_A)
00104 | _BV(PA13_SPI0_MOSI_A)
00105 | _BV(PA14_SPI0_SPCK_A)
00106 | _BV(PA30_IRQ1_A));
00107
00108
00109 outr(PIOA_PDR, _BV(PA12_SPI0_MISO_A)
00110 | _BV(PA13_SPI0_MOSI_A)
00111 | _BV(PA14_SPI0_SPCK_A)
00112 | _BV(PA30_IRQ1_A));
00113
00114
00115
00116 outr(PIOA_PER, _BV(VS10XX_XCS_BIT));
00117 outr(PIOA_SODR, _BV(VS10XX_XCS_BIT));
00118 outr(PIOA_OER, _BV(VS10XX_XCS_BIT));
00119
00120
00121 outr(PIOB_PER, _BV(VS10XX_XDCS_BIT));
00122 outr(PIOB_SODR, _BV(VS10XX_XDCS_BIT));
00123 outr(PIOB_OER, _BV(VS10XX_XDCS_BIT));
00124
00125
00126 outr(PIOB_PER, _BV(VS_XRESET_BIT));
00127 outr(PIOB_SODR, _BV(VS_XRESET_BIT));
00128 outr(PIOB_OER, _BV(VS_XRESET_BIT));
00129
00130
00131 outr(PIOA_PER, _BV(PA11_SPI0_NPCS0_A));
00132 outr(PIOA_SODR, _BV(PA11_SPI0_NPCS0_A));
00133 outr(PIOA_OER, _BV(PA11_SPI0_NPCS0_A));
00134
00135
00136 outr(PMC_PCER, _BV(SPI0_ID) | _BV(IRQ1_ID) | _BV(PIOA_ID) | _BV(PIOB_ID) | _BV(PIOC_ID));
00137
00138
00139 outr(SPI0_CR, SPI_SPIEN | SPI_SWRST);
00140 outr(SPI0_CR, SPI_SPIEN);
00141
00142 done = 1;
00143 }
00144 return 0;
00145 }
00146 #endif
00147
00148
00149
00150
00151
00152 int SpiSetMode(void)
00153 {
00154
00155 outr(SPI0_MR, SPI_MODFDIS | SPI_MSTR);
00156
00157
00158 outr(SPI0_CSR0, (255 << SPI_SCBR_LSB) | SPI_NCPHA);
00159
00160 return 0;
00161 }
00162
00163 static u_char SpiByte(u_char val)
00164 {
00165
00166
00167 outr(SPI0_TDR, val);
00168
00169 while((inr(SPI0_SR) & SPI_RDRF) == 0);
00170
00171 val = (u_char)inr(SPI0_RDR);
00172
00173
00174 return val;
00175 }
00176
00177 int At91SpiTransfer2(u_int base, u_int cs, CONST void *txbuf, void *rxbuf, int xlen, CONST void *txnbuf, void *rxnbuf, int xnlen)
00178 {
00179 u_char *txp;
00180 u_char *rxp;
00181 u_char b;
00182
00183
00184 SpiSetMode();
00185 outr(PIOA_CODR, _BV(PA11_SPI0_NPCS0_A));
00186 txp = (u_char *)txbuf;
00187 rxp = (u_char *)rxbuf;
00188 b = 0xff;
00189 while (xlen--) {
00190 if (txp) {
00191 b = *txp++;
00192 }
00193 b = SpiByte(b);
00194 if (rxp) {
00195 *rxp++ = b;
00196 }
00197 }
00198 txp = (u_char *)txnbuf;
00199 rxp = (u_char *)rxnbuf;
00200 b = 0xff;
00201 while (xnlen--) {
00202 if (txp) {
00203 b = *txp++;
00204 }
00205 b = SpiByte(b);
00206 if (rxp) {
00207 *rxp++ = b;
00208 }
00209 }
00210 outr(PIOA_SODR, _BV(PA11_SPI0_NPCS0_A));
00211
00212 return 0;
00213 }
00214
00215
00223 size_t ConfigSize(void)
00224 {
00225 size_t rc = 0;
00226 int idx;
00227 int i;
00228 RADIOSTATION *flp;
00229
00230 for (idx = 1; idx < MAX_FAVORITES; idx++) {
00231 flp = &favlist[idx];
00232 if (flp->rs_name) {
00233 rc += strlen(flp->rs_name) + 1;
00234 for (i = 0; i < flp->rs_streams; i++) {
00235 if (flp->rs_uri[i]) {
00236 rc += strlen(flp->rs_uri[i]) + 1;
00237 }
00238 }
00239 }
00240 }
00241 return rc + 1;
00242 }
00243
00244 static u_long pgnum;
00245 static int pgpos = -1;
00246 static u_char pgbuf[1056];
00247
00248 void ConfigFlush(void)
00249 {
00250 if (pgpos > 0) {
00251 At45dbPageErase(at45db, pgnum);
00252 At45dbPageWrite(at45db, pgnum, pgbuf, page_size);
00253 }
00254 }
00255
00256 static void ConfigPut(u_char ch)
00257 {
00258 if (pgpos < 0) {
00259 memset(pgbuf, 0xFF, page_size);
00260 pgpos = 0;
00261 }
00262 pgbuf[pgpos++] = ch;
00263 if (pgpos >= page_size) {
00264 ConfigFlush();
00265 pgnum++;
00266 pgpos = 0;
00267 }
00268 }
00269
00270 static u_char ConfigGet(void)
00271 {
00272 if (pgpos < 0 || pgpos >= page_size) {
00273 At45dbPageRead(at45db, pgnum, pgbuf, page_size);
00274 pgnum++;
00275 pgpos = 0;
00276 }
00277 return pgbuf[pgpos++];
00278 }
00279
00280 void ConfigSaveString(char *str)
00281 {
00282
00283 do {
00284 ConfigPut(*str);
00285 } while(*str++);
00286 }
00287
00288 size_t ConfigLoadString(char * str, size_t size)
00289 {
00290 size_t rc = 0;
00291 u_char ch;
00292
00293 while (rc < size && (ch = ConfigGet()) != 0) {
00294 str[rc++] = ch;
00295 }
00296 str[rc++] = 0;
00297
00298
00299 return rc;
00300 }
00301
00302 void ConfigSaveBinary(void *data, size_t len)
00303 {
00304 u_char *dp = (u_char *)data;
00305
00306 while (len--) {
00307 ConfigPut(*dp);
00308 dp++;
00309 }
00310 }
00311
00312 void ConfigLoadBinary(void *data, size_t len)
00313 {
00314 u_char *dp = (u_char *)data;
00315
00316 while (len--) {
00317 *dp++ = ConfigGet();
00318 }
00319 }
00320
00321 void ConfigRewind(u_long pgn)
00322 {
00323 pgnum = pgn;
00324 pgpos = -1;
00325 }
00326
00327
00328
00329
00330 CONFOS confos;
00331 CONFNET confnet;
00332
00341 int NutLoadConfig(void)
00342 {
00343 if (ConfigInit() == 0) {
00344 ConfigRewind(CONFOS_SECTOR);
00345 ConfigLoadBinary(&confos, sizeof(CONFOS));
00346 if (confos.size == sizeof(CONFOS) && confos.magic[0] == 'O' && confos.magic[1] == 'S') {
00347 return 0;
00348 }
00349 }
00350 memset(&confos, 0, sizeof(CONFOS));
00351 return -1;
00352 }
00353
00359 int NutSaveConfig(void)
00360 {
00361 confos.size = sizeof(CONFOS);
00362 confos.magic[0] = 'O';
00363 confos.magic[1] = 'S';
00364 ConfigRewind(CONFOS_SECTOR);
00365 ConfigSaveBinary(&confos, sizeof(CONFOS));
00366 ConfigFlush();
00367
00368 return 0;
00369 }
00370
00383 int NutNetLoadConfig(CONST char *name)
00384 {
00385 if (ConfigInit() == 0) {
00386 ConfigRewind(CONFNET_SECTOR);
00387 ConfigLoadBinary(&confnet, sizeof(CONFNET));
00388 if (confnet.cd_size == sizeof(CONFNET) && strcmp(confnet.cd_name, name) == 0) {
00389 return 0;
00390 }
00391 }
00392 memset(&confnet, 0, sizeof(confnet));
00393 memset(confnet.cdn_mac, 0xFF, sizeof(confnet.cdn_mac));
00394
00395 return -1;
00396 }
00397
00403 int NutNetSaveConfig(void)
00404 {
00405 confnet.cd_size = sizeof(CONFNET);
00406 ConfigRewind(CONFNET_SECTOR);
00407 ConfigSaveBinary(&confnet, sizeof(CONFNET));
00408 ConfigFlush();
00409
00410 return 0;
00411 }
00412
00416 int ConfigSave(void)
00417 {
00418
00419 ConfigRewind(CONFIG_SECTOR);
00420 ConfigSaveString(CONFIG_MAGIC);
00421
00422
00423 ConfigSaveBinary(&webradio.wr_gain, sizeof(webradio.wr_gain));
00424 ConfigSaveBinary(&webradio.wr_pridns, sizeof(webradio.wr_pridns));
00425 ConfigSaveBinary(&webradio.wr_secdns, sizeof(webradio.wr_secdns));
00426 ConfigSaveString(proxy.proxy_host);
00427 ConfigSaveBinary(&proxy.proxy_port, sizeof(proxy.proxy_port));
00428 ConfigFlush();
00429 LogMsg(LOG_CONFIG, "Saved %d %s %s %s:%u\n",
00430 webradio.wr_gain,
00431 inet_ntoa(webradio.wr_pridns),
00432 inet_ntoa(webradio.wr_secdns),
00433 proxy.proxy_host, proxy.proxy_port);
00434
00435 return 0;
00436 }
00437
00438 int ConfigLoad(void)
00439 {
00440 int rc = -1;
00441 char *buf;
00442
00443 buf = malloc(32);
00444
00445 ConfigRewind(CONFIG_SECTOR);
00446 ConfigLoadString(buf, 32);
00447 if (strcmp(buf, CONFIG_MAGIC) == 0) {
00448 rc = 0;
00449 ConfigLoadBinary(&webradio.wr_gain, sizeof(webradio.wr_gain));
00450 ConfigLoadBinary(&webradio.wr_pridns, sizeof(webradio.wr_pridns));
00451 ConfigLoadBinary(&webradio.wr_secdns, sizeof(webradio.wr_secdns));
00452 ConfigLoadString(proxy.proxy_host, sizeof(proxy.proxy_host));
00453 ConfigLoadBinary(&proxy.proxy_port, sizeof(proxy.proxy_port));
00454 LogMsg(LOG_CONFIG, "Loaded %d %s %s %s:%u\n",
00455 webradio.wr_gain,
00456 inet_ntoa(webradio.wr_pridns),
00457 inet_ntoa(webradio.wr_secdns),
00458 proxy.proxy_host, proxy.proxy_port);
00459 } else {
00460 LogMsg(LOG_CONFIG, "No configuration\n");
00461 }
00462 free(buf);
00463
00464 return rc;
00465 }
00466
00470 void ConfigResetFactory(void)
00471 {
00472 LogMsg(LOG_CONFIG, "Factory reset\n");
00473
00474 webradio.wr_gain = -12;
00475 webradio.wr_pridns = 0;
00476 webradio.wr_secdns = 0;
00477 memset(&proxy, 0, sizeof(proxy));
00478 }
00479
00480 int ConfigInit(void)
00481 {
00482 if (page_size == 0) {
00483 #if defined(ELEKTOR_IR1)
00484 InitElektorHardware();
00485 #endif
00486 if ((at45db = At45dbInit(SPI0_BASE, 0)) == -1) {
00487 return -1;
00488 }
00489 page_size = At45dbPageSize(at45db);
00490 }
00491 return 0;
00492 }