board.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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, void *param)
  81. {
  82. int status;
  83. struct rt_device *dev = (rt_device_t)param;
  84. switch (vector)
  85. {
  86. #ifdef RT_USING_UART0
  87. case AT91SAM9260_ID_US0:
  88. status = readl(AT91SAM9260_BASE_US0+AT91_US_CSR);
  89. if (!(status & readl(AT91SAM9260_BASE_US0+AT91_US_IMR)))
  90. {
  91. return;
  92. }
  93. rt_hw_serial_isr(dev);
  94. break;
  95. #endif
  96. #ifdef RT_USING_UART1
  97. case AT91SAM9260_ID_US1:
  98. status = readl(AT91SAM9260_BASE_US1+AT91_US_CSR);
  99. if (!(status & readl(AT91SAM9260_BASE_US1+AT91_US_IMR)))
  100. {
  101. return;
  102. }
  103. rt_hw_serial_isr(dev);
  104. break;
  105. #endif
  106. #ifdef RT_USING_UART2
  107. case AT91SAM9260_ID_US2:
  108. status = readl(AT91SAM9260_BASE_US2+AT91_US_CSR);
  109. if (!(status & readl(AT91SAM9260_BASE_US2+AT91_US_IMR)))
  110. {
  111. return;
  112. }
  113. rt_hw_serial_isr(dev);
  114. break;
  115. #endif
  116. #ifdef RT_USING_UART3
  117. case AT91SAM9260_ID_US3:
  118. status = readl(AT91SAM9260_BASE_US3+AT91_US_CSR);
  119. if (!(status & readl(AT91SAM9260_BASE_US3+AT91_US_IMR)))
  120. {
  121. return;
  122. }
  123. rt_hw_serial_isr(dev);
  124. break;
  125. #endif
  126. default: break;
  127. }
  128. }
  129. void uart_port_init(rt_uint32_t base)
  130. {
  131. #define BAUDRATE 115200
  132. rt_uint32_t cd;
  133. writel(AT91_US_RSTTX | AT91_US_RSTRX |
  134. AT91_US_RXDIS | AT91_US_TXDIS,
  135. base + AT91_US_CR);
  136. writel( AT91_US_USMODE_NORMAL | AT91_US_USCLKS_MCK |
  137. AT91_US_CHRL_8 | AT91_US_PAR_NONE |
  138. AT91_US_NBSTOP_1 | AT91_US_CHMODE_NORMAL,
  139. base + AT91_US_MR);
  140. cd = (clk_get_rate(clk_get("mck")) / 16 + BAUDRATE/2) / BAUDRATE;
  141. writel(cd, base + AT91_US_BRGR);
  142. writel(AT91_US_RXEN | AT91_US_TXEN, base + AT91_US_CR);
  143. writel(0x1, base + AT91_US_IER);
  144. }
  145. /**
  146. * This function will handle init uart
  147. */
  148. void rt_hw_uart_init(void)
  149. {
  150. #ifdef RT_USING_UART0
  151. at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US0);
  152. at91_sys_write(AT91_PIOB + PIO_IDR, (1<<4)|(1<<5));
  153. at91_sys_write(AT91_PIOB + PIO_PUER, (1<<4));
  154. at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<5));
  155. at91_sys_write(AT91_PIOB + PIO_ASR, (1<<4)|(1<<5));
  156. at91_sys_write(AT91_PIOB + PIO_PDR, (1<<4)|(1<<5));
  157. uart_port_init(AT91SAM9260_BASE_US0);
  158. /* install interrupt handler */
  159. rt_hw_interrupt_install(AT91SAM9260_ID_US0, rt_serial_handler,
  160. (void *)&uart1_device, "UART0");
  161. rt_hw_interrupt_umask(AT91SAM9260_ID_US0);
  162. #endif
  163. #ifdef RT_USING_UART1
  164. at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US1);
  165. at91_sys_write(AT91_PIOB + PIO_IDR, (1<<6)|(1<<7));
  166. at91_sys_write(AT91_PIOB + PIO_PUER, (1<<6));
  167. at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<7));
  168. at91_sys_write(AT91_PIOB + PIO_ASR, (1<<6)|(1<<7));
  169. at91_sys_write(AT91_PIOB + PIO_PDR, (1<<6)|(1<<7));
  170. uart_port_init(AT91SAM9260_BASE_US1);
  171. /* install interrupt handler */
  172. rt_hw_interrupt_install(AT91SAM9260_ID_US1, rt_serial_handler,
  173. (void *)&uart2_device, "UART1");
  174. rt_hw_interrupt_umask(AT91SAM9260_ID_US1);
  175. #endif
  176. #ifdef RT_USING_UART2
  177. at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US2);
  178. at91_sys_write(AT91_PIOB + PIO_IDR, (1<<8)|(1<<9));
  179. at91_sys_write(AT91_PIOB + PIO_PUER, (1<<8));
  180. at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<9));
  181. at91_sys_write(AT91_PIOB + PIO_ASR, (1<<8)|(1<<9));
  182. at91_sys_write(AT91_PIOB + PIO_PDR, (1<<8)|(1<<9));
  183. uart_port_init(AT91SAM9260_BASE_US2);
  184. /* install interrupt handler */
  185. rt_hw_interrupt_install(AT91SAM9260_ID_US2, rt_serial_handler,
  186. (void *)&uart3_device, "UART2");
  187. rt_hw_interrupt_umask(AT91SAM9260_ID_US2);
  188. #endif
  189. #ifdef RT_USING_UART3
  190. at91_sys_write(AT91_PMC_PCER, 1<<AT91SAM9260_ID_US3);
  191. at91_sys_write(AT91_PIOB + PIO_IDR, (1<<10)|(1<<11));
  192. at91_sys_write(AT91_PIOB + PIO_PUER, (1<<10));
  193. at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<11));
  194. at91_sys_write(AT91_PIOB + PIO_ASR, (1<<10)|(1<<11));
  195. at91_sys_write(AT91_PIOB + PIO_PDR, (1<<10)|(1<<11));
  196. uart_port_init(AT91SAM9260_BASE_US3);
  197. /* install interrupt handler */
  198. rt_hw_interrupt_install(AT91SAM9260_ID_US3, rt_serial_handler,
  199. (void *)&uart4_device, "UART3");
  200. rt_hw_interrupt_umask(AT91SAM9260_ID_US3);
  201. #endif
  202. #ifdef RT_USING_DBGU
  203. #define BAUDRATE 115200
  204. rt_uint32_t cd;
  205. at91_sys_write(AT91_PIOB + PIO_IDR, (1<<14)|(1<<15));
  206. //at91_sys_write(AT91_PIOB + PIO_PUER, (1<<6));
  207. at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<14)|(1<<15));
  208. at91_sys_write(AT91_PIOB + PIO_ASR, (1<<14)|(1<<15));
  209. at91_sys_write(AT91_PIOB + PIO_PDR, (1<<14)|(1<<15));
  210. at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_SYS);
  211. at91_sys_write(AT91_DBGU + AT91_US_CR, AT91_US_RSTTX | AT91_US_RSTRX | AT91_US_RXDIS | AT91_US_TXDIS);
  212. at91_sys_write(AT91_DBGU + AT91_US_IDR, 0xffffffff);
  213. at91_sys_write(AT91_DBGU + AT91_US_MR, AT91_US_USMODE_NORMAL | AT91_US_PAR_NONE);
  214. cd = (clk_get_rate(clk_get("mck")) / 16 + BAUDRATE/2) / BAUDRATE;
  215. at91_sys_write(AT91_DBGU + AT91_US_BRGR, cd);
  216. at91_sys_write(AT91_DBGU + AT91_US_CR, AT91_US_RXEN | AT91_US_TXEN);
  217. at91_sys_read(AT91_DBGU + AT91_US_CSR); //read for clearing interrupt
  218. at91_sys_write(AT91_DBGU + AT91_US_IER, 0x1);
  219. #endif
  220. }
  221. #define PIT_CPIV(x) ((x) & AT91_PIT_CPIV)
  222. #define PIT_PICNT(x) (((x) & AT91_PIT_PICNT) >> 20)
  223. static rt_uint32_t pit_cycle; /* write-once */
  224. static rt_uint32_t pit_cnt; /* access only w/system irq blocked */
  225. /**
  226. * This function will handle rtos timer
  227. */
  228. void rt_timer_handler(int vector, void *param)
  229. {
  230. #ifdef RT_USING_DBGU
  231. if (at91_sys_read(AT91_DBGU + AT91_US_CSR) & 0x1) {
  232. //rt_kprintf("DBGU interrupt occur\n");
  233. rt_hw_serial_isr(&uart0_device);
  234. }
  235. #endif
  236. if (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS) {
  237. unsigned nr_ticks;
  238. /* Get number of ticks performed before irq, and ack it */
  239. nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
  240. rt_tick_increase();
  241. }
  242. }
  243. static void at91sam926x_pit_reset(void)
  244. {
  245. /* Disable timer and irqs */
  246. at91_sys_write(AT91_PIT_MR, 0);
  247. /* Clear any pending interrupts, wait for PIT to stop counting */
  248. while (PIT_CPIV(at91_sys_read(AT91_PIT_PIVR)) != 0)
  249. ;
  250. /* Start PIT but don't enable IRQ */
  251. //at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
  252. pit_cnt += pit_cycle * PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
  253. at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN
  254. | AT91_PIT_PITIEN);
  255. rt_kprintf("PIT_MR=0x%08x\n", at91_sys_read(AT91_PIT_MR));
  256. }
  257. /*
  258. * Set up both clocksource and clockevent support.
  259. */
  260. static void at91sam926x_pit_init(void)
  261. {
  262. rt_uint32_t pit_rate;
  263. rt_uint32_t bits;
  264. /*
  265. * Use our actual MCK to figure out how many MCK/16 ticks per
  266. * 1/HZ period (instead of a compile-time constant LATCH).
  267. */
  268. pit_rate = clk_get_rate(clk_get("mck")) / 16;
  269. rt_kprintf("pit_rate=%dHZ\n", pit_rate);
  270. pit_cycle = (pit_rate + RT_TICK_PER_SECOND/2) / RT_TICK_PER_SECOND;
  271. /* Initialize and enable the timer */
  272. at91sam926x_pit_reset();
  273. }
  274. /**
  275. * This function will init pit for system ticks
  276. */
  277. void rt_hw_timer_init()
  278. {
  279. at91sam926x_pit_init();
  280. /* install interrupt handler */
  281. rt_hw_interrupt_install(AT91_ID_SYS, rt_timer_handler,
  282. RT_NULL, "system");
  283. rt_hw_interrupt_umask(AT91_ID_SYS);
  284. }
  285. void at91_tc1_init()
  286. {
  287. at91_sys_write(AT91_PMC_PCER, 1<<AT91SAM9260_ID_TC0);
  288. writel(AT91_TC_TC0XC0S_NONE | AT91_TC_TC1XC1S_NONE | AT91_TC_TC2XC2S_NONE, AT91SAM9260_BASE_TCB0 + AT91_TC_BMR);
  289. writel(AT91_TC_CLKDIS, AT91SAM9260_BASE_TC0 + AT91_TC_CCR);
  290. writel(AT91_TC_TIMER_CLOCK4, AT91SAM9260_BASE_TC0 + AT91_TC_CMR);
  291. writel(0xffff, AT91SAM9260_BASE_TC0 + AT91_TC_CV);
  292. }
  293. /**
  294. * This function will init at91sam9260 board
  295. */
  296. void rt_hw_board_init()
  297. {
  298. /* initialize the system clock */
  299. rt_hw_clock_init();
  300. /* initialize uart */
  301. rt_hw_uart_init();
  302. /* initialize mmu */
  303. rt_hw_mmu_init();
  304. /* initialize timer0 */
  305. rt_hw_timer_init();
  306. }
  307. /*@}*/