vs1001k.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984
  1. /*
  2. * Copyright (C) 2003 by Pavel Chromy. All rights reserved.
  3. * Copyright (C) 2001-2006 by egnite Software GmbH. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the copyright holders nor the names of
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  21. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  22. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  23. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  24. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  25. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  26. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  27. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  28. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. *
  31. * For additional information see http://www.ethernut.de/
  32. * -
  33. *
  34. * This software has been inspired by all the valuable work done by
  35. * Jesper Hansen <jesperh@telia.com>. Many thanks for all his help.
  36. */
  37. /*!
  38. * \file arch/avr/dev/vs1001k.c
  39. * \brief Legacy support for VS1001K.
  40. *
  41. * \verbatim
  42. * $Id: vs1001k.c 4937 2013-01-22 11:38:42Z haraldkipp $
  43. * \endverbatim
  44. */
  45. /*
  46. * This header file specifies the hardware port bits. You
  47. * need to change or replace it, if your hardware differs.
  48. */
  49. #include <cfg/arch/avr.h>
  50. #include <sys/atom.h>
  51. #include <sys/event.h>
  52. #include <sys/timer.h>
  53. #include <sys/heap.h>
  54. #include <dev/irqreg.h>
  55. #include <dev/vs1001k.h>
  56. #include <sys/bankmem.h>
  57. #include <stddef.h> /* NULL definition */
  58. /*!
  59. * \addtogroup xgVs1001
  60. */
  61. /*@{*/
  62. #ifndef VS_SCK_BIT
  63. /*!
  64. * \brief VS1001 serial control interface clock input bit.
  65. *
  66. * The first rising clock edge after XCS has gone low marks the first
  67. * bit to be written to the decoder.
  68. */
  69. #define VS_SCK_BIT 0
  70. #endif
  71. #if !defined(VS_SCK_AVRPORT) || (VS_SCK_AVRPORT == AVRPORTB)
  72. #define VS_SCK_PORT PORTB /*!< Port register of \ref VS_SCK_BIT. */
  73. #define VS_SCK_DDR DDRB /*!< Data direction register of \ref VS_SCK_BIT. */
  74. #elif (VS_SCK_AVRPORT == AVRPORTD)
  75. #define VS_SCK_PORT PORTD
  76. #define VS_SCK_DDR DDRD
  77. #elif (VS_SCK_AVRPORT == AVRPORTE)
  78. #define VS_SCK_PORT PORTE
  79. #define VS_SCK_DDR DDRE
  80. #elif (VS_SCK_AVRPORT == AVRPORTF)
  81. #define VS_SCK_PORT PORTF
  82. #define VS_SCK_DDR DDRF
  83. #else
  84. #warning "Bad SCK port specification"
  85. #endif
  86. #ifndef VS_SS_BIT
  87. /*!
  88. * \brief VS1001 serial data interface clock input bit.
  89. */
  90. #define VS_SS_BIT 1
  91. #endif
  92. #if !defined(VS_SS_AVRPORT) || (VS_SS_AVRPORT == AVRPORTB)
  93. #define VS_SS_PORT PORTB /*!< Port output register of \ref VS_SS_BIT. */
  94. #define VS_SS_DDR DDRB /*!< Data direction register of \ref VS_SS_BIT. */
  95. #elif (VS_SS_AVRPORT == AVRPORTD)
  96. #define VS_SS_PORT PORTD
  97. #define VS_SS_DDR DDRD
  98. #elif (VS_SS_AVRPORT == AVRPORTE)
  99. #define VS_SS_PORT PORTE
  100. #define VS_SS_DDR DDRE
  101. #elif (VS_SS_AVRPORT == AVRPORTF)
  102. #define VS_SS_PORT PORTF
  103. #define VS_SS_DDR DDRF
  104. #else
  105. #warning "Bad SS port specification"
  106. #endif
  107. #ifndef VS_SI_BIT
  108. /*!
  109. * \brief VS1001 serial control interface data input.
  110. *
  111. * The decoder samples this input on the rising edge of SCK if XCS is low.
  112. */
  113. #define VS_SI_BIT 2
  114. #endif
  115. #if !defined(VS_SI_AVRPORT) || (VS_SI_AVRPORT == AVRPORTB)
  116. #define VS_SI_PORT PORTB /*!< Port output register of \ref VS_SI_BIT. */
  117. #define VS_SI_DDR DDRB /*!< Data direction register of \ref VS_SI_BIT. */
  118. #elif (VS_SI_AVRPORT == AVRPORTD)
  119. #define VS_SI_PORT PORTD
  120. #define VS_SI_DDR DDRD
  121. #elif (VS_SI_AVRPORT == AVRPORTE)
  122. #define VS_SI_PORT PORTE
  123. #define VS_SI_DDR DDRE
  124. #elif (VS_SI_AVRPORT == AVRPORTF)
  125. #define VS_SI_PORT PORTF
  126. #define VS_SI_DDR DDRF
  127. #else
  128. #warning "Bad SI port specification"
  129. #endif
  130. #ifndef VS_SO_BIT
  131. /*!
  132. * \brief VS1001 serial control interface data output.
  133. *
  134. * If data is transfered from the decoder, bits are shifted out on the
  135. * falling SCK edge. If data is transfered to the decoder, SO is at a
  136. * high impedance state.
  137. */
  138. #define VS_SO_BIT 3
  139. #endif
  140. #if !defined(VS_SO_AVRPORT) || (VS_SO_AVRPORT == AVRPORTB)
  141. #define VS_SO_PIN PINB /*!< Port input register of \ref VS_SO_BIT. */
  142. #define VS_SO_DDR DDRB /*!< Data direction register of \ref VS_SO_BIT. */
  143. #elif (VS_SO_AVRPORT == AVRPORTD)
  144. #define VS_SO_PIN PIND
  145. #define VS_SO_DDR DDRD
  146. #elif (VS_SO_AVRPORT == AVRPORTE)
  147. #define VS_SO_PIN PINE
  148. #define VS_SO_DDR DDRE
  149. #elif (VS_SO_AVRPORT == AVRPORTF)
  150. #define VS_SO_PIN PINF
  151. #define VS_SO_DDR DDRF
  152. #else
  153. #warning "Bad SO port specification"
  154. #endif
  155. #ifndef VS_XCS_BIT
  156. /*!
  157. * \brief VS1001 active low chip select input.
  158. *
  159. * A high level forces the serial interface into standby mode, ending
  160. * the current operation. A high level also forces serial output (SO)
  161. * to high impedance state.
  162. */
  163. #define VS_XCS_BIT 4
  164. #endif
  165. #if !defined(VS_XCS_AVRPORT) || (VS_XCS_AVRPORT == AVRPORTB)
  166. #define VS_XCS_PORT PORTB /*!< Port output register of \ref VS_XCS_BIT. */
  167. #define VS_XCS_DDR DDRB /*!< Data direction register of \ref VS_XCS_BIT. */
  168. #elif (VS_XCS_AVRPORT == AVRPORTD)
  169. #define VS_XCS_PORT PORTD
  170. #define VS_XCS_DDR DDRD
  171. #elif (VS_XCS_AVRPORT == AVRPORTE)
  172. #define VS_XCS_PORT PORTE
  173. #define VS_XCS_DDR DDRE
  174. #elif (VS_XCS_AVRPORT == AVRPORTF)
  175. #define VS_XCS_PORT PORTF
  176. #define VS_XCS_DDR DDRF
  177. #else
  178. #warning "Bad XCS port specification"
  179. #endif
  180. #ifndef VS_BSYNC_BIT
  181. /*!
  182. * \brief VS1001 serial data interface bit sync.
  183. *
  184. * The first DCLK sampling edge, during which BSYNC is high, marks the
  185. * first bit of a data byte.
  186. */
  187. #define VS_BSYNC_BIT 5
  188. #endif
  189. #if !defined(VS_BSYNC_AVRPORT) || (VS_BSYNC_AVRPORT == AVRPORTB)
  190. #define VS_BSYNC_PORT PORTB /*!< Port output register of \ref VS_BSYNC_BIT. */
  191. #define VS_BSYNC_DDR DDRB /*!< Data direction register of \ref VS_BSYNC_BIT. */
  192. #elif (VS_BSYNC_AVRPORT == AVRPORTD)
  193. #define VS_BSYNC_PORT PORTD
  194. #define VS_BSYNC_DDR DDRD
  195. #elif (VS_BSYNC_AVRPORT == AVRPORTE)
  196. #define VS_BSYNC_PORT PORTE
  197. #define VS_BSYNC_DDR DDRE
  198. #elif (VS_BSYNC_AVRPORT == AVRPORTF)
  199. #define VS_BSYNC_PORT PORTF
  200. #define VS_BSYNC_DDR DDRF
  201. #else
  202. #warning "Bad BSYNC port specification"
  203. #endif
  204. #ifndef VS_RESET_BIT
  205. /*!
  206. * \brief VS1001 hardware reset input.
  207. */
  208. #define VS_RESET_BIT 7
  209. #endif
  210. #if !defined(VS_RESET_AVRPORT) || (VS_RESET_AVRPORT == AVRPORTB)
  211. #define VS_RESET_PORT PORTB /*!< Port output register of \ref VS_RESET_BIT. */
  212. #define VS_RESET_DDR DDRB /*!< Data direction register of \ref VS_RESET_BIT. */
  213. #elif (VS_RESET_AVRPORT == AVRPORTD)
  214. #define VS_RESET_PORT PORTD
  215. #define VS_RESET_DDR DDRD
  216. #elif (VS_RESET_AVRPORT == AVRPORTE)
  217. #define VS_RESET_PORT PORTE
  218. #define VS_RESET_DDR DDRE
  219. #elif (VS_RESET_AVRPORT == AVRPORTF)
  220. #define VS_RESET_PORT PORTF
  221. #define VS_RESET_DDR DDRF
  222. #else
  223. #warning "Bad RESET port specification"
  224. #endif
  225. #ifndef VS_SIGNAL_IRQ
  226. /*!
  227. * \brief VS1001 data request interrupt.
  228. */
  229. #define VS_SIGNAL sig_INTERRUPT6
  230. #define VS_DREQ_BIT 6
  231. #define VS_DREQ_PORT PORTE /*!< Port output register of \ref VS_DREQ_BIT. */
  232. #define VS_DREQ_PIN PINE /*!< Port input register of \ref VS_DREQ_BIT. */
  233. #define VS_DREQ_DDR DDRE /*!< Data direction register of \ref VS_DREQ_BIT. */
  234. #elif (VS_SIGNAL_IRQ == INT0)
  235. #define VS_SIGNAL sig_INTERRUPT0
  236. #define VS_DREQ_BIT 0
  237. #define VS_DREQ_PORT PORTD
  238. #define VS_DREQ_PIN PIND
  239. #define VS_DREQ_DDR DDRD
  240. #elif (VS_SIGNAL_IRQ == INT1)
  241. #define VS_SIGNAL sig_INTERRUPT1
  242. #define VS_DREQ_BIT 1
  243. #define VS_DREQ_PORT PORTD
  244. #define VS_DREQ_PIN PIND
  245. #define VS_DREQ_DDR DDRD
  246. #elif (VS_SIGNAL_IRQ == INT2)
  247. #define VS_SIGNAL sig_INTERRUPT2
  248. #define VS_DREQ_BIT 2
  249. #define VS_DREQ_PORT PORTD
  250. #define VS_DREQ_PIN PIND
  251. #define VS_DREQ_DDR DDRD
  252. #elif (VS_SIGNAL_IRQ == INT3)
  253. #define VS_SIGNAL sig_INTERRUPT3
  254. #define VS_DREQ_BIT 3
  255. #define VS_DREQ_PORT PORTD
  256. #define VS_DREQ_PIN PIND
  257. #define VS_DREQ_DDR DDRD
  258. #elif (VS_SIGNAL_IRQ == INT4)
  259. #define VS_SIGNAL sig_INTERRUPT4
  260. #define VS_DREQ_BIT 4
  261. #define VS_DREQ_PORT PORTE
  262. #define VS_DREQ_PIN PINE
  263. #define VS_DREQ_DDR DDRE
  264. #elif (VS_SIGNAL_IRQ == INT5)
  265. #define VS_SIGNAL sig_INTERRUPT5
  266. #define VS_DREQ_BIT 5
  267. #define VS_DREQ_PORT PORTE
  268. #define VS_DREQ_PIN PINE
  269. #define VS_DREQ_DDR DDRE
  270. #elif (VS_SIGNAL_IRQ == INT7)
  271. #define VS_SIGNAL sig_INTERRUPT7
  272. #define VS_DREQ_BIT 7
  273. #define VS_DREQ_PORT PORTE
  274. #define VS_DREQ_PIN PINE
  275. #define VS_DREQ_DDR DDRE
  276. #else
  277. #warning "Bad interrupt specification"
  278. #endif
  279. static volatile uint8_t vs_status = VS_STATUS_STOPPED;
  280. static volatile uint16_t vs_flush;
  281. /*
  282. * \brief Write a byte to the VS1001 data interface.
  283. *
  284. * The caller is responsible for checking the DREQ line. Also make sure,
  285. * that decoder interrupts are disabled.
  286. *
  287. * \param b Byte to be shifted to the decoder's data interface.
  288. */
  289. static INLINE void VsSdiPutByte(uint8_t b)
  290. {
  291. #ifdef VS_NOSPI
  292. uint8_t mask = 0x80;
  293. sbi(VS_BSYNC_PORT, VS_BSYNC_BIT);
  294. while (mask) {
  295. if (b & mask)
  296. sbi(VS_SI_PORT, VS_SI_BIT);
  297. else
  298. cbi(VS_SI_PORT, VS_SI_BIT);
  299. sbi(VS_SS_PORT, VS_SS_BIT);
  300. mask >>= 1;
  301. cbi(VS_SS_PORT, VS_SS_BIT);
  302. cbi(VS_BSYNC_PORT, VS_BSYNC_BIT);
  303. }
  304. #else
  305. /* Wait for previous SPI transfer to finish. */
  306. loop_until_bit_is_set(SPSR, SPIF);
  307. sbi(VS_BSYNC_PORT, VS_BSYNC_BIT);
  308. outb(SPDR, b);
  309. _NOP();
  310. _NOP();
  311. _NOP();
  312. _NOP();
  313. cbi(VS_BSYNC_PORT, VS_BSYNC_BIT);
  314. #endif
  315. }
  316. /*!
  317. * \brief Write a specified number of bytes to the VS1001 data interface.
  318. *
  319. * This function will check the DREQ line. Decoder interrupts must have
  320. * been disabled before calling this function.
  321. */
  322. static int VsSdiWrite(const uint8_t * data, uint16_t len)
  323. {
  324. uint16_t try = 5000;
  325. while (len--) {
  326. while (try-- && bit_is_clear(VS_DREQ_PIN, VS_DREQ_BIT));
  327. VsSdiPutByte(*data);
  328. data++;
  329. }
  330. return try ? 0 : -1;
  331. }
  332. /*!
  333. * \brief Write a specified number of bytes from program space to the
  334. * VS1001 data interface.
  335. *
  336. * This function is similar to VsSdiWrite() except that the data is
  337. * located in program space.
  338. */
  339. static int VsSdiWrite_P(PGM_P data, uint16_t len)
  340. {
  341. uint16_t try = 5000;
  342. while (len--) {
  343. while (try-- && bit_is_clear(VS_DREQ_PIN, VS_DREQ_BIT));
  344. VsSdiPutByte(PRG_RDB(data));
  345. data++;
  346. }
  347. return try ? 0 : -1;
  348. }
  349. /*!
  350. * \brief Write a byte to the serial control interface.
  351. *
  352. * Decoder interrupts must have been disabled and the decoder chip
  353. * select must have been enabled before calling this function.
  354. */
  355. static INLINE void VsSciPutByte(uint8_t data)
  356. {
  357. uint8_t mask = 0x80;
  358. /*
  359. * Loop until all 8 bits are processed.
  360. */
  361. while (mask) {
  362. /* Set data line. */
  363. if (data & mask)
  364. sbi(VS_SI_PORT, VS_SI_BIT);
  365. else
  366. cbi(VS_SI_PORT, VS_SI_BIT);
  367. /* Toggle clock and shift mask. */
  368. sbi(VS_SCK_PORT, VS_SCK_BIT);
  369. mask >>= 1;
  370. cbi(VS_SCK_PORT, VS_SCK_BIT);
  371. }
  372. }
  373. /*!
  374. * \brief Read a byte from the serial control interface.
  375. *
  376. * Decoder interrupts must have been disabled and the decoder chip
  377. * select must have been enabled before calling this function.
  378. */
  379. static INLINE uint8_t VsSciGetByte(void)
  380. {
  381. uint8_t mask = 0x80;
  382. uint8_t data = 0;
  383. /*
  384. * Loop until all 8 bits are processed.
  385. */
  386. while (mask) {
  387. /* Toggle clock and get the data. */
  388. sbi(VS_SCK_PORT, VS_SCK_BIT);
  389. if (bit_is_set(VS_SO_PIN, VS_SO_BIT))
  390. data |= mask;
  391. mask >>= 1;
  392. cbi(VS_SCK_PORT, VS_SCK_BIT);
  393. }
  394. return data;
  395. }
  396. /*!
  397. * \brief Write to a decoder register.
  398. *
  399. * Decoder interrupts must have been disabled before calling this function.
  400. */
  401. static void VsRegWrite(uint8_t reg, uint16_t data)
  402. {
  403. /* Select chip. */
  404. cbi(VS_XCS_PORT, VS_XCS_BIT);
  405. #ifndef VS_NOSPI
  406. /* Disable SPI */
  407. cbi(SPCR, SPE);
  408. #endif
  409. VsSciPutByte(VS_OPCODE_WRITE);
  410. VsSciPutByte(reg);
  411. VsSciPutByte((uint8_t) (data >> 8));
  412. VsSciPutByte((uint8_t) data);
  413. #ifndef VS_NOSPI
  414. /* Re-enable SPI. Hint given by Jesper Hansen. */
  415. outb(SPCR, BV(MSTR) | BV(SPE));
  416. outb(SPSR, inb(SPSR));
  417. #endif
  418. /* Deselect chip. */
  419. sbi(VS_XCS_PORT, VS_XCS_BIT);
  420. }
  421. /*
  422. * \brief Read from a register.
  423. *
  424. * Decoder interrupts must have been disabled before calling this function.
  425. *
  426. * \return Register contents.
  427. */
  428. static uint16_t VsRegRead(uint8_t reg)
  429. {
  430. uint16_t data;
  431. /* Disable interrupts and select chip. */
  432. cbi(VS_XCS_PORT, VS_XCS_BIT);
  433. #ifndef VS_NOSPI
  434. /* Disable SPI. */
  435. cbi(SPCR, SPE);
  436. #endif
  437. VsSciPutByte(VS_OPCODE_READ);
  438. VsSciPutByte(reg);
  439. data = (uint16_t)VsSciGetByte() << 8;
  440. data |= VsSciGetByte();
  441. #ifndef VS_NOSPI
  442. /* Re-enable SPI. Changed due to a hint by Jesper. */
  443. outb(SPCR, BV(MSTR) | BV(SPE));
  444. outb(SPSR, inb(SPSR));
  445. #endif
  446. /* Deselect chip and enable interrupts. */
  447. sbi(VS_XCS_PORT, VS_XCS_BIT);
  448. return data;
  449. }
  450. /*!
  451. * \brief Enable or disable player interrupts.
  452. *
  453. * This routine is typically used by applications when dealing with
  454. * unprotected buffers.
  455. *
  456. * \param enable Disables interrupts when zero. Otherwise interrupts
  457. * are enabled.
  458. *
  459. * \return Zero if interrupts were disabled before this call.
  460. */
  461. uint8_t VsPlayerInterrupts(uint8_t enable)
  462. {
  463. static uint8_t is_enabled = 0;
  464. uint8_t rc;
  465. rc = is_enabled;
  466. if(enable) {
  467. NutIrqEnable(&VS_SIGNAL);
  468. }
  469. else {
  470. NutIrqDisable(&VS_SIGNAL);
  471. }
  472. is_enabled = enable;
  473. return rc;
  474. }
  475. /*
  476. * \brief Feed the decoder with data.
  477. *
  478. * This function serves two purposes:
  479. * - It is called by VsPlayerKick() to initially fill the decoder buffer.
  480. * - It is used as an interrupt handler for the decoder.
  481. */
  482. static void VsPlayerFeed(void *arg)
  483. {
  484. uint8_t ief;
  485. uint8_t j = 32;
  486. size_t total = 0;
  487. if (bit_is_clear(VS_DREQ_PIN, VS_DREQ_BIT)) {
  488. return;
  489. }
  490. /*
  491. * We are hanging around here some time and may block other important
  492. * interrupts. Disable decoder interrupts and enable global interrupts.
  493. */
  494. ief = VsPlayerInterrupts(0);
  495. sei();
  496. /*
  497. * Feed the decoder until its buffer is full or we ran out of data.
  498. */
  499. if (vs_status == VS_STATUS_RUNNING) {
  500. char *bp = 0;
  501. size_t consumed = 0;
  502. size_t available = 0;
  503. do {
  504. if(consumed >= available) {
  505. /* Commit previously consumed bytes. */
  506. if(consumed) {
  507. NutSegBufReadCommit(consumed);
  508. consumed = 0;
  509. }
  510. /* All bytes consumed, request new. */
  511. bp = NutSegBufReadRequest(&available);
  512. if(available == 0) {
  513. /* End of stream. */
  514. vs_status = VS_STATUS_EOF;
  515. break;
  516. }
  517. }
  518. /* We have some data in the buffer, feed it. */
  519. VsSdiPutByte(*bp);
  520. bp++;
  521. consumed++;
  522. total++;
  523. if (total > 4096) {
  524. vs_status = VS_STATUS_EOF;
  525. break;
  526. }
  527. /* Allow 32 bytes to be sent as long as DREQ is set, This includes
  528. the one in progress. */
  529. if (bit_is_set(VS_DREQ_PIN, VS_DREQ_BIT))
  530. j = 32;
  531. } while(j--);
  532. /* Finally re-enable the producer buffer. */
  533. NutSegBufReadLast(consumed);
  534. }
  535. /*
  536. * Flush the internal VS buffer.
  537. */
  538. if(vs_status != VS_STATUS_RUNNING && vs_flush) {
  539. do {
  540. VsSdiPutByte(0);
  541. if (--vs_flush == 0) {
  542. /* Decoder internal buffer is flushed. */
  543. vs_status = VS_STATUS_EMPTY;
  544. break;
  545. }
  546. /* Allow 32 bytes to be sent as long as DREQ is set, This includes
  547. the one in progress. */
  548. if (bit_is_set(VS_DREQ_PIN, VS_DREQ_BIT))
  549. j = 32;
  550. } while(j--);
  551. }
  552. VsPlayerInterrupts(ief);
  553. }
  554. /*!
  555. * \brief Start playback.
  556. *
  557. * This routine will send the first MP3 data bytes to the
  558. * decoder, until it is completely filled. The data buffer
  559. * should have been filled before calling this routine.
  560. *
  561. * Decoder interrupts will be enabled.
  562. *
  563. * \return 0 on success, -1 otherwise.
  564. */
  565. int VsPlayerKick(void)
  566. {
  567. /*
  568. * Start feeding the decoder with data.
  569. */
  570. VsPlayerInterrupts(0);
  571. vs_status = VS_STATUS_RUNNING;
  572. VsPlayerFeed(NULL);
  573. VsPlayerInterrupts(1);
  574. return 0;
  575. }
  576. /*!
  577. * \brief Stops the playback.
  578. *
  579. * This routine will stops the MP3 playback, VsPlayerKick() may be used
  580. * to resume the playback.
  581. *
  582. * \return 0 on success, -1 otherwise.
  583. */
  584. int VsPlayerStop(void)
  585. {
  586. uint8_t ief;
  587. ief = VsPlayerInterrupts(0);
  588. /* Check whether we need to stop at all to not overwrite other than running status */
  589. if (vs_status == VS_STATUS_RUNNING) {
  590. vs_status = VS_STATUS_STOPPED;
  591. }
  592. VsPlayerInterrupts(ief);
  593. return 0;
  594. }
  595. /*!
  596. * \brief Sets up decoder internal buffer flushing.
  597. *
  598. * This routine will set up internal VS buffer flushing,
  599. * unless the buffer is already empty and starts the playback
  600. * if necessary. The internal VS buffer is flushed in VsPlayerFeed()
  601. * at the end of the stream.
  602. *
  603. * Decoder interrupts will be enabled.
  604. *
  605. * \return 0 on success, -1 otherwise.
  606. */
  607. int VsPlayerFlush(void)
  608. {
  609. VsPlayerInterrupts(0);
  610. /* Set up fluhing unless both buffers are empty. */
  611. if (vs_status != VS_STATUS_EMPTY || NutSegBufUsed()) {
  612. if (vs_flush == 0)
  613. vs_flush = VS_FLUSH_BYTES;
  614. /* start the playback if necessary */
  615. if (vs_status != VS_STATUS_RUNNING)
  616. VsPlayerKick();
  617. }
  618. VsPlayerInterrupts(1);
  619. return 0;
  620. }
  621. /*!
  622. * \brief Initialize the VS1001 hardware interface.
  623. *
  624. * \note The interrupt handler for this device uses a significant amount
  625. * of stack space, which may require to increase thread stacks of
  626. * all running threads. Furthermore, it requires quite some time
  627. * to execute and may degrade overall system performance.
  628. *
  629. * \return 0 on success, -1 otherwise.
  630. */
  631. int VsPlayerInit(void)
  632. {
  633. /* Disable decoder interrupts. */
  634. VsPlayerInterrupts(0);
  635. /* Keep decoder in reset state. */
  636. cbi(VS_RESET_PORT, VS_RESET_BIT);
  637. sbi(VS_RESET_DDR, VS_RESET_BIT);
  638. /* Set BSYNC output low. */
  639. cbi(VS_BSYNC_PORT, VS_BSYNC_BIT);
  640. sbi(VS_BSYNC_DDR, VS_BSYNC_BIT);
  641. /* Set MP3 chip select output low. */
  642. sbi(VS_XCS_PORT, VS_XCS_BIT);
  643. sbi(VS_XCS_DDR, VS_XCS_BIT);
  644. /* Set DREQ input with pullup. */
  645. sbi(VS_DREQ_PORT, VS_DREQ_BIT);
  646. cbi(VS_DREQ_DDR, VS_DREQ_BIT);
  647. /* Init SPI Port. */
  648. sbi(VS_SI_DDR, VS_SI_BIT);
  649. sbi(VS_SS_DDR, VS_SS_BIT);
  650. cbi(VS_SO_DDR, VS_SO_BIT);
  651. /* Set SCK output low. */
  652. cbi(VS_SCK_PORT, VS_SCK_BIT);
  653. sbi(VS_SCK_DDR, VS_SCK_BIT);
  654. #ifndef VS_NOSPI
  655. {
  656. uint8_t dummy; /* Required by some compilers. */
  657. /*
  658. * Init SPI mode to no interrupts, enabled, MSB first, master mode,
  659. * rising clock and fosc/4 clock speed. Send an initial zero byte to
  660. * make sure SPIF is set. Note, that the decoder reset line is still
  661. * active.
  662. */
  663. outb(SPCR, BV(MSTR) | BV(SPE));
  664. dummy = inb(SPSR);
  665. outb(SPDR, 0);
  666. }
  667. #endif
  668. /* Register the interrupt routine */
  669. if (NutRegisterIrqHandler(&VS_SIGNAL, VsPlayerFeed, NULL)) {
  670. return -1;
  671. }
  672. /* Rising edge will generate interrupts. */
  673. NutIrqSetMode(&VS_SIGNAL, NUT_IRQMODE_RISINGEDGE);
  674. /* Release decoder reset line. */
  675. sbi(VS_RESET_PORT, VS_RESET_BIT);
  676. NutDelay(4);
  677. /* Force frequency change (see datasheet). */
  678. VsRegWrite(VS_CLOCKF_REG, 0x9800);
  679. VsRegWrite(VS_INT_FCTLH_REG, 0x8008);
  680. NutDelay(200);
  681. /* Clear any spurious interrupt. */
  682. outb(EIFR, BV(VS_DREQ_BIT));
  683. return 0;
  684. }
  685. /*!
  686. * \brief Software reset the decoder.
  687. *
  688. * This function is typically called after VsPlayerInit() and at the end
  689. * of each track.
  690. *
  691. * \param mode Any of the following flags may be or'ed
  692. * - VS_SM_DIFF Left channel inverted.
  693. * - VS_SM_FFWD Fast forward.
  694. * - VS_SM_RESET Force hardware reset.
  695. * - VS_SM_PDOWN Switch to power down mode.
  696. * - VS_SM_BASS Bass/treble enhancer.
  697. *
  698. * \return 0 on success, -1 otherwise.
  699. */
  700. int VsPlayerReset(uint16_t mode)
  701. {
  702. /* Disable decoder interrupts and feeding. */
  703. VsPlayerInterrupts(0);
  704. vs_status = VS_STATUS_STOPPED;
  705. /* Software reset, set modes of decoder. */
  706. VsRegWrite(VS_MODE_REG, VS_SM_RESET | mode);
  707. NutDelay(2);
  708. /*
  709. * Check for correct reset.
  710. */
  711. if ((mode & VS_SM_RESET) != 0 || bit_is_clear(VS_DREQ_PIN, VS_DREQ_BIT)) {
  712. /* If not succeeded, give it one more chance and try hw reset,
  713. HW reset may also be forced by VS_SM_RESET mode bit. */
  714. cbi(VS_RESET_PORT, VS_RESET_BIT);
  715. _NOP();
  716. sbi(VS_RESET_PORT, VS_RESET_BIT);
  717. NutDelay(4);
  718. /* Set the requested modes. */
  719. VsRegWrite(VS_MODE_REG, VS_SM_RESET | mode);
  720. NutDelay(2);
  721. if (bit_is_clear(VS_DREQ_PIN, VS_DREQ_BIT))
  722. return -1;
  723. }
  724. /* Force frequency change (see datasheet). */
  725. VsRegWrite(VS_CLOCKF_REG, 0x9800);
  726. VsRegWrite(VS_INT_FCTLH_REG, 0x8008);
  727. NutDelay(2);
  728. /* Clear any spurious interrupts. */
  729. outb(EIFR, BV(VS_DREQ_BIT));
  730. return 0;
  731. }
  732. /*!
  733. * \brief Set mode register of the decoder.
  734. *
  735. * \param mode Any of the following flags may be or'ed
  736. * - VS_SM_DIFF Left channel inverted.
  737. * - VS_SM_FFWD Fast forward.
  738. * - VS_SM_RESET Software reset.
  739. * - VS_SM_PDOWN Switch to power down mode.
  740. * - VS_SM_BASS Bass/treble enhancer.
  741. *
  742. * \return 0 on success, -1 otherwise.
  743. */
  744. int VsPlayerSetMode(uint16_t mode)
  745. {
  746. uint8_t ief;
  747. ief = VsPlayerInterrupts(0);
  748. VsRegWrite(VS_MODE_REG, mode);
  749. VsPlayerInterrupts(ief);
  750. return 0;
  751. }
  752. /*!
  753. * \brief Returns play time since last reset.
  754. *
  755. * \return Play time since reset in seconds
  756. */
  757. uint16_t VsPlayTime(void)
  758. {
  759. uint16_t rc;
  760. uint8_t ief;
  761. ief = VsPlayerInterrupts(0);
  762. rc = VsRegRead(VS_DECODE_TIME_REG);
  763. VsPlayerInterrupts(ief);
  764. return rc;
  765. }
  766. /*!
  767. * \brief Returns status of the player.
  768. *
  769. * \return Any of the following value:
  770. * - VS_STATUS_STOPPED Player is ready to be started by VsPlayerKick().
  771. * - VS_STATUS_RUNNING Player is running.
  772. * - VS_STATUS_EOF Player has reached the end of a stream after VsPlayerFlush() has been called.
  773. * - VS_STATUS_EMPTY Player runs out of data. VsPlayerKick() will restart it.
  774. */
  775. uint8_t VsGetStatus(void)
  776. {
  777. return vs_status;
  778. }
  779. #ifdef __GNUC__
  780. /*!
  781. * \brief Query MP3 stream header information.
  782. *
  783. * \param vshi Pointer to VS_HEADERINFO structure.
  784. *
  785. * \return 0 on success, -1 otherwise.
  786. */
  787. int VsGetHeaderInfo(VS_HEADERINFO * vshi)
  788. {
  789. uint16_t *usp = (uint16_t *) vshi;
  790. uint8_t ief;
  791. ief = VsPlayerInterrupts(0);
  792. *usp = VsRegRead(VS_HDAT1_REG);
  793. *++usp = VsRegRead(VS_HDAT0_REG);
  794. VsPlayerInterrupts(ief);
  795. return 0;
  796. }
  797. #endif
  798. /*!
  799. * \brief Initialize decoder memory test and return result.
  800. *
  801. * \return Memory test result.
  802. * - Bit 0: Good X ROM
  803. * - Bit 1: Good Y ROM (high)
  804. * - Bit 2: Good Y ROM (low)
  805. * - Bit 3: Good Y RAM
  806. * - Bit 4: Good X RAM
  807. * - Bit 5: Good Instruction RAM (high)
  808. * - Bit 6: Good Instruction RAM (low)
  809. */
  810. uint16_t VsMemoryTest(void)
  811. {
  812. uint16_t rc;
  813. uint8_t ief;
  814. static const char mtcmd[] PROGMEM = { 0x4D, 0xEA, 0x6D, 0x54, 0x00, 0x00, 0x00, 0x00 };
  815. ief = VsPlayerInterrupts(0);
  816. VsSdiWrite_P(mtcmd, sizeof(mtcmd));
  817. NutDelay(40);
  818. rc = VsRegRead(VS_HDAT0_REG);
  819. VsPlayerInterrupts(ief);
  820. return rc;
  821. }
  822. /*!
  823. * \brief Set volume.
  824. *
  825. * \param left Left channel volume.
  826. * \param right Right channel volume.
  827. *
  828. * \return 0 on success, -1 otherwise.
  829. */
  830. int VsSetVolume(uint8_t left, uint8_t right)
  831. {
  832. uint8_t ief;
  833. ief = VsPlayerInterrupts(0);
  834. VsRegWrite(VS_VOL_REG, (((uint16_t) left) << 8) | (uint16_t) right);
  835. VsPlayerInterrupts(ief);
  836. return 0;
  837. }
  838. /*!
  839. * \brief Sine wave beep.
  840. *
  841. * \param fsin Frequency.
  842. * \param ms Duration.
  843. *
  844. * \return 0 on success, -1 otherwise.
  845. */
  846. int VsBeep(uint8_t fsin, uint8_t ms)
  847. {
  848. uint8_t ief;
  849. static const char on[] PROGMEM = { 0x53, 0xEF, 0x6E };
  850. static const char off[] PROGMEM = { 0x45, 0x78, 0x69, 0x74 };
  851. static const char end[] PROGMEM = { 0x00, 0x00, 0x00, 0x00 };
  852. /* Disable decoder interrupts. */
  853. ief = VsPlayerInterrupts(0);
  854. fsin = 56 + (fsin & 7) * 9;
  855. VsSdiWrite_P(on, sizeof(on));
  856. VsSdiWrite(&fsin, 1);
  857. VsSdiWrite_P(end, sizeof(end));
  858. NutDelay(ms);
  859. VsSdiWrite_P(off, sizeof(off));
  860. VsSdiWrite_P(end, sizeof(end));
  861. /* Enable decoder interrupts. */
  862. VsPlayerInterrupts(ief);
  863. return 0;
  864. }
  865. /*@}*/