vs10xx.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. /*
  2. * Copyright (C) 2003 by Pavel Chromy. All rights reserved.
  3. * Copyright (C) 2001-2003 by egnite Software GmbH. All rights reserved.
  4. * Copyright (C) 2003-2004 by Streamit. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the copyright holders nor the names of
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
  23. * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. * For additional information see http://www.ethernut.de/
  33. * -
  34. *
  35. * This software has been inspired by all the valuable work done by
  36. * Jesper Hansen <jesperh@telia.com>. Many thanks for all his help.
  37. */
  38. /*
  39. * [COPYRIGHT] Copyright (C) STREAMIT BV
  40. *
  41. *
  42. */
  43. #define LOG_MODULE LOG_VS10XX_MODULE
  44. #include <stdlib.h>
  45. #include <sys/atom.h>
  46. #include <sys/event.h>
  47. #include <sys/timer.h>
  48. #include <sys/heap.h>
  49. #include <dev/irqreg.h>
  50. #include <sys/bankmem.h>
  51. #if (NUTOS_VERSION >= 433)
  52. #include <cpu_load.h>
  53. #endif
  54. #include "system.h"
  55. #include "vs10xx.h"
  56. #include "platform.h"
  57. #include "log.h"
  58. #include "portio.h" // for debug purposes only
  59. #include "spidrv.h" // for debug purposes only
  60. #include "watchdog.h"
  61. /*-------------------------------------------------------------------------*/
  62. /* global variable definitions */
  63. /*-------------------------------------------------------------------------*/
  64. /*-------------------------------------------------------------------------*/
  65. /* local variable definitions */
  66. /*-------------------------------------------------------------------------*/
  67. #define LOW 0
  68. #define HIGH 1
  69. #define MONO 0
  70. #define STEREO 1
  71. #define VsDeselectVs() SPIdeselect()
  72. #define VsSelectVs() SPIselect(SPI_DEV_VS10XX)
  73. /*-------------------------------------------------------------------------*/
  74. /* local variable definitions */
  75. /*-------------------------------------------------------------------------*/
  76. static volatile u_char vs_status = VS_STATUS_STOPPED;
  77. static u_short g_vs_type;
  78. static void VsLoadProgramCode(void);
  79. /*-------------------------------------------------------------------------*/
  80. /* local routines (prototyping) */
  81. /*-------------------------------------------------------------------------*/
  82. #define CODE_SIZE 437
  83. static prog_char atab[CODE_SIZE] = { /* Register addresses */
  84. 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  85. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  86. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  87. 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6,
  88. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  89. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  90. 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  91. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  92. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  93. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  94. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  95. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  96. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  97. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  98. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  99. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 6, 6,
  100. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  101. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  102. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  103. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  104. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  105. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  106. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  107. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  108. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  109. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  110. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  111. 6, 6, 6, 6, 6
  112. };
  113. prog_int dtab[CODE_SIZE] = { /* Data to write */
  114. 0x8030, 0x0030, 0x0717, 0xb080, 0x3c17, 0x0006, 0x5017, 0x3f00,
  115. 0x0024, 0x0006, 0x2016, 0x0012, 0x578f, 0x0000, 0x10ce, 0x2912,
  116. 0x9900, 0x0000, 0x004d, 0x4080, 0x184c, 0x0006, 0x96d7, 0x2800,
  117. 0x0d55, 0x0000, 0x0d48, 0x0006, 0x5b50, 0x3009, 0x0042, 0xb080,
  118. 0x8001, 0x4214, 0xbc40, 0x2818, 0xc740, 0x3613, 0x3c42, 0x3e00,
  119. 0xb803, 0x0014, 0x1b03, 0x0015, 0x59c2, 0x6fd6, 0x0024, 0x3600,
  120. 0x9803, 0x2812, 0x57d5, 0x0000, 0x004d, 0x2800, 0x2b40, 0x36f3,
  121. 0x0024, 0x804c, 0x3e10, 0x3814, 0x3e10, 0x780a, 0x3e13, 0xb80d,
  122. 0x3e03, 0xf805, 0x0006, 0x5595, 0x3009, 0x1415, 0x001b, 0xffd4,
  123. 0x0003, 0xffce, 0x0001, 0x000a, 0x2400, 0x16ce, 0xb58a, 0x0024,
  124. 0xf292, 0x9400, 0x6152, 0x0024, 0xfe02, 0x0024, 0x48b2, 0x0024,
  125. 0x454a, 0xb601, 0x36f3, 0xd805, 0x36f3, 0x980d, 0x36f0, 0x580a,
  126. 0x2000, 0x0000, 0x36f0, 0x1814, 0x8061, 0x3613, 0x0024, 0x3e12,
  127. 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3625, 0x0024, 0x0000,
  128. 0x800a, 0x3e10, 0xb803, 0x4194, 0xb805, 0x3e11, 0x0024, 0x3e11,
  129. 0xb807, 0x3e14, 0x7812, 0x3e14, 0xf80d, 0x3e03, 0xf80e, 0x0006,
  130. 0x0051, 0x2800, 0x24d5, 0x0000, 0x0024, 0xb888, 0x0012, 0x6404,
  131. 0x0405, 0x0000, 0x0024, 0x2800, 0x2158, 0x4094, 0x0024, 0x2400,
  132. 0x2102, 0x0000, 0x0024, 0x6498, 0x0803, 0xfe56, 0x0024, 0x48b6,
  133. 0x0024, 0x4dd6, 0x0024, 0x3a10, 0xc024, 0x32f0, 0xc024, 0xfe56,
  134. 0x0024, 0x48b6, 0x0024, 0x4dd6, 0x0024, 0x4384, 0x4483, 0x6396,
  135. 0x888c, 0xf400, 0x40d5, 0x3d00, 0x8024, 0x0006, 0x0091, 0x003f,
  136. 0xfec3, 0x0006, 0x0053, 0x3101, 0x8024, 0xfe60, 0x0024, 0x48be,
  137. 0x0024, 0xa634, 0x0c03, 0x4324, 0x0024, 0x4284, 0x2c02, 0x0006,
  138. 0x0011, 0x2800, 0x24d8, 0x3100, 0x8024, 0x0006, 0x5011, 0x3900,
  139. 0x8024, 0x0006, 0x0011, 0x3100, 0x984c, 0x4284, 0x904c, 0xf400,
  140. 0x4088, 0x2800, 0x2845, 0x0000, 0x0024, 0x3cf0, 0x3840, 0x3009,
  141. 0x3841, 0x3009, 0x3810, 0x2000, 0x0000, 0x0000, 0x2788, 0x3009,
  142. 0x1bd0, 0x2800, 0x2880, 0x3009, 0x1b81, 0x34f3, 0x1bcc, 0x36f3,
  143. 0xd80e, 0x36f4, 0xd80d, 0x36f4, 0x5812, 0x36f1, 0x9807, 0x36f1,
  144. 0x1805, 0x36f0, 0x9803, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2,
  145. 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x80ad, 0x3e12, 0xb817,
  146. 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a,
  147. 0x3e10, 0x7802, 0x3e10, 0xf804, 0x3e11, 0x7810, 0x3e14, 0x7812,
  148. 0x2913, 0xc980, 0x3e14, 0xc024, 0x2913, 0xc980, 0x4088, 0x184c,
  149. 0xf400, 0x4005, 0x0000, 0x18c0, 0x6400, 0x0024, 0x0000, 0x1bc0,
  150. 0x2800, 0x3095, 0x0030, 0x0310, 0x2800, 0x3f80, 0x3801, 0x4024,
  151. 0x6400, 0x0024, 0x0000, 0x1a40, 0x2800, 0x3755, 0x0006, 0x55d0,
  152. 0x0000, 0x7d03, 0xb884, 0x184c, 0x3009, 0x3805, 0x3009, 0x0000,
  153. 0xff8a, 0x0024, 0x291d, 0x7b00, 0x48b2, 0x0024, 0x0000, 0x1841,
  154. 0x0006, 0x5010, 0x408a, 0xb844, 0x2900, 0x1300, 0x4088, 0x0024,
  155. 0x3000, 0x1bcc, 0x6014, 0x0024, 0x0030, 0x0351, 0x2800, 0x36d5,
  156. 0x0000, 0x0024, 0x0006, 0x0011, 0x3100, 0x0024, 0x0030, 0x0351,
  157. 0x3800, 0x0024, 0x2800, 0x3f80, 0x3901, 0x4024, 0x6400, 0x0024,
  158. 0x0030, 0x03d0, 0x2800, 0x3f55, 0x0000, 0x7d03, 0x0006, 0x55d0,
  159. 0xb884, 0x184c, 0x3009, 0x3805, 0x3009, 0x0000, 0xff8a, 0x0024,
  160. 0x291d, 0x7b00, 0x48b2, 0x0024, 0x408a, 0x9bcc, 0x0000, 0x1841,
  161. 0x2800, 0x3b55, 0x0006, 0x5010, 0x689a, 0x0024, 0x3000, 0x0024,
  162. 0x6014, 0x0024, 0x0030, 0x0392, 0x2800, 0x3e85, 0x0006, 0x0091,
  163. 0x0006, 0x0011, 0x0000, 0x1852, 0x0006, 0x0053, 0xb880, 0x2400,
  164. 0x0006, 0x0091, 0x3804, 0x8024, 0x0030, 0x0392, 0x3b00, 0x0024,
  165. 0x3901, 0x4024, 0x2800, 0x3f80, 0x3a01, 0x4024, 0x3801, 0x4024,
  166. 0xb880, 0x1bd3, 0x36f4, 0x5812, 0x36f1, 0x5810, 0x36f0, 0xd804,
  167. 0x36f0, 0x5802, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815,
  168. 0x2000, 0x0000, 0x36f2, 0x9817, 0x0030
  169. };
  170. /*!
  171. * \addtogroup VS1003B
  172. */
  173. /*@{*/
  174. /*-------------------------------------------------------------------------*/
  175. /* start of code */
  176. /*-------------------------------------------------------------------------*/
  177. /*!
  178. * \brief Write a specified number of bytes to the VS10XX data interface.
  179. *
  180. * Decoder interrupts must have been disabled before calling this function.
  181. */
  182. static void VsSdiWrite(CONST u_char * data, u_short len)
  183. {
  184. VsSelectVs();
  185. while (len--)
  186. {
  187. SPIputByte(*data);
  188. data++;
  189. }
  190. VsDeselectVs();
  191. return;
  192. }
  193. /*!
  194. * \brief Write a specified number of bytes from program space to the
  195. * VS10XX data interface.
  196. *
  197. * This function is similar to VsSdiWrite() except that the data is
  198. * located in program space.
  199. */
  200. static void VsSdiWrite_P(PGM_P data, u_short len)
  201. {
  202. VsSelectVs();
  203. while (len--)
  204. {
  205. SPIputByte(PRG_RDB(data));
  206. data++;
  207. }
  208. VsDeselectVs();
  209. return;
  210. }
  211. /*!
  212. * \brief Write to a decoder register.
  213. *
  214. * Decoder interrupts must have been disabled before calling this function.
  215. */
  216. void VsRegWrite(u_char reg, u_short data)
  217. {
  218. u_char spimode;
  219. spimode = SPIgetmode();
  220. SPImode(SPEED_SLOW);
  221. VsSelectVs();
  222. cbi(VS_XCS_PORT, VS_XCS_BIT);
  223. SPIputByte(VS_OPCODE_WRITE);
  224. SPIputByte(reg);
  225. SPIputByte((u_char) (data >> 8));
  226. SPIputByte((u_char) data);
  227. sbi(VS_XCS_PORT, VS_XCS_BIT);
  228. VsDeselectVs();
  229. SPImode(spimode);
  230. return;
  231. }
  232. /*!
  233. * \brief determine if the stream is valid. If true, returns value; if false returns 0
  234. *
  235. */
  236. u_short VsStreamValid(void)
  237. {
  238. u_short value;
  239. u_short result;
  240. value = VsRegInfo(VS_HDAT1_REG);
  241. if (value > 0xFFE0)
  242. {
  243. value = 0xFFE0;
  244. }
  245. switch (value)
  246. {
  247. case 0x7665: /* WAV */
  248. case 0x4154: /* AAC DTS */
  249. case 0x4144: /* AAC ADIF */
  250. case 0x4D34: /* AAC .mp4 / .m4a */
  251. case 0x574D: /* WMA without broadcast patch*/
  252. {
  253. result= (g_vs_type==VS_VS1003? 0 : value);
  254. }
  255. break;
  256. case 0x576d: /* WMA with broadcast patch*/
  257. case 0x4D54: /* MIDI */
  258. case 0xFFE0: /* MP3 */
  259. {
  260. result=value;
  261. }
  262. break;
  263. default:
  264. {
  265. result=0;
  266. }
  267. }
  268. return(result);
  269. }
  270. /*
  271. * \brief Read from a register.
  272. *
  273. * Decoder interrupts must have been disabled before calling this function.
  274. *
  275. * \return Register contents.
  276. */
  277. static u_short VsRegRead(u_char reg)
  278. {
  279. u_short data;
  280. u_char spimode;
  281. spimode = SPIgetmode();
  282. SPImode(SPEED_SLOW);
  283. VsSelectVs();
  284. cbi(VS_XCS_PORT, VS_XCS_BIT);
  285. SPIputByte(VS_OPCODE_READ);
  286. SPIputByte(reg);
  287. data=SPIgetByte()<<8; // get MSB
  288. data |= SPIgetByte(); // get LSB
  289. sbi(VS_XCS_PORT, VS_XCS_BIT);
  290. VsDeselectVs();
  291. SPImode(spimode);
  292. return(data);
  293. }
  294. /*!
  295. * \brief read data from a specified register from the VS10XX
  296. *
  297. */
  298. u_short VsRegInfo(u_char reg)
  299. {
  300. u_char ief;
  301. u_short value;
  302. ief = VsPlayerInterrupts(0);
  303. value = VsRegRead(reg);
  304. VsPlayerInterrupts(ief);
  305. return(value);
  306. }
  307. /*!
  308. * \brief Enable or disable player interrupts.
  309. *
  310. * This routine is typically used by applications when dealing with
  311. * unprotected buffers.
  312. *
  313. * \param enable Disables interrupts when zero. Otherwise interrupts
  314. * are enabled.
  315. *
  316. * \return Zero if interrupts were disabled before this call.
  317. */
  318. u_char VsPlayerInterrupts(u_char enable)
  319. {
  320. u_char rc;
  321. NutEnterCritical();
  322. rc = (inb(EIMSK) & _BV(VS_DREQ_BIT)) != 0;
  323. if (enable)
  324. {
  325. sbi(EIMSK, VS_DREQ_BIT);
  326. }
  327. else
  328. {
  329. cbi(EIMSK, VS_DREQ_BIT);
  330. }
  331. NutExitCritical();
  332. return(rc);
  333. }
  334. /*
  335. * \brief Feed the decoder with data.
  336. *
  337. * This function serves two purposes:
  338. * - It is called by VsPlayerKick() to initially fill the decoder buffer.
  339. * - It is used as an interrupt handler for the decoder.
  340. *
  341. * Note that although this routine is an ISR, it is called from 'VsPlayerKick' as well
  342. */
  343. static void VsPlayerFeed(void *arg)
  344. {
  345. u_short j = 32;
  346. u_char ief;
  347. char *bp;
  348. size_t consumed;
  349. size_t available;
  350. // leave if not running.
  351. if ((vs_status != VS_STATUS_RUNNING) || (bit_is_clear(VS_DREQ_PIN, VS_DREQ_BIT)))
  352. {
  353. return;
  354. }
  355. /*
  356. * We are hanging around here some time and may block other important
  357. * interrupts. Disable decoder interrupts and enable global interrupts.
  358. */
  359. ief = VsPlayerInterrupts(0);
  360. sei();
  361. bp = 0;
  362. consumed = 0;
  363. available = 0;
  364. /*
  365. * Feed the decoder with j bytes or we ran out of data.
  366. */
  367. VsSelectVs();
  368. do
  369. {
  370. if (consumed >= available)
  371. {
  372. // Commit previously consumed bytes.
  373. if (consumed)
  374. {
  375. NutSegBufReadCommit(consumed);
  376. consumed = 0;
  377. }
  378. // All bytes consumed, request new.
  379. bp = NutSegBufReadRequest(&available);
  380. if (available == 0)
  381. {
  382. /* End of stream. */
  383. vs_status = VS_STATUS_EOF;
  384. break;
  385. }
  386. }
  387. if (available != 0) // We have some data in the buffer, feed it.
  388. {
  389. SPIputByte(*bp);
  390. bp++;
  391. consumed++;
  392. }
  393. /*
  394. * appearantly DREQ goes low when less then 32 byte are available
  395. * in the internal buffer (2048 bytes)
  396. */
  397. /* Allow 32 bytes to be sent as long as DREQ is set. This includes the one in progress */
  398. if (bit_is_set(VS_DREQ_PIN, VS_DREQ_BIT))
  399. {
  400. j = 32;
  401. }
  402. } while (--j); // bug solved: j-- counts one too many....
  403. VsDeselectVs();
  404. /* Finally re-enable the producer buffer. */
  405. NutSegBufReadLast(consumed);
  406. VsPlayerInterrupts(ief);
  407. }
  408. /*!
  409. * \brief Start playback.
  410. *
  411. * This routine will send the first MP3 data bytes to the
  412. * decoder. The data buffer
  413. * should have been filled before calling this routine.
  414. *
  415. * Decoder interrupts will be enabled.
  416. *
  417. * \return 0 on success, -1 otherwise.
  418. */
  419. int VsPlayerKick(void)
  420. {
  421. /*
  422. * Start feeding the decoder with data.
  423. */
  424. if (vs_status != VS_STATUS_RUNNING)
  425. {
  426. VsPlayerInterrupts(0);
  427. /*
  428. * for the VS1003 we need an extra reset
  429. * here before we start playing a stream...
  430. */
  431. // VsPlayerSetMode(VS_SM_RESET);
  432. // NutDelay(10);
  433. // LogMsg_P(LOG_DEBUG,PSTR("Kick: CLOCKF = [0x%02X]"),VsRegRead(VS_CLOCKF_REG));
  434. // LogMsg_P(LOG_DEBUG,PSTR("Kick: CLOCKF = [0x%02X]"),VsRegRead(VS_CLOCKF_REG));
  435. // LogMsg_P(LOG_DEBUG,PSTR("Kick: CLOCKF = [0x%02X]"),VsRegRead(VS_CLOCKF_REG));
  436. // LogMsg_P(LOG_DEBUG,PSTR("Kick: CLOCKF = [0x%02X]"),VsRegRead(VS_CLOCKF_REG));
  437. // LogMsg_P(LOG_DEBUG,PSTR("Kick: CLOCKF = [0x%02X]"),VsRegRead(VS_CLOCKF_REG));
  438. // VsLoadProgramCode();
  439. vs_status = VS_STATUS_RUNNING;
  440. VsPlayerFeed(NULL);
  441. VsPlayerInterrupts(1);
  442. }
  443. return(0);
  444. }
  445. /*!
  446. * \brief Stops the playback.
  447. *
  448. * This routine will stops the MP3 playback, VsPlayerKick() may be used
  449. * to resume the playback.
  450. *
  451. * \return 0 on success, -1 otherwise.
  452. */
  453. int VsPlayerStop(void)
  454. {
  455. u_char ief;
  456. ief = VsPlayerInterrupts(0);
  457. /* Check whether we need to stop at all to not overwrite other than running status */
  458. if (vs_status == VS_STATUS_RUNNING)
  459. vs_status = VS_STATUS_STOPPED;
  460. VsPlayerInterrupts(ief);
  461. return(0);
  462. }
  463. /*!
  464. * \brief Initialize the VS10xx hardware interface.
  465. *
  466. * \return 0 on success, -1 otherwise.
  467. */
  468. int VsPlayerInit(void)
  469. {
  470. /* Disable decoder interrupts. */
  471. VsPlayerInterrupts(0);
  472. /* Keep decoder in reset state. */
  473. cbi(VS_RESET_PORT, VS_RESET_BIT);
  474. /* Set VS10XX chip select output inactive for SCI bus (high) */
  475. sbi(VS_XCS_PORT, VS_XCS_BIT);
  476. /* Set SCK output low. */
  477. cbi(VS_SCK_PORT, VS_SCK_BIT);
  478. sbi(VS_SCK_DDR, VS_SCK_BIT);
  479. /*
  480. * Init SPI mode to no interrupts, enabled, MSB first, master mode,
  481. * rising clock and fosc/8 clock speed. Send an initial byte to
  482. * make sure SPIF is set. Note, that the decoder reset line is still
  483. * active.
  484. */
  485. NutDelay(4);
  486. SPImode(SPEED_SLOW);
  487. vs_status = VS_STATUS_STOPPED;
  488. /* Release decoder reset line. */
  489. sbi(VS_RESET_PORT, VS_RESET_BIT);
  490. /* Wait until DREQ is active
  491. * Write 0x9800 to SCI_CLOCKF
  492. * do another register write
  493. * wait at least 11000 clockcycles
  494. */
  495. NutDelay(4);
  496. /* Read the status register to determine the VS type. */
  497. g_vs_type = (VsRegRead(VS_STATUS_REG) >> 4) & 7;
  498. /* Force frequency change (see datasheet). */
  499. switch (g_vs_type)
  500. {
  501. case VS_VS1003:
  502. {
  503. VsRegWrite(VS_CLOCKF_REG, 0xE000); // 4.5x
  504. break;
  505. }
  506. default:
  507. {
  508. VsRegWrite(VS_CLOCKF_REG, 0x9800); // 2x
  509. break;
  510. }
  511. }
  512. NutDelay(50);
  513. // Datasheet requires 2 write instructions before speeding up SPI interface
  514. VsPlayerSetMode(0);
  515. VsSetVolume(0,0);
  516. NutDelay(50);
  517. // now switch to new speed...
  518. switch (g_vs_type)
  519. {
  520. case VS_VS1003:
  521. case VS_VS1053:
  522. {
  523. SPImode(SPEED_ULTRA_FAST);
  524. break;
  525. }
  526. case VS_VS1011e:
  527. default:
  528. {
  529. SPImode(SPEED_FAST);
  530. break;
  531. }
  532. }
  533. /* Register the interrupt routine */
  534. NutRegisterIrqHandler(&sig_INTERRUPT6, VsPlayerFeed, NULL);
  535. /* Rising edge will generate interrupts. */
  536. NutIrqSetMode(&sig_INTERRUPT6, NUT_IRQMODE_RISINGEDGE);
  537. /* Clear any spurious interrupt. */
  538. outp(BV(VS_DREQ_BIT), EIFR);
  539. return(0);
  540. }
  541. /*!
  542. * \brief Software reset the decoder.
  543. *
  544. * This function is typically called after VsPlayerInit() and at the end
  545. * of each track.
  546. *
  547. * \param mode Any of the following flags may be or'ed
  548. * - VS_SM_DIFF Left channel inverted.
  549. * - VS_SM_FFWD Fast forward.
  550. * - VS_SM_RESET Force hardware reset.
  551. * - VS_SM_PDOWN Switch to power down mode.
  552. * - VS_SM_BASS Bass/treble enhancer.
  553. *
  554. * \return 0 on success, -1 otherwise.
  555. */
  556. int VsPlayerReset(u_short mode)
  557. {
  558. /* Disable decoder interrupts and feeding. */
  559. VsPlayerInterrupts(0);
  560. vs_status = VS_STATUS_STOPPED;
  561. /* Software reset, set modes of decoder. */
  562. VsPlayerSetMode(VS_SM_RESET | mode);
  563. NutDelay(10);
  564. /* Clear any spurious interrupts. */
  565. outp(BV(VS_DREQ_BIT), EIFR);
  566. return(0);
  567. }
  568. /*!
  569. * \brief Set mode register of the decoder.
  570. *
  571. * \param mode Any of the following flags may be or'ed
  572. * - VS_SM_DIFF Left channel inverted.
  573. * - VS_SM_FFWD Fast forward.
  574. * - VS_SM_RESET Software reset.
  575. * - VS_SM_PDOWN Switch to power down mode.
  576. * - VS_SM_BASS Bass/treble enhancer.
  577. *
  578. * \return 0 on success, -1 otherwise.
  579. */
  580. int VsPlayerSetMode(u_short mode)
  581. {
  582. u_char ief;
  583. ief = VsPlayerInterrupts(0);
  584. /*
  585. * We need to be sure that the way of interfacing
  586. * is not corrupted by setting some new mode
  587. * We need to have SM_SDINEW & SM_SDISHARE set to '1'
  588. * at all times
  589. */
  590. mode |= (VS_SM_SDISHARE | VS_SM_SDINEW);
  591. VsRegWrite(VS_MODE_REG, mode);
  592. VsPlayerInterrupts(ief);
  593. return(0);
  594. }
  595. /*!
  596. * \brief Returns status of the player.
  597. *
  598. * \return Any of the following value:
  599. * - VS_STATUS_STOPPED Player is ready to be started by VsPlayerKick().
  600. * - VS_STATUS_RUNNING Player is running.
  601. * - VS_STATUS_EOF Player has reached the end of a stream after VsPlayerFlush() has been called.
  602. * - VS_STATUS_EMPTY Player runs out of data. VsPlayerKick() will restart it.
  603. */
  604. u_char VsGetStatus(void)
  605. {
  606. return(vs_status);
  607. }
  608. /*!
  609. * \brief Initialize decoder memory test and return result.
  610. *
  611. * \return Memory test result.
  612. * - Bit(s) Mask Meaning
  613. VS1011e/ VS1053
  614. VS1003
  615. * - 15 0x8000 0x8000 Test finished
  616. * - 14:7 Unused
  617. * - 14:10 Unused
  618. * - 9: 0x0200 Mux test succeeded
  619. * - 8: 0x0100 Good MAC RAM
  620. * - 7: 0x0080 Good I RAM
  621. * - 6: 0x0040 Mux test succeeded
  622. * - 6: 0x0040 Good Y RAM
  623. * - 5: 0x0020 Good I RAM
  624. * - 5: 0x0020 Good X RAM
  625. * - 4: 0x0010 Good Y RAM
  626. * - 4: 0x0010 Good I ROM 1
  627. * - 3: 0x0008 Good X RAM
  628. * - 3: 0x0008 Good I ROM 2
  629. * - 2: 0x0004 Good I ROM
  630. * - 2: 0x0004 Good Y ROM
  631. * - 1: 0x0002 Good Y ROM
  632. * - 1: 0x0002 Good X ROM 1
  633. * - 0: 0x0001 Good X ROM
  634. * - 0: 0x0001 Good X ROM 2
  635. * 0x807F 0x83FF All ok
  636. *
  637. * - return 0 on succes; rc otherwise
  638. */
  639. u_short VsMemoryTest(void)
  640. {
  641. u_short rc = -1;
  642. u_char ief;
  643. static prog_char mtcmd[] = { 0x4D, 0xEA, 0x6D, 0x54, 0x00, 0x00, 0x00, 0x00};
  644. VsPlayerReset(0);
  645. VsPlayerSetMode(VS_SM_TESTS);
  646. ief = VsPlayerInterrupts(0);
  647. VsSdiWrite_P(mtcmd, sizeof(mtcmd));
  648. NutDelay(40);
  649. rc = VsRegRead(VS_HDAT0_REG);
  650. VsPlayerInterrupts(ief);
  651. if ((VsGetType()==VS_VS1003) && (rc == 0x807F))
  652. {
  653. rc=0;
  654. }
  655. return(rc);
  656. }
  657. /*!
  658. * \brief Set volume.
  659. *
  660. * \param left Left channel volume.
  661. * \param right Right channel volume.
  662. *
  663. * \return 0 on success, -1 otherwise.
  664. */
  665. int VsSetVolume(u_char left, u_char right)
  666. {
  667. u_char ief;
  668. ief = VsPlayerInterrupts(0);
  669. VsRegWrite(VS_VOL_REG, (((u_short) left) << 8) | (u_short) right);
  670. VsPlayerInterrupts(ief);
  671. return(0);
  672. }
  673. /*!
  674. * \brief Get volume.
  675. *
  676. * \return u_short Volume.
  677. */
  678. u_short VsGetVolume()
  679. {
  680. u_char ief;
  681. u_short vol;
  682. ief = VsPlayerInterrupts(0);
  683. vol=VsRegRead(VS_VOL_REG);
  684. VsPlayerInterrupts(ief);
  685. return(vol);
  686. }
  687. /*!
  688. * \brief Return the number of the VS10xx chip.
  689. *
  690. * \return The actual type number as defined
  691. */
  692. u_short VsGetType(void)
  693. {
  694. return(g_vs_type);
  695. }
  696. /*!
  697. * \brief Return the number of the VS10xx chip.
  698. *
  699. * \return The actual type number coded in HEX!
  700. */
  701. u_short VsGetTypeHex(void)
  702. {
  703. switch (g_vs_type)
  704. {
  705. case VS_VS1003: return(0x03);
  706. default: break; /* Other codes use the actual number. */
  707. }
  708. return(g_vs_type);
  709. }
  710. /*!
  711. * \brief Sine wave beep.
  712. *
  713. * \param fsin Frequency.
  714. * \param ms Duration.
  715. *
  716. * \return 0 on success, -1 otherwise.
  717. */
  718. int VsBeep(u_char fsin, u_short ms)
  719. {
  720. u_char ief;
  721. static prog_char on[] = { 0x53, 0xEF, 0x6E};
  722. static prog_char off[] = { 0x45, 0x78, 0x69, 0x74};
  723. static prog_char end[] = { 0x00, 0x00, 0x00, 0x00};
  724. /* Disable decoder interrupts. */
  725. ief = VsPlayerInterrupts(0);
  726. VsPlayerSetMode(VS_SM_TESTS);
  727. fsin = (fsin* 16) + 56;
  728. VsSdiWrite_P(on, sizeof(on));
  729. VsSdiWrite(&fsin, 1);
  730. VsSdiWrite_P(end, sizeof(end));
  731. NutDelay(ms);
  732. VsSdiWrite_P(off, sizeof(off));
  733. VsSdiWrite_P(end, sizeof(end));
  734. /* Enable decoder interrupts. */
  735. VsPlayerInterrupts(ief);
  736. return(0);
  737. }
  738. /*!
  739. * \brief Sine wave beep start.
  740. *
  741. * \param fsin Frequency.
  742. *
  743. * \note this routine uses a fixed sample rate (12.000Hz) and
  744. * therefor the possible frequencies are limited.
  745. * Use 'VsBeepStartRaw' to generate a sinus with
  746. * an arbitrary freqeuncy
  747. *
  748. * \return 0 on success, -1 otherwise.
  749. */
  750. int VsBeepStart(u_char fsin)
  751. {
  752. return(VsBeepStartRaw(56 + (fsin & 7) * 9));
  753. }
  754. /*!
  755. * \brief Sine wave beep start in Raw mode.
  756. *
  757. * \param Raw: b7..b5 determines samplerate
  758. * while b4..b0 determines finepitch
  759. *
  760. * \note use the VS1003/VS1011 datasheet to figure out
  761. * which value to use for Fs (b7..b5) and
  762. * which value to use for S (b4..b0)
  763. *
  764. *
  765. * \return 0 on success, -1 otherwise.
  766. */
  767. int VsBeepStartRaw(u_char Raw)
  768. {
  769. u_char ief;
  770. static prog_char on[] = { 0x53, 0xEF, 0x6E};
  771. static prog_char end[] = { 0x00, 0x00, 0x00, 0x00};
  772. /* Disable decoder interrupts. */
  773. ief = VsPlayerInterrupts(0);
  774. VsPlayerSetMode(VS_SM_TESTS);
  775. VsSdiWrite_P(on, sizeof(on));
  776. VsSdiWrite(&Raw, 1);
  777. VsSdiWrite_P(end, sizeof(end));
  778. /* Enable decoder interrupts. */
  779. VsPlayerInterrupts(ief);
  780. return(0);
  781. }
  782. /*!
  783. * \brief Sine wave beep stop.
  784. *
  785. * \return 0 on success, -1 otherwise.
  786. */
  787. int VsBeepStop()
  788. {
  789. u_char ief;
  790. static prog_char off[] = { 0x45, 0x78, 0x69, 0x74};
  791. static prog_char end[] = { 0x00, 0x00, 0x00, 0x00};
  792. /* Disable decoder interrupts. */
  793. ief = VsPlayerInterrupts(0);
  794. VsSdiWrite_P(off, sizeof(off));
  795. VsSdiWrite_P(end, sizeof(end));
  796. /* Enable decoder interrupts. */
  797. VsPlayerInterrupts(ief);
  798. return(0);
  799. }
  800. static void VsLoadProgramCode(void)
  801. {
  802. int i;
  803. for (i=0;i<CODE_SIZE;i++)
  804. {
  805. VsRegWrite(PRG_RDB(&atab[i]), PRG_RDW(&dtab[i]));
  806. // kick watchdog on a regular base
  807. if(i%500==0)
  808. {
  809. WatchDogRestart();
  810. }
  811. }
  812. }
  813. /*@}*/