samo_a1.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. #if !defined(SAMO_A1_H)
  2. #define SAMO_A1_H 1
  3. /* as long as we use the EVBs display ... */
  4. //#define DISPLAY_INVERTED 1
  5. #define EEPROM_PM25LV512 1
  6. #if !defined(CONSOLE_BPS)
  7. //#define CONSOLE_BPS 57600
  8. #define CONSOLE_BPS 19200
  9. #endif
  10. #if !defined(CTP_BPS)
  11. #define CTP_BPS 9600
  12. #endif
  13. // PA3210 Rev RAM
  14. // A1 -> 1000 0000 32M Prototype
  15. // A2 -> 1001 0001 32M Prototype
  16. // A3 -> 1010 0010 32M Prototype
  17. // A4 -> 1011 0011 32M Prototype
  18. // A5 -> 1100 0100 32M Prototype
  19. // V1 -> 1101 0101 32M Production
  20. // V2 -> 1110 0110 16M Production
  21. // V3 -> 1111 0111 32M Production
  22. // V4 -> 0000 1000 16M Production
  23. // V5 -> 0001 1001
  24. // V6 -> 0010 1010
  25. // V7 -> 0011 1011
  26. // V8 -> 0100 1100
  27. // V9 -> 0101 1101
  28. static inline int board_revision(void)
  29. {
  30. return 0x08 ^ (REG_PA_DATA & 0x0F);
  31. }
  32. // The ports are:
  33. // P32 = SD_CARD_VCCEN active low
  34. // P33 = SD_CARD_PWR active high
  35. // Note:
  36. // P33 is N/C on Caiac version and VCCEN derived from P32
  37. // with a special driver chip
  38. #define P32_BIT (1 << 2)
  39. #define P33_BIT (1 << 3)
  40. // P32 = 0, P33 = 1
  41. #define P3_23_MASK (P32_BIT | P33_BIT)
  42. static inline int check_card_power(void)
  43. {
  44. return (REG_P3_P3D & P3_23_MASK) == P33_BIT;
  45. }
  46. static inline void disable_card_power(void)
  47. {
  48. REG_P3_P3D = (REG_P3_P3D & ~P3_23_MASK) | P32_BIT;
  49. }
  50. static inline void disable_card_buffer(void)
  51. {
  52. REG_P3_P3D = (REG_P3_P3D & ~P3_23_MASK);
  53. }
  54. static inline void enable_card_buffer(void)
  55. {
  56. REG_P3_P3D = (REG_P3_P3D & ~P3_23_MASK) | P33_BIT;
  57. }
  58. #if !SAMO_RESTRICTIONS
  59. // this need delay - but jackknife cannot include it or it will be too big
  60. // so jacknife excludes this
  61. #include <delay.h>
  62. static inline void enable_card_power(void)
  63. {
  64. disable_card_power(); // Vcc = off, Buffer = off
  65. delay_us(10);
  66. disable_card_buffer(); // Vcc = on, Buffer = off
  67. delay_us(1000);
  68. enable_card_buffer(); // Vcc = on, Buffer = on
  69. }
  70. #endif
  71. #define SDCARD_CS_LO() do { REG_P5_P5D &= ~(1 << 0); } while (0)
  72. #define SDCARD_CS_HI() do { REG_P5_P5D |= (1 << 0); } while (0)
  73. #define EEPROM_WP_HI() do {} while (0)
  74. #define POWER_OFF_CYCLES 500000
  75. // toggle watchdog output to force power off
  76. static inline void power_off(void)
  77. {
  78. register int i;
  79. REG_P6_03_CFP &= ~0xc0; // select P63 as GPIO
  80. REG_P6_IOC6 |= (1 << 3);
  81. for (;;) {
  82. REG_P6_P6D |= (1 << 3); // P63 = High
  83. for (i = 0; i < POWER_OFF_CYCLES; ++i) {
  84. asm volatile ("nop");
  85. }
  86. REG_P6_P6D &= ~(1 << 3); // P63 = low
  87. for (i = 0; i < POWER_OFF_CYCLES; ++i) {
  88. asm volatile ("nop");
  89. }
  90. }
  91. // P04 high to switch off
  92. //REG_P0_IOC0 = 0x08;
  93. //REG_P0_P0D = 0x08;
  94. }
  95. // true if power switch is pressed
  96. // possible detect this an do orderly shut down
  97. // really need to be an interrupt
  98. // this is just a reminder
  99. //static inline int power_switch_pressed(void)
  100. //{
  101. // return 0 != (REG_P0_P0D & 0x08);
  102. //}
  103. #if BOARD_SAMO_Vx
  104. #define AVDD_MILLIVOLTS 3300
  105. #elif BOARD_SAMO_A3 || BOARD_SAMO_A5
  106. #define AVDD_MILLIVOLTS 3150
  107. #else
  108. #define AVDD_MILLIVOLTS 3000
  109. #endif
  110. #define ADC_SERIES_RESISTOR_K 150
  111. #define ADC_SHUNT_RESISTOR_K 1000
  112. #define BATTERY_FULL 3000
  113. #define BATTERY_LOW 2250
  114. #define BATTERY_EMPTY 2100
  115. static inline void init_pins(void)
  116. {
  117. // not enough space for adding this
  118. // A low on pin P63 shuts down the power supply - so try
  119. // to keep it high, without any glitched or we will power down
  120. // immediately.
  121. // This _must_ be the setting performed.
  122. // p60-63: wdt - ensure that P63(#WDTNMI) pin is set high
  123. //REG_P6_P6D |= (1 << 3); // P63 = 1 (for safety)
  124. /* P85: LCD_CS, P83: TFT_CTL1 */
  125. REG_P8_IOC8 = 0x28;
  126. REG_P8_03_CFP = 0x3f;
  127. REG_P8_45_CFP = 0x03;
  128. /* P07 = reset CTP */
  129. REG_P0_IOC0 = 0x80;
  130. // REG_P0_P0D = 0x80;
  131. /* P65-67: SPI */
  132. REG_P6_47_CFP = 0x54;
  133. /* Serial interface */
  134. REG_P0_03_CFP = 0x05; // Tx/Rx
  135. REG_P0_47_CFP = 0x01; // Rx
  136. /* SDCARD CS# */
  137. REG_P5_03_CFP = 0x01;
  138. /* LCD controller */
  139. REG_P8_03_CFP = 0x55;
  140. REG_P9_47_CFP = 0x55;
  141. /* SDCARD power */
  142. REG_P3_P3D = 0x0f;
  143. REG_P3_IOC3 = 0x0f;
  144. disable_card_power();
  145. /* pull ups */
  146. REG_MISC_PUP0 = (1 << 0) | (1 << 4);
  147. REG_MISC_PUP6 = (1 << 5) | (1 << 4) | (1 << 3);
  148. /* P50 & P52: CS lines */
  149. REG_P5_P5D = 0x07; // all cs lines high
  150. REG_P5_IOC5 = 0x07;
  151. REG_INT_FK01_FP03 = 0x3f; // clear outstanding interrupts
  152. #if _not_used_
  153. /* set FPT1 to another gpio, make it falling edge triggered */
  154. REG_PINTSEL_SPT03 |= 0xC;
  155. REG_PINTEL_SEPT07 |= 0x2;
  156. REG_PINTPOL_SPP07 &= ~0x2;
  157. #endif
  158. }
  159. // number of refresh cycles for initialisation
  160. #define REFRESH_COUNT 12
  161. // mode register settings
  162. #define BURST_LENGTH_1 0x00
  163. #define BURST_LENGTH_2 0x01
  164. #define BURST_LENGTH_4 0x02
  165. #define BURST_LENGTH_8 0x03
  166. #define BURST_TYPE_NORMAL (0x0 << 3)
  167. #define BURST_TYPE_INTERLEAVE (0x1 << 3)
  168. #define CAS_LATENCY_2 (0x2 << 4)
  169. #define CAS_LATENCY_3 (0x3 << 4)
  170. #define OPERATION_NORMAL (0x00 << 7)
  171. #define OPERATION_SINGLE (0x04 << 7)
  172. #define MODE_WORD (0 \
  173. | BURST_LENGTH_2 \
  174. | BURST_TYPE_NORMAL \
  175. | CAS_LATENCY_2 \
  176. | OPERATION_SINGLE \
  177. )
  178. // as SDRAM_A0 connects to CPU_A1 => shift of 1 bit
  179. #define ADDRESS_SHIFT 1
  180. // define the start if SDRAM ought to move to .lds file
  181. // since that should be the definitive reference for the memory map
  182. #define SDRAM_START ((volatile unsigned char *) 0x10000000)
  183. #define SDRAM_FIRST_BYTE ((SDRAM_START)[0])
  184. // put the above together to get the place to write the mode to the SDRAM
  185. #define SDRAM_MODE_STORE (SDRAM_START[(MODE_WORD << ADDRESS_SHIFT)])
  186. // 48MHz => 20ns clock cycle
  187. // e.g.
  188. // SDRAM = 4M * 4 Banks * 16 bits
  189. // refresh = 8k
  190. // Trp = Trcd = 15ns 1 clock (1..4)
  191. // Tras = 42ns 3 clocks (1..8)
  192. // Trc = 67ns 4 clocks (1..16)
  193. #define CLKS_TRP 4
  194. #define CLKS_TRAS 8
  195. #define CLKS_TRC 15
  196. #define SDRAM_CONFIGURATION_32M (0 \
  197. | ((CLKS_TRP - 1) << T24NS_SHIFT) \
  198. | ((CLKS_TRAS - 1) << T60NS_SHIFT) \
  199. | ((CLKS_TRC - 1) << T80NS_SHIFT) \
  200. | ADDRC_16M_x_16_bits_x_1)
  201. #define SDRAM_CONFIGURATION_16M (0 \
  202. | ((CLKS_TRP - 1) << T24NS_SHIFT) \
  203. | ((CLKS_TRAS - 1) << T60NS_SHIFT) \
  204. | ((CLKS_TRC - 1) << T80NS_SHIFT) \
  205. | ADDRC__8M_x_16_bits_x_1)
  206. #define SDRAM_CONFIGURATION_8M (0 \
  207. | ((CLKS_TRP - 1) << T24NS_SHIFT) \
  208. | ((CLKS_TRAS - 1) << T60NS_SHIFT) \
  209. | ((CLKS_TRC - 1) << T80NS_SHIFT) \
  210. | ADDRC__4M_x_16_bits_x_1)
  211. static inline void init_ram(void)
  212. {
  213. // SDRAM off
  214. REG_SDRAMC_INI = 0;
  215. // P20..P27 all to SDRAM control functions
  216. REG_P2_03_CFP = 0x55;
  217. REG_P2_47_CFP = 0x55;
  218. // enable SDA10 on P53
  219. REG_P5_03_CFP = (REG_P5_03_CFP & 0x3f) | 0x80;
  220. // enable SDRAM clocks
  221. REG_CMU_PROTECT = CMU_PROTECT_OFF;
  222. REG_CMU_GATEDCLK0 |=
  223. //USBSAPB_CKE |
  224. //USB_CKE |
  225. //SDAPCPU_HCKE |
  226. SDAPCPU_CKE |
  227. SDAPLCDC_CKE |
  228. SDSAPB_CKE |
  229. DSTRAM_CKE |
  230. //LCDCAHBIF_CKE |
  231. //LCDCSAPB_CKE |
  232. //LCDC_CKE |
  233. 0;
  234. REG_CMU_PROTECT = CMU_PROTECT_ON;
  235. // enable arbiter
  236. REG_SDRAMC_APP =
  237. ARBON |
  238. //DBF |
  239. //INCR |
  240. CAS1 |
  241. //CAS0 |
  242. APPON |
  243. IQB |
  244. 0;
  245. // SDRAM configuration register
  246. if (board_revision() >= 8 || board_revision() == 6) {
  247. REG_SDRAMC_CTL = SDRAM_CONFIGURATION_16M;
  248. } else {
  249. REG_SDRAMC_CTL = SDRAM_CONFIGURATION_32M;
  250. }
  251. // enable RAM self-refresh
  252. REG_SDRAMC_REF =
  253. SCKON |
  254. SELEN |
  255. (0x7f << SELCO_SHIFT) |
  256. (0x8c << AURCO_SHIFT) |
  257. 0;
  258. // begin SDRAM initialisation
  259. REG_SDRAMC_INI = SDRAM_CMD_FIRST;
  260. // delay more than 200 us
  261. {
  262. unsigned int i = 0;
  263. for (i = 0; i < 150000; ++i) {
  264. asm volatile ("nop");
  265. }
  266. }
  267. REG_SDRAMC_INI = SDRAM_CMD_PALL;
  268. SDRAM_FIRST_BYTE = 0x0;
  269. asm volatile ("nop");
  270. REG_SDRAMC_INI = SDRAM_CMD_PALL;
  271. SDRAM_FIRST_BYTE = 0x0;
  272. asm volatile ("nop");
  273. REG_SDRAMC_INI = SDRAM_CMD_MRS;
  274. SDRAM_MODE_STORE = 0x0; // the value is part of the address
  275. asm volatile ("nop");
  276. {
  277. unsigned int i = 0;
  278. for (i = 0; i < REFRESH_COUNT; ++i) {
  279. REG_SDRAMC_INI = SDRAM_CMD_REF;
  280. SDRAM_FIRST_BYTE = 0x0;
  281. asm volatile ("nop");
  282. }
  283. }
  284. //REG_SDRAMC_INI = SDRAM_CMD_MRS;
  285. //SDRAM_MODE_STORE = 0x0; // the value is part of the address
  286. //asm volatile ("nop");
  287. // finished the setup sequence
  288. REG_SDRAMC_INI = SDRAM_CMD_FINAL;
  289. // wait for SDRAM to come on-line
  290. BUSY_WAIT_FOR(REG_SDRAMC_INI & SDEN);
  291. }
  292. #if !defined(MEGA)
  293. #define MEGA(x) (1024 * 1024 * (x))
  294. #endif
  295. static inline unsigned long ram_size(void)
  296. {
  297. switch (REG_SDRAMC_CTL & ADDRC_MASK) {
  298. case ADDRC_32M_x_16_bits_x_1:
  299. return MEGA(32 * 2);
  300. break;
  301. case ADDRC_16M_x__8_bits_x_2:
  302. return MEGA(16 * 2);
  303. break;
  304. case ADDRC__8M_x__8_bits_x_2:
  305. return MEGA(8 * 2);
  306. break;
  307. case ADDRC__2M_x__8_bits_x_2:
  308. return MEGA(2 * 2);
  309. break;
  310. case ADDRC_16M_x_16_bits_x_1:
  311. return MEGA(16 * 2);
  312. break;
  313. case ADDRC__8M_x_16_bits_x_1:
  314. return MEGA(8 * 2);
  315. break;
  316. case ADDRC__4M_x_16_bits_x_1:
  317. return MEGA(4 * 2);
  318. break;
  319. case ADDRC__1M_x_16_bits_x_1:
  320. return MEGA(1 * 2);
  321. break;
  322. }
  323. return 0;
  324. }
  325. #endif