board.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /*
  2. * File : board.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2009 RT-Thread Develop Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2011-01-13 weety first version
  13. */
  14. #include <rtthread.h>
  15. #include <rthw.h>
  16. #include "board.h"
  17. /**
  18. * @addtogroup at91sam9260
  19. */
  20. /*@{*/
  21. extern void rt_hw_clock_init(void);
  22. extern void rt_hw_mmu_init(void);
  23. extern void rt_hw_get_clock(void);
  24. extern void rt_hw_set_dividor(rt_uint8_t hdivn, rt_uint8_t pdivn);
  25. extern void rt_hw_set_clock(rt_uint8_t sdiv, rt_uint8_t pdiv, rt_uint8_t mdiv);
  26. /*set debug serial port*/
  27. //#define USE_UART1
  28. //#define USE_UART3
  29. //#define USE_DBGU
  30. #define DBGU ((struct uartport *)0xfffff200)
  31. #define UART0 ((struct uartport *)AT91SAM9260_BASE_US0)
  32. #define UART1 ((struct uartport *)AT91SAM9260_BASE_US1)
  33. #define UART2 ((struct uartport *)AT91SAM9260_BASE_US2)
  34. #define UART3 ((struct uartport *)AT91SAM9260_BASE_US3)
  35. #define UART4 ((struct uartport *)AT91SAM9260_BASE_US4)
  36. #define UART5 ((struct uartport *)AT91SAM9260_BASE_US5)
  37. struct serial_int_rx uart0_int_rx;
  38. struct serial_device uart0 =
  39. {
  40. DBGU,
  41. &uart0_int_rx,
  42. RT_NULL
  43. };
  44. struct rt_device uart0_device;
  45. struct serial_int_rx uart1_int_rx;
  46. struct serial_device uart1 =
  47. {
  48. UART0,
  49. &uart1_int_rx,
  50. RT_NULL
  51. };
  52. struct rt_device uart1_device;
  53. struct serial_int_rx uart2_int_rx;
  54. struct serial_device uart2 =
  55. {
  56. UART1,
  57. &uart2_int_rx,
  58. RT_NULL
  59. };
  60. struct rt_device uart2_device;
  61. struct serial_int_rx uart3_int_rx;
  62. struct serial_device uart3 =
  63. {
  64. UART2,
  65. &uart3_int_rx,
  66. RT_NULL
  67. };
  68. struct rt_device uart3_device;
  69. struct serial_int_rx uart4_int_rx;
  70. struct serial_device uart4 =
  71. {
  72. UART3,
  73. &uart4_int_rx,
  74. RT_NULL
  75. };
  76. struct rt_device uart4_device;
  77. /**
  78. * This function will handle serial
  79. */
  80. void rt_serial_handler(int vector)
  81. {
  82. int status;
  83. switch (vector)
  84. {
  85. #ifdef RT_USING_UART0
  86. case AT91SAM9260_ID_US0:
  87. status = readl(AT91SAM9260_BASE_US0+AT91_US_CSR);
  88. if (!(status & readl(AT91SAM9260_BASE_US0+AT91_US_IMR)))
  89. {
  90. return;
  91. }
  92. rt_hw_serial_isr(&uart1_device);
  93. break;
  94. #endif
  95. #ifdef RT_USING_UART1
  96. case AT91SAM9260_ID_US1:
  97. status = readl(AT91SAM9260_BASE_US1+AT91_US_CSR);
  98. if (!(status & readl(AT91SAM9260_BASE_US1+AT91_US_IMR)))
  99. {
  100. return;
  101. }
  102. rt_hw_serial_isr(&uart2_device);
  103. break;
  104. #endif
  105. #ifdef RT_USING_UART2
  106. case AT91SAM9260_ID_US2:
  107. status = readl(AT91SAM9260_BASE_US2+AT91_US_CSR);
  108. if (!(status & readl(AT91SAM9260_BASE_US2+AT91_US_IMR)))
  109. {
  110. return;
  111. }
  112. rt_hw_serial_isr(&uart3_device);
  113. break;
  114. #endif
  115. #ifdef RT_USING_UART3
  116. case AT91SAM9260_ID_US3:
  117. status = readl(AT91SAM9260_BASE_US3+AT91_US_CSR);
  118. if (!(status & readl(AT91SAM9260_BASE_US3+AT91_US_IMR)))
  119. {
  120. return;
  121. }
  122. rt_hw_serial_isr(&uart4_device);
  123. break;
  124. #endif
  125. default: break;
  126. }
  127. }
  128. void uart_port_init(rt_uint32_t base)
  129. {
  130. #define BAUDRATE 115200
  131. rt_uint32_t cd;
  132. writel(AT91_US_RSTTX | AT91_US_RSTRX |
  133. AT91_US_RXDIS | AT91_US_TXDIS,
  134. base + AT91_US_CR);
  135. writel( AT91_US_USMODE_NORMAL | AT91_US_USCLKS_MCK |
  136. AT91_US_CHRL_8 | AT91_US_PAR_NONE |
  137. AT91_US_NBSTOP_1 | AT91_US_CHMODE_NORMAL,
  138. base + AT91_US_MR);
  139. cd = (clk_get_rate(clk_get("mck")) / 16 + BAUDRATE/2) / BAUDRATE;
  140. writel(cd, base + AT91_US_BRGR);
  141. writel(AT91_US_RXEN | AT91_US_TXEN, base + AT91_US_CR);
  142. writel(0x1, base + AT91_US_IER);
  143. }
  144. /**
  145. * This function will handle init uart
  146. */
  147. void rt_hw_uart_init(void)
  148. {
  149. #ifdef RT_USING_UART0
  150. at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US0);
  151. at91_sys_write(AT91_PIOB + PIO_IDR, (1<<4)|(1<<5));
  152. at91_sys_write(AT91_PIOB + PIO_PUER, (1<<4));
  153. at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<5));
  154. at91_sys_write(AT91_PIOB + PIO_ASR, (1<<4)|(1<<5));
  155. at91_sys_write(AT91_PIOB + PIO_PDR, (1<<4)|(1<<5));
  156. uart_port_init(AT91SAM9260_BASE_US0);
  157. /* install interrupt handler */
  158. rt_hw_interrupt_install(AT91SAM9260_ID_US0, rt_serial_handler, RT_NULL);
  159. rt_hw_interrupt_umask(AT91SAM9260_ID_US0);
  160. #endif
  161. #ifdef RT_USING_UART1
  162. at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US1);
  163. at91_sys_write(AT91_PIOB + PIO_IDR, (1<<6)|(1<<7));
  164. at91_sys_write(AT91_PIOB + PIO_PUER, (1<<6));
  165. at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<7));
  166. at91_sys_write(AT91_PIOB + PIO_ASR, (1<<6)|(1<<7));
  167. at91_sys_write(AT91_PIOB + PIO_PDR, (1<<6)|(1<<7));
  168. uart_port_init(AT91SAM9260_BASE_US1);
  169. /* install interrupt handler */
  170. rt_hw_interrupt_install(AT91SAM9260_ID_US1, rt_serial_handler, RT_NULL);
  171. rt_hw_interrupt_umask(AT91SAM9260_ID_US1);
  172. #endif
  173. #ifdef RT_USING_UART2
  174. at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US2);
  175. at91_sys_write(AT91_PIOB + PIO_IDR, (1<<8)|(1<<9));
  176. at91_sys_write(AT91_PIOB + PIO_PUER, (1<<8));
  177. at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<9));
  178. at91_sys_write(AT91_PIOB + PIO_ASR, (1<<8)|(1<<9));
  179. at91_sys_write(AT91_PIOB + PIO_PDR, (1<<8)|(1<<9));
  180. uart_port_init(AT91SAM9260_BASE_US2);
  181. /* install interrupt handler */
  182. rt_hw_interrupt_install(AT91SAM9260_ID_US2, rt_serial_handler, RT_NULL);
  183. rt_hw_interrupt_umask(AT91SAM9260_ID_US2);
  184. #endif
  185. #ifdef RT_USING_UART3
  186. at91_sys_write(AT91_PMC_PCER, 1<<AT91SAM9260_ID_US3);
  187. at91_sys_write(AT91_PIOB + PIO_IDR, (1<<10)|(1<<11));
  188. at91_sys_write(AT91_PIOB + PIO_PUER, (1<<10));
  189. at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<11));
  190. at91_sys_write(AT91_PIOB + PIO_ASR, (1<<10)|(1<<11));
  191. at91_sys_write(AT91_PIOB + PIO_PDR, (1<<10)|(1<<11));
  192. uart_port_init(AT91SAM9260_BASE_US3);
  193. /* install interrupt handler */
  194. rt_hw_interrupt_install(AT91SAM9260_ID_US3, rt_serial_handler, RT_NULL);
  195. rt_hw_interrupt_umask(AT91SAM9260_ID_US3);
  196. #endif
  197. #ifdef RT_USING_DBGU
  198. #define BAUDRATE 115200
  199. rt_uint32_t cd;
  200. at91_sys_write(AT91_PIOB + PIO_IDR, (1<<14)|(1<<15));
  201. //at91_sys_write(AT91_PIOB + PIO_PUER, (1<<6));
  202. at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<14)|(1<<15));
  203. at91_sys_write(AT91_PIOB + PIO_ASR, (1<<14)|(1<<15));
  204. at91_sys_write(AT91_PIOB + PIO_PDR, (1<<14)|(1<<15));
  205. at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_SYS);
  206. at91_sys_write(AT91_DBGU + AT91_US_CR, AT91_US_RSTTX | AT91_US_RSTRX | AT91_US_RXDIS | AT91_US_TXDIS);
  207. at91_sys_write(AT91_DBGU + AT91_US_IDR, 0xffffffff);
  208. at91_sys_write(AT91_DBGU + AT91_US_MR, AT91_US_USMODE_NORMAL | AT91_US_PAR_NONE);
  209. cd = (clk_get_rate(clk_get("mck")) / 16 + BAUDRATE/2) / BAUDRATE;
  210. at91_sys_write(AT91_DBGU + AT91_US_BRGR, cd);
  211. at91_sys_write(AT91_DBGU + AT91_US_CR, AT91_US_RXEN | AT91_US_TXEN);
  212. at91_sys_read(AT91_DBGU + AT91_US_CSR); //read for clearing interrupt
  213. at91_sys_write(AT91_DBGU + AT91_US_IER, 0x1);
  214. #endif
  215. }
  216. #define PIT_CPIV(x) ((x) & AT91_PIT_CPIV)
  217. #define PIT_PICNT(x) (((x) & AT91_PIT_PICNT) >> 20)
  218. static rt_uint32_t pit_cycle; /* write-once */
  219. static rt_uint32_t pit_cnt; /* access only w/system irq blocked */
  220. /**
  221. * This function will handle rtos timer
  222. */
  223. void rt_timer_handler(int vector)
  224. {
  225. #ifdef RT_USING_DBGU
  226. if (at91_sys_read(AT91_DBGU + AT91_US_CSR) & 0x1) {
  227. //rt_kprintf("DBGU interrupt occur\n");
  228. rt_hw_serial_isr(&uart0_device);
  229. }
  230. #endif
  231. if (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS) {
  232. unsigned nr_ticks;
  233. /* Get number of ticks performed before irq, and ack it */
  234. nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
  235. rt_tick_increase();
  236. }
  237. }
  238. static void at91sam926x_pit_reset(void)
  239. {
  240. /* Disable timer and irqs */
  241. at91_sys_write(AT91_PIT_MR, 0);
  242. /* Clear any pending interrupts, wait for PIT to stop counting */
  243. while (PIT_CPIV(at91_sys_read(AT91_PIT_PIVR)) != 0)
  244. ;
  245. /* Start PIT but don't enable IRQ */
  246. //at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
  247. pit_cnt += pit_cycle * PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
  248. at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN
  249. | AT91_PIT_PITIEN);
  250. rt_kprintf("PIT_MR=0x%08x\n", at91_sys_read(AT91_PIT_MR));
  251. }
  252. /*
  253. * Set up both clocksource and clockevent support.
  254. */
  255. static void at91sam926x_pit_init(void)
  256. {
  257. rt_uint32_t pit_rate;
  258. rt_uint32_t bits;
  259. /*
  260. * Use our actual MCK to figure out how many MCK/16 ticks per
  261. * 1/HZ period (instead of a compile-time constant LATCH).
  262. */
  263. pit_rate = clk_get_rate(clk_get("mck")) / 16;
  264. rt_kprintf("pit_rate=%dHZ\n", pit_rate);
  265. pit_cycle = (pit_rate + RT_TICK_PER_SECOND/2) / RT_TICK_PER_SECOND;
  266. /* Initialize and enable the timer */
  267. at91sam926x_pit_reset();
  268. }
  269. /**
  270. * This function will init pit for system ticks
  271. */
  272. void rt_hw_timer_init()
  273. {
  274. at91sam926x_pit_init();
  275. /* install interrupt handler */
  276. rt_hw_interrupt_install(AT91_ID_SYS, rt_timer_handler, RT_NULL);
  277. rt_hw_interrupt_umask(AT91_ID_SYS);
  278. }
  279. void at91_tc1_init()
  280. {
  281. at91_sys_write(AT91_PMC_PCER, 1<<AT91SAM9260_ID_TC0);
  282. writel(AT91_TC_TC0XC0S_NONE | AT91_TC_TC1XC1S_NONE | AT91_TC_TC2XC2S_NONE, AT91SAM9260_BASE_TCB0 + AT91_TC_BMR);
  283. writel(AT91_TC_CLKDIS, AT91SAM9260_BASE_TC0 + AT91_TC_CCR);
  284. writel(AT91_TC_TIMER_CLOCK4, AT91SAM9260_BASE_TC0 + AT91_TC_CMR);
  285. writel(0xffff, AT91SAM9260_BASE_TC0 + AT91_TC_CV);
  286. }
  287. /**
  288. * This function will init at91sam9260 board
  289. */
  290. void rt_hw_board_init()
  291. {
  292. /* initialize the system clock */
  293. rt_hw_clock_init();
  294. /* initialize uart */
  295. rt_hw_uart_init();
  296. /* initialize mmu */
  297. //rt_hw_mmu_init();
  298. /* initialize timer0 */
  299. rt_hw_timer_init();
  300. }
  301. /*@}*/