3 static void ConfigClocks(void)
5 // we are using a 16 MHz crystal as the basis for everything
6 // slow clock runs at 32Khz typical regardless of crystal
8 // enable system clock and USB clock
9 PMC_SYS_CLK_ENABLE
= PMC_SYS_CLK_PROCESSOR_CLK
| PMC_SYS_CLK_UDP_CLK
;
11 // enable the clock to the following peripherals
12 PMC_PERIPHERAL_CLK_ENABLE
=
20 // worst case scenario, with 16Mhz xtal startup delay is 14.5ms
21 // with a slow clock running at it worst case (max) frequency of 42khz
22 // max startup delay = (14.5ms*42k)/8 = 76 = 0x4C round up to 0x50
24 // enable main oscillator and set startup delay
25 PMC_MAIN_OSCILLATOR
= PMC_MAIN_OSCILLATOR_ENABLE
|
26 PMC_MAIN_OSCILLATOR_STARTUP_DELAY(0x50);
28 // wait for main oscillator to stabilize
29 while ( !(PMC_INTERRUPT_STATUS
& PMC_MAIN_OSCILLATOR_STABILIZED
) )
32 // minimum PLL clock frequency is 80 MHz in range 00 (96 here so okay)
33 // frequency is crystal * multiplier / divisor = 16Mhz * 12 / 2 = 96Mhz
34 PMC_PLL
= PMC_PLL_DIVISOR(2) | PMC_PLL_COUNT_BEFORE_LOCK(0x50) |
35 PMC_PLL_FREQUENCY_RANGE(0) | PMC_PLL_MULTIPLIER(12) |
36 PMC_PLL_USB_DIVISOR(1);
38 // wait for PLL to lock
39 while ( !(PMC_INTERRUPT_STATUS
& PMC_MAIN_OSCILLATOR_PLL_LOCK
) )
42 // we want a master clock (MCK) to be PLL clock / 2 = 96Mhz / 2 = 48Mhz
43 // as per datasheet, this register must be programmed in two operations
44 // when changing to PLL, program the prescaler first then the source
45 PMC_MASTER_CLK
= PMC_CLK_PRESCALE_DIV_2
;
47 // wait for main clock ready signal
48 while ( !(PMC_INTERRUPT_STATUS
& PMC_MAIN_OSCILLATOR_MCK_READY
) )
51 // set the source to PLL
52 PMC_MASTER_CLK
= PMC_CLK_SELECTION_PLL_CLOCK
| PMC_CLK_PRESCALE_DIV_2
;
54 // wait for main clock ready signal
55 while ( !(PMC_INTERRUPT_STATUS
& PMC_MAIN_OSCILLATOR_MCK_READY
) )
59 static void Fatal(void)
64 void UsbPacketReceived(BYTE
*packet
, int len
)
67 UsbCommand
*c
= (UsbCommand
*)packet
;
70 if(len
!= sizeof(*c
)) {
79 p
= (volatile DWORD
*)0;
80 for(i
= 0; i
< 12; i
++) {
81 p
[i
+c
->ext1
] = c
->d
.asDwords
[i
];
85 case CMD_FINISH_WRITE
:
86 p
= (volatile DWORD
*)0;
87 for(i
= 0; i
< 4; i
++) {
88 p
[i
+60] = c
->d
.asDwords
[i
];
91 MC_FLASH_COMMAND
= MC_FLASH_COMMAND_KEY
|
92 MC_FLASH_COMMAND_PAGEN(c
->ext1
/FLASH_PAGE_SIZE_BYTES
) |
94 while(!(MC_FLASH_STATUS
& MC_FLASH_STATUS_READY
))
98 case CMD_HARDWARE_RESET
:
107 UsbSendPacket(packet
, len
);
110 extern char _osimage_entry
;
114 // First set up all the I/O pins; GPIOs configured directly, other ones
115 // just need to be assigned to the appropriate peripheral.
117 // Kill all the pullups, especially the one on USB D+; leave them for
118 // the unused pins, though.
119 PIO_NO_PULL_UP_ENABLE
= (1 << GPIO_USB_PU
) |
124 (1 << GPIO_FPGA_DIN
) |
125 (1 << GPIO_FPGA_DOUT
) |
126 (1 << GPIO_FPGA_CCLK
) |
127 (1 << GPIO_FPGA_NINIT
) |
128 (1 << GPIO_FPGA_NPROGRAM
) |
129 (1 << GPIO_FPGA_DONE
) |
130 (1 << GPIO_MUXSEL_HIPKD
) |
131 (1 << GPIO_MUXSEL_HIRAW
) |
132 (1 << GPIO_MUXSEL_LOPKD
) |
133 (1 << GPIO_MUXSEL_LORAW
) |
136 // (and add GPIO_FPGA_ON)
137 // These pins are outputs
138 PIO_OUTPUT_ENABLE
= (1 << GPIO_LED_A
) |
144 // PIO controls the following pins
145 PIO_ENABLE
= (1 << GPIO_USB_PU
) |
151 USB_D_PLUS_PULLUP_OFF();
157 // if 512K FLASH part - TODO make some defines :)
158 if ((DBGU_CIDR
| 0xf00) == 0xa00) {
159 MC_FLASH_MODE0
= MC_FLASH_MODE_FLASH_WAIT_STATES(1) |
160 MC_FLASH_MODE_MASTER_CLK_IN_MHZ(0x48);
161 MC_FLASH_MODE1
= MC_FLASH_MODE_FLASH_WAIT_STATES(1) |
162 MC_FLASH_MODE_MASTER_CLK_IN_MHZ(0x48);
164 MC_FLASH_MODE0
= MC_FLASH_MODE_FLASH_WAIT_STATES(0) |
165 MC_FLASH_MODE_MASTER_CLK_IN_MHZ(48);
168 // Initialize all system clocks
182 if(!BUTTON_PRESS()) {
183 USB_D_PLUS_PULLUP_OFF();
186 // jump to Flash address of the osimage entry point (LSBit set for thumb mode)
187 asm("bx %0\n" : : "r" ( ((int)&_osimage_entry
) | 0x1 ) );