spidrv.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /* ========================================================================
  2. * [PROJECT] SIR100
  3. * [MODULE] SPI
  4. * [TITLE] SPI source file
  5. * [FILE] spi.c
  6. * [VSN] 1.0
  7. * [CREATED] 06102006
  8. * [LASTCHNGD] 06102006
  9. * [COPYRIGHT] Copyright (C) STREAMIT BV 2010
  10. * [PURPOSE] contains all interface- and low-level routines to
  11. * control audiofunctions of the VS1003//AT45DBXX/MMC-SD(HC)card
  12. * ======================================================================== */
  13. #define LOG_MODULE LOG_SPIDRV_MODULE
  14. /*-------------------------------------------------------------------------*/
  15. /* includes */
  16. /*-------------------------------------------------------------------------*/
  17. #include <stdio.h>
  18. #include "system.h"
  19. #include "spidrv.h"
  20. #include "portio.h"
  21. #include "log.h"
  22. #include "vs10xx.h"
  23. #include <sys/timer.h>
  24. /*-------------------------------------------------------------------------*/
  25. /* local defines */
  26. /*-------------------------------------------------------------------------*/
  27. /*-------------------------------------------------------------------------*/
  28. /* typedefs & structs */
  29. /*-------------------------------------------------------------------------*/
  30. /*-------------------------------------------------------------------------*/
  31. /* local variable definitions */
  32. /*-------------------------------------------------------------------------*/
  33. static u_char g_Speedmode;
  34. /*-------------------------------------------------------------------------*/
  35. /* local routines (prototyping) */
  36. /*-------------------------------------------------------------------------*/
  37. /*!
  38. * \addtogroup Drivers
  39. */
  40. /*@{*/
  41. /*-------------------------------------------------------------------------*/
  42. /* start of code */
  43. /*-------------------------------------------------------------------------*/
  44. /*!
  45. * \brief enable SPI-logic for given device
  46. *
  47. * SPI bits:
  48. * SPSR: SPI2X double speed as set in SPR0, SPR1
  49. * SPCR: SPIE: SPI interrupt enable
  50. * SPE: SPI enable
  51. * SPR1, SPR0: clockrate
  52. * MSTR: set to master
  53. *
  54. * SPI2X SPR1 SPR0 for a ATMEGA @ 14.7456 MHz
  55. *
  56. * 1 0 0: fosc/2 = 136 ns -> 7.37 MHz
  57. * 0 0 0: fosc/4 = 271 ns -> 3.6864 MHz
  58. * 1 0 1: fosc/8 = 542 ns -> 1.8432 MHz
  59. * 0 0 1: fosc/16 = 1085 ns -> 0.9216 MHz
  60. *
  61. */
  62. void SPIselect(TSPIDevice Device)
  63. {
  64. // set SPI-speed for selected device
  65. if (Device==SPI_DEV_VS10XX)
  66. {
  67. if (g_Speedmode==SPEED_SLOW)
  68. {
  69. // set speed to Fosc/8
  70. outb(SPSR, BV(SPI2X));
  71. outb(SPCR, BV(MSTR) | BV(SPE) | BV(SPR0));
  72. }
  73. else if (g_Speedmode==SPEED_FAST)
  74. {
  75. // set speed to Fosc/4
  76. outb(SPSR, 0);
  77. outb(SPCR, BV(MSTR) | BV(SPE));
  78. }
  79. else if (g_Speedmode==SPEED_ULTRA_FAST)
  80. {
  81. // set speed to Fosc/2
  82. outb(SPSR, BV(SPI2X));
  83. outb(SPCR, BV(MSTR) | BV(SPE));
  84. }
  85. else
  86. {
  87. LogMsg_P(LOG_ERR,PSTR("invalid Speed"));
  88. }
  89. }
  90. else if (Device==SPI_DEV_FLASH)
  91. {
  92. // set speed for flash to Fosc/2
  93. outb(SPSR, BV(SPI2X));
  94. outb(SPCR, BV(MSTR) | BV(SPE));
  95. }
  96. else
  97. {
  98. // set speed for flash to Fosc/2
  99. // outb(SPSR, BV(SPI2X));
  100. // outb(SPCR, BV(MSTR) | BV(SPE));
  101. // set speed for card to Fosc/4
  102. outb(SPSR, 0);
  103. outb(SPCR, BV(MSTR) | BV(SPE));
  104. // set speed for card to Fosc/8
  105. // outb(SPSR, BV(SPI2X));
  106. // outb(SPCR, BV(MSTR) | BV(SPE) | BV(SPR0));
  107. // set speed for card to Fosc/16
  108. // outb(SPSR, 0);
  109. // outb(SPCR, BV(MSTR) | BV(SPE) | BV(SPR0));
  110. }
  111. // enable selected device
  112. switch (Device)
  113. {
  114. case SPI_DEV_VS10XX:
  115. {
  116. sbi(FLASH_OUT_WRITE, FLASH_ENABLE); // disable serial Flash
  117. sbi(MMCVS_OUT_WRITE, MMC_ENABLE); // disable MMC/SDHC
  118. sbi(MMCVS_OUT_WRITE, VS_ENABLE); // enable VS10XX
  119. break;
  120. }
  121. case SPI_DEV_FLASH:
  122. {
  123. sbi(MMCVS_OUT_WRITE, MMC_ENABLE); // disable MMC/SDHC
  124. cbi(MMCVS_OUT_WRITE, VS_ENABLE); // disable VS10XX
  125. cbi(FLASH_OUT_WRITE, FLASH_ENABLE); // enable serial Flash
  126. break;
  127. }
  128. case SPI_DEV_MMC:
  129. {
  130. sbi(FLASH_OUT_WRITE, FLASH_ENABLE); // disable serial Flash
  131. cbi(MMCVS_OUT_WRITE, VS_ENABLE); // disable VS10XX
  132. cbi(MMCVS_OUT_WRITE, MMC_ENABLE); // enable MMC/SDHC
  133. break;
  134. }
  135. default: break;
  136. }
  137. }
  138. /*!
  139. * \brief disable SPI-logic for ALL devices
  140. *
  141. */
  142. void SPIdeselect()
  143. {
  144. sbi(FLASH_OUT_WRITE, FLASH_ENABLE); // disable serial Flash
  145. cbi(MMCVS_OUT_WRITE, VS_ENABLE); // disable VS10XX
  146. sbi(MMCVS_OUT_WRITE, MMC_ENABLE); // disable MMC/SDHC
  147. }
  148. /*!
  149. * \brief not all devices can operate always on maximum speed. This routine determines the several speed modes.
  150. *
  151. */
  152. void SPImode(u_char data)
  153. {
  154. g_Speedmode = data;
  155. }
  156. u_char SPIgetmode(void)
  157. {
  158. return(g_Speedmode);
  159. }
  160. /*!
  161. * \brief send a byte using SPI, ignore result
  162. *
  163. */
  164. void SPIputByte(u_char data)
  165. {
  166. SPDR = data;
  167. while (!(SPSR & (1<<SPIF))); // wait for completion
  168. }
  169. /*!
  170. * \brief read byte using SPI, don't use any input
  171. *
  172. */
  173. u_char SPIgetByte()
  174. {
  175. SPDR = 0xFF; // dummy
  176. while (!(SPSR & (1<<SPIF))); // wait for completion
  177. return(SPDR); // return with byte shifted in from receiver
  178. }
  179. /*!
  180. * \brief send byte using SPI, return result
  181. *
  182. */
  183. u_char SPItransferByte(u_char data)
  184. {
  185. SPDR = data;
  186. while (!(SPSR & (1<<SPIF))); // wait for completion
  187. return(SPDR); // return with byte shifted in from receiver
  188. }
  189. /*!
  190. * \brief Initialise SPI registers (speed)
  191. *
  192. * Note that the IO-lines (SCK, SI, SO) are already set in 'SysInitIO()'
  193. * in the main-module
  194. *
  195. */
  196. void SPIinit()
  197. {
  198. sbi(FLASH_OUT_WRITE, FLASH_ENABLE); // disable serial Flash
  199. cbi(MMCVS_OUT_WRITE, VS_ENABLE); // disable VS10XX
  200. sbi(MMCVS_OUT_WRITE, MMC_ENABLE); // disable MMC/SDHC
  201. }
  202. /* ÍÍÍÍ End Of File ÍÍÍÍÍÍÍÍ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */