mirror of
https://git.code.sf.net/p/newrpl/sources
synced 2024-11-16 19:51:25 +01:00
Used RTC tick counter for low level delays.
Added timeout on NAND operations. Removed tmrsetup() calls from all drivers (no setup needed, added to boot_prime.c)
This commit is contained in:
parent
8a1657f442
commit
341e4f329e
6 changed files with 55 additions and 62 deletions
|
@ -877,13 +877,17 @@ extern void ts_init();
|
||||||
#define PIXELS_PER_WORD 8
|
#define PIXELS_PER_WORD 8
|
||||||
|
|
||||||
// LOW LEVEL TIMER FUNCTIONS FOR HARDWARE SETUP
|
// LOW LEVEL TIMER FUNCTIONS FOR HARDWARE SETUP
|
||||||
void __tmr_setupdelay();
|
|
||||||
// Do a single delay 100 usec
|
// Do a single delay 100 usec
|
||||||
void __tmr_delay100us();
|
void __tmr_delay100us();
|
||||||
// Do a single delay 10 msec
|
// Do a single delay 10 msec
|
||||||
void __tmr_delay10ms();
|
void __tmr_delay10ms();
|
||||||
// Do a single delay 20 msec
|
// Do a single delay 20 msec
|
||||||
void __tmr_delay20ms();
|
void __tmr_delay20ms();
|
||||||
|
// Prepare for an open loop timeout
|
||||||
|
void __tmr_setuptimeoutms(int delayms,unsigned int *start,unsigned int *end);
|
||||||
|
// Check if clock timed out or not
|
||||||
|
int __tmr_timedout(unsigned int start,unsigned int end);
|
||||||
|
|
||||||
|
|
||||||
// OTHER ADDITIONAL HARDWARE FUNCTIONS
|
// OTHER ADDITIONAL HARDWARE FUNCTIONS
|
||||||
|
|
|
@ -225,9 +225,6 @@ void setup_hardware()
|
||||||
|
|
||||||
lcd_off();
|
lcd_off();
|
||||||
|
|
||||||
// Playing it safe for testing -
|
|
||||||
NANDWriteProtect();
|
|
||||||
|
|
||||||
*PWRCFG |= 0x20000; // Enable Wait for Interrupt mode
|
*PWRCFG |= 0x20000; // Enable Wait for Interrupt mode
|
||||||
|
|
||||||
// Disable SoC blocks that we don't use
|
// Disable SoC blocks that we don't use
|
||||||
|
@ -236,6 +233,10 @@ void setup_hardware()
|
||||||
*PCLKCON &= ~0x8034e; // Disable PCLK going to SPI_HS0, AC97, I2S0, and PCM audio interfaces
|
*PCLKCON &= ~0x8034e; // Disable PCLK going to SPI_HS0, AC97, I2S0, and PCM audio interfaces
|
||||||
*SCLKCON &= ~0xa05242; // Disable special clocks to HSMMC0, I2S0, PCM0, SPI, USB Host
|
*SCLKCON &= ~0xa05242; // Disable special clocks to HSMMC0, I2S0, PCM0, SPI, USB Host
|
||||||
|
|
||||||
|
*RTCCON = 0x10; // RTC clock set to defaults, plus tick counter at 1/32768 second
|
||||||
|
*TICNT0 = 0x80; // Enable tick interrupt, counter to zero (make TICKCNT tick at 32.768 kHz)
|
||||||
|
*TICNT1 = 0; // Counter to zero
|
||||||
|
*TICNT2 = 0; // Counter to zero
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -339,8 +339,6 @@ int lcd_setmode(int mode, unsigned int *physbuf)
|
||||||
void lcd_poweron()
|
void lcd_poweron()
|
||||||
{
|
{
|
||||||
|
|
||||||
__tmr_setupdelay(); // SETUP TIMERS TO GET ACCURATE DELAYS
|
|
||||||
|
|
||||||
// Setup GPIO
|
// Setup GPIO
|
||||||
|
|
||||||
*GPCCON = (*GPCCON&0xfc00) | 0xaaaa02aa; // ALL GPC PINS SET FOR LCD FUNCTION
|
*GPCCON = (*GPCCON&0xfc00) | 0xaaaa02aa; // ALL GPC PINS SET FOR LCD FUNCTION
|
||||||
|
|
|
@ -104,7 +104,12 @@ static inline void NANDEnableChipSelect(void)
|
||||||
|
|
||||||
static inline void NANDWaitReady(void)
|
static inline void NANDWaitReady(void)
|
||||||
{
|
{
|
||||||
while ((*NFSTAT & NFSTAT_RnB_TransDetect) == 0);
|
unsigned int start,end;
|
||||||
|
// Flash datasheet lists Block Erase as the longest operation with a max. 10 ms
|
||||||
|
// So in 12 ms it MUST have finished or there was an error.
|
||||||
|
__tmr_setuptimeoutms(12,&start,&end);
|
||||||
|
|
||||||
|
while ((*NFSTAT & NFSTAT_RnB_TransDetect) == 0) if(__tmr_timedout(start,end)) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void NANDClearReady(void)
|
static inline void NANDClearReady(void)
|
||||||
|
@ -511,12 +516,17 @@ int NANDBlockErase(uint32_t nand_address)
|
||||||
|
|
||||||
*NFCMMD = NAND_CMD_BLOCK_ERASE2nd;
|
*NFCMMD = NAND_CMD_BLOCK_ERASE2nd;
|
||||||
|
|
||||||
|
red_led_on();
|
||||||
|
|
||||||
NANDWaitReady();
|
NANDWaitReady();
|
||||||
|
|
||||||
|
blue_led_on();
|
||||||
|
|
||||||
// NOTE BL2 does not check NFSTAT_IllegalAccess here
|
// NOTE BL2 does not check NFSTAT_IllegalAccess here
|
||||||
if (NANDCheckWrite() == 0) {
|
if (NANDCheckWrite() == 0) {
|
||||||
retval = 0;
|
retval = 0;
|
||||||
}
|
}
|
||||||
|
green_led_on();
|
||||||
|
|
||||||
NANDDisableChipSelect();
|
NANDDisableChipSelect();
|
||||||
|
|
||||||
|
@ -592,7 +602,7 @@ int NANDWrite(uint32_t virtual_address, uint8_t const *source_address, unsigned
|
||||||
|
|
||||||
uint32_t nand_write_address = NANDTranslateVirtualAddress(block_start);
|
uint32_t nand_write_address = NANDTranslateVirtualAddress(block_start);
|
||||||
|
|
||||||
if (offset != 0 || num_bytes < NAND_BLOCK_SIZE) {
|
if ( (offset != 0) || (num_bytes < NAND_BLOCK_SIZE)) {
|
||||||
if (NANDReadBlock(nand_write_address, nand_buffer) == 0) {
|
if (NANDReadBlock(nand_write_address, nand_buffer) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -455,74 +455,57 @@ void tmr_eventkill(HEVENT event)
|
||||||
// INDEPENDENT TIMING FUNCTIONS THAT DON'T DEPEND ON INTERRUPTS OR THE TIMER MODULE TO BE INITIALIZED TO WORK
|
// INDEPENDENT TIMING FUNCTIONS THAT DON'T DEPEND ON INTERRUPTS OR THE TIMER MODULE TO BE INITIALIZED TO WORK
|
||||||
// USED MAINLY FOR HARDWARE SETUP THAT NEEDS ACCURATE TIMING
|
// USED MAINLY FOR HARDWARE SETUP THAT NEEDS ACCURATE TIMING
|
||||||
|
|
||||||
// Setup TIMER 4 for delays in LCD chip communications
|
// Use RTC tick counter for delays in LCD chip communications
|
||||||
#define __LLTIMER_FREQ 100000 // 100 kHz tick
|
#define __LLTIMER_FREQ 32768 // 32.768 kHz tick
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void __tmr_setupdelay()
|
|
||||||
{
|
|
||||||
unsigned int pclk = __cpu_getPCLK();
|
|
||||||
|
|
||||||
unsigned int divider, prescaler;
|
|
||||||
|
|
||||||
prescaler = (pclk << 3) / __LLTIMER_FREQ;
|
|
||||||
divider = 1;
|
|
||||||
|
|
||||||
while(prescaler > (1 << (11 + divider))) {
|
|
||||||
divider++;
|
|
||||||
}
|
|
||||||
|
|
||||||
prescaler += (1 << (2 + divider));
|
|
||||||
prescaler >>= divider + 3;
|
|
||||||
|
|
||||||
//if(divider>4) PCLK TOO HIGH TO ACHIEVE TIMER FREQUENCY, USE HIGHER MULTIPLE
|
|
||||||
if(divider > 4)
|
|
||||||
divider = 4;
|
|
||||||
|
|
||||||
// SET PRESCALER VALUES FOR TIMERS 2,3 AND 4
|
|
||||||
*TCFG0 = (*TCFG0 & (~0xFF00)) | ((prescaler - 1)<<8);
|
|
||||||
*TCFG1 =
|
|
||||||
(*TCFG1 & (~0xf0000)) | ((divider - 1) << 16);
|
|
||||||
|
|
||||||
// SET COUNT VALUES TO MAXIMUM
|
|
||||||
*TCNTB4 = 0xffff;
|
|
||||||
|
|
||||||
// Make sure no interrupts are fired by timer4
|
|
||||||
*INTMSK1 |= 0x4000;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do a single delay 100 usec
|
// Do a single delay 100 usec
|
||||||
void __tmr_delay100us()
|
void __tmr_delay100us()
|
||||||
{
|
{
|
||||||
*TCNTB4= (__LLTIMER_FREQ * 100) / 1000000;
|
unsigned int start,end;
|
||||||
*TCON= (*TCON&~0x700000) | 0x200000; // Update the count
|
start = *TICKCNT;
|
||||||
*TCON= (*TCON&~0x700000) | 0x100000; // Start the timer, single shot
|
end = *TICKCNT + (__LLTIMER_FREQ * 100) / 1000000;
|
||||||
|
|
||||||
while((*TCNTO4&0xffff)!=0); // And wait for the timer to count to zero
|
if(end<start) while(*TICKCNT>=start); // Wait for the counter to wrap
|
||||||
|
|
||||||
|
while(*TICKCNT<end); // And wait for the timer count to reach the end
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do a single delay 100 usec
|
// Do a single delay 10 msec
|
||||||
void __tmr_delay10ms()
|
void __tmr_delay10ms()
|
||||||
{
|
{
|
||||||
*TCNTB4= (__LLTIMER_FREQ * 10) / 1000;
|
unsigned int start,end;
|
||||||
*TCON= (*TCON&~0x700000) | 0x200000; // Update the count
|
start = *TICKCNT;
|
||||||
*TCON= (*TCON&~0x700000) | 0x100000; // Start the timer, single shot
|
end = *TICKCNT + (__LLTIMER_FREQ * 10) / 1000;
|
||||||
|
|
||||||
while((*TCNTO4&0xffff)!=0); // And wait for the timer to count to zero
|
if(end<start) while(*TICKCNT>=start); // Wait for the counter to wrap
|
||||||
|
|
||||||
|
while(*TICKCNT<end); // And wait for the timer count to reach the end
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do a single delay 100 usec
|
// Do a single delay 100 usec
|
||||||
void __tmr_delay20ms()
|
void __tmr_delay20ms()
|
||||||
{
|
{
|
||||||
*TCNTB4= (__LLTIMER_FREQ * 20) / 1000;
|
unsigned int start,end;
|
||||||
*TCON= (*TCON&~0x700000) | 0x200000; // Update the count
|
start = *TICKCNT;
|
||||||
*TCON= (*TCON&~0x700000) | 0x100000; // Start the timer, single shot
|
end = *TICKCNT + (__LLTIMER_FREQ * 20) / 1000;
|
||||||
|
|
||||||
while((*TCNTO4&0xffff)!=0); // And wait for the timer to count to zero
|
if(end<start) while(*TICKCNT>=start); // Wait for the counter to wrap
|
||||||
|
|
||||||
|
while(*TICKCNT<end); // And wait for the timer count to reach the end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prepare for an open loop timeout
|
||||||
|
void __tmr_setuptimeoutms(int delayms,unsigned int *start,unsigned int *end)
|
||||||
|
{
|
||||||
|
*start = *TICKCNT;
|
||||||
|
*end = *TICKCNT + (__LLTIMER_FREQ * delayms) / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if clock timed out or not
|
||||||
|
int __tmr_timedout(unsigned int start,unsigned int end)
|
||||||
|
{
|
||||||
|
if(end<start) if(*TICKCNT>=start) return 0; // Wait for the counter to wrap
|
||||||
|
|
||||||
|
if(*TICKCNT>=end) return 1; // And wait for the timer count to reach the end
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -378,9 +378,6 @@ static void usb_reset_full(void)
|
||||||
void usb_hwsetup()
|
void usb_hwsetup()
|
||||||
{
|
{
|
||||||
|
|
||||||
__tmr_setupdelay(); // SETUP SOME TIMERS TO GET ACCURATE DELAYS
|
|
||||||
|
|
||||||
|
|
||||||
// POWER OFF FIRST TO CAUSE A FULL RESET OF THE USB BLOCK
|
// POWER OFF FIRST TO CAUSE A FULL RESET OF THE USB BLOCK
|
||||||
|
|
||||||
*UCLKCON &= ~0x80000000; // SIGNAL THE HOST A DEVICE HAS BEEN DISCONNECTED
|
*UCLKCON &= ~0x80000000; // SIGNAL THE HOST A DEVICE HAS BEEN DISCONNECTED
|
||||||
|
|
Loading…
Reference in a new issue