board.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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 UART1 ((struct uartport *)AT91SAM9260_BASE_US1)
  32. #define UART3 ((struct uartport *)AT91SAM9260_BASE_US3)
  33. struct serial_int_rx uart0_int_rx;
  34. struct serial_device uart0 =
  35. {
  36. //UART0,
  37. DBGU,
  38. //UART1,
  39. //UART3,
  40. &uart0_int_rx,
  41. RT_NULL
  42. };
  43. struct rt_device uart0_device;
  44. /**
  45. * This function will handle serial
  46. */
  47. void rt_serial_handler(int vector)
  48. {
  49. #ifdef USE_UART1
  50. int status;
  51. status = readl(AT91SAM9260_BASE_US1+AT91_US_CSR);
  52. if (!(status & readl(AT91SAM9260_BASE_US1+AT91_US_IMR)))
  53. {
  54. return;
  55. }
  56. #endif
  57. #ifdef USE_UART3
  58. at91_sys_read(AT91_USART3+AT91_US_CSR);
  59. #endif
  60. rt_hw_serial_isr(&uart0_device);
  61. }
  62. /**
  63. * This function will handle init uart
  64. */
  65. void rt_hw_uart_init(void)
  66. {
  67. rt_uint32_t cd;
  68. #ifdef USE_UART1
  69. #define BAUDRATE 115200
  70. //rt_uint32_t uart_rate;
  71. //at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_PIOB);
  72. at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US1);
  73. at91_sys_write(AT91_PIOB + PIO_IDR, (1<<6)|(1<<7));
  74. at91_sys_write(AT91_PIOB + PIO_PUER, (1<<6));
  75. at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<7));
  76. at91_sys_write(AT91_PIOB + PIO_ASR, (1<<6)|(1<<7));
  77. at91_sys_write(AT91_PIOB + PIO_PDR, (1<<6)|(1<<7));
  78. writel(AT91_US_RSTTX | AT91_US_RSTRX | AT91_US_RXDIS | AT91_US_TXDIS, AT91SAM9260_BASE_US1 + AT91_US_CR);
  79. writel( AT91_US_USMODE_NORMAL | AT91_US_USCLKS_MCK | AT91_US_CHRL_8 | AT91_US_PAR_NONE | AT91_US_NBSTOP_1 | AT91_US_CHMODE_NORMAL, AT91SAM9260_BASE_US1 + AT91_US_MR);//0x100108c0
  80. //at91_sys_write(AT91_USART1 + AT91_US_MR, 0x000008c0);//0x100108c0
  81. cd = (clk_get_rate(clk_get("mck")) / 16 + BAUDRATE/2) / BAUDRATE;
  82. writel(cd, AT91SAM9260_BASE_US1 + AT91_US_BRGR);
  83. writel(AT91_US_RXEN | AT91_US_TXEN, AT91SAM9260_BASE_US1 + AT91_US_CR);
  84. writel(0x1, AT91SAM9260_BASE_US1 + AT91_US_IER);
  85. /* install interrupt handler */
  86. rt_hw_interrupt_install(AT91SAM9260_ID_US1, rt_serial_handler, RT_NULL);
  87. rt_hw_interrupt_umask(AT91SAM9260_ID_US1);
  88. #endif
  89. #ifdef USE_UART3
  90. #define BAUDRATE 115200
  91. //rt_uint32_t uart_rate;
  92. at91_sys_write(AT91_PMC_PCER, 1<<AT91SAM9260_ID_US3);
  93. at91_sys_write(AT91_PIOB+0x04, (1<<10)|(1<<11));
  94. at91_sys_write(AT91_PIOB+0x70, (1<<10)|(1<<11));
  95. writel(AT91_US_RSTTX | AT91_US_RSTRX | AT91_US_RXDIS | AT91_US_TXDIS, AT91SAM9260_BASE_US1 + AT91_US_CR);
  96. writel( AT91_US_USMODE_NORMAL | AT91_US_USCLKS_MCK | AT91_US_CHRL_8 | AT91_US_PAR_NONE | AT91_US_NBSTOP_1 | AT91_US_CHMODE_NORMAL, AT91SAM9260_BASE_US3 + AT91_US_MR);
  97. cd = (clk_get_rate(clk_get("mck")) / 16 + BAUDRATE/2) / BAUDRATE;
  98. writel(cd, AT91SAM9260_BASE_US3 + AT91_US_BRGR);
  99. writel(AT91_US_RXEN | AT91_US_TXEN, AT91SAM9260_BASE_US3 + AT91_US_CR);
  100. writel(0x1, AT91SAM9260_BASE_US3 + AT91_US_IER);
  101. /* install interrupt handler */
  102. rt_hw_interrupt_install(AT91SAM9260_ID_US3, rt_serial_handler, RT_NULL);
  103. rt_hw_interrupt_umask(AT91SAM9260_ID_US3);
  104. #endif
  105. #ifdef USE_DBGU
  106. #define BAUDRATE 115200
  107. //rt_uint32_t cd;
  108. at91_sys_write(AT91_PIOB + PIO_IDR, (1<<14)|(1<<15));
  109. //at91_sys_write(AT91_PIOB + PIO_PUER, (1<<6));
  110. at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<14)|(1<<15));
  111. at91_sys_write(AT91_PIOB + PIO_ASR, (1<<14)|(1<<15));
  112. at91_sys_write(AT91_PIOB + PIO_PDR, (1<<14)|(1<<15));
  113. at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_SYS);
  114. at91_sys_write(AT91_DBGU + AT91_US_CR, AT91_US_RSTTX | AT91_US_RSTRX | AT91_US_RXDIS | AT91_US_TXDIS);
  115. at91_sys_write(AT91_DBGU + AT91_US_IDR, 0xffffffff);
  116. at91_sys_write(AT91_DBGU + AT91_US_MR, AT91_US_USMODE_NORMAL | AT91_US_PAR_NONE);
  117. cd = (clk_get_rate(clk_get("mck")) / 16 + BAUDRATE/2) / BAUDRATE;
  118. at91_sys_write(AT91_DBGU + AT91_US_BRGR, cd);
  119. at91_sys_write(AT91_DBGU + AT91_US_CR, AT91_US_RXEN | AT91_US_TXEN);
  120. at91_sys_read(AT91_DBGU + AT91_US_CSR); //read for clearing interrupt
  121. at91_sys_write(AT91_DBGU + AT91_US_IER, 0x1);
  122. #endif
  123. }
  124. #define PIT_CPIV(x) ((x) & AT91_PIT_CPIV)
  125. #define PIT_PICNT(x) (((x) & AT91_PIT_PICNT) >> 20)
  126. static rt_uint32_t pit_cycle; /* write-once */
  127. static rt_uint32_t pit_cnt; /* access only w/system irq blocked */
  128. /**
  129. * This function will handle rtos timer
  130. */
  131. void rt_timer_handler(int vector)
  132. {
  133. #ifdef USE_DBGU
  134. if (at91_sys_read(AT91_DBGU + AT91_US_CSR) & 0x1) {
  135. //rt_kprintf("DBGU interrupt occur\n");
  136. rt_serial_handler(1);
  137. }
  138. #endif
  139. if (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS) {
  140. unsigned nr_ticks;
  141. /* Get number of ticks performed before irq, and ack it */
  142. nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
  143. rt_tick_increase();
  144. }
  145. }
  146. static void at91sam926x_pit_reset(void)
  147. {
  148. /* Disable timer and irqs */
  149. at91_sys_write(AT91_PIT_MR, 0);
  150. /* Clear any pending interrupts, wait for PIT to stop counting */
  151. while (PIT_CPIV(at91_sys_read(AT91_PIT_PIVR)) != 0)
  152. ;
  153. /* Start PIT but don't enable IRQ */
  154. //at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
  155. pit_cnt += pit_cycle * PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
  156. at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN
  157. | AT91_PIT_PITIEN);
  158. rt_kprintf("PIT_MR=0x%08x\n", at91_sys_read(AT91_PIT_MR));
  159. }
  160. /*
  161. * Set up both clocksource and clockevent support.
  162. */
  163. static void at91sam926x_pit_init(void)
  164. {
  165. rt_uint32_t pit_rate;
  166. rt_uint32_t bits;
  167. /*
  168. * Use our actual MCK to figure out how many MCK/16 ticks per
  169. * 1/HZ period (instead of a compile-time constant LATCH).
  170. */
  171. pit_rate = clk_get_rate(clk_get("mck")) / 16;
  172. rt_kprintf("pit_rate=%dHZ\n", pit_rate);
  173. pit_cycle = (pit_rate + RT_TICK_PER_SECOND/2) / RT_TICK_PER_SECOND;
  174. /* Initialize and enable the timer */
  175. at91sam926x_pit_reset();
  176. }
  177. /**
  178. * This function will init pit for system ticks
  179. */
  180. void rt_hw_timer_init()
  181. {
  182. at91sam926x_pit_init();
  183. /* install interrupt handler */
  184. rt_hw_interrupt_install(AT91_ID_SYS, rt_timer_handler, RT_NULL);
  185. rt_hw_interrupt_umask(AT91_ID_SYS);
  186. }
  187. void at91_tc1_init()
  188. {
  189. at91_sys_write(AT91_PMC_PCER, 1<<AT91SAM9260_ID_TC0);
  190. writel(AT91_TC_TC0XC0S_NONE | AT91_TC_TC1XC1S_NONE | AT91_TC_TC2XC2S_NONE, AT91SAM9260_BASE_TCB0 + AT91_TC_BMR);
  191. writel(AT91_TC_CLKDIS, AT91SAM9260_BASE_TC0 + AT91_TC_CCR);
  192. writel(AT91_TC_TIMER_CLOCK4, AT91SAM9260_BASE_TC0 + AT91_TC_CMR);
  193. writel(0xffff, AT91SAM9260_BASE_TC0 + AT91_TC_CV);
  194. }
  195. /**
  196. * This function will init at91sam9260 board
  197. */
  198. void rt_hw_board_init()
  199. {
  200. /* initialize the system clock */
  201. rt_hw_clock_init();
  202. /* initialize uart */
  203. rt_hw_uart_init();
  204. /* initialize mmu */
  205. //rt_hw_mmu_init();
  206. /* initialize timer0 */
  207. rt_hw_timer_init();
  208. }
  209. /*@}*/