main.c
来自「Centrality Atlas II development software」· C语言 代码 · 共 387 行
C
387 行
/* * $QNXLicenseC: * Copyright 2007,2008, QNX Software Systems. * * Licensed under the Apache License, Version 2.0 (the "License"). You * may not reproduce, modify or distribute this software except in * compliance with the License. You may obtain a copy of the License * at: http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OF ANY KIND, either express or implied. * * This file may contain contributions from others, either as * contributors under the License or as licensors under other terms. * Please review this entire file for other proprietary rights or license * notices, as well as the QNX Development Suite License Guide at * http://licensing.qnx.com/license-guide/ for other information. * $ *//* * IPL for Centrality Atlas-II development board, with Arm 926 core */#include "ipl.h"#include <hw/inout.h>#include "atlasii.h"#include "nand.h"#define DNLD_ADDR 0xC1000000#define NAND_RESERVED_BLOCK 10#define IO_CLK 50000000#define FREQ_IN 12000000#define UART_BAUD 115200#define UART_DIV 16int bootcs;int updatecs;extern void init_seratlasii(unsigned address, unsigned baud, unsigned clk, unsigned divisor);extern void board_init(void);extern int SelectClock();extern int CheckClkCfg();void Show_LED(int led, int val){ unsigned char ret; switch (val){ case 0: ret=0x40; break; case 1: ret=0x79; break; case 2: ret=0x24; break; case 3: ret=0x30; break; case 4: ret=0x19; break; case 5: ret=0x12; break; case 6: ret=0x02; break; case 7: ret=0x78; break; case 8: ret=0x00; break; case 9: ret=0x18; break; case 10: ret=0x08; break; case 11: ret=0x03; break; case 12: ret=0x46; break; case 13: ret=0x21; break; case 14: ret=0x06; break; case 15: ret=0x0e; break; default: ret=0xff; break; } if(led==0) *(unsigned char *)(EXT_PIO_BASE+0xA00)=ret; else if(led==1) *(unsigned char *)(EXT_PIO_BASE+0xC00)=ret;}void unsigned_divide(unsigned int dividend, unsigned int divisor, unsigned int *quotient, unsigned int *remainder ){ unsigned int t, num_bits; unsigned int q, bit, d=0; int i; *remainder = 0; *quotient = 0; if (divisor == 0) return; if (divisor > dividend) { *remainder = dividend; return; } if (divisor == dividend) { *quotient = 1; return; } num_bits = 32; while (*remainder < divisor) { bit = (dividend & 0x80000000) >> 31; *remainder = (*remainder << 1) | bit; d = dividend; dividend = dividend << 1; num_bits--; } /* The loop, above, always goes one iteration too far. To avoid inserting an "if" statement inside the loop the last iteration is simply reversed. */ dividend = d; *remainder = *remainder >> 1; num_bits++; for (i = 0; i < num_bits; i++) { bit = (dividend & 0x80000000) >> 31; *remainder = (*remainder << 1) | bit; t = *remainder - divisor; q = !((t & 0x80000000) >> 31); dividend = dividend << 1; *quotient = (*quotient << 1) | q; if (q) { *remainder = t; } }} unsigned long atlasii_clock(int OP) { unsigned int dwPll1Clk; unsigned int dwClk; unsigned int dwSysClkSW, dwRat=1; unsigned int dwFd, dwId, dwOd; unsigned int bBp; unsigned int divisor, remainder; dwSysClkSW = PWR_CLK_SWITCH & 0x3; dwClk = PWR_PLL1_CONFIG; bBp = (dwClk >> 11) & 1; if (bBp) { dwPll1Clk = FREQ_IN; } else { dwFd = dwClk & 0x3f; dwId = (dwClk >> 6) & 0xf; dwOd = (dwClk >> 10) & 1; divisor=dwId+1; unsigned_divide( ((3 - (dwOd + 1)) * (dwFd + 2)), divisor, &dwPll1Clk, &remainder); if((remainder<<1)>>divisor) dwPll1Clk++; dwPll1Clk*=FREQ_IN ; } switch (dwSysClkSW) { case 0: dwClk = FREQ_IN; break; case 1: dwClk = dwPll1Clk; break; default: break; } switch(OP) { case 0: //cpu clock dwRat = (PWR_CLK_RATIO ) & 0xf; break; case 1: //sysclock dwRat = (PWR_CLK_RATIO >>8 ) & 0xf; break; case 2: //ioclock dwRat = (PWR_CLK_RATIO>>12 ) & 0xf; break; case 3: //usb clock dwRat = (PWR_CLK_RATIO >>16) & 0xf; break; default: return 0; break; } if ((dwRat > 8) && (dwRat & 0x3)) { dwRat = (dwRat & ~0x3) + 4; } else if ((dwRat > 4) && (dwRat & 0x1)) { dwRat = (dwRat & ~0x1) + 2; } if(OP==3 && dwRat==12) //usb dwRat=16; if(dwRat==0) { return 0; } unsigned_divide(dwClk, dwRat, &dwPll1Clk, &remainder); if((remainder<<1)>dwRat) dwPll1Clk++; return dwPll1Clk;}int main(){ unsigned long image; int i; unsigned clk; bootcs= *(volatile unsigned char*)(EXT_PIO_BASE+0x1A00); bootcs>>=1; updatecs=0; Show_LED(0, 1); Show_LED(1, 1); board_init(); /* initialice serial device, autodetect clock */ clk=atlasii_clock(2); if(clk<0) clk=IO_CLK; init_seratlasii(0, UART_BAUD, clk, UART_DIV); Show_LED(0, 2); Show_LED(1, 2); ser_putstr((unsigned char *)"\n\nQNX Neutrino Initial Program Loader for Centrality ATLAS-II board\n"); if(CheckClkCfg()==0) { clk=atlasii_clock(2); if(clk<0) clk=IO_CLK; init_seratlasii(0, UART_BAUD, clk, UART_DIV); } while (1) { ser_putstr((unsigned char *)"Commands:\n"); ser_putstr((unsigned char *)"\nPress 'D' for serial download, using the 'sendnto' utility\n"); ser_putstr((unsigned char *)"Press 'F' to Boot an OS image from NAND flash\n"); ser_putstr((unsigned char *)"Press 'U' to Copy an OS image to NAND flash\n"); ser_putstr((unsigned char *)"Press 'I' to Update the IPL\n"); ser_putstr((unsigned char *)"Press 'S' to Select Clock\n"); switch (ser_getchar()) { case 'D': case 'd': ser_putstr((unsigned char *)"send image now...\n"); image = DNLD_ADDR; if (image_download_ser(image)) { ser_putstr((unsigned char *)"download failed...\n"); continue; } else ser_putstr((unsigned char *)"download OK...\n"); break; case 'F': case 'f': updatecs=0; image = DNLD_ADDR; ser_putstr((unsigned char *)"reading from NAND flash ........\n"); if(read_image_from_nand(NAND_RESERVED_BLOCK, (unsigned)image)!=0) { ser_putstr((unsigned char *)"read from NAND flash failed...\n"); continue; } break; case 'S': case 's': if(SelectClock()==0) { clk=atlasii_clock(2); if(clk<0) clk=IO_CLK; init_seratlasii(0, UART_BAUD, clk, UART_DIV); } continue; break; case 'U': case 'u': updatecs=0; ser_putstr((unsigned char *)"send image now...\n"); image = DNLD_ADDR; if (image_download_ser(image)) { ser_putstr((unsigned char *)"download failed...\n"); //read all left bytes for(i=0; i<200; i++) ; while(ser_poll()) { ser_getchar(); for(i=0; i<200; i++) ; } continue; } else ser_putstr((unsigned char *)"download OK...\n"); ser_putstr((unsigned char *)"writing to NAND flash ..........\n"); if(upgrade_nand_flash(NAND_RESERVED_BLOCK, (unsigned)image)!=0) ser_putstr((unsigned char *)"writing to NAND flash failed...\n"); else ser_putstr((unsigned char *)"Update IFS OK\n"); //read all left bytes while(ser_poll()) { ser_getchar(); for(i=0; i<100; i++) ; } continue; break; case 'I': case 'i': if(bootcs==0) { ser_putstr((unsigned char *)"\nBooting from on-board NAND flash\n"); ser_putstr((unsigned char *)"Press '1' to update IPL on SM card\n"); ser_putstr((unsigned char *)"Press any other key to update IPL on on-board NAND flash\n"); if(ser_getchar()=='1') updatecs=1; else updatecs=0; } else if(bootcs==7) { ser_putstr((unsigned char *)"\nBooting from SM Card\n"); ser_putstr((unsigned char *)"Press '1' to update IPL on MB NAND flash (CM NAND flash update not supported)\n"); ser_putstr((unsigned char *)"Press any other key to update IPL on SM card\n"); if(ser_getchar()=='1') updatecs=1; else updatecs=0; } else updatecs=0; ser_putstr((unsigned char *)"send the IPL now...\n"); image = DNLD_ADDR; if (image_download_ser(image)) { ser_putstr((unsigned char *)"download failed...\n"); //read all left bytes for(i=0; i<200; i++) ; while(ser_poll()) { ser_getchar(); for(i=0; i<200; i++) ; } continue; } else ser_putstr((unsigned char *)"download OK...\n"); ser_putstr((unsigned char *)"writing to NAND flash ..........\n"); if(upgrade_IPL((unsigned)image)!=0) ser_putstr((unsigned char *)"writing to NAND flash failed...\n"); else ser_putstr((unsigned char *)"Update IPL OK\n"); updatecs=0; //read all left bytes while(ser_poll()) { ser_getchar(); for(i=0; i<100; i++) ; } continue; break; default: continue; } image = image_scan(image, image + 0x200); if (image != 0xffffffff) { ser_putstr((unsigned char *)"found image, calling image setup...\n"); image_setup(image); ser_putstr((unsigned char *)"image_setup OK, calling image start...\n\n"); image_start(image); return 0; } else ser_putstr((unsigned char *)"image_scan failed...\n"); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?