mmc.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /* ========================================================================
  2. * [PROJECT] SIR100
  3. * [MODULE] MMC driver
  4. * [TITLE] Media Card driver
  5. * [FILE] mmc.c
  6. * [VSN] 1.0
  7. * [CREATED] 02 october 2006
  8. * [LASTCHNGD] 20 may 2007
  9. * [COPYRIGHT] Copyright (C) STREAMIT BV 2010
  10. * [PURPOSE] routines and API to support MMC-application
  11. * ======================================================================== */
  12. #define LOG_MODULE LOG_MMC_MODULE
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include <io.h>
  16. #include <fcntl.h>
  17. #include <errno.h>
  18. #include <ctype.h>
  19. #include <sys/event.h>
  20. #include <sys/thread.h>
  21. #include <sys/timer.h>
  22. #include <sys/device.h>
  23. #include <sys/bankmem.h>
  24. #include <sys/heap.h>
  25. //#pragma text:appcode
  26. #include "system.h"
  27. #include "mmc.h"
  28. #include "portio.h"
  29. #include "vs10xx.h"
  30. #include "display.h"
  31. #include "log.h"
  32. #include "fat.h"
  33. #include "mmcdrv.h"
  34. #include "led.h"
  35. #include "keyboard.h"
  36. #ifdef DEBUG
  37. //#define MMC__DEBUG
  38. #endif /* #ifdef DEBUG */
  39. /*-------------------------------------------------------------------------*/
  40. /* local defines */
  41. /*-------------------------------------------------------------------------*/
  42. #define CARD_PRESENT_COUNTER_OK 30
  43. #define CARD_NOT_PRESENT_COUNTER_OK 20
  44. /*--------------------------------------------------------------------------*/
  45. /* Type declarations */
  46. /*--------------------------------------------------------------------------*/
  47. /*!\brief Statemachine for card-detection */
  48. typedef enum T_CARD_STATE
  49. {
  50. CARD_IDLE, /* nothing to do */
  51. CARD_PRESENT, /* card seen at least one time */
  52. CARD_VALID, /* card seen at least <valid> times */
  53. CARD_NOT_PRESENT /* card not seen at least (valid> times */
  54. }TCardState;
  55. /*-------------------------------------------------------------------------*/
  56. /* local variable definitions */
  57. /*-------------------------------------------------------------------------*/
  58. static u_char CardPresentFlag;
  59. static u_char ValidateCounter;
  60. /*!\brief state-variable for Card-statemachine */
  61. static TCardState CardState;
  62. /*!\brief Status of this module */
  63. static TError g_tStatus;
  64. /*-------------------------------------------------------------------------*/
  65. /* local routines (prototyping) */
  66. /*-------------------------------------------------------------------------*/
  67. /*!
  68. * \addtogroup Card
  69. */
  70. /*@{*/
  71. /*-------------------------------------------------------------------------*/
  72. /* start of code */
  73. /*-------------------------------------------------------------------------*/
  74. /*!
  75. * \brief check if MM-Card is inserted or removed.
  76. *
  77. * \Note: this routine is called from an ISR !
  78. *
  79. */
  80. u_char CardCheckCard(void)
  81. {
  82. u_char RetValue=CARD_NO_CHANGE;
  83. switch (CardState)
  84. {
  85. case CARD_IDLE:
  86. {
  87. if (bit_is_clear(MMC_IN_READ, MMC_CDETECT))
  88. {
  89. ValidateCounter=1;
  90. CardState = CARD_PRESENT;
  91. }
  92. }
  93. break;
  94. case CARD_PRESENT:
  95. {
  96. if (bit_is_clear(MMC_IN_READ, MMC_CDETECT))
  97. {
  98. if (++ValidateCounter==CARD_PRESENT_COUNTER_OK)
  99. {
  100. CardPresentFlag=CARD_IS_PRESENT;
  101. CardState=CARD_VALID;
  102. RetValue=CARD_IS_PRESENT;
  103. }
  104. }
  105. else
  106. {
  107. CardState=CARD_IDLE; // false alarm,start over again
  108. }
  109. }
  110. break;
  111. case CARD_VALID:
  112. {
  113. if (bit_is_set(MMC_IN_READ, MMC_CDETECT))
  114. {
  115. ValidateCounter=1;
  116. CardState=CARD_NOT_PRESENT; // Card removed
  117. }
  118. }
  119. break;
  120. case CARD_NOT_PRESENT:
  121. {
  122. if (++ValidateCounter==CARD_NOT_PRESENT_COUNTER_OK)
  123. {
  124. CardPresentFlag=CARD_IS_NOT_PRESENT;
  125. CardState=CARD_IDLE;
  126. RetValue=CARD_IS_NOT_PRESENT;
  127. }
  128. }
  129. break;
  130. }
  131. return(RetValue);
  132. }
  133. /*!
  134. * \brief return status of "Card is Present"
  135. *
  136. */
  137. u_char CardCheckPresent()
  138. {
  139. return(CardPresentFlag);
  140. }
  141. /*!
  142. * \brief initialise the card by reading card contents (.pls files)
  143. *
  144. * We initialse the card by registering the card and the filesystem
  145. * that is on the card.
  146. *
  147. * Then we start checking if a number of playlists are
  148. * present on the card. The names of these playlists are hardcoded
  149. * (1.pls, 2.pls, to 20.pls). We 'search' the card for these list
  150. * of playlists by trying to open them. If succesfull, we read the
  151. * number of songs present (int) in that list
  152. * Finally we update some administration (global) variables
  153. *
  154. */
  155. int CardInitCard()
  156. {
  157. int iResult=-1;
  158. int fid; // current file descriptor
  159. char szFileName[10];
  160. //u_char i;
  161. u_char ief;
  162. /*
  163. * Register our device for the file system (if not done already.....)
  164. */
  165. if (NutDeviceLookup(devFAT.dev_name) == 0)
  166. {
  167. ief = VsPlayerInterrupts(0);
  168. if ((iResult=NutRegisterDevice(&devFAT, FAT_MODE_MMC, 0)) == 0)
  169. {
  170. iResult=NutRegisterDevice(&devFATMMC0, FAT_MODE_MMC, 0);
  171. }
  172. VsPlayerInterrupts(ief);
  173. }
  174. else
  175. {
  176. NUTDEVICE * dev;
  177. /*
  178. * we must call 'FatInit' here to initialise and mount the filesystem (again)
  179. */
  180. FATRelease();
  181. ief = VsPlayerInterrupts(0);
  182. dev=&devFAT;
  183. if (dev->dev_init == 0 || (*dev->dev_init)(dev) == 0)
  184. {
  185. dev=&devFATMMC0;
  186. if (dev->dev_init == 0 || (*dev->dev_init)(dev) == 0)
  187. {
  188. iResult=0;
  189. }
  190. }
  191. VsPlayerInterrupts(ief);
  192. }
  193. if (iResult==0)
  194. {
  195. LogMsg_P(LOG_INFO, PSTR("Card mounted"));
  196. /*
  197. * try to open the playlists. If an error is returned, we assume the
  198. * playlist does not exist and we do not check any further lists
  199. */
  200. /* Kroeske: onderstaande code ter illustratie om file op card te openen */
  201. // for (i=1; i<SETTINGS_NROF_PLAYLISTST; ++i)
  202. // {
  203. // compose name to open
  204. //sprintf_P(szFileName, PSTR("FM0:%d.pls"), i);
  205. if ((fid = _open(szFileName, _O_RDONLY)) != -1)
  206. {
  207. _close(fid);
  208. }
  209. else
  210. {
  211. //g_NrofPlayLists=i-1;
  212. //LogMsg_P(LOG_INFO, PSTR("Found %d Playlists on the Card"), i-1);
  213. // break;
  214. }
  215. // }
  216. }
  217. else
  218. {
  219. LogMsg_P(LOG_ERR, PSTR("Error initialising File system and Card-driver"));
  220. }
  221. return(iResult);
  222. }
  223. /*!
  224. * \brief The CardPresent thread.
  225. *
  226. * execute code when card is inserted or redrawn
  227. *
  228. * \param -
  229. *
  230. * \return -
  231. */
  232. THREAD(CardPresent, pArg)
  233. {
  234. static u_char OldCardStatus;
  235. OldCardStatus=CardPresentFlag;
  236. for (;;)
  237. {
  238. if ((CardPresentFlag==CARD_IS_PRESENT) && (OldCardStatus==CARD_IS_NOT_PRESENT))
  239. {
  240. LogMsg_P(LOG_INFO, PSTR("Card inserted"));
  241. if (CardInitCard()==0)
  242. {
  243. KbInjectKey(KEY_MMC_IN);
  244. }
  245. OldCardStatus=CardPresentFlag;
  246. }
  247. else if ((CardPresentFlag==CARD_IS_NOT_PRESENT) && (OldCardStatus==CARD_IS_PRESENT))
  248. {
  249. LogMsg_P(LOG_INFO, PSTR("Card removed"));
  250. CardClose();
  251. OldCardStatus=CardPresentFlag;
  252. }
  253. else
  254. {
  255. NutSleep(500);
  256. }
  257. }
  258. }
  259. /*!
  260. * \brief return global variable that indicates the status of this module
  261. *
  262. */
  263. TError CardStatus(void)
  264. {
  265. return(g_tStatus);
  266. }
  267. /*!
  268. * \brief Stop playing.
  269. *
  270. * \param -
  271. *
  272. * \return -
  273. */
  274. void CardClose(void)
  275. {
  276. }
  277. /*!
  278. * \brief initialise this module
  279. *
  280. */
  281. void CardInit()
  282. {
  283. char ThreadName[10];
  284. CardState=CARD_IDLE;
  285. CardPresentFlag=CARD_IS_NOT_PRESENT;
  286. /*
  287. * Create a CardPresent thread
  288. */
  289. strcpy_P(ThreadName, PSTR("CardPres"));
  290. if (GetThreadByName((char *)ThreadName) == NULL)
  291. {
  292. if (NutThreadCreate((char *)ThreadName, CardPresent, 0, 768) == 0)
  293. {
  294. LogMsg_P(LOG_EMERG, PSTR("Thread failed"));
  295. }
  296. }
  297. }
  298. /* ---------- end of module ------------------------------------------------ */
  299. /*@}*/