oehansens i2c and spi extensions
This commit is contained in:
309
i2cspi_BaS_gcc/sources/BaS.c
Normal file
309
i2cspi_BaS_gcc/sources/BaS.c
Normal file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* BaS
|
||||
*
|
||||
* This file is part of BaS_gcc.
|
||||
*
|
||||
* BaS_gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BaS_gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright 2010 - 2012 F. Aschwanden
|
||||
* Copyright 2011 - 2012 V. Riviere
|
||||
* Copyright 2012 M. Froeschle
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "MCF5475.h"
|
||||
#include "MCF5475_SLT.h"
|
||||
#include "startcf.h"
|
||||
#include "cache.h"
|
||||
#include "bas_printf.h"
|
||||
#include "bas_types.h"
|
||||
#include "sd_card.h"
|
||||
#include "wait.h"
|
||||
|
||||
#include "diskio.h"
|
||||
#include "ff.h"
|
||||
#include "s19reader.h"
|
||||
|
||||
/* imported routines */
|
||||
extern int mmu_init();
|
||||
extern int vec_init();
|
||||
|
||||
/* Symbols from the linker script */
|
||||
extern uint8_t _STRAM_END[];
|
||||
#define STRAM_END ((uint32_t)_STRAM_END)
|
||||
extern uint8_t _TOS[];
|
||||
#define TOS ((uint32_t)_TOS) /* final TOS location */
|
||||
extern uint8_t _FASTRAM_END[];
|
||||
#define FASTRAM_END ((uint32_t)_FASTRAM_END)
|
||||
extern uint8_t _EMUTOS[];
|
||||
#define EMUTOS ((uint32_t)_EMUTOS) /* where EmuTOS is stored in flash */
|
||||
extern uint8_t _EMUTOS_SIZE[];
|
||||
#define EMUTOS_SIZE ((uint32_t)_EMUTOS_SIZE) /* size of EmuTOS, in bytes */
|
||||
|
||||
/*
|
||||
* check if it is possible to transfer data to PIC
|
||||
*/
|
||||
static inline bool pic_txready(void)
|
||||
{
|
||||
if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_TXRDY)
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* check if it is possible to receive data from PIC
|
||||
*/
|
||||
static inline bool pic_rxready(void)
|
||||
{
|
||||
if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_RXRDY)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void write_pic_byte(uint8_t value)
|
||||
{
|
||||
/* Wait until the transmitter is ready or 1000us are passed */
|
||||
waitfor(1000, pic_txready);
|
||||
|
||||
/* Transmit the byte */
|
||||
*(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit
|
||||
}
|
||||
|
||||
uint8_t read_pic_byte(void)
|
||||
{
|
||||
/* Wait until a byte has been received or 1000us are passed */
|
||||
waitfor(1000, pic_rxready);
|
||||
|
||||
/* Return the received byte */
|
||||
return *(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT); // Really 8-bit
|
||||
}
|
||||
|
||||
void pic_init(void)
|
||||
{
|
||||
char answer[4] = "OLD";
|
||||
|
||||
xprintf("initialize the PIC: ");
|
||||
|
||||
/* Send the PIC initialization string */
|
||||
write_pic_byte('A');
|
||||
write_pic_byte('C');
|
||||
write_pic_byte('P');
|
||||
write_pic_byte('F');
|
||||
|
||||
/* Read the 3-char answer string. Should be "OK!". */
|
||||
answer[0] = read_pic_byte();
|
||||
answer[1] = read_pic_byte();
|
||||
answer[2] = read_pic_byte();
|
||||
answer[3] = '\0';
|
||||
|
||||
if (answer[0] != 'O' || answer[1] != 'K' || answer[2] != '!')
|
||||
{
|
||||
xprintf("PIC initialization failed. Already initialized?\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("%s\r\n", answer);
|
||||
}
|
||||
}
|
||||
|
||||
void nvram_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
xprintf("Restore the NVRAM data: ");
|
||||
|
||||
/* Request for NVRAM backup data */
|
||||
write_pic_byte(0x01);
|
||||
|
||||
/* Check answer type */
|
||||
if (read_pic_byte() != 0x81)
|
||||
{
|
||||
// FIXME: PIC protocol error
|
||||
xprintf("FAILED\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Restore the NVRAM backup to the FPGA */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
uint8_t data = read_pic_byte();
|
||||
*(volatile uint8_t*)0xffff8961 = i;
|
||||
*(volatile uint8_t*)0xffff8963 = data;
|
||||
}
|
||||
|
||||
xprintf("finished\r\n");
|
||||
}
|
||||
|
||||
void enable_coldfire_interrupts()
|
||||
{
|
||||
xprintf("enable interrupts: ");
|
||||
* (volatile uint32_t *) 0xf0010004 = 0L; /* disable all interrupts */
|
||||
MCF_EPORT_EPPAR = 0xaaa8; /* all interrupts on falling edge */
|
||||
|
||||
MCF_GPT0_GMS = MCF_GPT_GMS_ICT(1) | /* timer 0 on, video change capture on rising edge */
|
||||
MCF_GPT_GMS_IEN |
|
||||
MCF_GPT_GMS_TMS(1);
|
||||
MCF_INTC_ICR62 = 0x3f;
|
||||
|
||||
* (volatile uint8_t *) 0xf0010004 = 0xfe; /* enable int 1-7 */
|
||||
MCF_EPORT_EPIER = 0xfe; /* int 1-7 on */
|
||||
MCF_EPORT_EPFR = 0xff; /* clear all pending interrupts */
|
||||
MCF_INTC_IMRL = 0xffffff00; /* int 1-7 on */
|
||||
MCF_INTC_IMRH = 0xbffffffe; /* psc3 and timer 0 int on */
|
||||
|
||||
xprintf("finished\r\n");
|
||||
}
|
||||
|
||||
void disable_coldfire_interrupts()
|
||||
{
|
||||
* (volatile uint32_t *) 0xf0010004 = 0L; /* disable all interrupts */
|
||||
}
|
||||
|
||||
void BaS(void)
|
||||
{
|
||||
uint8_t *src;
|
||||
uint8_t *dst = (uint8_t *)TOS;
|
||||
uint32_t *adr;
|
||||
|
||||
pic_init();
|
||||
nvram_init();
|
||||
|
||||
xprintf("copy EmuTOS: ");
|
||||
|
||||
/* copy EMUTOS */
|
||||
src = (uint8_t *) EMUTOS;
|
||||
while (src < (uint8_t *)(EMUTOS + EMUTOS_SIZE))
|
||||
{
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
xprintf("finished\r\n");
|
||||
|
||||
/* we have copied a code area, so flush the caches */
|
||||
flush_and_invalidate_caches();
|
||||
|
||||
xprintf("initialize MMU: ");
|
||||
mmu_init();
|
||||
xprintf("finished\r\n");
|
||||
|
||||
xprintf("initialize exception vector table: ");
|
||||
vec_init();
|
||||
xprintf("finished\r\n");
|
||||
|
||||
MCF_MMU_MMUCR = MCF_MMU_MMUCR_EN; /* MMU on */
|
||||
|
||||
xprintf("IDE reset: ");
|
||||
/* IDE reset */
|
||||
* (volatile uint8_t *) (0xffff8802 - 2) = 14;
|
||||
* (volatile uint8_t *) (0xffff8802 - 0) = 0x80;
|
||||
wait(1);
|
||||
|
||||
* (volatile uint8_t *) (0xffff8802 - 0) = 0;
|
||||
|
||||
xprintf("finished\r\n");
|
||||
xprintf("enable video: ");
|
||||
/*
|
||||
* video setup (25MHz)
|
||||
*/
|
||||
* (volatile uint32_t *) (0xf0000410 + 0) = 0x032002ba; /* horizontal 640x480 */
|
||||
* (volatile uint32_t *) (0xf0000410 + 4) = 0x020c020a; /* vertical 640x480 */
|
||||
* (volatile uint32_t *) (0xf0000410 + 8) = 0x0190015d; /* horizontal 320x240 */
|
||||
* (volatile uint32_t *) (0xf0000410 + 12) = 0x020C020A; /* vertical 320x230 */
|
||||
|
||||
#ifdef _NOT_USED_
|
||||
// 32MHz
|
||||
move.l #0x037002ba,(a0)+ // horizontal 640x480
|
||||
move.l #0x020d020a,(a0)+ // vertikal 640x480
|
||||
move.l #0x02A001e0,(a0)+ // horizontal 320x240
|
||||
move.l #0x05a00160,(a0)+ // vertikal 320x240
|
||||
#endif /* _NOT_USED_ */
|
||||
|
||||
/* fifo on, refresh on, ddrcs and cke on, video dac on */
|
||||
* (volatile uint32_t *) (0xf0000410 - 0x20) = 0x01070002;
|
||||
|
||||
xprintf("finished\r\n");
|
||||
|
||||
sd_card_init();
|
||||
|
||||
/*
|
||||
* memory setup
|
||||
*/
|
||||
for (adr = (uint32_t *) 0x400L; adr < (uint32_t *) 0x800L; ) {
|
||||
*adr++ = 0x0L;
|
||||
*adr++ = 0x0L;
|
||||
*adr++ = 0x0L;
|
||||
*adr++ = 0x0L;
|
||||
}
|
||||
|
||||
* (volatile uint8_t *) 0xffff8007 = 0x48; /* FIXME: what's that ? */
|
||||
|
||||
/* ST RAM */
|
||||
|
||||
* (uint32_t *) 0x42e = STRAM_END; /* phystop TOS system variable */
|
||||
* (uint32_t *) 0x420 = 0x752019f3; /* memvalid TOS system variable */
|
||||
* (uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */
|
||||
* (uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */
|
||||
|
||||
/* TT-RAM */
|
||||
|
||||
* (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */
|
||||
* (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */
|
||||
|
||||
#define NOP() __asm__ __volatile__("nop\n\t" : : : "memory")
|
||||
|
||||
xprintf("init ACIA: ");
|
||||
/* init ACIA */
|
||||
* (uint8_t *) 0xfffffc00 = 3;
|
||||
NOP();
|
||||
|
||||
* (uint8_t *) 0xfffffc04 = 3;
|
||||
NOP();
|
||||
|
||||
* (uint8_t *) 0xfffffc00 = 0x96;
|
||||
NOP();
|
||||
|
||||
* (uint8_t *) 0xfffffa0f = -1;
|
||||
NOP();
|
||||
|
||||
* (uint8_t *) 0xfffffa11 = -1;
|
||||
NOP();
|
||||
|
||||
xprintf("finished\r\n");
|
||||
|
||||
/* Test for pseudo-supervisor mode: DIP switch #6 down */
|
||||
if (DIP_SWITCH & (1 << 7)) {
|
||||
/* In this mode, the OS actually runs in user mode
|
||||
* and all the supervisor instructions are emulated. */
|
||||
__asm__ __volatile__("move.w #0x0700,sr \n\t" : : : "memory");
|
||||
}
|
||||
|
||||
srec_execute("BASFLASH.S19");
|
||||
|
||||
/* Jump into the OS */
|
||||
typedef void void_func(void);
|
||||
typedef struct {
|
||||
void *initial_sp;
|
||||
void_func *initial_pc;
|
||||
} ROM_HEADER;
|
||||
|
||||
xprintf("Call OS. BaS initialization finished...\r\n");
|
||||
enable_coldfire_interrupts();
|
||||
|
||||
ROM_HEADER* os_header = (ROM_HEADER*)TOS;
|
||||
os_header->initial_pc();
|
||||
}
|
||||
366
i2cspi_BaS_gcc/sources/bas_printf.c
Normal file
366
i2cspi_BaS_gcc/sources/bas_printf.c
Normal file
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* tc.printf.c: A public-domain, minimal printf/sprintf routine that prints
|
||||
* through the putchar() routine. Feel free to use for
|
||||
* anything... -- 7/17/87 Paul Placeway
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "MCF5475.h"
|
||||
#include "bas_printf.h"
|
||||
#include "bas_string.h"
|
||||
|
||||
/*
|
||||
* Lexical definitions.
|
||||
*
|
||||
* All lexical space is allocated dynamically.
|
||||
* The eighth/sixteenth bit of characters is used to prevent recognition,
|
||||
* and eventually stripped.
|
||||
*/
|
||||
#define META 0200
|
||||
#define ASCII 0177
|
||||
#define QUOTE ((char) 0200) /* Eighth char bit used for 'ing */
|
||||
#define TRIM 0177 /* Mask to strip quote bit */
|
||||
#define UNDER 0000000 /* No extra bits to do both */
|
||||
#define BOLD 0000000 /* Bold flag */
|
||||
#define STANDOUT META /* Standout flag */
|
||||
#define LITERAL 0000000 /* Literal character flag */
|
||||
#define ATTRIBUTES 0200 /* The bits used for attributes */
|
||||
#define CHAR 0000177 /* Mask to mask out the character */
|
||||
|
||||
#define INF 32766 /* should be bigger than any field to print */
|
||||
|
||||
static char snil[] = "(nil)";
|
||||
|
||||
static void xputchar(int c)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
".extern printf_helper\n\t"
|
||||
"move.b %0,d0\n\t"
|
||||
"bsr printf_helper\n\t"
|
||||
/* output */:
|
||||
/* input */: "r" (c)
|
||||
/* clobber */: "d0","d2","a0","memory"
|
||||
);
|
||||
}
|
||||
|
||||
static void doprnt(void (*addchar)(int), const char *sfmt, va_list ap)
|
||||
{
|
||||
char buf[128]; /* FIXME: this gets allocated in BSS which is not reachable in -mpcrel code */
|
||||
char *bp;
|
||||
const char *f;
|
||||
long l;
|
||||
unsigned long u;
|
||||
int i;
|
||||
int fmt;
|
||||
unsigned char pad = ' ';
|
||||
int flush_left = 0;
|
||||
int f_width = 0;
|
||||
int prec = INF;
|
||||
int hash = 0;
|
||||
int do_long = 0;
|
||||
int sign = 0;
|
||||
int attributes = 0;
|
||||
|
||||
f = sfmt;
|
||||
for (; *f; f++)
|
||||
{
|
||||
if (*f != '%')
|
||||
{
|
||||
/* then just out the char */
|
||||
(*addchar)((int) (((unsigned char) *f) | attributes));
|
||||
}
|
||||
else
|
||||
{
|
||||
f++; /* skip the % */
|
||||
|
||||
if (*f == '-')
|
||||
{ /* minus: flush left */
|
||||
flush_left = 1;
|
||||
f++;
|
||||
}
|
||||
|
||||
if (*f == '0' || *f == '.')
|
||||
{
|
||||
/* padding with 0 rather than blank */
|
||||
pad = '0';
|
||||
f++;
|
||||
}
|
||||
if (*f == '*')
|
||||
{
|
||||
/* field width */
|
||||
f_width = va_arg(ap, int);
|
||||
f++;
|
||||
}
|
||||
else if (isdigit((unsigned char)*f))
|
||||
{
|
||||
f_width = atoi(f);
|
||||
while (isdigit((unsigned char)*f))
|
||||
f++; /* skip the digits */
|
||||
}
|
||||
|
||||
if (*f == '.')
|
||||
{ /* precision */
|
||||
f++;
|
||||
if (*f == '*')
|
||||
{
|
||||
prec = va_arg(ap, int);
|
||||
f++;
|
||||
}
|
||||
else if (isdigit((unsigned char)*f))
|
||||
{
|
||||
prec = atoi(f);
|
||||
while (isdigit((unsigned char)*f))
|
||||
f++; /* skip the digits */
|
||||
}
|
||||
}
|
||||
|
||||
if (*f == '#')
|
||||
{ /* alternate form */
|
||||
hash = 1;
|
||||
f++;
|
||||
}
|
||||
|
||||
if (*f == 'l')
|
||||
{ /* long format */
|
||||
do_long++;
|
||||
f++;
|
||||
if (*f == 'l')
|
||||
{
|
||||
do_long++;
|
||||
f++;
|
||||
}
|
||||
}
|
||||
|
||||
fmt = (unsigned char) *f;
|
||||
if (fmt != 'S' && fmt != 'Q' && isupper(fmt))
|
||||
{
|
||||
do_long = 1;
|
||||
fmt = tolower(fmt);
|
||||
}
|
||||
bp = buf;
|
||||
switch (fmt)
|
||||
{ /* do the format */
|
||||
case 'd':
|
||||
switch (do_long)
|
||||
{
|
||||
case 0:
|
||||
l = (long) (va_arg(ap, int));
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
l = va_arg(ap, long);
|
||||
break;
|
||||
}
|
||||
|
||||
if (l < 0)
|
||||
{
|
||||
sign = 1;
|
||||
l = -l;
|
||||
}
|
||||
do
|
||||
{
|
||||
*bp++ = (char) (l % 10) + '0';
|
||||
} while ((l /= 10) > 0);
|
||||
if (sign)
|
||||
*bp++ = '-';
|
||||
f_width = f_width - (int) (bp - buf);
|
||||
if (!flush_left)
|
||||
while (f_width-- > 0)
|
||||
(*addchar)((int) (pad | attributes));
|
||||
for (bp--; bp >= buf; bp--)
|
||||
(*addchar)((int) (((unsigned char) *bp) | attributes));
|
||||
if (flush_left)
|
||||
while (f_width-- > 0)
|
||||
(*addchar)((int) (' ' | attributes));
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
do_long = 1;
|
||||
hash = 1;
|
||||
fmt = 'x';
|
||||
/* no break */
|
||||
case 'o':
|
||||
case 'x':
|
||||
case 'u':
|
||||
switch (do_long)
|
||||
{
|
||||
case 0:
|
||||
u = (unsigned long) (va_arg(ap, unsigned int));
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
u = va_arg(ap, unsigned long);
|
||||
break;
|
||||
}
|
||||
if (fmt == 'u')
|
||||
{ /* unsigned decimal */
|
||||
do
|
||||
{
|
||||
*bp++ = (char) (u % 10) + '0';
|
||||
} while ((u /= 10) > 0);
|
||||
}
|
||||
else if (fmt == 'o')
|
||||
{ /* octal */
|
||||
do
|
||||
{
|
||||
*bp++ = (char) (u % 8) + '0';
|
||||
} while ((u /= 8) > 0);
|
||||
if (hash)
|
||||
*bp++ = '0';
|
||||
}
|
||||
else if (fmt == 'x')
|
||||
{ /* hex */
|
||||
do
|
||||
{
|
||||
i = (int) (u % 16);
|
||||
if (i < 10)
|
||||
*bp++ = i + '0';
|
||||
else
|
||||
*bp++ = i - 10 + 'a';
|
||||
} while ((u /= 16) > 0);
|
||||
if (hash)
|
||||
{
|
||||
*bp++ = 'x';
|
||||
*bp++ = '0';
|
||||
}
|
||||
}
|
||||
i = f_width - (int) (bp - buf);
|
||||
if (!flush_left)
|
||||
while (i-- > 0)
|
||||
(*addchar)((int) (pad | attributes));
|
||||
for (bp--; bp >= buf; bp--)
|
||||
(*addchar)((int) (((unsigned char) *bp) | attributes));
|
||||
if (flush_left)
|
||||
while (i-- > 0)
|
||||
(*addchar)((int) (' ' | attributes));
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
i = va_arg(ap, int);
|
||||
(*addchar)((int) (i | attributes));
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
case 'Q':
|
||||
case 's':
|
||||
case 'q':
|
||||
bp = va_arg(ap, char *);
|
||||
if (!bp)
|
||||
bp = snil;
|
||||
f_width = f_width - strlen((char *) bp);
|
||||
if (!flush_left)
|
||||
while (f_width-- > 0)
|
||||
(*addchar)((int) (pad | attributes));
|
||||
for (i = 0; *bp && i < prec; i++)
|
||||
{
|
||||
if (fmt == 'q' && (*bp & QUOTE))
|
||||
(*addchar)((int) ('\\' | attributes));
|
||||
(*addchar)(
|
||||
(int) (((unsigned char) *bp & TRIM) | attributes));
|
||||
bp++;
|
||||
}
|
||||
if (flush_left)
|
||||
while (f_width-- > 0)
|
||||
(*addchar)((int) (' ' | attributes));
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
attributes = va_arg(ap, int);
|
||||
break;
|
||||
|
||||
case '%':
|
||||
(*addchar)((int) ('%' | attributes));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
|
||||
sign = 0;
|
||||
pad = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *xstring, *xestring;
|
||||
|
||||
static void xaddchar(int c)
|
||||
{
|
||||
if (xestring == xstring)
|
||||
*xstring = '\0';
|
||||
else
|
||||
*xstring++ = (char) c;
|
||||
}
|
||||
|
||||
void xsnprintf(char *str, size_t size, const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
|
||||
xstring = str;
|
||||
xestring = str + size - 1;
|
||||
doprnt(xaddchar, fmt, va);
|
||||
va_end(va);
|
||||
*xstring++ = '\0';
|
||||
}
|
||||
|
||||
void xprintf(const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
doprnt(xputchar, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void xvprintf(const char *fmt, va_list va)
|
||||
{
|
||||
doprnt(xputchar, fmt, va);
|
||||
}
|
||||
|
||||
void xvsnprintf(char *str, size_t size, const char *fmt, va_list va)
|
||||
{
|
||||
xstring = str;
|
||||
xestring = str + size - 1;
|
||||
doprnt(xaddchar, fmt, va);
|
||||
*xstring++ = '\0';
|
||||
}
|
||||
|
||||
|
||||
void display_progress()
|
||||
{
|
||||
static int _progress_index;
|
||||
char progress_char[] = "|/-\\";
|
||||
|
||||
xputchar(progress_char[_progress_index++ % strlen(progress_char)]);
|
||||
xputchar('\r');
|
||||
}
|
||||
|
||||
74
i2cspi_BaS_gcc/sources/bas_string.c
Normal file
74
i2cspi_BaS_gcc/sources/bas_string.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* bas_string.c
|
||||
*
|
||||
* Created on: 26.02.2013
|
||||
* Author: mfro
|
||||
*/
|
||||
|
||||
#include "bas_string.h"
|
||||
|
||||
int strncmp(const char *s1, const char *s2, int max)
|
||||
{
|
||||
int i;
|
||||
int cmp;
|
||||
|
||||
for (i = 0; i < max && *s1++ && *s2++; i++);
|
||||
{
|
||||
cmp = (*s1 - *s2);
|
||||
if (cmp != 0) return cmp;
|
||||
}
|
||||
return cmp;
|
||||
}
|
||||
|
||||
char *strcpy(char *dst, const char *src)
|
||||
{
|
||||
char *ptr = dst;
|
||||
|
||||
while ((*dst++ = *src++) != '\0');
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int atoi(const char *c)
|
||||
{
|
||||
int value = 0;
|
||||
while (isdigit(*c))
|
||||
{
|
||||
value *= 10;
|
||||
value += (int) (*c - '0');
|
||||
c++;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
const char *start = s;
|
||||
|
||||
while (*s++);
|
||||
|
||||
return s - start - 1;
|
||||
}
|
||||
|
||||
|
||||
char *strcat(char *dst, const char *src)
|
||||
{
|
||||
char *ret = dst;
|
||||
dst = &dst[strlen(dst)];
|
||||
while ((*dst++ = *src++) != '\0');
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *strncat(char *dst, const char *src, int max)
|
||||
{
|
||||
int i;
|
||||
char *ret = dst;
|
||||
|
||||
dst = &dst[strlen(dst)];
|
||||
for (i = 0; i < max && *src; i++)
|
||||
{
|
||||
*dst++ = *src++;
|
||||
}
|
||||
*dst++ = '\0';
|
||||
|
||||
return ret;
|
||||
}
|
||||
420
i2cspi_BaS_gcc/sources/basflash.c
Normal file
420
i2cspi_BaS_gcc/sources/basflash.c
Normal file
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
* basflash.c
|
||||
*
|
||||
* Created on: 18.12.2012
|
||||
* Author: mfro
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "bas_string.h"
|
||||
#include "bas_printf.h"
|
||||
#include "diskio.h"
|
||||
#include "ff.h"
|
||||
#include "s19reader.h"
|
||||
|
||||
|
||||
|
||||
static uint32_t mx29lv640d_flash_sectors[] =
|
||||
{
|
||||
0xe0000000, 0xe0002000, 0xe0004000, 0xe0006000, 0xe0008000, 0xe000a000, 0xe000c000, 0xe000e000,
|
||||
0xe0010000, 0xe0020000, 0xe0030000, 0xe0040000, 0xe0050000, 0xe0060000, 0xe0070000, 0xe0080000,
|
||||
0xe0090000, 0xe00a0000, 0xe00b0000, 0xe00c0000, 0xe00d0000, 0xe00e0000, 0xe00f0000, 0xe0100000,
|
||||
0xe0110000, 0xe0120000, 0xe0130000, 0xe0140000, 0xe0150000, 0xe0160000, 0xe0170000, 0xe0180000,
|
||||
0xe0190000, 0xe01a0000, 0xe01b0000, 0xe01c0000, 0xe01d0000, 0xe01e0000, 0xe01f0000, 0xe0200000,
|
||||
0xe0210000, 0xe0220000, 0xe0230000, 0xe0240000, 0xe0250000, 0xe0260000, 0xe0270000, 0xe0280000,
|
||||
0xe0290000, 0xe02a0000, 0xe02b0000, 0xe02c0000, 0xe02d0000, 0xe02e0000, 0xe02f0000, 0xe0300000,
|
||||
0xe0310000, 0xe0320000, 0xe0330000, 0xe0340000, 0xe0350000, 0xe0360000, 0xe0370000, 0xe0380000,
|
||||
0xe0390000, 0xe03a0000, 0xe03b0000, 0xe03c0000, 0xe03d0000, 0xe03e0000, 0xe03f0000, 0xe0400000,
|
||||
0xe0410000, 0xe0420000, 0xe0430000, 0xe0440000, 0xe0450000, 0xe0460000, 0xe0470000, 0xe0480000,
|
||||
0xe0490000, 0xe04a0000, 0xe04b0000, 0xe04c0000, 0xe04d0000, 0xe04e0000, 0xe04f0000, 0xe0500000,
|
||||
0xe0510000, 0xe0520000, 0xe0530000, 0xe0540000, 0xe0550000, 0xe0560000, 0xe0570000, 0xe0580000,
|
||||
0xe0590000, 0xe05a0000, 0xe05b0000, 0xe05c0000, 0xe05d0000, 0xe05e0000, 0xe05f0000, 0xe0600000,
|
||||
0xe0610000, 0xe0620000, 0xe0630000, 0xe0640000, 0xe0650000, 0xe0660000, 0xe0670000, 0xe0680000,
|
||||
0xe0690000, 0xe06a0000, 0xe06b0000, 0xe06c0000, 0xe06d0000, 0xe06e0000, 0xe06f0000, 0xe0700000,
|
||||
0xe0710000, 0xe0720000, 0xe0730000, 0xe0740000, 0xe0750000, 0xe0760000, 0xe0770000, 0xe0780000,
|
||||
0xe0790000, 0xe07a0000, 0xe07b0000, 0xe07c0000, 0xe07d0000, 0xe07e0000, 0xe07f0000, 0xe0800000
|
||||
};
|
||||
static const int num_flash_sectors = sizeof(mx29lv640d_flash_sectors) / sizeof(uint32_t);
|
||||
|
||||
typedef struct romram
|
||||
{
|
||||
uint32_t flash_address;
|
||||
uint32_t ram_address;
|
||||
char *name;
|
||||
} ROMRAM;
|
||||
|
||||
static const struct romram flash_areas[] =
|
||||
{
|
||||
{ 0xe0600000, 0x00e00000, "EmuTOS" }, /* EmuTOS */
|
||||
{ 0xe0400000, 0x00e00000, "FireTOS" }, /* FireTOS */
|
||||
{ 0xe0700000, 0x00e00000, "FPGA" }, /* FPGA config */
|
||||
};
|
||||
static const int num_flash_areas = sizeof(flash_areas) / sizeof(struct romram);
|
||||
|
||||
#define FLASH_ADDRESS 0xe0000000
|
||||
static volatile uint16_t *flash_unlock1 = (volatile uint16_t *) FLASH_ADDRESS + 0xaaa;
|
||||
static volatile uint16_t *flash_unlock2 = (volatile uint16_t *) FLASH_ADDRESS + 0x554;
|
||||
static const uint16_t cmd_unlock1 = 0xaa;
|
||||
static const uint16_t cmd_unlock2 = 0x55;
|
||||
static const uint16_t cmd_sector_erase1 = 0x80;
|
||||
static const uint16_t cmd_sector_erase2 = 0x30;
|
||||
static const uint16_t cmd_sector_erase_suspend = 0xb0;
|
||||
static const uint16_t cmd_sector_erase_resume = 0x30;
|
||||
static const uint16_t cmd_program = 0xa0;
|
||||
static const uint16_t cmd_autoselect = 0x90;
|
||||
static const uint16_t cmd_read = 0xf0;
|
||||
|
||||
/*
|
||||
* this callback just does nothing besides returning OK. Meant to do a dry run over the file to check its integrity
|
||||
*/
|
||||
static err_t simulate()
|
||||
{
|
||||
err_t ret = OK;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static err_t memcpy(uint8_t *dst, uint8_t *src, uint32_t length)
|
||||
{
|
||||
uint8_t *end = src + length;
|
||||
|
||||
do
|
||||
{
|
||||
*dst++ = *src++;
|
||||
} while (src < end);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static err_t flash(uint8_t *dst, uint8_t *src, uint32_t length)
|
||||
{
|
||||
err_t ret = OK;
|
||||
|
||||
/* TODO: do the actual flash */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* this callback verifies the data against the S-record file contents after a write to destination
|
||||
*/
|
||||
static err_t verify(uint8_t *dst, uint8_t *src, uint32_t length)
|
||||
{
|
||||
uint8_t *end = src + length;
|
||||
|
||||
do
|
||||
{
|
||||
if (*src++ != *dst++)
|
||||
return FAIL;
|
||||
} while (src < end);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* unlock a flash sector
|
||||
*/
|
||||
|
||||
err_t unlock_flash_sector(int sector_num)
|
||||
{
|
||||
volatile uint32_t rd;
|
||||
uint32_t size = (sector_num < num_flash_sectors ?
|
||||
mx29lv640d_flash_sectors[sector_num + 1] - mx29lv640d_flash_sectors[sector_num] :
|
||||
0);
|
||||
|
||||
*flash_unlock1 = cmd_unlock1;
|
||||
*flash_unlock2 = cmd_unlock2;
|
||||
*flash_unlock1 = cmd_autoselect;
|
||||
rd = * (volatile uint32_t *) FLASH_ADDRESS;
|
||||
* (volatile uint32_t *) FLASH_ADDRESS = size;
|
||||
(void) rd; /* get rid of "unused variable" compiler warning */
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* erase a flash sector
|
||||
*
|
||||
* sector_num is the index into the sector table above.
|
||||
*
|
||||
* FIXME: need to disable data cache to ensure proper operation
|
||||
*/
|
||||
err_t erase_flash_sector(int sector_num)
|
||||
{
|
||||
volatile uint32_t rd;
|
||||
uint32_t size = (sector_num < num_flash_sectors ?
|
||||
mx29lv640d_flash_sectors[sector_num + 1] - mx29lv640d_flash_sectors[sector_num] :
|
||||
0);
|
||||
|
||||
if (unlock_flash_sector(sector_num) == OK)
|
||||
{
|
||||
*flash_unlock1 = cmd_unlock1;
|
||||
*flash_unlock2 = cmd_unlock2;
|
||||
*flash_unlock1 = cmd_sector_erase1;
|
||||
*flash_unlock1 = cmd_unlock1;
|
||||
*flash_unlock2 = cmd_unlock2;
|
||||
*flash_unlock1 = cmd_sector_erase1;
|
||||
rd = * (volatile uint32_t *) FLASH_ADDRESS;
|
||||
* (volatile uint32_t *) FLASH_ADDRESS = size;
|
||||
(void) rd; /* get rid of "unused variable" compiler warning */
|
||||
return OK;
|
||||
}
|
||||
return ILLEGAL_SECTOR;
|
||||
}
|
||||
|
||||
err_t erase_flash_region(void *start_address, uint32_t length)
|
||||
{
|
||||
err_t err;
|
||||
int sector = -1;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* determine first sector to erase
|
||||
*
|
||||
* FIXME: if the start address of the .s19 file does not fall on a sector boundary, we
|
||||
* will probably erase vital code in the previous flash sector. This should not happen on the Firebee
|
||||
* where we have fixed areas for the different flash codes, but we should probably take care anyway
|
||||
*/
|
||||
for (i = 0; i < num_flash_sectors; i++)
|
||||
{
|
||||
if (start_address >= (void *) mx29lv640d_flash_sectors[i] && start_address <= (void *) mx29lv640d_flash_sectors[i])
|
||||
sector = i;
|
||||
}
|
||||
|
||||
if (sector >= 0 && sector <= num_flash_sectors)
|
||||
{
|
||||
/*
|
||||
* erase sectors until free space equals length
|
||||
*
|
||||
* FIXME: same as above. Currently, there is no prevention against overlapping flash areas.
|
||||
*/
|
||||
do {
|
||||
err = erase_flash_sector(sector);
|
||||
sector++;
|
||||
} while ((uint8_t *) mx29lv640d_flash_sectors[sector] < (uint8_t *) start_address + length && ! err);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = ILLEGAL_SECTOR;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void srec_flash(char *flash_filename)
|
||||
{
|
||||
DRESULT res;
|
||||
FRESULT fres;
|
||||
FATFS fs;
|
||||
FIL file;
|
||||
err_t err;
|
||||
void *start_address;
|
||||
uint32_t length;
|
||||
|
||||
res = disk_status(0);
|
||||
if (res == RES_OK)
|
||||
{
|
||||
fres = f_mount(0, &fs);
|
||||
if (fres == FR_OK)
|
||||
{
|
||||
if ((fres = f_open(&file, flash_filename, FA_READ) != FR_OK))
|
||||
{
|
||||
xprintf("flasher file %s not present on disk\r\n", flash_filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
f_close(&file);
|
||||
|
||||
/* first pass: parse and check for inconsistencies */
|
||||
xprintf("check file integrity: ");
|
||||
err = read_srecords(flash_filename, &start_address, &length, simulate);
|
||||
if (err == OK)
|
||||
{
|
||||
xprintf("OK.\r\nerase flash area (from %p, length 0x%lx): ", start_address, length);
|
||||
err = erase_flash_region(start_address, length);
|
||||
|
||||
/* next pass: copy data to destination */
|
||||
xprintf("OK.\r\flash data: ");
|
||||
err = read_srecords(flash_filename, &start_address, &length, memcpy);
|
||||
if (err == OK)
|
||||
{
|
||||
/* next pass: verify data */
|
||||
xprintf("OK.\r\nverify data: ");
|
||||
err = read_srecords(flash_filename, &start_address, &length, verify);
|
||||
if (err == OK)
|
||||
{
|
||||
typedef void void_func(void);
|
||||
void_func *func;
|
||||
|
||||
xprintf("OK.\r\n");
|
||||
|
||||
xprintf("target successfully written and verified. Start address: %p\r\n", start_address);
|
||||
|
||||
func = (void_func *) start_address;
|
||||
(*func)();
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("failed\r\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("failed\r\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("failed\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// xprintf("could not mount FAT FS\r\n");
|
||||
}
|
||||
f_mount(0, 0L);
|
||||
}
|
||||
else
|
||||
{
|
||||
// xprintf("could not initialize SD card\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
err_t srec_load(char *flash_filename)
|
||||
{
|
||||
FRESULT fres;
|
||||
FIL file;
|
||||
err_t err;
|
||||
void *start_address;
|
||||
uint32_t length;
|
||||
|
||||
if ((fres = f_open(&file, flash_filename, FA_READ) != FR_OK))
|
||||
{
|
||||
xprintf("flasher file %s not present on disk\r\n", flash_filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
f_close(&file);
|
||||
|
||||
/* first pass: parse and check for inconsistencies */
|
||||
xprintf("check file integrity: ");
|
||||
err = read_srecords(flash_filename, &start_address, &length, simulate);
|
||||
if (err == OK)
|
||||
{
|
||||
/* next pass: copy data to destination */
|
||||
xprintf("OK.\r\ncopy/flash data: ");
|
||||
err = read_srecords(flash_filename, &start_address, &length, memcpy);
|
||||
if (err == OK)
|
||||
{
|
||||
/* next pass: verify data */
|
||||
xprintf("OK.\r\nverify data: ");
|
||||
err = read_srecords(flash_filename, &start_address, &length, verify);
|
||||
if (err == OK)
|
||||
{
|
||||
typedef void void_func(void);
|
||||
void_func *func;
|
||||
|
||||
xprintf("OK.\r\n");
|
||||
xprintf("target successfully written and verified. Start address: %p\r\n", start_address);
|
||||
|
||||
func = (void_func *) start_address;
|
||||
(*func)();
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("failed\r\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("failed\r\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("failed\r\n");
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
void basflash(void)
|
||||
{
|
||||
const char *basflash_str = "\\BASFLASH";
|
||||
const char *bastest_str = "\\BASTEST";
|
||||
DRESULT res;
|
||||
FRESULT fres;
|
||||
FATFS fs;
|
||||
|
||||
xprintf("\r\nHello from BASFLASH.S19!\r\n\r\n");
|
||||
|
||||
/*
|
||||
* read \BASTEST\ folder contents (search for .S19-files). If found load them to their final destination
|
||||
* (after BaS has copied them, not their flash location) and return.
|
||||
*
|
||||
* Files located in the BASTEST-folder thus override those in flash. Useful for testing before flashing
|
||||
*/
|
||||
res = disk_status(0);
|
||||
xprintf("disk_status(0) = %d\r\n", res);
|
||||
if (res == RES_OK)
|
||||
{
|
||||
fres = f_mount(0, &fs);
|
||||
xprintf("f_mount() = %d\r\n", fres);
|
||||
if (fres == FR_OK)
|
||||
{
|
||||
DIR directory;
|
||||
|
||||
fres = f_opendir(&directory, bastest_str);
|
||||
xprintf("f_opendir() = %d\r\n", fres);
|
||||
if (fres == FR_OK)
|
||||
{
|
||||
FILINFO fileinfo;
|
||||
|
||||
fres = f_readdir(&directory, &fileinfo);
|
||||
xprintf("f_readdir() = %d\r\n", fres);
|
||||
while (fres == FR_OK)
|
||||
{
|
||||
const char *srec_ext = ".S19";
|
||||
char path[30];
|
||||
|
||||
if (fileinfo.fname[0] != '\0') /* found a file */
|
||||
{
|
||||
xprintf("check file %s (%s == %s ?)\r\n", fileinfo.fname, &fileinfo.fname[strlen(fileinfo.fname) - 4], srec_ext);
|
||||
if (strlen(fileinfo.fname) >= 4 && strncmp(&fileinfo.fname[strlen(fileinfo.fname) - 4], srec_ext, 4) == 0) /* we have a .S19 file */
|
||||
{
|
||||
/*
|
||||
* build path + filename
|
||||
*/
|
||||
strcpy(path, bastest_str);
|
||||
strcat(path, "\\");
|
||||
strncat(path, fileinfo.fname, 13);
|
||||
|
||||
xprintf("loading file %s\r\n", path);
|
||||
/*
|
||||
* load file
|
||||
*/
|
||||
if (srec_load(path) != OK)
|
||||
{
|
||||
xprintf("failed to load file %s\r\n", path);
|
||||
// error handling
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
break; /* exit if no file found */
|
||||
fres = f_readdir(&directory, &fileinfo);
|
||||
xprintf("f_readdir() = %d\r\n", fres);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("f_opendir %s failed with error code %d\r\n", bastest_str, fres);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// xprintf("could not mount FAT FS\r\n");
|
||||
}
|
||||
f_mount(0, 0L); /* unmount SD card */
|
||||
}
|
||||
}
|
||||
26
i2cspi_BaS_gcc/sources/basflash_start.c
Normal file
26
i2cspi_BaS_gcc/sources/basflash_start.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* basflash_start.c
|
||||
*
|
||||
* Created on: 16.02.2013
|
||||
* Author: mfro
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static uint32_t ownstack[4096];
|
||||
static uint32_t *stackptr = &ownstack[4095];
|
||||
|
||||
/*
|
||||
* setup our own stack in SDRAM to prevent clashing BaS's in SRAM (size limited).
|
||||
*/
|
||||
void startup(void)
|
||||
{
|
||||
static uint32_t oldstack;
|
||||
|
||||
void basflash(void);
|
||||
__asm__ __volatile__("move.l sp,%0\n\t" : "=g"(oldstack) : :);
|
||||
__asm__ __volatile__("move.l %0,sp\n\t" : : "g"(stackptr) : );
|
||||
basflash();
|
||||
__asm__ __volatile__("move.l %0,sp\n\t" : : "g"(oldstack) : "sp");
|
||||
(void) stackptr; /* make compiler happy about unused variables */
|
||||
}
|
||||
48
i2cspi_BaS_gcc/sources/cache.c
Normal file
48
i2cspi_BaS_gcc/sources/cache.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* cache handling
|
||||
*
|
||||
* This file is part of BaS_gcc.
|
||||
*
|
||||
* BaS_gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BaS_gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright 2010 - 2012 F. Aschwanden
|
||||
* Copyright 2011 - 2012 V. Riviere
|
||||
* Copyright 2012 M. Froeschle
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cache.h"
|
||||
|
||||
void flush_and_invalidate_caches(void)
|
||||
{
|
||||
__asm__ (
|
||||
" clr.l d0\n\t"
|
||||
" clr.l d1\n\t"
|
||||
" move.l d0,a0\n\t"
|
||||
"cfa_setloop:\n\t"
|
||||
" cpushl bc,(a0) | flush\n\t"
|
||||
" lea 0x10(a0),a0 | index+1\n\t"
|
||||
" addq.l #1,d1 | index+1\n\t"
|
||||
" cmpi.w #512,d1 | all sets?\n\t"
|
||||
" bne.s cfa_setloop | no->\n\t"
|
||||
" clr.l d1\n\t"
|
||||
" addq.l #1,d0\n\t"
|
||||
" move.l d0,a0\n\t"
|
||||
" cmpi.w #4,d0 | all ways?\n\t"
|
||||
" bne.s cfa_setloop | no->\n\t"
|
||||
/* input */ :
|
||||
/* output */ :
|
||||
/* clobber */ : "d0", "d1", "a0"
|
||||
);
|
||||
}
|
||||
3798
i2cspi_BaS_gcc/sources/cc932.c
Normal file
3798
i2cspi_BaS_gcc/sources/cc932.c
Normal file
File diff suppressed because it is too large
Load Diff
10973
i2cspi_BaS_gcc/sources/cc936.c
Normal file
10973
i2cspi_BaS_gcc/sources/cc936.c
Normal file
File diff suppressed because it is too large
Load Diff
8603
i2cspi_BaS_gcc/sources/cc949.c
Normal file
8603
i2cspi_BaS_gcc/sources/cc949.c
Normal file
File diff suppressed because it is too large
Load Diff
6829
i2cspi_BaS_gcc/sources/cc950.c
Normal file
6829
i2cspi_BaS_gcc/sources/cc950.c
Normal file
File diff suppressed because it is too large
Load Diff
540
i2cspi_BaS_gcc/sources/ccsbcs.c
Normal file
540
i2cspi_BaS_gcc/sources/ccsbcs.c
Normal file
@@ -0,0 +1,540 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Unicode - Local code bidirectional converter (C)ChaN, 2009 */
|
||||
/* (SBCS code pages) */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 437 U.S. (OEM)
|
||||
/ 720 Arabic (OEM)
|
||||
/ 1256 Arabic (Windows)
|
||||
/ 737 Greek (OEM)
|
||||
/ 1253 Greek (Windows)
|
||||
/ 1250 Central Europe (Windows)
|
||||
/ 775 Baltic (OEM)
|
||||
/ 1257 Baltic (Windows)
|
||||
/ 850 Multilingual Latin 1 (OEM)
|
||||
/ 852 Latin 2 (OEM)
|
||||
/ 1252 Latin 1 (Windows)
|
||||
/ 855 Cyrillic (OEM)
|
||||
/ 1251 Cyrillic (Windows)
|
||||
/ 866 Russian (OEM)
|
||||
/ 857 Turkish (OEM)
|
||||
/ 1254 Turkish (Windows)
|
||||
/ 858 Multilingual Latin 1 + Euro (OEM)
|
||||
/ 862 Hebrew (OEM)
|
||||
/ 1255 Hebrew (Windows)
|
||||
/ 874 Thai (OEM, Windows)
|
||||
/ 1258 Vietnam (OEM, Windows)
|
||||
*/
|
||||
|
||||
#include <ff.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if _CODE_PAGE == 437
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
||||
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 720
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
|
||||
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
|
||||
0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
|
||||
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642,
|
||||
0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
|
||||
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0xO650, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 737
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
|
||||
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
|
||||
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
|
||||
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
|
||||
0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
|
||||
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
|
||||
0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD,
|
||||
0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
|
||||
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 775
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
|
||||
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
|
||||
0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
|
||||
0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
|
||||
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6,
|
||||
0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118,
|
||||
0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
|
||||
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B,
|
||||
0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144,
|
||||
0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
|
||||
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E,
|
||||
0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 850
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
|
||||
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 852
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
|
||||
0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
|
||||
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
|
||||
0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E,
|
||||
0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A,
|
||||
0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE,
|
||||
0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
|
||||
0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
|
||||
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 855
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
|
||||
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
|
||||
0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
|
||||
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
|
||||
0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
|
||||
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414,
|
||||
0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438,
|
||||
0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E,
|
||||
0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
|
||||
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
|
||||
0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
|
||||
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D,
|
||||
0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 857
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000,
|
||||
0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 858
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
|
||||
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 862
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
|
||||
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
|
||||
0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
||||
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 866
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
|
||||
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
|
||||
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
|
||||
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
|
||||
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 874
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
|
||||
0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
|
||||
0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
|
||||
0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
|
||||
0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
|
||||
0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
|
||||
0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
|
||||
0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
|
||||
0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
|
||||
0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
|
||||
0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
|
||||
0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1250
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP1250(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
|
||||
0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
|
||||
0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
|
||||
0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
|
||||
0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
|
||||
0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
|
||||
0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
|
||||
0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
|
||||
0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
|
||||
0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
|
||||
0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1251
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP1251(0x80-0xFF) to Unicode conversion table */
|
||||
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
|
||||
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
|
||||
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
|
||||
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
|
||||
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
|
||||
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
|
||||
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
|
||||
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
|
||||
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1252
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP1252(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1253
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP1253(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
|
||||
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
|
||||
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
|
||||
0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
|
||||
0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
|
||||
0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
|
||||
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
|
||||
0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
|
||||
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1254
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP1254(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1255
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP1255(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
|
||||
0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
|
||||
0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
|
||||
0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
|
||||
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
|
||||
0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1256
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP1256(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
|
||||
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
|
||||
0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
|
||||
0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
|
||||
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
|
||||
0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643,
|
||||
0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
|
||||
0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
|
||||
0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2
|
||||
}
|
||||
|
||||
#elif _CODE_PAGE == 1257
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP1257(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
|
||||
0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
|
||||
0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
|
||||
0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
|
||||
0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
|
||||
0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
|
||||
0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
|
||||
0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
|
||||
0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1258
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const uint16_t Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if !_TBLDEF || !_USE_LFN
|
||||
#error This file is not needed in current configuration. Remove from the project.
|
||||
#endif
|
||||
|
||||
|
||||
uint16_t ff_convert ( /* Converted character, Returns zero on error */
|
||||
uint16_t src, /* Character code to be converted */
|
||||
uint32_t dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
|
||||
)
|
||||
{
|
||||
uint16_t c;
|
||||
|
||||
|
||||
if (src < 0x80) { /* ASCII */
|
||||
c = src;
|
||||
|
||||
} else {
|
||||
if (dir) { /* OEMCP to Unicode */
|
||||
c = (src >= 0x100) ? 0 : Tbl[src - 0x80];
|
||||
|
||||
} else { /* Unicode to OEMCP */
|
||||
for (c = 0; c < 0x80; c++) {
|
||||
if (src == Tbl[c]) break;
|
||||
}
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
uint16_t ff_wtoupper ( /* Upper converted character */
|
||||
uint16_t chr /* Input character */
|
||||
)
|
||||
{
|
||||
static const uint16_t tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 };
|
||||
static const uint16_t tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 };
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ;
|
||||
|
||||
return tbl_lower[i] ? tbl_upper[i] : chr;
|
||||
}
|
||||
839
i2cspi_BaS_gcc/sources/exceptions.S
Normal file
839
i2cspi_BaS_gcc/sources/exceptions.S
Normal file
@@ -0,0 +1,839 @@
|
||||
/*
|
||||
* initialize exception vectors
|
||||
*/
|
||||
#include "startcf.h"
|
||||
|
||||
.extern __Bas_base
|
||||
.extern __SUP_SP
|
||||
.extern _rom_entry
|
||||
.extern __RAMBAR0
|
||||
.extern _rt_cacr
|
||||
.extern _rt_mod
|
||||
.extern _rt_ssp
|
||||
.extern _rt_usp
|
||||
.extern _rt_vbr
|
||||
.extern _illegal_instruction
|
||||
.extern _privileg_violation
|
||||
.extern _mmutr_miss
|
||||
.extern __MBAR
|
||||
.extern __MMUBAR
|
||||
.extern _video_tlb
|
||||
.extern _video_sbt
|
||||
.extern cpusha
|
||||
|
||||
/* Register read/write macros */
|
||||
#define MCF_MMU_MMUCR __MMUBAR
|
||||
#define MCF_MMU_MMUOR __MMUBAR+0x04
|
||||
#define MCF_MMU_MMUSR __MMUBAR+0x08
|
||||
#define MCF_MMU_MMUAR __MMUBAR+0x10
|
||||
#define MCF_MMU_MMUTR __MMUBAR+0x14
|
||||
#define MCF_MMU_MMUDR __MMUBAR+0x18
|
||||
|
||||
#define MCF_EPORT_EPPAR __MBAR+0xF00
|
||||
#define MCF_EPORT_EPDDR __MBAR+0xF04
|
||||
#define MCF_EPORT_EPIER __MBAR+0xF05
|
||||
#define MCF_EPORT_EPDR __MBAR+0xF08
|
||||
#define MCF_EPORT_EPPDR __MBAR+0xF09
|
||||
#define MCF_EPORT_EPFR __MBAR+0xF0C
|
||||
|
||||
#define MCF_GPIO_PODR_FEC1L __MBAR+0xA07
|
||||
|
||||
#define MCF_PSC0_PSCTB_8BIT __MBAR+0x860C
|
||||
|
||||
#define MCF_PSC3_PSCRB_8BIT __MBAR+0x890C
|
||||
#define MCF_PSC3_PSCTB_8BIT __MBAR+0x890C
|
||||
|
||||
.global _vec_init
|
||||
|
||||
//mmu ---------------------------------------------------
|
||||
/* Register read/write macros */
|
||||
#define MCF_MMU_MMUCR __MMUBAR
|
||||
#define MCF_MMU_MMUOR __MMUBAR+0x04
|
||||
#define MCF_MMU_MMUSR __MMUBAR+0x08
|
||||
#define MCF_MMU_MMUAR __MMUBAR+0x10
|
||||
#define MCF_MMU_MMUTR __MMUBAR+0x14
|
||||
#define MCF_MMU_MMUDR __MMUBAR+0x18
|
||||
|
||||
|
||||
/* Bit definitions and macros for MCF_MMU_MMUCR */
|
||||
#define MCF_MMU_MMUCR_EN (0x1)
|
||||
#define MCF_MMU_MMUCR_ASM (0x2)
|
||||
|
||||
/* Bit definitions and macros for MCF_MMU_MMUOR */
|
||||
#define MCF_MMU_MMUOR_UAA (0x1)
|
||||
#define MCF_MMU_MMUOR_ACC (0x2)
|
||||
#define MCF_MMU_MMUOR_RW (0x4)
|
||||
#define MCF_MMU_MMUOR_ADR (0x8)
|
||||
#define MCF_MMU_MMUOR_ITLB (0x10)
|
||||
#define MCF_MMU_MMUOR_CAS (0x20)
|
||||
#define MCF_MMU_MMUOR_CNL (0x40)
|
||||
#define MCF_MMU_MMUOR_CA (0x80)
|
||||
#define MCF_MMU_MMUOR_STLB (0x100)
|
||||
#define MCF_MMU_MMUOR_AA(x) (((x)&0xFFFF)<<0x10)
|
||||
|
||||
/* Bit definitions and macros for MCF_MMU_MMUSR */
|
||||
#define MCF_MMU_MMUSR_HIT (0x2)
|
||||
#define MCF_MMU_MMUSR_WF (0x8)
|
||||
#define MCF_MMU_MMUSR_RF (0x10)
|
||||
#define MCF_MMU_MMUSR_SPF (0x20)
|
||||
|
||||
/* Bit definitions and macros for MCF_MMU_MMUAR */
|
||||
#define MCF_MMU_MMUAR_FA(x) (((x)&0xFFFFFFFF)<<0)
|
||||
|
||||
/* Bit definitions and macros for MCF_MMU_MMUTR */
|
||||
#define MCF_MMU_MMUTR_V (0x1)
|
||||
#define MCF_MMU_MMUTR_SG (0x2)
|
||||
#define MCF_MMU_MMUTR_ID(x) (((x)&0xFF)<<0x2)
|
||||
#define MCF_MMU_MMUTR_VA(x) (((x)&0x3FFFFF)<<0xA)
|
||||
|
||||
/* Bit definitions and macros for MCF_MMU_MMUDR */
|
||||
#define MCF_MMU_MMUDR_LK (0x2)
|
||||
#define MCF_MMU_MMUDR_X (0x4)
|
||||
#define MCF_MMU_MMUDR_W (0x8)
|
||||
#define MCF_MMU_MMUDR_R (0x10)
|
||||
#define MCF_MMU_MMUDR_SP (0x20)
|
||||
#define MCF_MMU_MMUDR_CM(x) (((x)&0x3)<<0x6)
|
||||
#define MCF_MMU_MMUDR_SZ(x) (((x)&0x3)<<0x8)
|
||||
#define MCF_MMU_MMUDR_PA(x) (((x)&0x3FFFFF)<<0xA)
|
||||
|
||||
#define std_mmutr (MCF_MMU_MMUTR_SG|MCF_MMU_MMUTR_V)
|
||||
#define mmuord_d ( MCF_MMU_MMUOR_ACC|MCF_MMU_MMUOR_UAA)
|
||||
#define mmuord_i (MCF_MMU_MMUOR_ITLB|MCF_MMU_MMUOR_ACC|MCF_MMU_MMUOR_UAA)
|
||||
#define wt_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(00)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
||||
#define cb_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(01)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
||||
#define nc_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(10)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
||||
//---------------------------------------------------
|
||||
/*********************************************************************
|
||||
*
|
||||
* General Purpose Timers (GPT)
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
/* Register read/write macros */
|
||||
#define MCF_GPT0_GMS __MBAR+0x800
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Slice Timers (SLT)
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#define MCF_SLT0_SCNT __MBAR+0x908
|
||||
|
||||
/**********************************************************/
|
||||
// macros
|
||||
/**********************************************************/
|
||||
.altmacro
|
||||
.macro irq vector,int_mask,clr_int
|
||||
local irq_protect
|
||||
local sev_supint
|
||||
local irq_end
|
||||
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
subq.l #8,a7
|
||||
movem.l d0/a5,(a7) // register sichern
|
||||
lea MCF_EPORT_EPFR,a5
|
||||
move.b #\clr_int,(a5) // clear int pending
|
||||
// test auf protect mode ---------------------
|
||||
move.b DIP_SWITCHa,d0
|
||||
btst #7,d0
|
||||
bne irq_protect // ja->
|
||||
// -------------------------------------------
|
||||
movem.l (a7),d0/a5 // register zurück
|
||||
addq.l #8,a7
|
||||
move.l \vector,-(a7)
|
||||
move #0x2\int_mask\()00,sr
|
||||
rts
|
||||
irq_protect:
|
||||
move.l usp,a5 // usp holen
|
||||
tst.b _rt_mod // supervisor?
|
||||
bne sev_supint // ja ->
|
||||
mov3q.l #-1,_rt_mod // auf supervisor setzen
|
||||
move.l a5,_rt_usp // rt_usp speichern
|
||||
move.l _rt_ssp,a5 // rt_ssp holen
|
||||
#ifdef cf_stack
|
||||
move.l 12(a7),-(a5) // pc transferieren
|
||||
move.l 8(a7),-(a5) // sr,vec
|
||||
#else
|
||||
move.w 8(a7),-(a5) // vector nr.
|
||||
move.l 12(a7),-(a5) // pc verschieben
|
||||
move.w 10(a7),-(a5) // sr verschieben
|
||||
#endif
|
||||
bra irq_end
|
||||
sev_supint:
|
||||
#ifdef cf_stack
|
||||
move.l 12(a7),-(a5) // pc transferieren
|
||||
move.l 8(a7),-(a5) // sr,vec
|
||||
bset #5,2(a5) // auf super setzen
|
||||
#else
|
||||
move.w 8(a7),-(a5) // vector nr.
|
||||
move.l 12(a7),-(a5) // pc verschieben
|
||||
move.w 10(a7),-(a5) // sr verschieben
|
||||
bset #5,(a5) // auf super
|
||||
#endif
|
||||
irq_end:
|
||||
move.l a5,usp // usp setzen
|
||||
lea \vector,a5
|
||||
adda.l _rt_vbr,a5
|
||||
move.l (a5),12(a7) // vectoradresse eintragen
|
||||
move.b #\int_mask,10(a7) // intmaske setzen
|
||||
movem.l (a7),d0/a5 // register zur<EFBFBD>ck
|
||||
addq.l #8,a7
|
||||
rte // und weg
|
||||
.endm
|
||||
|
||||
/*
|
||||
* FIXME: this is a GNU gas kludge. Ugly, but I just can't come up with any smarter solution
|
||||
*
|
||||
* GNU as does not support multi-character constants. At least I don't know of any way it would.
|
||||
* The following might look more than strange, but I considered the statement
|
||||
*
|
||||
* mchar move.l, 'T,'E,'S,'T,-(SP)
|
||||
*
|
||||
* somewhat more readable than
|
||||
*
|
||||
* move.l #1413829460,-(SP)
|
||||
*
|
||||
* If anybody knows of any better way on how to do this - please do!
|
||||
*
|
||||
*/
|
||||
.macro mchar st,a,b,c,d,tgt
|
||||
\st #\a << 24|\b<<16|\c<<8|\d,\tgt
|
||||
.endm
|
||||
|
||||
.text
|
||||
_vec_init:
|
||||
move.l a2,-(sp) // Backup registers
|
||||
|
||||
mov3q.l #-1,_rt_mod // rt_mod auf super
|
||||
clr.l _rt_ssp
|
||||
clr.l _rt_usp
|
||||
clr.l _rt_vbr
|
||||
move.l #__RAMBAR0,d0 // sind in rambar0
|
||||
movec d0,VBR
|
||||
move.l d0,a0
|
||||
move.l a0,a2
|
||||
init_vec:
|
||||
move.l #256,d0
|
||||
lea std_exc_vec(pc),a1 // standard vector
|
||||
init_vec_loop:
|
||||
move.l a1,(a2)+ // mal standard vector f<EFBFBD>r alle setzen
|
||||
subq.l #1,d0
|
||||
bne init_vec_loop
|
||||
|
||||
move.l #__SUP_SP,(a0)
|
||||
lea reset_vector(pc),a1
|
||||
move.l a1,0x04(a0)
|
||||
lea acess(pc),a1
|
||||
move.l a1,0x08(a0)
|
||||
|
||||
move.b DIP_SWITCHa,d0 // ++ vr
|
||||
btst #7,d0
|
||||
beq no_protect_vectors
|
||||
|
||||
lea _illegal_instruction(pc),a1
|
||||
move.l a1,0x0c(a0)
|
||||
lea _illegal_instruction(pc),a1
|
||||
move.l a1,0x10(a0)
|
||||
lea zero_divide(pc),a1
|
||||
move.l a1,0x14(a0)
|
||||
lea _privileg_violation(pc),a1
|
||||
move.l a1,0x20(a0)
|
||||
lea linea(pc),a1
|
||||
move.l a1,0x28(a0)
|
||||
lea linef(pc),a1
|
||||
move.l a1,0x2c(a0)
|
||||
lea format(pc),a1
|
||||
move.l a1,0x38(a0)
|
||||
|
||||
// floating point overflow
|
||||
lea flpoow(pc),a1
|
||||
move.l a1,0xc0(a0)
|
||||
lea flpoow(pc),a1
|
||||
move.l a1,0xc4(a0)
|
||||
lea flpoow(pc),a1
|
||||
move.l a1,0xc8(a0)
|
||||
lea flpoow(pc),a1
|
||||
move.l a1,0xcc(a0)
|
||||
lea flpoow(pc),a1
|
||||
move.l a1,0xd0(a0)
|
||||
lea flpoow(pc),a1
|
||||
move.l a1,0xd4(a0)
|
||||
lea flpoow(pc),a1
|
||||
move.l a1,0xd8(a0)
|
||||
lea flpoow(pc),a1
|
||||
move.l a1,0xdc(a0)
|
||||
no_protect_vectors:
|
||||
|
||||
|
||||
// int 1-7
|
||||
lea irq1(pc),a1
|
||||
move.l a1,0x104(a0)
|
||||
lea irq2(pc),a1
|
||||
move.l a1,0x108(a0)
|
||||
lea irq3(pc),a1
|
||||
move.l a1,0x10c(a0)
|
||||
lea irq4(pc),a1
|
||||
move.l a1,0x110(a0)
|
||||
lea irq5(pc),a1
|
||||
move.l a1,0x114(a0)
|
||||
lea irq6(pc),a1
|
||||
move.l a1,0x118(a0)
|
||||
lea irq7(pc),a1
|
||||
move.l a1,0x11c(a0)
|
||||
//psc_vectors
|
||||
lea psc3(pc),a1
|
||||
move.l a1,0x180(a0)
|
||||
//timer 1 vectors
|
||||
lea timer0(pc),a1
|
||||
move.l a1,0x1f8(a0)
|
||||
|
||||
move.l (sp)+,a2 // Restore registers
|
||||
rts
|
||||
/*
|
||||
* exception vector routines
|
||||
*/
|
||||
vector_table_start:
|
||||
std_exc_vec:
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
subq.l #8,a7
|
||||
movem.l d0/a5,(a7) // register sichern
|
||||
// test auf protect mode -------------------------------
|
||||
move.b DIP_SWITCHa,d0
|
||||
btst #7,d0
|
||||
bne stv_protect // ja->
|
||||
//------------------------------------------------------
|
||||
move.w 8(a7),d0 // vector holen
|
||||
and.l #0x3fc,d0 // vector nummer ausmaskieren
|
||||
add.l _rt_vbr,d0 // + basis
|
||||
move.l d0,a5
|
||||
move.l (a5),d0
|
||||
move.l 4(a7),a5 // a5 zur<EFBFBD>ck
|
||||
move.l d0,4(a7)
|
||||
move.w 10(a7),d0
|
||||
bset #13,d0 // super
|
||||
move.w d0,sr // orginal sr wert in super setzen
|
||||
move.l (a7)+,d0 // d0 zur<EFBFBD>ck
|
||||
rts
|
||||
stv_protect:
|
||||
move.l usp,a5 // usp holen
|
||||
tst.b _rt_mod // supervisor?
|
||||
bne sev_sup // ja ->
|
||||
mov3q.l #-1,_rt_mod // auf supervisor setzen
|
||||
move.l a5,_rt_usp // rt_usp speichern
|
||||
move.l _rt_ssp,a5 // rt_ssp holen
|
||||
#ifdef cf_stack
|
||||
move.l 12(a7),-(a5) // pc transferieren
|
||||
move.l 8(a7),d0 // sr holen
|
||||
move.l d0,-(a5) // sr transferieren
|
||||
swap d0 // vec -> lw
|
||||
#else
|
||||
move.w 8(a7),d0 // vector holen
|
||||
move.w d0,-(a5) // ablegen
|
||||
move.l 12(a7),-(a5) // pc transferieren
|
||||
move.w 10(a7),-(a5) // sr transferieren
|
||||
#endif
|
||||
move.l a5,usp // usp setzen
|
||||
and.l #0x3fc,d0 // vector nummer ausmaskieren
|
||||
add.l _rt_vbr,d0 // + basis
|
||||
move.l d0,a5
|
||||
move.l (a5),12(a7) // hier geht's weiter
|
||||
movem.l (a7),d0/a5 // register zur<EFBFBD>ck
|
||||
addq.l #8,a7
|
||||
rte // und weg
|
||||
sev_sup:
|
||||
#ifdef cf_stack
|
||||
move.l 12(a7),-(a5) // pc transferieren
|
||||
move.l 8(a7),d0 // sr holen
|
||||
bset #13,d0 // war aus rt super
|
||||
move.l d0,-(a5) // sr transferieren
|
||||
swap d0 // vec -> lw
|
||||
#else
|
||||
move.w 8(a7),d0 // vector holen
|
||||
move.w d0,-(a5) // ablegen
|
||||
move.l 12(a7),-(a5) // pc transferieren
|
||||
move.w 10(a7),-(a5) // sr transferieren
|
||||
bset #5,(a5) // war aus super
|
||||
#endif
|
||||
move.l a5,usp // usp setzen
|
||||
and.l #0x3fc,d0 // vector nummer ausmaskieren
|
||||
add.l _rt_vbr,d0 // + basis
|
||||
move.l d0,a5
|
||||
move.l (a5),12(a7) // hier geht's weiter
|
||||
movem.l (a7),d0/a5 // register zur<EFBFBD>ck
|
||||
addq.l #8,a7
|
||||
rte // und weg
|
||||
//*******************************************
|
||||
reset_vector:
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
move.l #0x31415926,d0
|
||||
cmp.l 0x426,d0 // reset vector g<EFBFBD>ltg?
|
||||
beq std_exc_vec // ja->
|
||||
jmp _rom_entry // sonst kaltstart
|
||||
acess:
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
move.l d0,-(sp) // ++ vr
|
||||
move.w 4(sp),d0
|
||||
andi.l #0x0c03,d0
|
||||
cmpi.l #0x0401,d0
|
||||
beq access_mmu
|
||||
cmpi.l #0x0402,d0
|
||||
beq access_mmu
|
||||
cmpi.l #0x0802,d0
|
||||
beq access_mmu
|
||||
cmpi.l #0x0c02,d0
|
||||
beq access_mmu
|
||||
bra bus_error
|
||||
access_mmu:
|
||||
move.l MCF_MMU_MMUSR,d0
|
||||
btst #1,d0
|
||||
bne bus_error
|
||||
move.l MCF_MMU_MMUAR,d0
|
||||
cmp.l #__FASTRAM_END,d0 // max User RAM Bereich
|
||||
bge bus_error // grösser -> bus error
|
||||
bra _mmutr_miss
|
||||
bus_error:
|
||||
move.l (sp)+,d0
|
||||
bra std_exc_vec
|
||||
|
||||
zero_divide:
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
move.l a0,-(a7)
|
||||
move.l d0,-(a7)
|
||||
move.l 12(a7),a0 // pc
|
||||
move.w (a0)+,d0 // befehlscode
|
||||
btst #7,d0 // long?
|
||||
beq zd_word // nein->
|
||||
addq.l #2,a0
|
||||
zd_word:
|
||||
and.l 0x3f,d0 // ea ausmaskieren
|
||||
cmp.w #0x08,d0 // -(ax) oder weniger
|
||||
ble zd_end
|
||||
addq.l #2,a0
|
||||
cmp.w #0x39,d0 // xxx.L
|
||||
bne zd_nal
|
||||
addq.l #2,a0
|
||||
bra zd_end
|
||||
zd_nal: cmp.w #0x3c,d0 // immediate?
|
||||
bne zd_end // nein->
|
||||
btst #7,d0 // long?
|
||||
beq zd_end // nein
|
||||
addq.l #2,a0
|
||||
zd_end:
|
||||
move.l a0,12(a7)
|
||||
move.l (a7)+,d0
|
||||
move.l (a7)+,a0
|
||||
rte
|
||||
|
||||
linea:
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
halt
|
||||
nop
|
||||
nop
|
||||
linef:
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
halt
|
||||
nop
|
||||
nop
|
||||
format:
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
halt
|
||||
nop
|
||||
nop
|
||||
//floating point
|
||||
flpoow:
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
halt
|
||||
nop
|
||||
nop
|
||||
irq1:
|
||||
irq 0x64,1,0x02
|
||||
irq2: // hbl
|
||||
// move.b #3,2(a7)
|
||||
// rte
|
||||
irq 0x68,2,0x04
|
||||
irq3:
|
||||
irq 0x6c,3,0x08
|
||||
irq4: // vbl
|
||||
irq 0x70,4,0x10
|
||||
irq5: // acp
|
||||
irq 0x74,5,0x20
|
||||
irq6: // mfp
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
subq.l #8,a7
|
||||
movem.l d0/a5,(a7) // register sichern
|
||||
lea MCF_EPORT_EPFR,a5
|
||||
move.b #0x40,(a5) // clear int6
|
||||
// test auf timeout screen adr change -------------------------------------------------------
|
||||
move.l _video_sbt,d0
|
||||
beq irq6_non_sca // wenn 0 nichts zu tun
|
||||
sub.l #0x70000000,d0 // 14 sec abz<EFBFBD>hlen
|
||||
lea MCF_SLT0_SCNT,a5
|
||||
cmp.l (a5),d0 // aktuelle zeit weg
|
||||
ble irq6_non_sca // noch nicht abgelaufen
|
||||
lea -28(a7),a7
|
||||
movem.l d0-d4/a0-a1,(a7) // register sichern
|
||||
clr.l d3 // beginn mit 0
|
||||
bsr cpusha // cache leeren
|
||||
// eintrag suchen
|
||||
irq6_next_sca:
|
||||
move.l d3,d0
|
||||
move.l d0,MCF_MMU_MMUAR // addresse
|
||||
move.l #0x106,d4
|
||||
move.l d4,MCF_MMU_MMUOR // suchen ->
|
||||
nop
|
||||
move.l MCF_MMU_MMUOR,d4
|
||||
clr.w d4
|
||||
swap d4
|
||||
move.l d4,MCF_MMU_MMUAR
|
||||
mvz.w #0x10e,d4
|
||||
move.l d4,MCF_MMU_MMUOR // eintr<EFBFBD>ge holen aus mmu
|
||||
nop
|
||||
move.l MCF_MMU_MMUTR,d4 // ID holen
|
||||
lsr.l #2,d4 // bit 9 bis 2
|
||||
cmp.w #sca_page_ID,d4 // ist screen change ID?
|
||||
bne irq6_sca_pn // nein -> page keine screen area next
|
||||
// eintrag <EFBFBD>ndern
|
||||
add.l #std_mmutr,d0
|
||||
move.l d3,d1 // page 0?
|
||||
beq irq6_sca_pn0 // ja ->
|
||||
add.l #cb_mmudr,d1 // sonst page cb
|
||||
bra irq6_sca_pn1c
|
||||
irq6_sca_pn0:
|
||||
add.l #wt_mmudr|MCF_MMU_MMUDR_LK,d1 // page wt and locked
|
||||
irq6_sca_pn1c:
|
||||
mvz.w #0x10b,d2 // MMU update
|
||||
move.l d0,MCF_MMU_MMUTR
|
||||
move.l d1,MCF_MMU_MMUDR
|
||||
move.l d2,MCF_MMU_MMUOR // setze tlb data only
|
||||
nop
|
||||
// page copy
|
||||
move.l d3,a0
|
||||
add.l #0x60000000,a0
|
||||
move.l d3,a1
|
||||
move.l #0x10000,d4 // die ganze page
|
||||
irq6_vcd0_loop:
|
||||
move.l (a0)+,(a1)+ // page copy
|
||||
move.l (a0)+,(a1)+
|
||||
move.l (a0)+,(a1)+
|
||||
move.l (a0)+,(a1)+
|
||||
subq.l #1,d4
|
||||
bne irq6_vcd0_loop
|
||||
nop
|
||||
irq6_sca_pn:
|
||||
add.l #0x00100000,d3 // next
|
||||
cmp.l #0x00d00000,d3 // ende?
|
||||
blt irq6_next_sca // nein->
|
||||
|
||||
move.l #0x2000,d0
|
||||
move.l d0,_video_tlb // anfangszustand wieder herstellen
|
||||
clr.l _video_sbt // zeit l<EFBFBD>schen
|
||||
|
||||
movem.l (a7),d0-d4/a0-a1 // register zur<EFBFBD>ck
|
||||
lea 28(a7),a7
|
||||
irq6_non_sca:
|
||||
// test auf acsi dma -----------------------------------------------------------------
|
||||
lea 0xfffffa0b,a5
|
||||
bset #7,-4(a5) // int ena
|
||||
btst.b #7,(a5) // acsi dma int?
|
||||
beq non_acsi_dma
|
||||
bsr acsi_dma
|
||||
non_acsi_dma:
|
||||
// ----------------------------------------------------------------------------------
|
||||
tst.b (a5)
|
||||
bne irq6_1
|
||||
tst.b 2(a5)
|
||||
bne irq6_1
|
||||
movem.l (a7),d0/a5
|
||||
addq.l #8,a7
|
||||
rte
|
||||
irq6_1:
|
||||
lea MCF_GPIO_PODR_FEC1L,a5
|
||||
bclr.b #4,(a5) // led on
|
||||
lea blinker,a5
|
||||
addq.l #1,(a5) // +1
|
||||
move.l (a5),d0
|
||||
and.l #0x80,d0
|
||||
bne irq6_2
|
||||
lea MCF_GPIO_PODR_FEC1L,a5
|
||||
bset.b #4,(a5) // led off
|
||||
irq6_2:
|
||||
// test auf protect mode ---------------------
|
||||
move.b DIP_SWITCHa,d0
|
||||
btst #7,d0
|
||||
bne irq6_3 // ja->
|
||||
// -------------------------------------------
|
||||
move.l 0xF0020000,a5 // vector holen
|
||||
add.l _rt_vbr,a5 // basis
|
||||
move.l (a5),d0 // vector holen
|
||||
move.l 4(a7),a5 // a5 zur<EFBFBD>ck
|
||||
move.l d0,4(a7) // vector eintragen
|
||||
move.l (a7)+,d0 // d0 zur<EFBFBD>ck
|
||||
move #0x2600,sr
|
||||
rts
|
||||
irq6_3:
|
||||
move.l usp,a5 // usp holen
|
||||
tst.b _rt_mod // supervisor?
|
||||
bne sev_sup6 // ja ->
|
||||
mov3q.l #-1,_rt_mod // auf supervisor setzen
|
||||
move.l a5,_rt_usp // rt_usp speichern
|
||||
move.l _rt_ssp,a5 // rt_ssp holen
|
||||
#ifdef cf_stack
|
||||
move.l 12(a7),-(a5) // pc transferieren
|
||||
move.l 8(a7),-(a5) // sr transferieren
|
||||
#else
|
||||
move.w 8(a7),-(a5) // vector transferieren
|
||||
move.l 12(a7),-(a5) // pc transferieren
|
||||
move.w 10(a7),-(a5) // sr transferieren
|
||||
#endif
|
||||
move.l a5,usp // usp setzen
|
||||
move.l 0xF0020000,a5 // vector holen: intack routine
|
||||
add.l _rt_vbr,a5 // virtuelle VBR des Systems
|
||||
move.l (a5),12(a7) // hier gehts weiter
|
||||
movem.l (a7),d0/a5 // register zur<EFBFBD>ck
|
||||
addq.l #8,a7
|
||||
move.b #6,2(a7) // intmaske setzen
|
||||
rte // und weg
|
||||
sev_sup6:
|
||||
#ifdef cf_stack
|
||||
move.l 12(a7),-(a5) // pc transferieren
|
||||
move.l 8(a7),-(a5) // sr,vec
|
||||
bset #5,2(a5) // auf super setzen
|
||||
#else
|
||||
move.w 8(a7),-(a5) // vector nr.
|
||||
move.l 12(a7),-(a5) // pc verschieben
|
||||
move.w 10(a7),-(a5) // sr verschieben
|
||||
bset #5,(a5) // auf super
|
||||
#endif
|
||||
move.l a5,usp // usp setzen
|
||||
move.l 0xF0020000,a5 // vector holen: intack routine
|
||||
add.l _rt_vbr,a5 // virtuelle VBR des Systems
|
||||
move.l (a5),12(a7) // hier gehts weiter
|
||||
movem.l (a7),d0/a5 // register zur<EFBFBD>ck
|
||||
rts
|
||||
|
||||
.data
|
||||
blinker:.long 0
|
||||
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* pseudo dma
|
||||
*/
|
||||
acsi_dma: // atari dma
|
||||
move.l a1,-(a7)
|
||||
move.l d1,-(a7)
|
||||
|
||||
lea MCF_PSC0_PSCTB_8BIT,a1 // ++ vr
|
||||
mchar move.l, 'D,'M','A,'\ ,(a1)
|
||||
//move.l #"DMA ",(a1)
|
||||
mchar move.l,'I,'N,'T,'!,(a1)
|
||||
// move.l #'INT!',(a1)
|
||||
|
||||
lea 0xf0020110,a5 // fifo daten
|
||||
acsi_dma_start:
|
||||
move.l -12(a5),a1 // dma adresse
|
||||
move.l -8(a5),d0 // byt counter
|
||||
ble acsi_dma_end
|
||||
btst.b #0,-16(a5) // write? (dma modus reg)
|
||||
bne acsi_dma_wl // ja->
|
||||
acsi_dma_rl:
|
||||
tst.b -4(a5) // dma req?
|
||||
bpl acsi_dma_fertig // nein->
|
||||
move.l (a5),(a1)+ // read 4 bytes
|
||||
move.l (a5),(a1)+ // read 4 bytes
|
||||
move.l (a5),(a1)+ // read 4 bytes
|
||||
move.l (a5),(a1)+ // read 4 bytes
|
||||
|
||||
moveq #'.',d1
|
||||
move.b d1,MCF_PSC0_PSCTB_8BIT
|
||||
|
||||
sub.l #16,d0 // byt counter -16
|
||||
bpl acsi_dma_rl
|
||||
bra acsi_dma_fertig
|
||||
acsi_dma_wl:
|
||||
tst.b -4(a5) // dma req?
|
||||
bpl acsi_dma_fertig // nein->
|
||||
move.l (a1)+,(a5) // write 4 byts
|
||||
move.l (a1)+,(a5) // write 4 byts
|
||||
move.l (a1)+,(a5) // write 4 byts
|
||||
move.l (a1)+,(a5) // write 4 byts
|
||||
|
||||
moveq #'.',d1
|
||||
move.b d1,MCF_PSC0_PSCTB_8BIT
|
||||
|
||||
sub.l #16,d0 // byt counter -16
|
||||
bpl acsi_dma_wl
|
||||
acsi_dma_fertig:
|
||||
move.l a1,-12(a5) // adresse zur<EFBFBD>ck
|
||||
move.l d0,-8(a5) // byt counter zur<EFBFBD>ck
|
||||
acsi_dma_end:
|
||||
tst.b -4(a5) // dma req?
|
||||
bmi acsi_dma_start // ja->
|
||||
lea 0xfffffa0b,a5
|
||||
bclr.b #7,4(a5) // clear int in service mfp
|
||||
bclr.b #7,(a5) // clear int pending mfp 0xfffffa0b
|
||||
|
||||
move.w #0x0d0a,d1
|
||||
move.w d1,MCF_PSC0_PSCTB_8BIT
|
||||
|
||||
move.l (a7)+,d1
|
||||
move.l (a7)+,a1
|
||||
rts
|
||||
/*
|
||||
* irq 7 = pseudo bus error
|
||||
*/
|
||||
irq7:
|
||||
lea -12(sp),sp
|
||||
movem.l d0/a0,(sp)
|
||||
|
||||
move.l __RAMBAR0+0x008,a0 // Real Access Error handler
|
||||
move.l a0,8(sp) // This will be the return address for rts
|
||||
|
||||
move.w 12(sp),d0 // Format/Vector word
|
||||
andi.l #0xf000,d0 // Keep only the Format
|
||||
ori.l #2*4,d0 // Simulate Vector #2, no Fault
|
||||
move.w d0,12(sp)
|
||||
|
||||
// TODO: Inside an interrupt handler, 16(sp) is the return address.
|
||||
// For an Access Error, it should be the address of the fault instruction instead
|
||||
|
||||
lea MCF_EPORT_EPFR,a0
|
||||
move.b #0x80,(a0) // clear int7
|
||||
move.l (sp)+,d0
|
||||
move.l (sp)+,a0
|
||||
rts // Forward to the Access Error handler
|
||||
|
||||
/*
|
||||
* psc3 com PIC MCF
|
||||
*/
|
||||
psc3:
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
lea -20(a7),a7
|
||||
movem.l d0-d2/a0/a3,(a7)
|
||||
lea MCF_PSC3_PSCRB_8BIT,a3
|
||||
move.b (a3),d1
|
||||
cmp.b #2,d1 // anforderung rtc daten?
|
||||
bne psc3_fertig
|
||||
|
||||
lea MCF_PSC0_PSCTB_8BIT,a0 // ++ vr
|
||||
mchar move.l,'\P,'\I,'C,' ,(a0)
|
||||
// move.l #'PIC ',(a0)
|
||||
mchar move.l,'I,'N,'T,'\ ,(a0)
|
||||
// move.l #'INT ',(a0)
|
||||
mchar move.l,'R,'T,'C,'!,(a0)
|
||||
// move.l #'RTC!',(a0)
|
||||
mchar move.l,0x0d,0x0a,0,0,(a0)
|
||||
//move.l #0x0d0a,(a0)
|
||||
|
||||
lea 0xffff8961,a0
|
||||
lea MCF_PSC3_PSCTB_8BIT,a3
|
||||
clr.l d1
|
||||
moveq #64,d2
|
||||
move.b #0x82,(a3) // header: rtcd mcf->pic
|
||||
loop_sr2:
|
||||
move.b d1,(a0)
|
||||
move.b 2(a0),d0
|
||||
move.b d0,(a3)
|
||||
addq.l #1,d1
|
||||
cmp.b d1,d2
|
||||
bne loop_sr2
|
||||
psc3_fertig:
|
||||
movem.l (a7),d0-d2/a0/a3 // register zur<EFBFBD>ck
|
||||
lea 20(a7),a7
|
||||
RTE
|
||||
|
||||
/*
|
||||
* timer 0: video change later also others
|
||||
*/
|
||||
timer0:
|
||||
move #0x2700,sr
|
||||
// halt
|
||||
lea -28(a7),a7
|
||||
movem.l d0-d4/a0-a1,(a7)
|
||||
mvz.b 0xffff8201,d0 // l<EFBFBD>schen und high byt
|
||||
cmp.w #2,d0
|
||||
blt video_chg_end
|
||||
cmp.w #0xd0,d0 // normale addresse
|
||||
blt sca_other // nein->
|
||||
lea MCF_SLT0_SCNT,a0
|
||||
move.l (a0),d4
|
||||
move.l d4,_video_sbt // time sichern
|
||||
sca_other:
|
||||
lsl.l #8,d0
|
||||
move.b 0xffff8203,d0 // mid byt
|
||||
lsl.l #8,d0
|
||||
move.b 0xffff820d,d0 // low byt
|
||||
move.l d0,d3
|
||||
video_chg_1page:
|
||||
// test ob page schon gesetzt
|
||||
moveq #20,d4
|
||||
move.l d0,d2
|
||||
lsr.l d4,d2 // neue page
|
||||
move.l _video_tlb,d4
|
||||
bset.l d2,d4 // setzen als ge<EFBFBD>ndert
|
||||
bne video_chg_2page // schon gesetzt gewesen? ja->weg
|
||||
move.l d4,_video_tlb
|
||||
bsr cpusha // cache leeren
|
||||
// daten copieren
|
||||
video_copy_data:
|
||||
move.l d4,_video_tlb
|
||||
and.l #0x00f00000,d0
|
||||
move.l d0,a0
|
||||
move.l a0,a1
|
||||
add.l #0x60000000,a1
|
||||
move.l #0x10000,d4 // die ganze page
|
||||
video_copy_data_loop:
|
||||
move.l (a0)+,(a1)+
|
||||
move.l (a0)+,(a1)+
|
||||
move.l (a0)+,(a1)+
|
||||
move.l (a0)+,(a1)+
|
||||
subq.l #1,d4
|
||||
bne video_copy_data_loop
|
||||
// eintrag suchen
|
||||
move.l d0,MCF_MMU_MMUAR // addresse
|
||||
move.l #0x106,d4
|
||||
move.l d4,MCF_MMU_MMUOR // suchen -> schl<EFBFBD>gt neuen vor wenn keiner
|
||||
nop
|
||||
move.l MCF_MMU_MMUOR,d4
|
||||
clr.w d4
|
||||
swap d4
|
||||
move.l d4,MCF_MMU_MMUAR
|
||||
move.l d0,d1
|
||||
add.l #MCF_MMU_MMUTR_ID(sca_page_ID)|std_mmutr,d0
|
||||
add.l #0x60000000|wt_mmudr|MCF_MMU_MMUDR_LK,d1
|
||||
mvz.w #0x10b,d2 // MMU update
|
||||
move.l d0,MCF_MMU_MMUTR
|
||||
move.l d1,MCF_MMU_MMUDR
|
||||
move.l d2,MCF_MMU_MMUOR // setzen vidoe maped to 60xxx only data
|
||||
nop
|
||||
video_chg_2page:
|
||||
// test ob evt. anschliessende page gesetzt werden muss
|
||||
move.l d3,d0
|
||||
mvz.w 0xffff8210,d4 // byts pro zeile
|
||||
mvz.w 0xffff82aa,d2 // zeilen ende
|
||||
mvz.w 0xffff82a8,d1 // zeilenstart
|
||||
sub.l d1,d2 // differenz = anzahl zeilen
|
||||
mulu d2,d4 // maximal 480 zeilen
|
||||
add.l d4,d0 // video gr<EFBFBD>sse
|
||||
cmp.l #__STRAM_END,d0 // maximale addresse
|
||||
bge video_chg_end // wenn gleich oder gr<EFBFBD>sser -> fertig
|
||||
moveq #20,d4
|
||||
move.l d0,d2
|
||||
lsr.l d4,d2 // neue page
|
||||
move.l _video_tlb,d4
|
||||
bset.l d2,d4 // setzen als ge<EFBFBD>ndert
|
||||
beq video_copy_data // nein nochmal
|
||||
video_chg_end:
|
||||
// int pending l<EFBFBD>schen
|
||||
lea MCF_GPT0_GMS,a0
|
||||
bclr.b #0,3(a0)
|
||||
nop
|
||||
bset.b #0,3(a0)
|
||||
|
||||
movem.l (a7),d0-d4/a0-a1
|
||||
lea 28(a7),a7
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
RTE
|
||||
|
||||
4158
i2cspi_BaS_gcc/sources/ff.c
Normal file
4158
i2cspi_BaS_gcc/sources/ff.c
Normal file
File diff suppressed because it is too large
Load Diff
111
i2cspi_BaS_gcc/sources/flash.c
Normal file
111
i2cspi_BaS_gcc/sources/flash.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* flash.c
|
||||
*
|
||||
* flashing routines for BaS_gcc
|
||||
*
|
||||
* Created on: 19.12.2012
|
||||
* Author: mfro
|
||||
* The ACP Firebee project
|
||||
*
|
||||
* This file is part of BaS_gcc.
|
||||
*
|
||||
* BaS_gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BaS_gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright 2012 M. Froeschle
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void chip_erase(uint8_t *address)
|
||||
{
|
||||
* (volatile uint8_t *) (address + 0xaaa) = 0xaa;
|
||||
* (volatile uint8_t *) (address + 0x555) = 0x55;
|
||||
* (volatile uint8_t *) (address + 0xaaa) = 0x80;
|
||||
* (volatile uint8_t *) (address + 0xaaa) = 0xaa;
|
||||
* (volatile uint8_t *) (address + 0x555) = 0x55;
|
||||
* (volatile uint8_t *) (address + 0xaaa) = 0x10;
|
||||
}
|
||||
|
||||
void sector_erase(uint8_t *address, uint16_t sector)
|
||||
{
|
||||
* (volatile uint8_t *) (address + 0xaaa) = 0xaa;
|
||||
* (volatile uint8_t *) (address + 0x555) = 0x55;
|
||||
* (volatile uint8_t *) (address + 0xaaa) = 0x80;
|
||||
* (volatile uint8_t *) (address + 0xaaa) = 0xaa;
|
||||
* (volatile uint8_t *) (address + 0x555) = 0x55;
|
||||
* (volatile uint8_t *) (address + sector) = 0x30;
|
||||
|
||||
do {
|
||||
;
|
||||
} while (* (volatile uint32_t *) (address + sector) != 0xffffffff);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _NOT_USED_
|
||||
* MX28LV640DB.alg
|
||||
bra lab0x5a
|
||||
move.w #0xaa,d0
|
||||
move.w d0,0xaaa(a5)
|
||||
move.w #0xff,d0
|
||||
move.w d0,0x554(a5)
|
||||
move.w #0x20,d0
|
||||
move.w d0,0xaaa(a5)
|
||||
lab0x1c:
|
||||
move.w #0xa0,d0
|
||||
move.w d0,(a5)
|
||||
moveq #0,d0
|
||||
move.w (a3),d0
|
||||
move.w d0,(a4)
|
||||
lab0x28:
|
||||
move.w (a4),d1
|
||||
andi.l #0xffff,d1
|
||||
cmp.l d1,d0
|
||||
bne.s lab0x28
|
||||
adda.l #2,a3
|
||||
adda.l #2,a4
|
||||
cmpa.l a2,a3
|
||||
blt.s lab0x1c
|
||||
move.w #0x90,d0
|
||||
move.w d0,(a5)
|
||||
move.w #0,d0
|
||||
move.w d0,(a5)
|
||||
lab0x50:
|
||||
nop
|
||||
nop
|
||||
halt
|
||||
nop
|
||||
bra.s lab0x50
|
||||
lab0x5a:
|
||||
move.w #0xaa,d0
|
||||
move.w d0,0xaaa(a5)
|
||||
move.w #0x55,d0
|
||||
move.w d0,0x554(a5)
|
||||
move.w #0x80,d0
|
||||
move.w d0,0xaaa(a5)
|
||||
move.w #0xaa,d0
|
||||
move.w d0,0xaaa(a5)
|
||||
move.w #0x55,d0
|
||||
move.w d0,0x554(a5)
|
||||
move.w #0x30,d0
|
||||
move.w d0,(a4)
|
||||
lab0x88:
|
||||
move.l (a4),d1
|
||||
move.l #-1,d0
|
||||
cmp.l d1,d0
|
||||
bne.s lab0x88
|
||||
nop
|
||||
nop
|
||||
halt
|
||||
nop
|
||||
#endif /* _NOT_USED_ */
|
||||
42
i2cspi_BaS_gcc/sources/illegal_instruction.S
Normal file
42
i2cspi_BaS_gcc/sources/illegal_instruction.S
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* illegal_instruction.S
|
||||
*
|
||||
* This file is part of BaS_gcc.
|
||||
*
|
||||
* BaS_gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BaS_gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright 2010 - 2012 F. Aschwanden
|
||||
* Copyright 2011 - 2012 V. Riviere
|
||||
* Copyright 2012 M. Froeschle
|
||||
*/
|
||||
|
||||
.global _illegal_instruction
|
||||
.global _illegal_table_make
|
||||
|
||||
#include "startcf.h"
|
||||
|
||||
.extern _ii_shift_vec
|
||||
.extern ewf
|
||||
|
||||
/*******************************************************/
|
||||
.text
|
||||
ii_error:
|
||||
nop
|
||||
halt
|
||||
nop
|
||||
nop
|
||||
|
||||
_illegal_instruction:
|
||||
_illegal_table_make:
|
||||
rts
|
||||
113
i2cspi_BaS_gcc/sources/init_fpga.c
Normal file
113
i2cspi_BaS_gcc/sources/init_fpga.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* init_fpga.c
|
||||
*
|
||||
* This file is part of BaS_gcc.
|
||||
*
|
||||
* BaS_gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BaS_gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright 2010 - 2012 F. Aschwanden
|
||||
* Copyright 2011 - 2012 V. Riviere
|
||||
* Copyright 2012 M. Froeschle
|
||||
*
|
||||
*/
|
||||
|
||||
#include <MCF5475.h>
|
||||
#include "sysinit.h"
|
||||
|
||||
#define FPGA_STATUS (1 << 0)
|
||||
#define FPGA_CLOCK (1 << 1)
|
||||
#define FPGA_CONFIG (1 << 2)
|
||||
#define FPGA_DATA0 (1 << 3)
|
||||
#define FPGA_CONF_DONE (1 << 5)
|
||||
|
||||
extern void xprintf_before_copy(const char *fmt, ...);
|
||||
|
||||
#define xprintf xprintf_before_copy
|
||||
#define display_progress display_progress_before_copy
|
||||
/*
|
||||
* load FPGA
|
||||
*/
|
||||
void init_fpga(void)
|
||||
{
|
||||
register uint8_t *fpga_data;
|
||||
register int i;
|
||||
|
||||
xprintf("FPGA load config... ");
|
||||
|
||||
|
||||
MCF_GPIO_PODR_FEC1L &= ~FPGA_CLOCK; /* FPGA clock => low */
|
||||
MCF_GPIO_PODR_FEC1L &= ~FPGA_CONFIG; /* FPGA config => low */
|
||||
|
||||
while ((MCF_GPIO_PPDSDR_FEC1L & FPGA_STATUS) && (MCF_GPIO_PPDSDR_FEC1L & FPGA_CONF_DONE));
|
||||
MCF_GPIO_PODR_FEC1L |= FPGA_CONFIG; /* pull FPGA_CONFIG high */
|
||||
while (!(MCF_GPIO_PPDSDR_FEC1L & FPGA_STATUS)); /* wait until status becomes high */
|
||||
|
||||
/*
|
||||
* excerpt from an Altera configuration manual:
|
||||
*
|
||||
* The low-to-high transition of nCONFIG on the FPGA begins the configuration cycle. The
|
||||
* configuration cycle consists of 3 stages<65>reset, configuration, and initialization.
|
||||
* While nCONFIG is low, the device is in reset. When the device comes out of reset,
|
||||
* nCONFIG must be at a logic high level in order for the device to release the open-drain
|
||||
* nSTATUS pin. After nSTATUS is released, it is pulled high by a pull-up resistor and the FPGA
|
||||
* is ready to receive configuration data. Before and during configuration, all user I/O pins
|
||||
* are tri-stated. Stratix series, Arria series, and Cyclone series have weak pull-up resistors
|
||||
* on the I/O pins which are on, before and during configuration.
|
||||
*
|
||||
* To begin configuration, nCONFIG and nSTATUS must be at a logic high level. You can delay
|
||||
* configuration by holding the nCONFIG low. The device receives configuration data on its
|
||||
* DATA0 pins. Configuration data is latched into the FPGA on the rising edge of DCLK. After
|
||||
* the FPGA has received all configuration data successfully, it releases the CONF_DONE pin,
|
||||
* which is pulled high by a pull-up resistor. A low to high transition on CONF_DONE indicates
|
||||
* configuration is complete and initialization of the device can begin.
|
||||
*/
|
||||
fpga_data = (uint8_t *) FPGA_FLASH_DATA;
|
||||
do
|
||||
{
|
||||
uint8_t value = *fpga_data++;
|
||||
for (i = 0; i < 8; i++, value >>= 1)
|
||||
{
|
||||
|
||||
if (value & 1)
|
||||
{
|
||||
/* bit set -> toggle DATA0 to high */
|
||||
MCF_GPIO_PODR_FEC1L |= FPGA_DATA0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bit is cleared -> toggle DATA0 to low */
|
||||
MCF_GPIO_PODR_FEC1L &= ~FPGA_DATA0;
|
||||
}
|
||||
/* toggle DCLK -> FPGA reads the bit */
|
||||
MCF_GPIO_PODR_FEC1L |= FPGA_CLOCK;
|
||||
MCF_GPIO_PODR_FEC1L &= ~FPGA_CLOCK;
|
||||
}
|
||||
} while ((!(MCF_GPIO_PPDSDR_FEC1L & FPGA_CONF_DONE)) && (fpga_data < (uint8_t *) FPGA_FLASH_DATA_END));
|
||||
|
||||
if (fpga_data < (uint8_t *) FPGA_FLASH_DATA_END)
|
||||
{
|
||||
while (fpga_data++ < (uint8_t *) FPGA_FLASH_DATA_END)
|
||||
{
|
||||
/* toggle a little more since it's fun ;) */
|
||||
MCF_GPIO_PODR_FEC1L |= FPGA_CLOCK;
|
||||
MCF_GPIO_PODR_FEC1L &= ~FPGA_CLOCK;
|
||||
}
|
||||
|
||||
xprintf("finished\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("FAILED!\r\n");
|
||||
}
|
||||
}
|
||||
100
i2cspi_BaS_gcc/sources/main.c
Normal file
100
i2cspi_BaS_gcc/sources/main.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* FatFs sample project for generic microcontrollers (C)ChaN, 2012 */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ff.h"
|
||||
|
||||
|
||||
FATFS Fatfs; /* File system object */
|
||||
FIL Fil; /* File object */
|
||||
uint8_t Buff[128]; /* File read buffer */
|
||||
|
||||
|
||||
void die ( /* Stop with dying message */
|
||||
FRESULT rc /* FatFs return value */
|
||||
)
|
||||
{
|
||||
xprintf("Failed with rc=%u.\n", rc);
|
||||
for (;;) ;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Program Main */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
int main (void)
|
||||
{
|
||||
FRESULT rc; /* Result code */
|
||||
DIR dir; /* Directory object */
|
||||
FILINFO fno; /* File information object */
|
||||
uint32_t bw, br, i;
|
||||
|
||||
|
||||
f_mount(0, &Fatfs); /* Register volume work area (never fails) */
|
||||
|
||||
xprintf("\nOpen an existing file (message.txt).\n");
|
||||
rc = f_open(&Fil, "MESSAGE.TXT", FA_READ);
|
||||
if (rc) die(rc);
|
||||
|
||||
xprintf("\nType the file content.\n");
|
||||
for (;;) {
|
||||
rc = f_read(&Fil, Buff, sizeof Buff, &br); /* Read a chunk of file */
|
||||
if (rc || !br) break; /* Error or end of file */
|
||||
for (i = 0; i < br; i++) /* Type the data */
|
||||
putchar(Buff[i]);
|
||||
}
|
||||
if (rc) die(rc);
|
||||
|
||||
xprintf("\nClose the file.\n");
|
||||
rc = f_close(&Fil);
|
||||
if (rc) die(rc);
|
||||
|
||||
xprintf("\nCreate a new file (hello.txt).\n");
|
||||
rc = f_open(&Fil, "HELLO.TXT", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
if (rc) die(rc);
|
||||
|
||||
xprintf("\nWrite a text data. (Hello world!)\n");
|
||||
rc = f_write(&Fil, "Hello world!\r\n", 14, &bw);
|
||||
if (rc) die(rc);
|
||||
xprintf("%u bytes written.\n", bw);
|
||||
|
||||
xprintf("\nClose the file.\n");
|
||||
rc = f_close(&Fil);
|
||||
if (rc) die(rc);
|
||||
|
||||
xprintf("\nOpen root directory.\n");
|
||||
rc = f_opendir(&dir, "");
|
||||
if (rc) die(rc);
|
||||
|
||||
xprintf("\nDirectory listing...\n");
|
||||
for (;;) {
|
||||
rc = f_readdir(&dir, &fno); /* Read a directory item */
|
||||
if (rc || !fno.fname[0]) break; /* Error or end of dir */
|
||||
if (fno.fattrib & AM_DIR)
|
||||
xprintf(" <dir> %s\n", fno.fname);
|
||||
else
|
||||
xprintf("%8lu %s\n", fno.fsize, fno.fname);
|
||||
}
|
||||
if (rc) die(rc);
|
||||
|
||||
xprintf("\nTest completed.\n");
|
||||
for (;;) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------*/
|
||||
/* User Provided Timer Function for FatFs module */
|
||||
/*---------------------------------------------------------*/
|
||||
|
||||
uint32_t get_fattime (void)
|
||||
{
|
||||
return ((uint32_t)(2012 - 1980) << 25) /* Year = 2012 */
|
||||
| ((uint32_t)1 << 21) /* Month = 1 */
|
||||
| ((uint32_t)1 << 16) /* Day_m = 1*/
|
||||
| ((uint32_t)0 << 11) /* Hour = 0 */
|
||||
| ((uint32_t)0 << 5) /* Min = 0 */
|
||||
| ((uint32_t)0 >> 1); /* Sec = 0 */
|
||||
}
|
||||
652
i2cspi_BaS_gcc/sources/mmc.c
Normal file
652
i2cspi_BaS_gcc/sources/mmc.c
Normal file
@@ -0,0 +1,652 @@
|
||||
#include <stdint.h>
|
||||
#include <bas_types.h>
|
||||
#include <sd_card.h>
|
||||
#include <bas_printf.h>
|
||||
#include <sysinit.h>
|
||||
#include <wait.h>
|
||||
#include <MCF5475.h>
|
||||
|
||||
/*
|
||||
* Firebee: MMCv3/SDv1/SDv2 (SPI mode) control module
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2011, ChaN, all right reserved.
|
||||
*
|
||||
* This software is a free software and there is NO WARRANTY.
|
||||
* No restriction on use. You can use, modify and redistribute it for
|
||||
* personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
|
||||
* Redistributions of source code must retain the above copyright notice.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2012, mfro, all rights reserved. */
|
||||
|
||||
|
||||
#define CS_HIGH() { dspi_fifo_val &= ~MCF_DSPI_DTFR_CS5; }
|
||||
#define CS_LOW() { dspi_fifo_val |= MCF_DSPI_DTFR_CS5; }
|
||||
|
||||
#define SPICLK_FAST() { MCF_DSPI_DCTAR0 = MCF_DSPI_DCTAR_TRSZ(0b111) | /* transfer size = 8 bit */ \
|
||||
MCF_DSPI_DCTAR_PCSSCK(0b01) | /* 1 clock DSPICS to DSPISCK delay prescaler */ \
|
||||
MCF_DSPI_DCTAR_PASC_1CLK | /* 1 clock DSPISCK to DSPICS negation prescaler */ \
|
||||
MCF_DSPI_DCTAR_PDT_1CLK | /* 1 clock delay between DSPICS assertions prescaler */ \
|
||||
MCF_DSPI_DCTAR_PBR_3CLK | /* 3 clock Baudrate prescaler */ \
|
||||
MCF_DSPI_DCTAR_ASC(0b0000) | /* 2 */ \
|
||||
MCF_DSPI_DCTAR_DT(0b0000) | /* 2 */ \
|
||||
MCF_DSPI_DCTAR_BR(0b0000); } /* clock / 2 */
|
||||
|
||||
#define SPICLK_SLOW() { MCF_DSPI_DCTAR0 = MCF_DSPI_DCTAR_TRSZ(0b111) | /* transfer size = 8 bit */ \
|
||||
MCF_DSPI_DCTAR_PCSSCK(0b01) | /* 3 clock DSPICS to DSPISCK delay prescaler */ \
|
||||
MCF_DSPI_DCTAR_PASC_3CLK | /* 3 clock DSPISCK to DSPICS negation prescaler */ \
|
||||
MCF_DSPI_DCTAR_PDT_3CLK | /* 3 clock delay between DSPICS assertions prescaler */ \
|
||||
MCF_DSPI_DCTAR_PBR_3CLK | /* 3 clock prescaler */ \
|
||||
MCF_DSPI_DCTAR_ASC(0b1001) | /* 1024 */ \
|
||||
MCF_DSPI_DCTAR_DT(0b1001) | /* 1024 */ \
|
||||
MCF_DSPI_DCTAR_BR(0b0111); }
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Module Private Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#include "diskio.h"
|
||||
|
||||
|
||||
/* MMC/SD command */
|
||||
#define CMD0 (0) /* GO_IDLE_STATE */
|
||||
#define CMD1 (1) /* SEND_OP_COND (MMC) */
|
||||
#define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */
|
||||
#define CMD8 (8) /* SEND_IF_COND */
|
||||
#define CMD9 (9) /* SEND_CSD */
|
||||
#define CMD10 (10) /* SEND_CID */
|
||||
#define CMD12 (12) /* STOP_TRANSMISSION */
|
||||
#define ACMD13 (0x80+13) /* SD_STATUS (SDC) */
|
||||
#define CMD16 (16) /* SET_BLOCKLEN */
|
||||
#define CMD17 (17) /* READ_SINGLE_BLOCK */
|
||||
#define CMD18 (18) /* READ_MULTIPLE_BLOCK */
|
||||
#define CMD23 (23) /* SET_BLOCK_COUNT (MMC) */
|
||||
#define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
|
||||
#define CMD24 (24) /* WRITE_BLOCK */
|
||||
#define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
|
||||
#define CMD32 (32) /* ERASE_ER_BLK_START */
|
||||
#define CMD33 (33) /* ERASE_ER_BLK_END */
|
||||
#define CMD38 (38) /* ERASE */
|
||||
#define CMD55 (55) /* APP_CMD */
|
||||
#define CMD58 (58) /* READ_OCR */
|
||||
|
||||
|
||||
static volatile DSTATUS Stat = 0 /* STA_NOINIT */; /* Physical drive status */
|
||||
static uint8_t CardType; /* Card type flags */
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Send/Receive data to the MMC (Platform dependent) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static uint32_t dspi_fifo_val = /* CONT disable continous chip select */
|
||||
/* CTAS use DCTAR0 for clock and attributes */
|
||||
MCF_DSPI_DTFR_EOQ | /* current transfer is last in queue */
|
||||
MCF_DSPI_DTFR_CTCNT;
|
||||
|
||||
/* Exchange a byte */
|
||||
static uint8_t xchg_spi(uint8_t byte)
|
||||
{
|
||||
uint32_t fifo = dspi_fifo_val | byte;
|
||||
uint8_t res;
|
||||
|
||||
MCF_DSPI_DTFR = fifo;
|
||||
while (! (MCF_DSPI_DSR & MCF_DSPI_DSR_TCF)); /* wait until DSPI transfer complete */
|
||||
MCF_DSPI_DSR = 0xffffffff; /* clear DSPI status register */
|
||||
|
||||
fifo = MCF_DSPI_DRFR;
|
||||
MCF_DSPI_DSR = 0xffffffff;
|
||||
res = fifo & 0xff;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* Receive multiple byte
|
||||
*
|
||||
* buff: pointer to data buffer
|
||||
* btr: number of bytes to receive (16, 64 or 512)
|
||||
*/
|
||||
static void rcvr_spi_multi(uint8_t *buff, uint32_t count)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
*buff++ = xchg_spi(0xff);
|
||||
}
|
||||
|
||||
|
||||
#if _USE_WRITE
|
||||
/* Send multiple byte
|
||||
*
|
||||
* buff: pointer to data
|
||||
* btx: number of bytes to send
|
||||
*/
|
||||
static void xmit_spi_multi(const uint8_t *buff, uint32_t btx)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < btx; i++)
|
||||
xchg_spi(*buff++);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static bool card_ready(void)
|
||||
{
|
||||
uint8_t d;
|
||||
|
||||
d = xchg_spi(0xff);
|
||||
return (d == 0xff);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for card ready
|
||||
*
|
||||
* wt: timeout in ms
|
||||
* returns 1: ready, 0: timeout
|
||||
*/
|
||||
static int wait_ready(uint32_t wt)
|
||||
{
|
||||
return waitfor(wt, card_ready);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Deselect card and release SPI
|
||||
*/
|
||||
static void deselect(void)
|
||||
{
|
||||
CS_HIGH();
|
||||
xchg_spi(0xFF); /* Dummy clock (force DO hi-z for multiple slave SPI) */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Select card and wait for ready
|
||||
*/
|
||||
|
||||
static int select(void) /* 1:OK, 0:Timeout */
|
||||
{
|
||||
CS_LOW();
|
||||
|
||||
xchg_spi(0xFF); /* Dummy clock (force DO enabled) */
|
||||
|
||||
if (wait_ready(5000000))
|
||||
return 1; /* OK */
|
||||
deselect();
|
||||
return 0; /* Timeout */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Control SPI module (Platform dependent)
|
||||
*/
|
||||
static void power_on (void) /* Enable SSP module */
|
||||
{
|
||||
MCF_PAD_PAR_DSPI = 0x1fff; /* configure all DSPI GPIO pins for DSPI usage */
|
||||
|
||||
/*
|
||||
* FIXME: really necessary or just an oversight
|
||||
* that PAD_PAR_DSPI is only 16 bit?
|
||||
*/
|
||||
// MCF_PAD_PAR_TIMER = 0xff; leave off for now
|
||||
|
||||
/*
|
||||
* initialize DSPI module configuration register
|
||||
*/
|
||||
MCF_DSPI_DMCR = MCF_DSPI_DMCR_MSTR | /* FireBee is DSPI master*/
|
||||
MCF_DSPI_DMCR_CSIS5 | /* CS5 inactive state high */
|
||||
MCF_DSPI_DMCR_CSIS3 | /* CS3 inactive state high */
|
||||
MCF_DSPI_DMCR_CSIS2 | /* CS2 inactive state high */
|
||||
MCF_DSPI_DMCR_DTXF | /* disable transmit FIFO */
|
||||
MCF_DSPI_DMCR_DRXF | /* disable receive FIFO */
|
||||
MCF_DSPI_DMCR_CTXF | /* clear transmit FIFO */
|
||||
MCF_DSPI_DMCR_CRXF; /* clear receive FIFO */
|
||||
|
||||
/* initialize DSPI clock and transfer attributes register 0 */
|
||||
MCF_DSPI_DCTAR0 = MCF_DSPI_DCTAR_TRSZ(0b111) | /* transfer size = 8 bit */
|
||||
MCF_DSPI_DCTAR_PCSSCK(0b01) | /* 3 clock DSPICS to DSPISCK delay prescaler */
|
||||
MCF_DSPI_DCTAR_PASC_3CLK | /* 3 clock DSPISCK to DSPICS negation prescaler */
|
||||
MCF_DSPI_DCTAR_PDT_3CLK | /* 3 clock delay between DSPICS assertions prescaler */
|
||||
MCF_DSPI_DCTAR_PBR_3CLK | /* 3 clock prescaler */
|
||||
MCF_DSPI_DCTAR_ASC(0b1001) | /* 1024 */
|
||||
MCF_DSPI_DCTAR_DT(0b1001) | /* 1024 */
|
||||
MCF_DSPI_DCTAR_BR(0b0111);
|
||||
|
||||
CS_HIGH(); /* Set CS# high */
|
||||
|
||||
/* card should now be initialized as MMC */
|
||||
|
||||
wait(10 * 1000); /* 10ms */
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void power_off (void) /* Disable SPI function */
|
||||
{
|
||||
select(); /* Wait for card ready */
|
||||
deselect();
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Receive a data packet from the MMC */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static
|
||||
int rcvr_datablock ( /* 1:OK, 0:Error */
|
||||
uint8_t *buff, /* Data buffer */
|
||||
uint32_t btr /* Data block length (byte) */
|
||||
)
|
||||
{
|
||||
uint8_t token;
|
||||
uint32_t target = MCF_SLT_SCNT(0) - (200 * 1000L * 132);
|
||||
|
||||
do { /* Wait for DataStart token in timeout of 200ms */
|
||||
token = xchg_spi(0xFF);
|
||||
/* This loop will take a time. Insert rot_rdq() here for multitask envilonment. */
|
||||
} while ((token == 0xFF) && MCF_SLT_SCNT(0) > target);
|
||||
if(token != 0xFE) return 0; /* Function fails if invalid DataStart token or timeout */
|
||||
|
||||
rcvr_spi_multi(buff, btr); /* Store trailing data to the buffer */
|
||||
xchg_spi(0xFF); xchg_spi(0xFF); /* Discard CRC */
|
||||
|
||||
return 1; /* Function succeeded */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Send a data packet to the MMC */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_WRITE
|
||||
static
|
||||
int xmit_datablock ( /* 1:OK, 0:Failed */
|
||||
const uint8_t *buff, /* Ponter to 512 byte data to be sent */
|
||||
uint8_t token /* Token */
|
||||
)
|
||||
{
|
||||
uint8_t resp;
|
||||
|
||||
|
||||
if (!wait_ready(500)) return 0; /* Wait for card ready */
|
||||
|
||||
xchg_spi(token); /* Send token */
|
||||
if (token != 0xFD) { /* Send data if token is other than StopTran */
|
||||
xmit_spi_multi(buff, 512); /* Data */
|
||||
xchg_spi(0xFF); xchg_spi(0xFF); /* Dummy CRC */
|
||||
|
||||
resp = xchg_spi(0xFF); /* Receive data resp */
|
||||
if ((resp & 0x1F) != 0x05) /* Function fails if the data packet was not accepted */
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Send a command packet to the MMC */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static uint8_t send_cmd ( /* Return value: R1 resp (bit7==1:Failed to send) */
|
||||
uint8_t cmd, /* Command index */
|
||||
uint32_t arg /* Argument */
|
||||
)
|
||||
{
|
||||
uint8_t n, res;
|
||||
|
||||
|
||||
if (cmd & 0x80) { /* Send a CMD55 prior to ACMD<n> */
|
||||
cmd &= 0x7F;
|
||||
res = send_cmd(CMD55, 0);
|
||||
if (res > 1) return res;
|
||||
}
|
||||
|
||||
/* Select card */
|
||||
deselect();
|
||||
if (!select()) return 0xFF;
|
||||
|
||||
/* Send command packet */
|
||||
xchg_spi(0x40 | cmd); /* Start + command index */
|
||||
xchg_spi((uint8_t)(arg >> 24)); /* Argument[31..24] */
|
||||
xchg_spi((uint8_t)(arg >> 16)); /* Argument[23..16] */
|
||||
xchg_spi((uint8_t)(arg >> 8)); /* Argument[15..8] */
|
||||
xchg_spi((uint8_t)arg); /* Argument[7..0] */
|
||||
n = 0x01; /* Dummy CRC + Stop */
|
||||
if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */
|
||||
if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */
|
||||
xchg_spi(n);
|
||||
|
||||
/* Receive command resp */
|
||||
if (cmd == CMD12) xchg_spi(0xFF); /* Diacard following one byte when CMD12 */
|
||||
n = 10; /* Wait for response (10 bytes max) */
|
||||
do
|
||||
res = xchg_spi(0xFF);
|
||||
while ((res & 0x80) && --n);
|
||||
|
||||
return res; /* Return received response */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Public Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*
|
||||
* Initialize disk drive
|
||||
*
|
||||
* drv: physical drive number (0)
|
||||
*/
|
||||
DSTATUS disk_initialize(uint8_t drv)
|
||||
{
|
||||
uint8_t n, cmd, ty, ocr[4];
|
||||
|
||||
|
||||
if (drv) return STA_NOINIT; /* Supports only drive 0 */
|
||||
power_on(); /* Initialize SPI */
|
||||
|
||||
if (Stat & STA_NODISK) return Stat; /* Is card existing in the socket? */
|
||||
|
||||
SPICLK_SLOW();
|
||||
for (n = 10; n; n--) xchg_spi(0xFF); /* Send 80 dummy clocks */
|
||||
|
||||
ty = 0;
|
||||
if (send_cmd(CMD0, 0) == 1) { /* Put the card SPI/Idle state */
|
||||
uint32_t target = MCF_SLT_SCNT(0) - (1000L * 1000L * 132); /* 1 sec */
|
||||
|
||||
if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2? */
|
||||
for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); /* Get 32 bit return value of R7 resp */
|
||||
if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* Is the card supports vcc of 2.7-3.6V? */
|
||||
while (MCF_SLT_SCNT(0) > target && send_cmd(ACMD41, 1UL << 30)) ; /* Wait for end of initialization with ACMD41(HCS) */
|
||||
if (MCF_SLT_SCNT(0) > target && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
|
||||
for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);
|
||||
ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* Card id SDv2 */
|
||||
}
|
||||
}
|
||||
} else { /* Not SDv2 card */
|
||||
if (send_cmd(ACMD41, 0) <= 1) { /* SDv1 or MMC? */
|
||||
ty = CT_SD1; cmd = ACMD41; /* SDv1 (ACMD41(0)) */
|
||||
} else {
|
||||
ty = CT_MMC; cmd = CMD1; /* MMCv3 (CMD1(0)) */
|
||||
}
|
||||
while (MCF_SLT_SCNT(0) > target && send_cmd(cmd, 0)) ; /* Wait for end of initialization */
|
||||
if (!MCF_SLT_SCNT(0) > target || send_cmd(CMD16, 512) != 0) /* Set block length: 512 */
|
||||
ty = 0;
|
||||
}
|
||||
}
|
||||
CardType = ty; /* Card type */
|
||||
deselect();
|
||||
|
||||
if (ty) { /* OK */
|
||||
SPICLK_FAST(); /* Set fast clock */
|
||||
Stat &= ~STA_NOINIT; /* Clear STA_NOINIT flag */
|
||||
} else { /* Failed */
|
||||
power_off();
|
||||
Stat = STA_NOINIT;
|
||||
}
|
||||
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get disk status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
uint8_t drv /* Physical drive number (0) */
|
||||
)
|
||||
{
|
||||
if (drv) return STA_NOINIT; /* Supports only drive 0 */
|
||||
|
||||
return Stat; /* Return disk status */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read (
|
||||
uint8_t drv, /* Physical drive number (0) */
|
||||
uint8_t *buff, /* Pointer to the data buffer to store read data */
|
||||
uint32_t sector, /* Start sector number (LBA) */
|
||||
uint8_t count /* Number of sectors to read (1..128) */
|
||||
)
|
||||
{
|
||||
if (drv || !count) return RES_PARERR; /* Check parameter */
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */
|
||||
|
||||
if (!(CardType & CT_BLOCK)) sector *= 512; /* LBA ot BA conversion (byte addressing cards) */
|
||||
|
||||
if (count == 1) { /* Single sector read */
|
||||
if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */
|
||||
&& rcvr_datablock(buff, 512))
|
||||
count = 0;
|
||||
}
|
||||
else { /* Multiple sector read */
|
||||
if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */
|
||||
do {
|
||||
if (!rcvr_datablock(buff, 512)) break;
|
||||
buff += 512;
|
||||
} while (--count);
|
||||
send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
|
||||
}
|
||||
}
|
||||
deselect();
|
||||
|
||||
return count ? RES_ERROR : RES_OK; /* Return result */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_WRITE
|
||||
DRESULT disk_write (
|
||||
uint8_t drv, /* Physical drive number (0) */
|
||||
const uint8_t *buff, /* Ponter to the data to write */
|
||||
uint32_t sector, /* Start sector number (LBA) */
|
||||
uint8_t count /* Number of sectors to write (1..128) */
|
||||
)
|
||||
{
|
||||
if (drv || !count) return RES_PARERR; /* Check parameter */
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check drive status */
|
||||
if (Stat & STA_PROTECT) return RES_WRPRT; /* Check write protect */
|
||||
|
||||
if (!(CardType & CT_BLOCK)) sector *= 512; /* LBA ==> BA conversion (byte addressing cards) */
|
||||
|
||||
if (count == 1) { /* Single sector write */
|
||||
if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
|
||||
&& xmit_datablock(buff, 0xFE))
|
||||
count = 0;
|
||||
}
|
||||
else { /* Multiple sector write */
|
||||
if (CardType & CT_SDC) send_cmd(ACMD23, count); /* Predefine number of sectors */
|
||||
if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
|
||||
do {
|
||||
if (!xmit_datablock(buff, 0xFC)) break;
|
||||
buff += 512;
|
||||
} while (--count);
|
||||
if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
deselect();
|
||||
|
||||
return count ? RES_ERROR : RES_OK; /* Return result */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous drive controls other than data read/write */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_IOCTL
|
||||
DRESULT disk_ioctl (
|
||||
uint8_t drv, /* Physical drive number (0) */
|
||||
uint8_t ctrl, /* Control command code */
|
||||
void *buff /* Pointer to the conrtol data */
|
||||
)
|
||||
{
|
||||
DRESULT res;
|
||||
uint8_t n, csd[16], *ptr = buff;
|
||||
uint32_t *dp, st, ed, csize;
|
||||
|
||||
|
||||
if (drv) return RES_PARERR; /* Check parameter */
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */
|
||||
|
||||
res = RES_ERROR;
|
||||
|
||||
switch (ctrl) {
|
||||
case CTRL_SYNC : /* Wait for end of internal write process of the drive */
|
||||
if (select()) {
|
||||
deselect();
|
||||
res = RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case GET_SECTOR_COUNT : /* Get drive capacity in unit of sector (DWORD) */
|
||||
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
|
||||
if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
|
||||
csize = csd[9] + ((uint16_t)csd[8] << 8) + ((uint32_t)(csd[7] & 63) << 16) + 1;
|
||||
*(uint32_t*)buff = csize << 10;
|
||||
} else { /* SDC ver 1.XX or MMC ver 3 */
|
||||
n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
|
||||
csize = (csd[8] >> 6) + ((uint16_t)csd[7] << 2) + ((uint16_t)(csd[6] & 3) << 10) + 1;
|
||||
*(uint32_t*)buff = csize << (n - 9);
|
||||
}
|
||||
res = RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case GET_SECTOR_SIZE : /* Get sector size in unit of byte (WORD) */
|
||||
*(uint16_t*)buff = 512;
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
|
||||
if (CardType & CT_SD2) { /* SDC ver 2.00 */
|
||||
if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */
|
||||
xchg_spi(0xFF);
|
||||
if (rcvr_datablock(csd, 16)) { /* Read partial block */
|
||||
for (n = 64 - 16; n; n--) xchg_spi(0xFF); /* Purge trailing data */
|
||||
*(uint32_t*)buff = 16UL << (csd[10] >> 4);
|
||||
res = RES_OK;
|
||||
}
|
||||
}
|
||||
} else { /* SDC ver 1.XX or MMC */
|
||||
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */
|
||||
if (CardType & CT_SD1) { /* SDC ver 1.XX */
|
||||
*(uint32_t*)buff = (((csd[10] & 63) << 1) + ((uint16_t)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
|
||||
} else { /* MMC */
|
||||
*(uint32_t*)buff = ((uint16_t)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
|
||||
}
|
||||
res = RES_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CTRL_ERASE_SECTOR : /* Erase a block of sectors (used when _USE_ERASE == 1) */
|
||||
if (!(CardType & CT_SDC)) break; /* Check if the card is SDC */
|
||||
if (disk_ioctl(drv, MMC_GET_CSD, csd)) break; /* Get CSD */
|
||||
if (!(csd[0] >> 6) && !(csd[10] & 0x40)) break; /* Check if sector erase can be applied to the card */
|
||||
dp = buff; st = dp[0]; ed = dp[1]; /* Load sector block */
|
||||
if (!(CardType & CT_BLOCK)) {
|
||||
st *= 512; ed *= 512;
|
||||
}
|
||||
if (send_cmd(CMD32, st) == 0 && send_cmd(CMD33, ed) == 0 && send_cmd(CMD38, 0) == 0 && wait_ready(30000)) /* Erase sector block */
|
||||
res = RES_OK; /* FatFs does not check result of this command */
|
||||
break;
|
||||
|
||||
/* Following command are not used by FatFs module */
|
||||
|
||||
case MMC_GET_TYPE : /* Get MMC/SDC type (BYTE) */
|
||||
*ptr = CardType;
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case MMC_GET_CSD : /* Read CSD (16 bytes) */
|
||||
if (send_cmd(CMD9, 0) == 0 /* READ_CSD */
|
||||
&& rcvr_datablock(ptr, 16))
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case MMC_GET_CID : /* Read CID (16 bytes) */
|
||||
if (send_cmd(CMD10, 0) == 0 /* READ_CID */
|
||||
&& rcvr_datablock(ptr, 16))
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case MMC_GET_OCR : /* Read OCR (4 bytes) */
|
||||
if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */
|
||||
for (n = 4; n; n--) *ptr++ = xchg_spi(0xFF);
|
||||
res = RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case MMC_GET_SDSTAT : /* Read SD status (64 bytes) */
|
||||
if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */
|
||||
xchg_spi(0xFF);
|
||||
if (rcvr_datablock(ptr, 64))
|
||||
res = RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
res = RES_PARERR;
|
||||
break;
|
||||
}
|
||||
|
||||
deselect();
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Device timer function */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* This function must be called from timer interrupt routine in period
|
||||
/ of 1 ms to generate card control timing.
|
||||
*/
|
||||
|
||||
#ifdef _NOT_USED_
|
||||
void disk_timerproc (void)
|
||||
{
|
||||
uint8_t s;
|
||||
|
||||
s = Stat;
|
||||
if (WP) /* Write protected */
|
||||
s |= STA_PROTECT;
|
||||
else /* Write enabled */
|
||||
s &= ~STA_PROTECT;
|
||||
//if (INS) /* Card is in socket */
|
||||
s &= ~STA_NODISK;
|
||||
//else /* Socket empty */
|
||||
// s |= (STA_NODISK | STA_NOINIT);
|
||||
Stat = s;
|
||||
}
|
||||
#endif /* _NOT_USED_ */
|
||||
195
i2cspi_BaS_gcc/sources/mmu.S
Normal file
195
i2cspi_BaS_gcc/sources/mmu.S
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* INIT ACR and MMU
|
||||
*/
|
||||
|
||||
#include "startcf.h"
|
||||
|
||||
.extern _rt_vbr
|
||||
.extern _rt_cacr
|
||||
.extern _rt_asid
|
||||
.extern _rt_acr0
|
||||
.extern _rt_acr1
|
||||
.extern _rt_acr2
|
||||
.extern _rt_acr3
|
||||
.extern _rt_mmubar
|
||||
.extern ___MMUBAR
|
||||
.extern cpusha
|
||||
.extern _video_tlb
|
||||
.extern _video_sbt
|
||||
.extern __TOS
|
||||
|
||||
/* Register read/write macros */
|
||||
#define MCF_MMU_MMUCR __MMUBAR
|
||||
#define MCF_MMU_MMUOR __MMUBAR+0x04
|
||||
#define MCF_MMU_MMUSR __MMUBAR+0x08
|
||||
#define MCF_MMU_MMUAR __MMUBAR+0x10
|
||||
#define MCF_MMU_MMUTR __MMUBAR+0x14
|
||||
#define MCF_MMU_MMUDR __MMUBAR+0x18
|
||||
|
||||
|
||||
/* Bit definitions and macros for MCF_MMU_MMUCR */
|
||||
#define MCF_MMU_MMUCR_EN (0x1)
|
||||
#define MCF_MMU_MMUCR_ASM (0x2)
|
||||
|
||||
/* Bit definitions and macros for MCF_MMU_MMUOR */
|
||||
#define MCF_MMU_MMUOR_UAA (0x1)
|
||||
#define MCF_MMU_MMUOR_ACC (0x2)
|
||||
#define MCF_MMU_MMUOR_RW (0x4)
|
||||
#define MCF_MMU_MMUOR_ADR (0x8)
|
||||
#define MCF_MMU_MMUOR_ITLB (0x10)
|
||||
#define MCF_MMU_MMUOR_CAS (0x20)
|
||||
#define MCF_MMU_MMUOR_CNL (0x40)
|
||||
#define MCF_MMU_MMUOR_CA (0x80)
|
||||
#define MCF_MMU_MMUOR_STLB (0x100)
|
||||
#define MCF_MMU_MMUOR_AA(x) (((x)&0xFFFF)<<0x10)
|
||||
|
||||
/* Bit definitions and macros for MCF_MMU_MMUSR */
|
||||
#define MCF_MMU_MMUSR_HIT (0x2)
|
||||
#define MCF_MMU_MMUSR_WF (0x8)
|
||||
#define MCF_MMU_MMUSR_RF (0x10)
|
||||
#define MCF_MMU_MMUSR_SPF (0x20)
|
||||
|
||||
/* Bit definitions and macros for MCF_MMU_MMUAR */
|
||||
#define MCF_MMU_MMUAR_FA(x) (((x)&0xFFFFFFFF)<<0)
|
||||
|
||||
/* Bit definitions and macros for MCF_MMU_MMUTR */
|
||||
#define MCF_MMU_MMUTR_V (0x1)
|
||||
#define MCF_MMU_MMUTR_SG (0x2)
|
||||
#define MCF_MMU_MMUTR_ID(x) (((x)&0xFF)<<0x2)
|
||||
#define MCF_MMU_MMUTR_VA(x) (((x)&0x3FFFFF)<<0xA)
|
||||
|
||||
/* Bit definitions and macros for MCF_MMU_MMUDR */
|
||||
#define MCF_MMU_MMUDR_LK (0x2)
|
||||
#define MCF_MMU_MMUDR_X (0x4)
|
||||
#define MCF_MMU_MMUDR_W (0x8)
|
||||
#define MCF_MMU_MMUDR_R (0x10)
|
||||
#define MCF_MMU_MMUDR_SP (0x20)
|
||||
#define MCF_MMU_MMUDR_CM(x) (((x)&0x3)<<0x6)
|
||||
#define MCF_MMU_MMUDR_SZ(x) (((x)&0x3)<<0x8)
|
||||
#define MCF_MMU_MMUDR_PA(x) (((x)&0x3FFFFF)<<0xA)
|
||||
|
||||
#define std_mmutr (MCF_MMU_MMUTR_SG|MCF_MMU_MMUTR_V)
|
||||
#define mmuord_d ( MCF_MMU_MMUOR_ACC|MCF_MMU_MMUOR_UAA)
|
||||
#define mmuord_i (MCF_MMU_MMUOR_ITLB|MCF_MMU_MMUOR_ACC|MCF_MMU_MMUOR_UAA)
|
||||
#define wt_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(00)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
||||
#define cb_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(01)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
||||
#define nc_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(10)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
|
||||
|
||||
.global _mmu_init
|
||||
.global _mmutr_miss
|
||||
|
||||
.text
|
||||
_mmu_init:
|
||||
move.l d3,-(sp) // Backup registers
|
||||
move.l d2,-(sp)
|
||||
|
||||
clr.l d0
|
||||
movec d0,ASID // ASID allways 0
|
||||
move.l d0,_rt_asid // sichern
|
||||
|
||||
move.l #0xC03FC040,d0 // data r/w precise c000'0000-ffff'ffff
|
||||
movec d0,ACR0
|
||||
move.l d0,_rt_acr0 // sichern
|
||||
|
||||
move.l #0x601FC000,d0 // data r/w wt 6000'0000-7fff'ffff
|
||||
movec d0,ACR1
|
||||
move.l d0,_rt_acr1 // sichern
|
||||
|
||||
move.l #0xe007C400,d0 // instruction r wt e000'0000-e07f'ffff
|
||||
movec d0,ACR2
|
||||
move.l d0,_rt_acr2 // sichern
|
||||
|
||||
clr.l d0 // acr3 aus
|
||||
movec d0,ACR3
|
||||
move.l d0,_rt_acr3 // sichern
|
||||
|
||||
move.l #__MMUBAR+1,d0
|
||||
movec d0,MMUBAR //mmubar setzen
|
||||
move.l d0,_rt_mmubar // sichern
|
||||
|
||||
nop
|
||||
|
||||
move.l #MCF_MMU_MMUOR_CA,d0 // clear all entries,
|
||||
move.l d0,MCF_MMU_MMUOR
|
||||
nop
|
||||
// 0000'0000 locked
|
||||
moveq.l #0x00000000|std_mmutr,d0
|
||||
moveq.l #0x00000000|cb_mmudr|MCF_MMU_MMUDR_LK,d1
|
||||
moveq.l #mmuord_d,d2 // MMU update date
|
||||
moveq.l #mmuord_i,d3 // MMU update instruction
|
||||
move.l d0,MCF_MMU_MMUTR
|
||||
move.l d1,MCF_MMU_MMUDR
|
||||
move.l d2,MCF_MMU_MMUOR // MMU update date
|
||||
move.l d3,MCF_MMU_MMUOR // MMU update instruction
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// 00d0'0000 locked ID=6
|
||||
// video ram: read write execute normal write true
|
||||
move.l #0x00d00000|MCF_MMU_MMUTR_ID(sca_page_ID)|std_mmutr,d0
|
||||
move.l #0x60d00000|wt_mmudr|MCF_MMU_MMUDR_LK,d1
|
||||
move.l d0,MCF_MMU_MMUTR
|
||||
move.l d1,MCF_MMU_MMUDR
|
||||
move.l d2,MCF_MMU_MMUOR // MMU update date
|
||||
move.l #0x00d00000|std_mmutr,d0
|
||||
move.l d3,MCF_MMU_MMUOR // MMU update instruction
|
||||
|
||||
move.l #0x2000,d0
|
||||
move.l d0,_video_tlb // set page as video page
|
||||
clr.l _video_sbt // clear time
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Make the TOS (in SDRAM) read-only
|
||||
move.l #__TOS+std_mmutr,d0
|
||||
move.l #__TOS+cb_mmudr+MCF_MMU_MMUDR_LK,d1
|
||||
move.l d0,MCF_MMU_MMUTR
|
||||
move.l d1,MCF_MMU_MMUDR
|
||||
move.l d2,MCF_MMU_MMUOR // setzen read only ?????? noch nicht
|
||||
move.l d3,MCF_MMU_MMUOR // setzen
|
||||
// 00f0'0000 locked
|
||||
move.l #0x00f00000|std_mmutr,d0
|
||||
move.l #0xfff00000|nc_mmudr|MCF_MMU_MMUDR_LK,d1
|
||||
move.l d0,MCF_MMU_MMUTR
|
||||
move.l d1,MCF_MMU_MMUDR
|
||||
move.l d2,MCF_MMU_MMUOR // maped to ffffxxx, precise,
|
||||
move.l d3,MCF_MMU_MMUOR // maped to ffffxxx, precise,
|
||||
// 1fe0'0000 locked
|
||||
move.l #0x1FE00000|std_mmutr,d0
|
||||
move.l #0x1FE00000|cb_mmudr|MCF_MMU_MMUDR_LK,d1
|
||||
move.l d0,MCF_MMU_MMUTR
|
||||
move.l d1,MCF_MMU_MMUDR
|
||||
move.l d2,MCF_MMU_MMUOR // setzen data
|
||||
move.l d3,MCF_MMU_MMUOR // setzen instr
|
||||
// 1ff0'0000 locked
|
||||
move.l #0x1FF00000|std_mmutr,d0
|
||||
move.l #0x1FF00000|cb_mmudr|MCF_MMU_MMUDR_LK,d1
|
||||
move.l d0,MCF_MMU_MMUTR
|
||||
move.l d1,MCF_MMU_MMUDR
|
||||
move.l d2,MCF_MMU_MMUOR // setzen data
|
||||
move.l d3,MCF_MMU_MMUOR // setzen instr
|
||||
// instr 0xFFF0'0000 nach 0x1FF0'0000 umleiten -->> short sprung
|
||||
/* move.l #0xFFF00000|std_mmutr,d0
|
||||
move.l #0x1FF00000|cb_mmudr|MCF_MMU_MMUDR_LK,d1
|
||||
move.l d0,MCF_MMU_MMUTR
|
||||
move.l d1,MCF_MMU_MMUDR
|
||||
move.l d3,MCF_MMU_MMUOR // setzen instr
|
||||
*/
|
||||
move.l (sp)+,d2 // Restore registers
|
||||
move.l (sp)+,d3
|
||||
rts
|
||||
|
||||
/*
|
||||
* MMU table search
|
||||
*/
|
||||
_mmutr_miss:
|
||||
bsr cpusha
|
||||
and.l #0xFFF00000,d0
|
||||
or.l #std_mmutr,d0
|
||||
move.l d0,MCF_MMU_MMUTR
|
||||
and.l #0xFFF00000,d0
|
||||
or.l #cb_mmudr,d0
|
||||
move.l d0,MCF_MMU_MMUDR
|
||||
moveq.l #mmuord_d,d0 // MMU update data
|
||||
move.l d0,MCF_MMU_MMUOR // setzen
|
||||
moveq.l #mmuord_i,d0 // MMU update instruction
|
||||
move.l d0,MCF_MMU_MMUOR // setzen
|
||||
move.l (sp)+,d0
|
||||
rte
|
||||
36
i2cspi_BaS_gcc/sources/printf_helper.S
Normal file
36
i2cspi_BaS_gcc/sources/printf_helper.S
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* printf_helper.S
|
||||
*
|
||||
* assembler trampoline to let printf (compiled -mpcrel) indirectly reference __MBAR
|
||||
*
|
||||
* This file is part of BaS_gcc.
|
||||
*
|
||||
* BaS_gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BaS_gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright 2010 - 2012 F. Aschwanden
|
||||
* Copyright 2011 - 2012 V. Riviere
|
||||
* Copyright 2012 M. Froeschle
|
||||
*/
|
||||
|
||||
|
||||
.global printf_helper
|
||||
printf_helper:
|
||||
.extern __MBAR
|
||||
.wait_txready:
|
||||
move.w __MBAR+0x8604,d2 // PSCSCR0 status register
|
||||
btst #10,d2 // space left in TX fifo?
|
||||
beq.s .wait_txready // no, loop
|
||||
lea __MBAR+0x860C,a0 // PSCSTB0 transmitter buffer register
|
||||
move.b d0,(a0) // send byte
|
||||
rts
|
||||
424
i2cspi_BaS_gcc/sources/s19reader.c
Normal file
424
i2cspi_BaS_gcc/sources/s19reader.c
Normal file
@@ -0,0 +1,424 @@
|
||||
/*
|
||||
* s19reader.c
|
||||
*
|
||||
* Created on: 17.12.2012
|
||||
* Author: mfro
|
||||
* The ACP Firebee project
|
||||
*
|
||||
* This file is part of BaS_gcc.
|
||||
*
|
||||
* BaS_gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BaS_gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright 2012 M. Froeschle
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bas_printf.h"
|
||||
#include "sd_card.h"
|
||||
#include "diskio.h"
|
||||
#include "ff.h"
|
||||
#include "s19reader.h"
|
||||
#include "cache.h"
|
||||
|
||||
/*
|
||||
* Yes, I know. The following doesn't really look like code should look like...
|
||||
*
|
||||
* I did try to map structures over the S-records with (packed) which didn't work reliably due to gcc _not_ packing them appropiate
|
||||
* and finally ended up with this. Not nice, put paid (and working).
|
||||
*
|
||||
*/
|
||||
#define SREC_TYPE(a) (a)[0] /* type of record */
|
||||
#define SREC_COUNT(a) (a)[1] /* length of valid bytes to follow */
|
||||
#define SREC_ADDR16(a) (256 * (a)[2] + (a)[3]) /* 2 byte address field */
|
||||
#define SREC_ADDR24(a) (0x10000 * (a)[2] + 0x100 * \
|
||||
(a)[3] + (a)[4]) /* 3 byte address field */
|
||||
#define SREC_ADDR32(a) (0x1000000 * a[2] + 0x10000 * \
|
||||
a[3] + 0x100 * (a)[4] + (a)[5]) /* 4 byte address field */
|
||||
#define SREC_DATA16(a) ((uint8_t *)&((a)[4])) /* address of first byte of data in a record */
|
||||
#define SREC_DATA24(a) ((uint8_t *)&((a)[5])) /* address of first data byte in 24 bit record */
|
||||
#define SREC_DATA32(a) ((uint8_t *)&((a)[6])) /* adress of first byte of a record with 32 bit address field */
|
||||
#define SREC_DATA16_SIZE(a) (SREC_COUNT((a)) - 3) /* length of the data[] array without the checksum field */
|
||||
#define SREC_DATA24_SIZE(a) (SREC_COUNT((a)) - 4) /* length of the data[] array without the checksum field */
|
||||
#define SREC_DATA32_SIZE(a) (SREC_COUNT((a)) - 5) /* length of the data[] array without the checksum field */
|
||||
#define SREC_CHECKSUM(a) (a)[SREC_COUNT(a) + 2 - 1] /* record's checksum (two's complement of the sum of all bytes) */
|
||||
|
||||
/*
|
||||
* convert a single hex character into byte
|
||||
*/
|
||||
static uint8_t nibble_to_byte(uint8_t nibble)
|
||||
{
|
||||
if ((nibble >= '0') && (nibble <= '9'))
|
||||
return nibble - '0';
|
||||
else if ((nibble >= 'A' && nibble <= 'F'))
|
||||
return 10 + nibble - 'A';
|
||||
else if ((nibble >= 'a' && nibble <= 'f'))
|
||||
return 10 + nibble - 'a';
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert two hex characters into byte
|
||||
*/
|
||||
static uint8_t hex_to_byte(uint8_t hex[2])
|
||||
{
|
||||
return 16 * (nibble_to_byte(hex[0])) + (nibble_to_byte(hex[1]));
|
||||
}
|
||||
|
||||
/*
|
||||
* convert four hex characters into a 16 bit word
|
||||
*/
|
||||
static uint16_t hex_to_word(uint8_t hex[4])
|
||||
{
|
||||
return 256 * hex_to_byte(&hex[0]) + hex_to_byte(&hex[2]);
|
||||
}
|
||||
|
||||
/*
|
||||
* convert eight hex characters into a 32 bit word
|
||||
*/
|
||||
static uint32_t hex_to_long(uint8_t hex[8])
|
||||
{
|
||||
return 65536 * hex_to_word(&hex[0]) + hex_to_word(&hex[4]);
|
||||
}
|
||||
|
||||
/*
|
||||
* compute the record checksum
|
||||
*
|
||||
* it consists of the one's complement of the byte sum of the data from the count field until the end
|
||||
*/
|
||||
static uint8_t checksum(uint8_t arr[])
|
||||
{
|
||||
int i;
|
||||
uint8_t checksum = SREC_COUNT(arr);
|
||||
|
||||
for (i = 0; i < SREC_COUNT(arr) - 1; i++)
|
||||
{
|
||||
checksum += arr[i + 2];
|
||||
}
|
||||
return ~checksum;
|
||||
}
|
||||
|
||||
#ifdef _NOT_USED_
|
||||
void print_record(uint8_t *arr)
|
||||
{
|
||||
switch (SREC_TYPE(arr))
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
xprintf("type 0x%x ", SREC_TYPE(arr));
|
||||
xprintf("count 0x%x ", SREC_COUNT(arr));
|
||||
xprintf("addr 0x%x ", SREC_ADDR16(arr));
|
||||
xprintf("module %11.11s ", SREC_DATA16(arr));
|
||||
xprintf("chk 0x%x 0x%x\r\n", SREC_CHECKSUM(arr), checksum(arr));
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 7:
|
||||
{
|
||||
xprintf("type 0x%x ", SREC_TYPE(arr));
|
||||
xprintf("count 0x%x ", SREC_COUNT(arr));
|
||||
xprintf("addr 0x%x ", SREC_ADDR32(arr));
|
||||
xprintf("data %02x,%02x,%02x,%02x,... ",
|
||||
SREC_DATA32(arr)[0], SREC_DATA32(arr)[1], SREC_DATA32(arr)[3], SREC_DATA32(arr)[4]);
|
||||
xprintf("chk 0x%x 0x%x\r\n", SREC_CHECKSUM(arr), checksum(arr));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
xprintf("unsupported report type %d in print_record\r\n", arr[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* _NOT_USED_ */
|
||||
|
||||
/*
|
||||
* convert an S-record line into its corresponding byte vector (ASCII->binary)
|
||||
*/
|
||||
static void line_to_vector(uint8_t *buff, uint8_t *vector)
|
||||
{
|
||||
int i;
|
||||
int length;
|
||||
uint8_t *vp = vector;
|
||||
|
||||
length = hex_to_byte(buff + 2);
|
||||
|
||||
buff++;
|
||||
*vp++ = nibble_to_byte(*buff); /* record type. Only one single nibble */
|
||||
buff++;
|
||||
|
||||
for (i = 0; i <= length; i++)
|
||||
{
|
||||
*vp++ = hex_to_byte(buff);
|
||||
buff += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* read and parse a Motorola S-record file and copy contents to dst. The theory of operation is to read and parse the S-record file
|
||||
* and to use the supplied callback routine to copy the buffer to the destination once the S-record line is converted.
|
||||
* The memcpy callback can be anything (as long as it conforms parameter-wise) - a basically empty function to just let
|
||||
* read_srecords validate the file, a standard memcpy() to copy file contents to destination RAM or a more sophisticated
|
||||
* routine that does write/erase flash
|
||||
*
|
||||
* FIXME: Currently only records that the gcc toolchain emits are supported.
|
||||
*
|
||||
* Parameters:
|
||||
* IN
|
||||
* filename - the filename that contains the S-records
|
||||
* callback - the memcpy() routine discussed above
|
||||
* OUT
|
||||
* start_address - the execution address of the code as read from the file. Can be used to jump into and execute it
|
||||
* actual_length - the overall length of the binary code read from the file
|
||||
* returns
|
||||
* OK or an err_t error code if anything failed
|
||||
*/
|
||||
err_t read_srecords(char *filename, void **start_address, uint32_t *actual_length, memcpy_callback_t callback)
|
||||
{
|
||||
FRESULT fres;
|
||||
FIL file;
|
||||
err_t ret = OK;
|
||||
|
||||
if ((fres = f_open(&file, filename, FA_READ) == FR_OK))
|
||||
{
|
||||
uint8_t line[80];
|
||||
int lineno = 0;
|
||||
int data_records = 0;
|
||||
bool found_block_header = false;
|
||||
bool found_block_end = false;
|
||||
bool found_block_data = false;
|
||||
|
||||
while (ret == OK && (uint8_t *) f_gets((char *) line, sizeof(line), &file) != NULL)
|
||||
{
|
||||
lineno++;
|
||||
uint8_t vector[80];
|
||||
|
||||
line_to_vector(line, vector); /* vector now contains the decoded contents of line, from line[1] on */
|
||||
|
||||
if (line[0] == 'S')
|
||||
{
|
||||
if (SREC_CHECKSUM(vector) != checksum(vector))
|
||||
{
|
||||
xprintf("invalid checksum 0x%x (should be 0x%x) in line %d\r\n",
|
||||
SREC_CHECKSUM(vector), checksum(vector), lineno);
|
||||
ret = FAIL;
|
||||
}
|
||||
|
||||
switch (vector[0])
|
||||
{
|
||||
case 0: /* block header */
|
||||
found_block_header = true;
|
||||
if (found_block_data || found_block_end)
|
||||
{
|
||||
xprintf("S7 or S3 record found before S0: S-records corrupt?\r\n");
|
||||
ret = FAIL;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2: /* three byte address field data record */
|
||||
if (!found_block_header || found_block_end)
|
||||
{
|
||||
xprintf("S3 record found before S0 or after S7: S-records corrupt?\r\n");
|
||||
ret = FAIL;
|
||||
}
|
||||
ret = callback((uint8_t *) SREC_ADDR24(vector), SREC_DATA24(vector), SREC_DATA24_SIZE(vector));
|
||||
data_records++;
|
||||
break;
|
||||
|
||||
case 3: /* four byte address field data record */
|
||||
if (!found_block_header || found_block_end)
|
||||
{
|
||||
xprintf("S3 record found before S0 or after S7: S-records corrupt?\r\n");
|
||||
ret = FAIL;
|
||||
}
|
||||
ret = callback((uint8_t *) SREC_ADDR32(vector), SREC_DATA32(vector), SREC_DATA32_SIZE(vector));
|
||||
data_records++;
|
||||
break;
|
||||
|
||||
case 7: /* four byte address field end record */
|
||||
if (!found_block_header || found_block_end)
|
||||
{
|
||||
xprintf("S7 record found before S0 or after S7: S-records corrupt?\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// xprintf("S7 record (end) found after %d valid data blocks\r\n", data_records);
|
||||
*start_address = (void *) SREC_ADDR32(vector);
|
||||
}
|
||||
break;
|
||||
|
||||
case 8: /* three byte address field end record */
|
||||
if (!found_block_header || found_block_end)
|
||||
{
|
||||
xprintf("S8 record found before S0 or after S8: S-records corrupt?\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// xprintf("S7 record (end) found after %d valid data blocks\r\n", data_records);
|
||||
*start_address = (void *) SREC_ADDR24(vector);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
xprintf("unsupported record type (%d) found in line %d\r\n", vector[0], lineno);
|
||||
xprintf("offending line: \r\n");
|
||||
xprintf("%s\r\n", line);
|
||||
ret = FAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("illegal character ('%c') found on line %d: S-records corrupt?\r\n", line[0], lineno);
|
||||
ret = FAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
f_close(&file);
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("could not open file %s\r\n", filename);
|
||||
ret = FILE_OPEN;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* this callback just does nothing besides returning OK. Meant to do a dry run over the file to check its integrity
|
||||
*/
|
||||
static err_t simulate()
|
||||
{
|
||||
err_t ret = OK;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static err_t memcpy(uint8_t *dst, uint8_t *src, uint32_t length)
|
||||
{
|
||||
uint8_t *end = src + length;
|
||||
|
||||
do
|
||||
{
|
||||
*dst++ = *src++;
|
||||
} while (src < end);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static err_t flash(uint8_t *dst, uint8_t *src, uint32_t length)
|
||||
{
|
||||
err_t ret = OK;
|
||||
|
||||
/* TODO: do the actual flash */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* this callback verifies the data against the S-record file contents after a write to destination
|
||||
*/
|
||||
static err_t verify(uint8_t *dst, uint8_t *src, uint32_t length)
|
||||
{
|
||||
uint8_t *end = src + length;
|
||||
|
||||
do
|
||||
{
|
||||
if (*src++ != *dst++)
|
||||
return FAIL;
|
||||
} while (src < end);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void srec_execute(char *flasher_filename)
|
||||
{
|
||||
DRESULT res;
|
||||
FRESULT fres;
|
||||
FATFS fs;
|
||||
FIL file;
|
||||
err_t err;
|
||||
void *start_address;
|
||||
uint32_t length;
|
||||
|
||||
disk_initialize(0);
|
||||
res = disk_status(0);
|
||||
if (res == RES_OK)
|
||||
{
|
||||
fres = f_mount(0, &fs);
|
||||
if (fres == FR_OK)
|
||||
{
|
||||
if ((fres = f_open(&file, flasher_filename, FA_READ) != FR_OK))
|
||||
{
|
||||
xprintf("flasher file %s not present on disk\r\n", flasher_filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
f_close(&file);
|
||||
|
||||
/* first pass: parse and check for inconsistencies */
|
||||
xprintf("check file integrity: ");
|
||||
err = read_srecords(flasher_filename, &start_address, &length, simulate);
|
||||
if (err == OK)
|
||||
{
|
||||
/* next pass: copy data to destination */
|
||||
xprintf("OK.\r\ncopy/flash data: ");
|
||||
err = read_srecords(flasher_filename, &start_address, &length, memcpy);
|
||||
if (err == OK)
|
||||
{
|
||||
/* next pass: verify data */
|
||||
xprintf("OK.\r\nverify data: ");
|
||||
err = read_srecords(flasher_filename, &start_address, &length, verify);
|
||||
if (err == OK)
|
||||
{
|
||||
xprintf("OK.\r\n");
|
||||
typedef void void_func(void);
|
||||
void_func *func;
|
||||
xprintf("target successfully written and verified. Start address: %p\r\n", start_address);
|
||||
|
||||
func = start_address;
|
||||
flush_and_invalidate_caches();
|
||||
(*func)();
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("failed\r\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("failed\r\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("failed\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// xprintf("could not mount FAT FS\r\n");
|
||||
}
|
||||
f_mount(0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// xprintf("could not initialize SD card\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
121
i2cspi_BaS_gcc/sources/sd_card.c
Normal file
121
i2cspi_BaS_gcc/sources/sd_card.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* sd_card.c
|
||||
*
|
||||
* Created on: 16.12.2012
|
||||
* Author: mfro
|
||||
*
|
||||
* This file is part of BaS_gcc.
|
||||
*
|
||||
* BaS_gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BaS_gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright 2012 M. Froeschle
|
||||
*/
|
||||
|
||||
#include <sd_card.h>
|
||||
#include <diskio.h>
|
||||
#include <ff.h>
|
||||
#include <bas_printf.h>
|
||||
|
||||
#define WELCOME_NAME "WELCOME.MSG"
|
||||
#define FLASHCODE_NAME "BENCH.BIN"
|
||||
|
||||
#define FLASHCODE_ADDRESS 0x03000000L
|
||||
|
||||
/*
|
||||
* initialize SD-card and FF FAT filesystem routines. Harness to load a file during boot.
|
||||
*
|
||||
* This is currently more like a proof of concept,
|
||||
* but will be extended to load and execute a bootstrap flasher to be able to flash the Bee directly
|
||||
* from card.
|
||||
*/
|
||||
void sd_card_init(void)
|
||||
{
|
||||
DRESULT res;
|
||||
FATFS fs;
|
||||
FRESULT fres;
|
||||
|
||||
disk_initialize(0);
|
||||
res = disk_status(0);
|
||||
xprintf("disk status of SD card is %d\r\n", res);
|
||||
if (res == RES_OK)
|
||||
{
|
||||
fres = f_mount(0, &fs);
|
||||
xprintf("mount status of SD card fs is %d\r\n", fres);
|
||||
if (fres == FR_OK)
|
||||
{
|
||||
DIR directory;
|
||||
FIL file;
|
||||
|
||||
fres = f_opendir(&directory, "\\");
|
||||
if (fres == FR_OK)
|
||||
{
|
||||
FILINFO fi;
|
||||
|
||||
while (((fres = f_readdir(&directory, &fi)) == FR_OK) && fi.fname[0])
|
||||
{
|
||||
xprintf("%13.13s %d\r\n", fi.fname, fi.fsize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("could not open directory \"\\\" on SD-card! Error code: %d\r\n", fres);
|
||||
}
|
||||
|
||||
/*
|
||||
* let's see if we find our boot flashing executable on disk
|
||||
*/
|
||||
fres = f_open(&file, FLASHCODE_NAME, FA_READ);
|
||||
if (fres == FR_OK)
|
||||
{
|
||||
/*
|
||||
* yes, load and execute it
|
||||
*
|
||||
* FIXME: we will need some kind of user confirmation here
|
||||
* to avoid unwanted flashing or "bootsector viruses" before going productive
|
||||
*/
|
||||
uint32_t size; /* length of code piece read */
|
||||
uint32_t total_size = 0L;
|
||||
uint32_t start_time = MCF_SLT_SCNT(0);
|
||||
uint32_t end_time;
|
||||
uint32_t time = 0;
|
||||
|
||||
while ((fres = f_read(&file, (void *) FLASHCODE_ADDRESS, 1024 * 1000, &size)) == FR_OK && size > 0)
|
||||
{
|
||||
total_size += size / 1024;
|
||||
xprintf("read hunk of %d bytes, total_size = %d kBytes\r\n", size, total_size);
|
||||
}
|
||||
end_time = MCF_SLT_SCNT(0);
|
||||
time = (end_time - start_time) / 132L;
|
||||
xprintf("result of f_read: %ld, %ld kbytes read\r\n", fres, total_size);
|
||||
xprintf("time to load %s: %ld s\r\n", FLASHCODE_NAME, time / 1000 / 100);
|
||||
xprintf("equals to about %ld kBytes/second\r\n", total_size / (time / 1000 / 100));
|
||||
|
||||
}
|
||||
f_close(&file);
|
||||
|
||||
fres = f_open(&file, WELCOME_NAME, FA_READ);
|
||||
if (fres == FR_OK)
|
||||
{
|
||||
char line[128];
|
||||
|
||||
while (f_gets(line, sizeof(line), &file))
|
||||
{
|
||||
xprintf("%s", line);
|
||||
}
|
||||
}
|
||||
f_close(&file);
|
||||
}
|
||||
f_mount(0, 0L); /* release work area */
|
||||
}
|
||||
}
|
||||
63
i2cspi_BaS_gcc/sources/startcf.S
Normal file
63
i2cspi_BaS_gcc/sources/startcf.S
Normal file
@@ -0,0 +1,63 @@
|
||||
/* This object file must be the first to be linked,
|
||||
* so it will be placed at the very beginning of the ROM.
|
||||
*/
|
||||
|
||||
.equ MCF_MMU_MMUCR, __MMUBAR + 0
|
||||
|
||||
.global _rom_header
|
||||
.global _rom_entry
|
||||
|
||||
.extern _initialize_hardware
|
||||
.extern _rt_mbar
|
||||
|
||||
/* ROM header */
|
||||
_rom_header:
|
||||
/* The first long is supposed to be the initial SP.
|
||||
* We replace it by bra.s to allow running the ROM from the first byte.
|
||||
* Then we add a fake jmp instruction for pretty disassembly.
|
||||
*/
|
||||
bra.s _rom_entry // Short jump to the real entry point
|
||||
.short 0x4ef9 // Fake jmp instruction
|
||||
/* The second long is the initial PC */
|
||||
.long _rom_entry // Real entry point
|
||||
|
||||
/* ROM entry point */
|
||||
_rom_entry:
|
||||
/* disable interrupts */
|
||||
move.w #0x2700,SR
|
||||
|
||||
/* Initialize MBAR */
|
||||
move.l #__MBAR,d0
|
||||
movec d0,MBAR
|
||||
move.l d0,_rt_mbar
|
||||
|
||||
/* mmu off */
|
||||
move.l #__MMUBAR+1,d0
|
||||
movec d0,MMUBAR
|
||||
|
||||
clr.l d0
|
||||
move.l d0,MCF_MMU_MMUCR
|
||||
|
||||
/* Initialize RAMBARs: locate SRAM and validate it */
|
||||
move.l #__RAMBAR0 + 0x7,d0 /* supervisor only */
|
||||
movec d0,RAMBAR0
|
||||
move.l #__RAMBAR1 + 0x1,d0
|
||||
movec d0,RAMBAR1
|
||||
|
||||
/* set stack pointer to end of SRAM1 */
|
||||
lea __SUP_SP,a7
|
||||
move.l #0,(sp)
|
||||
|
||||
/* Initialize the processor caches.
|
||||
* The instruction cache is fully enabled.
|
||||
* The data cache is enabled, but cache-inhibited by default.
|
||||
* Later, the MMU will fully activate the data cache for specific areas.
|
||||
* It is important to enable both caches now, otherwise cpushl would hang.
|
||||
*/
|
||||
move.l #0xa50c8120,d0
|
||||
movec d0,cacr
|
||||
andi.l #0xfefbfeff,d0 // Clear invalidate bits
|
||||
move.l d0,_rt_cacr
|
||||
|
||||
/* initialize any hardware specific issues */
|
||||
bra _initialize_hardware
|
||||
565
i2cspi_BaS_gcc/sources/supervisor.S
Normal file
565
i2cspi_BaS_gcc/sources/supervisor.S
Normal file
@@ -0,0 +1,565 @@
|
||||
/*
|
||||
* user/supervisor handler
|
||||
*/
|
||||
|
||||
#include "startcf.h"
|
||||
#define cf_stack
|
||||
|
||||
.extern _rt_cacr;
|
||||
.extern _rt_mod;
|
||||
.extern _rt_ssp;
|
||||
.extern _rt_usp;
|
||||
.extern ___MMUBAR
|
||||
.extern _flush_and_invalidate_caches
|
||||
|
||||
/* Register read/write macros */
|
||||
#define MCF_MMU_MMUCR __MMUBAR
|
||||
#define MCF_MMU_MMUOR __MMUBAR+0x04
|
||||
#define MCF_MMU_MMUSR __MMUBAR+0x08
|
||||
#define MCF_MMU_MMUAR __MMUBAR+0x10
|
||||
#define MCF_MMU_MMUTR __MMUBAR+0x14
|
||||
#define MCF_MMU_MMUDR __MMUBAR+0x18
|
||||
|
||||
.global _privileg_violation
|
||||
.global cpusha
|
||||
|
||||
.text
|
||||
_privileg_violation:
|
||||
move.w #0x2700,sr
|
||||
lea -12(a7),a7
|
||||
movem.l d0/a0/a5,(a7)
|
||||
#ifndef cf_stack
|
||||
lea 0x52f0,a0
|
||||
move.l #0x20,(a0) // set auf 68030
|
||||
#endif
|
||||
lea _rt_mod,a0 // zugriff setzen
|
||||
tst.b (a0) // vom rt_supervisormodus?
|
||||
bne pv_work // ja->
|
||||
// tats<EFBFBD>chlich privileg violation
|
||||
mov3q.l #-1,(a0) // sr_mod setzen
|
||||
move.l usp,a5 // usp holen
|
||||
move.l a5,8(a0) // sichern
|
||||
move.l 4(a0),a5 // rt_ssp holen
|
||||
#ifdef cf_stack
|
||||
move.l 16(a7),-(a5) // pc verschieben
|
||||
move.l 12(a7),-(a5) // sr verschieben
|
||||
bset #5,2(a5) // auf super setzen
|
||||
#else
|
||||
move.w 12(a7),-(a5) // vector nr.
|
||||
move.l 16(a7),-(a5) // pc verschieben
|
||||
move.w 14(a7),-(a5) // sr verschieben
|
||||
bset #5,(a5) // auf super
|
||||
#endif
|
||||
move.l a5,usp
|
||||
move.l 12(a0),a5 // rt_vbr
|
||||
lea 0x18(a5),a5 // vector
|
||||
move.l (a5),16(a7) // vector privileg violation
|
||||
movem.l (a7),d0/a0/a5 // register zur<EFBFBD>ck
|
||||
lea 12(a7),a7
|
||||
rte
|
||||
// privileg violation
|
||||
pv_work:
|
||||
move.l 16(a7),a5 // fault pc
|
||||
move.b (a5),d0 // fault code
|
||||
cmp.b #0x4e,d0 // 1.byt 0x4e
|
||||
beq pv_4e // ja->
|
||||
cmp.b #0x46,d0 // 1.byt 0x46
|
||||
beq pv_46 // ja->
|
||||
cmp.b #0x40,d0 // 1.byt 0x40
|
||||
beq pv_40 // ja->
|
||||
cmp.b #0xf4,d0 // 0xf4?
|
||||
beq pv_f4
|
||||
cmp.b #0xf3,d0 // 0xf3?
|
||||
beq pv_f3
|
||||
// hierher sollt man nicht kommen
|
||||
nop
|
||||
halt
|
||||
nop
|
||||
// code 0x4exx ********************************************
|
||||
pv_4e:
|
||||
move.b 1(a5),d0
|
||||
cmp.b #0x73,d0 //rte?
|
||||
beq pv_rte //ja->
|
||||
cmp.b #0x72,d0 //stop?
|
||||
beq pv_stop //ja->
|
||||
cmp.b #0x7B,d0 //movec?
|
||||
beq pv_movec //ja->
|
||||
// move usp
|
||||
btst #3,d0 // to or from
|
||||
bne pv_usp_to_ax // usp -> ax
|
||||
// move ax->usp
|
||||
cmp.b #0x60,d0 //movec?
|
||||
beq pv_a0_usp //ja->
|
||||
cmp.b #0x61,d0 //movec?
|
||||
beq pv_a1_usp //ja->
|
||||
cmp.b #0x62,d0 //movec?
|
||||
beq pv_a2_usp //ja->
|
||||
cmp.b #0x63,d0 //movec?
|
||||
beq pv_a3_usp //ja->
|
||||
cmp.b #0x64,d0 //movec?
|
||||
beq pv_a4_usp //ja->
|
||||
cmp.b #0x65,d0 //movec?
|
||||
beq pv_a5_usp //ja->
|
||||
cmp.b #0x66,d0 //movec?
|
||||
beq pv_a6_usp //ja->
|
||||
halt
|
||||
bra pv_a7_usp //ja->
|
||||
// move usp->ax
|
||||
pv_usp_to_ax:
|
||||
move.l 8(a0),a5 //rt_usp holen
|
||||
cmp.b #0x68,d0 //movec?
|
||||
beq pv_usp_a0 //ja->
|
||||
cmp.b #0x69,d0 //movec?
|
||||
beq pv_usp_a1 //ja->
|
||||
cmp.b #0x6a,d0 //movec?
|
||||
beq pv_usp_a2 //ja->
|
||||
cmp.b #0x6b,d0 //movec?
|
||||
beq pv_usp_a3 //ja->
|
||||
cmp.b #0x6c,d0 //movec?
|
||||
beq pv_usp_a4 //ja->
|
||||
cmp.b #0x6d,d0 //movec?
|
||||
beq pv_usp_a5 //ja->
|
||||
cmp.b #0x6e,d0 //movec?
|
||||
beq pv_usp_a6 //ja->
|
||||
// usp->a7
|
||||
move.l a5,4(a0) // rt usp -> rt ssp
|
||||
move.l a5,usp // und setzen
|
||||
bra pv_usp_ax
|
||||
// a0->usp
|
||||
pv_a0_usp: move.l 4(a7),a5
|
||||
bra pv_ax_usp
|
||||
// a1->usp
|
||||
pv_a1_usp: move.l a1,a5
|
||||
bra pv_ax_usp
|
||||
// a2->usp
|
||||
pv_a2_usp: move.l a2,a5
|
||||
bra pv_ax_usp
|
||||
// a3->usp
|
||||
pv_a3_usp: move.l a3,a5
|
||||
bra pv_ax_usp
|
||||
// a4->usp
|
||||
pv_a4_usp: move.l a4,a5
|
||||
bra pv_ax_usp
|
||||
// a5->usp
|
||||
pv_a5_usp: move.l 8(a7),a5
|
||||
bra pv_ax_usp
|
||||
// a6->usp
|
||||
pv_a6_usp: move.l a6,a5
|
||||
bra pv_ax_usp
|
||||
// a7->usp
|
||||
pv_a7_usp: move.l 4(a0),a5 // rt_ssp -> a5
|
||||
pv_ax_usp:
|
||||
move.l a5,8(a0) // usp -> rt_usp
|
||||
addq.l #2,16(a7) // next
|
||||
movem.l (a7),d0/a0/a5 // register zur<EFBFBD>ck
|
||||
lea 12(a7),a7
|
||||
rte
|
||||
// usp->a0
|
||||
pv_usp_a0:
|
||||
move.l a5,4(a7)
|
||||
bra pv_usp_ax
|
||||
pv_usp_a1:
|
||||
move.l a5,a1
|
||||
bra pv_usp_ax
|
||||
pv_usp_a2:
|
||||
move.l a5,a2
|
||||
bra pv_usp_ax
|
||||
pv_usp_a3:
|
||||
move.l a5,a3
|
||||
bra pv_usp_ax
|
||||
pv_usp_a4:
|
||||
move.l a5,a4
|
||||
bra pv_usp_ax
|
||||
pv_usp_a5:
|
||||
move.l a5,8(a7)
|
||||
bra pv_usp_ax
|
||||
pv_usp_a6:
|
||||
move.l a5,a6
|
||||
pv_usp_ax:
|
||||
addq.l #2,16(a7) // next
|
||||
movem.l (a7),d0/a0/a5 // register zur<EFBFBD>ck
|
||||
lea 12(a7),a7
|
||||
rte
|
||||
// rte
|
||||
pv_rte:
|
||||
move.l usp,a5
|
||||
#ifdef cf_stack
|
||||
move.l (a5)+,12(a7) // sr verschieben
|
||||
move.l (a5)+,16(a7) // pc verschieben
|
||||
#else
|
||||
move.w (a5)+,14(a7) // sr verschieben
|
||||
move.l (a5)+,16(a7) // pc verschieben
|
||||
move.w (a5)+,12(a7) // vector
|
||||
#endif
|
||||
bclr #5,14(a7) // war es von super?
|
||||
bne pv_rte_sup // ja->
|
||||
clr.l (a0) // rt_mod auf user
|
||||
move.l a5,4(a0) // rt_ssp sichern
|
||||
move.l 8(a0),a5 // rt_usp holen
|
||||
pv_rte_sup:
|
||||
move.l a5,usp // usp setzen
|
||||
movem.l (a7),d0/a0/a5 // register zur<EFBFBD>ck
|
||||
lea 12(a7),a7
|
||||
rte
|
||||
// stop
|
||||
pv_stop:
|
||||
move.b 2(a5),d0 // sr wert
|
||||
and.l #0x0700,d0 // int mask
|
||||
cmp.w #0x700,d0
|
||||
beq stop7
|
||||
cmp.w #0x600,d0
|
||||
beq stop6
|
||||
cmp.w #0x500,d0
|
||||
beq stop5
|
||||
cmp.w #0x400,d0
|
||||
beq stop4
|
||||
cmp.w #0x300,d0
|
||||
beq stop3
|
||||
cmp.w #0x200,d0
|
||||
beq stop2
|
||||
cmp.w #0x100,d0
|
||||
beq stop1
|
||||
stop #0x2000
|
||||
bra stop_weiter
|
||||
stop1:
|
||||
stop #0x2100
|
||||
bra stop_weiter
|
||||
stop2:
|
||||
stop #0x2200
|
||||
bra stop_weiter
|
||||
stop3:
|
||||
stop #0x2300
|
||||
bra stop_weiter
|
||||
stop4:
|
||||
stop #0x2400
|
||||
bra stop_weiter
|
||||
stop5:
|
||||
stop #0x2500
|
||||
bra stop_weiter
|
||||
stop6:
|
||||
stop #0x2600
|
||||
bra stop_weiter
|
||||
stop7:
|
||||
stop #0x2700
|
||||
stop_weiter:
|
||||
addq.l #4,16(a7) // next
|
||||
movem.l (a7),d0/a0/a5 // register zur<EFBFBD>ck
|
||||
lea 12(a7),a7
|
||||
rte
|
||||
// movec ???????
|
||||
pv_movec:
|
||||
move.w 2(a5),d0 // 2.word holen
|
||||
and.l #0xf000,d0
|
||||
btst #15,d0 // addressregister?
|
||||
bne pv_movec_ax // ja->
|
||||
tst.w d0 // d0?
|
||||
bne pvm_d1 // nein->
|
||||
move.l (a7),-(a7) // d0 holen und sichern
|
||||
bra pvm_me
|
||||
pvm_d1:
|
||||
cmp.w #0x1000,d0 // d1?
|
||||
bne pvm_d2 // nein->
|
||||
move.l d1,-(a7) // d1 holen und sichern
|
||||
bra pvm_me // fertig machen
|
||||
pvm_d2:
|
||||
cmp.w #0x2000,d0 // d1?
|
||||
bne pvm_d3 // nein->
|
||||
move.l d2,-(a7) // d2 holen und sichern
|
||||
bra pvm_me // fertig machen
|
||||
pvm_d3:
|
||||
cmp.w #0x3000,d0 // d1?
|
||||
bne pvm_d4 // nein->
|
||||
move.l d3,-(a7) // d3 holen und sichern
|
||||
bra pvm_me // fertig machen
|
||||
pvm_d4:
|
||||
cmp.w #0x4000,d0 // d1?
|
||||
bne pvm_d5 // nein->
|
||||
move.l d4,-(a7) // d4 holen und sichern
|
||||
bra pvm_me // fertig machen
|
||||
pvm_d5:
|
||||
cmp.w #0x5000,d0 // d1?
|
||||
bne pvm_d6 // nein->
|
||||
move.l d5,-(a7) // d5 holen und sichern
|
||||
bra pvm_me // fertig machen
|
||||
pvm_d6:
|
||||
cmp.w #0x6000,d0 // d1?
|
||||
bne pvm_d7 // nein->
|
||||
move.l d6,-(a7) // d6 holen und sichern
|
||||
bra pvm_me // fertig machen
|
||||
pvm_d7:
|
||||
move.l d7,-(a7) // d7 holen und sichern
|
||||
bra pvm_me // fertig machen
|
||||
pv_movec_ax:
|
||||
cmp.w #0x8000,d0 // a0?
|
||||
bne pvm_a1 // nein->
|
||||
move.l 4(a7),-(a7) // a0 holen und sichern
|
||||
bra pvm_me // fertig machen
|
||||
pvm_a1:
|
||||
cmp.w #0x9000,d0 // a0?
|
||||
bne pvm_a2 // nein->
|
||||
move.l a1,-(a7) // a1 holen und sichern
|
||||
bra pvm_me // fertig machen
|
||||
pvm_a2:
|
||||
cmp.w #0xa000,d0 // a0?
|
||||
bne pvm_a3 // nein->
|
||||
move.l a2,-(a7) // a2 holen und sichern
|
||||
bra pvm_me // fertig machen
|
||||
pvm_a3:
|
||||
cmp.w #0xb000,d0 // a0?
|
||||
bne pvm_a4 // nein->
|
||||
move.l a3,-(a7) // a3 holen und sichern
|
||||
bra pvm_me // fertig machen
|
||||
pvm_a4:
|
||||
cmp.w #0xc000,d0 // a0?
|
||||
bne pvm_a5 // nein->
|
||||
move.l a4,-(a7) // a4 holen und sichern
|
||||
bra pvm_me // fertig machen
|
||||
pvm_a5:
|
||||
cmp.w #0xd000,d0 // a0?
|
||||
bne pvm_a6 // nein->
|
||||
move.l 8(a7),-(a7) // a5 holen und sichern
|
||||
bra pvm_me // fertig machen
|
||||
pvm_a6:
|
||||
cmp.w #0xe000,d0 // a0?
|
||||
bne pvm_a7 // nein->
|
||||
move.l a6,-(a7) // a6 holen und sichern
|
||||
bra pvm_me // fertig machen
|
||||
pvm_a7:
|
||||
move.l 4(a7),-(a7) // a7 holen und sichern
|
||||
pvm_me:
|
||||
move.w 2(a5),d0 // 2.word holen
|
||||
andi.l #0xf,d0 // nur letzte 4 bits
|
||||
move.l (a7)+,8(a0,d0*4) // start bei +8, *4 weil long
|
||||
jsr cpusha // gesammten cache flushen
|
||||
rte
|
||||
// code 0x46xx *****************************************
|
||||
pv_46:
|
||||
move.b 1(a5),d0
|
||||
cmp.b #0xfc,d0 //#d16->sr
|
||||
beq im_sr //ja->
|
||||
//move dx->sr (sr und rt_mod ist supervisor sonst w<EFBFBD>re es privileg violation
|
||||
cmp.b #0xc0,d0 //d0->sr?
|
||||
bne d1_sr //nein->
|
||||
move.w 2(a7),d0 //hier ist d0 gesichert
|
||||
bra d0_sr
|
||||
d1_sr:
|
||||
cmp.b #0xc1,d0 //d1->sr?
|
||||
bne d2_sr //nein->
|
||||
move.w d1,d0
|
||||
bra d0_sr
|
||||
d2_sr:
|
||||
cmp.b #0xc2,d0 //d2->sr?
|
||||
bne d3_sr
|
||||
move.w d2,d0
|
||||
bra d0_sr
|
||||
d3_sr:
|
||||
cmp.b #0xc3,d0 //d3->sr?
|
||||
bne d4_sr
|
||||
move.w d3,d0
|
||||
bra d0_sr
|
||||
d4_sr:
|
||||
cmp.b #0xc4,d0 //d4->sr?
|
||||
bne d5_sr
|
||||
move.w d4,d0
|
||||
bra d0_sr
|
||||
d5_sr:
|
||||
cmp.b #0xc5,d0 //d5->sr?
|
||||
bne d6_sr
|
||||
move.w d5,d0
|
||||
bra d0_sr
|
||||
d6_sr:
|
||||
cmp.b #0xc6,d0 //d6->sr?
|
||||
bne d7_sr
|
||||
move.w d6,d0
|
||||
bra d0_sr
|
||||
d7_sr:
|
||||
move.w d7,d0 // sonst d7->sr
|
||||
d0_sr:
|
||||
addq.l #2,16(a7) // next
|
||||
bra pv_set_sr_end // fertig machen
|
||||
// move #xxxx,sr
|
||||
im_sr:
|
||||
addq.l #4,16(a7) // next
|
||||
move.w 2(a5),d0 // data
|
||||
pv_set_sr_end:
|
||||
bclr #13,d0 // war super?
|
||||
bne pv_sre2 // ja ->
|
||||
clr.l (a0)
|
||||
move.l usp,a5 // usp
|
||||
move.l a5,4(a0) // rt_ssp speichern
|
||||
move.l 8(a0),a5 // rt_usp holen
|
||||
move.l a5,usp // setzen
|
||||
pv_sre2:
|
||||
move.w d0,14(a7) // sr setzen
|
||||
movem.l (a7),d0/a0/a5 // register zur<EFBFBD>ck
|
||||
lea 12(a7),a7
|
||||
rte
|
||||
// code 0x40xx *****************************************
|
||||
pv_40:
|
||||
move.b 1(a5),d0 // 2.byt
|
||||
cmp.b #0xe7,d0
|
||||
beq pv_strldsr
|
||||
// move sr->dx
|
||||
move.l 12(a7),a5 // sr holen
|
||||
tst.b (a0) // super?
|
||||
beq pv_40_user // nein?
|
||||
lea 0x2000(a5),a5 // super zuaddieren
|
||||
pv_40_user:
|
||||
cmp.b #0xc0,d0
|
||||
bne nsr_d1
|
||||
move.w a5,2(a7)
|
||||
bra sr_dx_end
|
||||
nsr_d1:
|
||||
cmp.b #0xc1,d0
|
||||
bne nsr_d2
|
||||
move.w a5,d1
|
||||
bra sr_dx_end
|
||||
nsr_d2:
|
||||
cmp.b #0xc2,d0
|
||||
bne nsr_d3
|
||||
move.w a5,d2
|
||||
bra sr_dx_end
|
||||
nsr_d3:
|
||||
cmp.b #0xc3,d0
|
||||
bne nsr_d4
|
||||
move.w a5,d3
|
||||
bra sr_dx_end
|
||||
nsr_d4:
|
||||
cmp.b #0xc4,d0
|
||||
bne nsr_d5
|
||||
move.w a5,d4
|
||||
bra sr_dx_end
|
||||
nsr_d5:
|
||||
cmp.b #0xc5,d0
|
||||
bne nsr_d6
|
||||
move.w a5,d5
|
||||
bra sr_dx_end
|
||||
nsr_d6:
|
||||
cmp.b #0xc6,d0
|
||||
bne nsr_d7
|
||||
move.w a5,d6
|
||||
bra sr_dx_end
|
||||
nsr_d7:
|
||||
move.w a5,d7
|
||||
halt
|
||||
sr_dx_end:
|
||||
addq.l #2,16(a7) // next
|
||||
movem.l (a7),d0/a0/a5 // register zur<EFBFBD>ck
|
||||
lea 12(a7),a7
|
||||
rte
|
||||
// strldsr
|
||||
pv_strldsr:
|
||||
nop
|
||||
halt
|
||||
nop
|
||||
// code 0xf4xx ***********************************
|
||||
pv_f4:
|
||||
addq.l #2,16(a7) // next instr
|
||||
move.b 1(a5),d0 // 2.byt
|
||||
bsr pv_ax_a0 // richtiges register
|
||||
move.b 1(a5),d0 // 2.byt
|
||||
cmp.b #0x30,d0 // >0xf430
|
||||
blo pv_intouch
|
||||
// cpushl
|
||||
cpushl bc,(a0)
|
||||
movem.l (a7),d0/a0/a5
|
||||
lea 12(a7),a7
|
||||
rte
|
||||
pv_intouch:
|
||||
intouch a0
|
||||
movem.l (a7),d0/a0/a5
|
||||
lea 12(a7),a7
|
||||
rte
|
||||
// subroutine register ax->a0
|
||||
pv_ax_a0:
|
||||
and.l #0x7,d0 // nur register nummer
|
||||
subq.l #1,d0
|
||||
bmi pv_a0_a0
|
||||
subq.l #1,d0
|
||||
bmi pv_a1_a0
|
||||
subq.l #1,d0
|
||||
bmi pv_a2_a0
|
||||
subq.l #1,d0
|
||||
bmi pv_a3_a0
|
||||
subq.l #1,d0
|
||||
bmi pv_a4_a0
|
||||
subq.l #1,d0
|
||||
bmi pv_a5_a0
|
||||
subq.l #1,d0
|
||||
bmi pv_a6_a0
|
||||
move.l a7,a0
|
||||
rts
|
||||
pv_a0_a0:
|
||||
move.l 8(a7),a0
|
||||
rts
|
||||
pv_a1_a0:
|
||||
move.l a1,a0
|
||||
rts
|
||||
pv_a2_a0:
|
||||
move.l a2,a0
|
||||
rts
|
||||
pv_a3_a0:
|
||||
move.l a3,a0
|
||||
rts
|
||||
pv_a4_a0:
|
||||
move.l a4,a0
|
||||
rts
|
||||
pv_a5_a0:
|
||||
move.l 12(a7),a0
|
||||
rts
|
||||
pv_a6_a0:
|
||||
move.l a6,a0
|
||||
rts
|
||||
// code 0xf4xx ***********************************
|
||||
pv_f3:
|
||||
addq.l #2,16(a7) // next instr
|
||||
move.b 1(a5),d0 // 2. byt
|
||||
cmp.b #0x40,d0
|
||||
bgt pv_frestore
|
||||
//fsave (ax) oder d16(ax)
|
||||
jsr pv_ax_a0 // richtiges register holen
|
||||
move.b 1(a5),d0
|
||||
cmp.b #0x20,d0
|
||||
// +d16
|
||||
blt pv_f3_ax
|
||||
addq.l #2,16(a7) // next instr
|
||||
clr.l d0
|
||||
move.w 2(a0),d0 // d16
|
||||
add.l d0,a0
|
||||
pv_f3_ax:
|
||||
fsave (a0)
|
||||
movem.l (a7),d0/a0/a5
|
||||
lea 12(a7),a7
|
||||
rte
|
||||
pv_frestore:
|
||||
cmp.b #0x7a,d0
|
||||
beq pv_f_d16pc
|
||||
// frestore (ax) oder d16(ax)
|
||||
jsr pv_ax_a0 // richtiges register holen
|
||||
move.b 1(a5),d0
|
||||
cmp.b #0x60,d0
|
||||
blt pv_frestore_ax
|
||||
pv_fend:
|
||||
addq.l #2,16(a7) // next instr
|
||||
clr.l d0
|
||||
move.w 2(a0),d0 // d16
|
||||
add.l d0,a0
|
||||
pv_frestore_ax:
|
||||
frestore (a0)
|
||||
movem.l (a7),d0/a0/a5
|
||||
lea 12(a7),a7
|
||||
rte
|
||||
// frestore d16(pc)
|
||||
pv_f_d16pc:
|
||||
move.l 16(a7),a0 // pc holen
|
||||
bra pv_fend
|
||||
//*****************************************************
|
||||
cpusha:
|
||||
lea -16(a7),a7
|
||||
movem.l d0-d1/a0-a1,(a7) // backup C trash registers
|
||||
jsr _flush_and_invalidate_caches
|
||||
movem.l (a7),d0-d1/a0-a1 // restore C trash registers
|
||||
lea 16(a7),a7
|
||||
rts
|
||||
//*******************************************************33
|
||||
|
||||
877
i2cspi_BaS_gcc/sources/sysinit.c
Normal file
877
i2cspi_BaS_gcc/sources/sysinit.c
Normal file
@@ -0,0 +1,877 @@
|
||||
/*
|
||||
* File: sysinit.c
|
||||
* Purpose: Power-on Reset configuration of the Firebee board.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* This file is part of BaS_gcc.
|
||||
*
|
||||
* BaS_gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BaS_gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright 2010 - 2012 F. Aschwanden
|
||||
* Copyright 2011 - 2012 V. Riviere
|
||||
* Copyright 2012 M. Froeschle
|
||||
*
|
||||
*/
|
||||
|
||||
#include "MCF5475.h"
|
||||
#include "startcf.h"
|
||||
#include "cache.h"
|
||||
#include "sysinit.h"
|
||||
#include "bas_printf.h"
|
||||
#include "bas_types.h"
|
||||
#include "wait.h"
|
||||
|
||||
extern void xprintf_before_copy(const char *fmt, ...);
|
||||
#define xprintf xprintf_before_copy
|
||||
extern void flush_and_invalidate_caches_before_copy(void);
|
||||
#define flush_and_invalidate_caches flush_and_invalidate_caches_before_copy
|
||||
|
||||
#define UNUSED(x) (void)(x) /* Unused variable */
|
||||
|
||||
extern volatile long _VRAM; /* start address of video ram from linker script */
|
||||
|
||||
/*
|
||||
* init SLICE TIMER 0
|
||||
* all = 32.538 sec = 30.736mHz
|
||||
* BYT0 = 127.1ms/tick = 7.876Hz offset 0
|
||||
* BYT1 = 496.5us/tick = 2.014kHz offset 1
|
||||
* BYT2 = 1.939us/tick = 515.6kHz offset 2
|
||||
* BYT3 = 7.576ns/tick = 132.00MHz offset 3
|
||||
* count down!!! 132MHz!!!
|
||||
*/
|
||||
void init_slt(void)
|
||||
{
|
||||
xprintf("slice timer initialization: ");
|
||||
MCF_SLT0_STCNT = 0xffffffff;
|
||||
MCF_SLT0_SCR = MCF_SLT_SCR_TEN | MCF_SLT_SCR_RUN; /* enable and run continuously */
|
||||
xprintf("finished\r\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* init GPIO general purpose I/O module
|
||||
*/
|
||||
void init_gpio(void)
|
||||
{
|
||||
/*
|
||||
* pad register P.S.:FBCTL and FBCS set correctly at reset
|
||||
*/
|
||||
|
||||
/*
|
||||
* configure all four 547x GPIO module DMA pins:
|
||||
*
|
||||
* /DACK1 - DMA acknowledge 1
|
||||
* /DACK0 - DMA acknowledge 0
|
||||
* /DREQ1 - DMA request 1
|
||||
* /DREQ0 - DMA request 0
|
||||
*
|
||||
* for DMA operation
|
||||
*/
|
||||
MCF_PAD_PAR_DMA = MCF_PAD_PAR_DMA_PAR_DACK0_DACK0 |
|
||||
MCF_PAD_PAR_DMA_PAR_DACK1_DACK1 |
|
||||
MCF_PAD_PAR_DMA_PAR_DREQ1_DREQ1 |
|
||||
MCF_PAD_PAR_DMA_PAR_DREQ0_DREQ0;
|
||||
|
||||
/*
|
||||
* configure FEC0 pin assignment on GPIO module as FEC0
|
||||
* configure FEC1 pin assignment (PAR_E17, PAR_E1MII) as GPIO,
|
||||
* /IRQ5 and /IRQ6 from GPIO (needs to be disabled on EPORT module, which also can
|
||||
* use those INTs).
|
||||
*/
|
||||
MCF_PAD_PAR_FECI2CIRQ = MCF_PAD_PAR_FECI2CIRQ_PAR_E07 |
|
||||
MCF_PAD_PAR_FECI2CIRQ_PAR_E0MII |
|
||||
MCF_PAD_PAR_FECI2CIRQ_PAR_E0MDIO |
|
||||
MCF_PAD_PAR_FECI2CIRQ_PAR_E0MDC |
|
||||
MCF_PAD_PAR_FECI2CIRQ_PAR_E1MDIO_E1MDIO |
|
||||
MCF_PAD_PAR_FECI2CIRQ_PAR_E1MDC_E1MDC |
|
||||
MCF_PAD_PAR_FECI2CIRQ_PAR_SDA |
|
||||
MCF_PAD_PAR_FECI2CIRQ_PAR_SCL |
|
||||
MCF_PAD_PAR_FECI2CIRQ_PAR_IRQ6 |
|
||||
MCF_PAD_PAR_FECI2CIRQ_PAR_IRQ5;
|
||||
|
||||
/*
|
||||
* configure PCI Grant pin assignment on GPIO module:
|
||||
*
|
||||
* /PCIBG4 used as FlexBus /TBST
|
||||
* /PCIBG3 used as general purpose I/O
|
||||
* /PCIBG2 used as /PCIBG2
|
||||
* /PCIBG1 used as /PCIBG1
|
||||
* /PCIBG0 used as /PCIBG0
|
||||
*/
|
||||
MCF_PAD_PAR_PCIBG = MCF_PAD_PAR_PCIBG_PAR_PCIBG4_TBST |
|
||||
MCF_PAD_PAR_PCIBG_PAR_PCIBG3_GPIO |
|
||||
MCF_PAD_PAR_PCIBG_PAR_PCIBG2_PCIBG2 |
|
||||
MCF_PAD_PAR_PCIBG_PAR_PCIBG1_PCIBG1 |
|
||||
MCF_PAD_PAR_PCIBG_PAR_PCIBG0_PCIBG0;
|
||||
|
||||
/*
|
||||
* configure PCI request pin assignment on GPIO module:
|
||||
* /PCIBR4 as /IRQ4
|
||||
* /PCIBR3 as GPIO (PIC)
|
||||
* /PCIBR2 as /PCIBR2
|
||||
* /PCIBR1 as /PCIBR1
|
||||
* /PCIBR0 as /PCIBR0
|
||||
*/
|
||||
MCF_PAD_PAR_PCIBR = MCF_PAD_PAR_PCIBR_PAR_PCIBR4_IRQ4 |
|
||||
MCF_PAD_PAR_PCIBR_PAR_PCIBR3_GPIO |
|
||||
MCF_PAD_PAR_PCIBR_PAR_PCIBR2_PCIBR2 |
|
||||
MCF_PAD_PAR_PCIBR_PAR_PCIBR1_PCIBR1 |
|
||||
MCF_PAD_PAR_PCIBR_PAR_PCIBR0_PCIBR0;
|
||||
|
||||
/*
|
||||
* configure PSC3 pin assignment on GPIO module:
|
||||
* /PSC3CTS as /PSC3PTS
|
||||
* /PSC3RTS as /PSC3RTS
|
||||
* PSC3RXD as PSC3RXD
|
||||
* PSC3TXD as PSC3TXD
|
||||
*/
|
||||
|
||||
MCF_PAD_PAR_PSC3 = MCF_PAD_PAR_PSC3_PAR_TXD3 | MCF_PAD_PAR_PSC3_PAR_RXD3;
|
||||
|
||||
/*
|
||||
* Configure PSC1 pin assignment on GPIO module:
|
||||
* - all pins configured for serial interface operation
|
||||
*/
|
||||
|
||||
MCF_PAD_PAR_PSC1 = MCF_PAD_PAR_PSC1_PAR_CTS1_CTS |
|
||||
MCF_PAD_PAR_PSC1_PAR_RTS1_RTS |
|
||||
MCF_PAD_PAR_PSC1_PAR_RXD1 |
|
||||
MCF_PAD_PAR_PSC1_PAR_TXD1;
|
||||
|
||||
/*
|
||||
* Configure PSC0 Pin Assignment on GPIO module:
|
||||
* - all pins configured for serial interface operation
|
||||
*/
|
||||
|
||||
MCF_PAD_PAR_PSC0 = MCF_PAD_PAR_PSC0_PAR_CTS0_CTS |
|
||||
MCF_PAD_PAR_PSC0_PAR_RTS0_RTS |
|
||||
MCF_PAD_PAR_PSC0_PAR_RXD0 |
|
||||
MCF_PAD_PAR_PSC0_PAR_TXD0;
|
||||
|
||||
MCF_PAD_PAR_DSPI = 0b0001111111111111; /* DSPI NORMAL */
|
||||
|
||||
MCF_PAD_PAR_TIMER = 0b00101101; /* TIN3..2=#IRQ3..2;TOUT3..2=NORMAL */
|
||||
|
||||
// ALLE OUTPUTS NORMAL LOW
|
||||
|
||||
|
||||
// ALLE DIR NORMAL INPUT = 0
|
||||
MCF_GPIO_PDDR_FEC1L = 0b00011110; /* OUT: 4=LED,3=PRG_DQ0,2=#FPGA_CONFIG,1=PRG_CLK(FPGA) */
|
||||
|
||||
#define FPGA_STATUS (1 << 0)
|
||||
#define FPGA_CLOCK (1 << 1)
|
||||
#define FPGA_CONFIG (1 << 2)
|
||||
#define FPGA_DATA0 (1 << 3)
|
||||
#define FPGA_CONF_DONE (1 << 5)
|
||||
|
||||
/* pull FPGA config to low as early as possible */
|
||||
MCF_GPIO_PODR_FEC1L &= ~FPGA_CLOCK; /* FPGA clock => low */
|
||||
MCF_GPIO_PODR_FEC1L &= ~FPGA_CONFIG; /* FPGA config => low */
|
||||
}
|
||||
|
||||
/*
|
||||
* init serial
|
||||
*/
|
||||
void init_serial(void)
|
||||
{
|
||||
/* PSC0: SER1 */
|
||||
MCF_PSC0_PSCSICR = 0; /* PSC control register: select UART mode */
|
||||
MCF_PSC0_PSCCSR = 0xDD; /* use TX and RX baud rate from PSC timer */
|
||||
MCF_PSC0_PSCCTUR = 0x00; /* =\ */
|
||||
MCF_PSC0_PSCCTLR = 36; /* divide sys_clk by 36 => BAUD RATE = 115200 bps */
|
||||
MCF_PSC0_PSCCR = 0x20; /* reset receiver and RxFIFO */
|
||||
MCF_PSC0_PSCCR = 0x30; /* reset transmitter and TxFIFO */
|
||||
MCF_PSC0_PSCCR = 0x40; /* reset all error status */
|
||||
MCF_PSC0_PSCCR = 0x50; /* reset break change interrupt */
|
||||
MCF_PSC0_PSCCR = 0x10; /* reset MR pointer */
|
||||
MCF_PSC0_PSCIMR = 0x8700; /* enable input port change interrupt, enable delta break interrupt, */
|
||||
/* enable receiver interrupt/request, enable transceiver interrupt/request */
|
||||
|
||||
MCF_PSC0_PSCACR = 0x03; /* enable state change of CTS */
|
||||
MCF_PSC0_PSCMR1 = 0xb3; /* 8 bit, no parity */
|
||||
MCF_PSC0_PSCMR2 = 0x07; /* 1 stop bit */
|
||||
MCF_PSC0_PSCRFCR = 0x0F;
|
||||
MCF_PSC0_PSCTFCR = 0x0F;
|
||||
MCF_PSC0_PSCRFAR = 0x00F0;
|
||||
MCF_PSC0_PSCTFAR = 0x00F0;
|
||||
MCF_PSC0_PSCOPSET = 0x01;
|
||||
MCF_PSC0_PSCCR = 0x05;
|
||||
|
||||
/* PSC3: PIC */
|
||||
MCF_PSC3_PSCSICR = 0; // UART
|
||||
MCF_PSC3_PSCCSR = 0xDD;
|
||||
MCF_PSC3_PSCCTUR = 0x00;
|
||||
MCF_PSC3_PSCCTLR = 36; // BAUD RATE = 115200
|
||||
MCF_PSC3_PSCCR = 0x20;
|
||||
MCF_PSC3_PSCCR = 0x30;
|
||||
MCF_PSC3_PSCCR = 0x40;
|
||||
MCF_PSC3_PSCCR = 0x50;
|
||||
MCF_PSC3_PSCCR = 0x10;
|
||||
MCF_PSC3_PSCIMR = 0x0200; // receiver interrupt enable
|
||||
MCF_PSC3_PSCACR = 0x03;
|
||||
MCF_PSC3_PSCMR1 = 0xb3;
|
||||
MCF_PSC3_PSCMR2 = 0x07;
|
||||
MCF_PSC3_PSCRFCR = 0x0F;
|
||||
MCF_PSC3_PSCTFCR = 0x0F;
|
||||
MCF_PSC3_PSCRFAR = 0x00F0;
|
||||
MCF_PSC3_PSCTFAR = 0x00F0;
|
||||
MCF_PSC3_PSCOPSET = 0x01;
|
||||
MCF_PSC3_PSCCR = 0x05;
|
||||
MCF_INTC_ICR32 = 0x3F; //MAXIMALE PRIORITY/**********/
|
||||
|
||||
xprintf("serial interfaces initialization: finished\r\n");
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/* Initialize DDR DIMMs on the EVB board */
|
||||
/********************************************************************/
|
||||
void init_ddram(void)
|
||||
{
|
||||
xprintf("SDRAM controller initialization: ");
|
||||
|
||||
/*
|
||||
* Check to see if the SDRAM has already been initialized
|
||||
* by a run control tool
|
||||
*/
|
||||
if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
|
||||
/* Basic configuration and initialization */
|
||||
|
||||
/*
|
||||
* SB_E (Bits 9-8): 10 <=> 7.6 mA (SDCKE)
|
||||
* SB_C (Bits 7-6): 10 <=> 7.6 mA (SDRAM Clocks)
|
||||
* SB_A (Bits 5-4): 10 <=> 7.6 mA (RAS, CAS, SDWE, SDADDR[12:0], and SDBA)
|
||||
* SB_S (Bits 3-2): 10 <=> 7.6 mA (SDRDQS)
|
||||
* SB_D (Bits 1-0): 10 <=> 7.6 mA (SDRDQS)
|
||||
*
|
||||
* -> lowest setting the Coldfire SDRAM controller allows
|
||||
*/
|
||||
MCF_SDRAMC_SDRAMDS = 0x000002AA;/* SDRAMDS configuration */
|
||||
|
||||
MCF_SDRAMC_CS0CFG = 0x0000001A; /* SDRAM CS0 configuration (128Mbytes 0000_0000 - 07FF_FFFF) */
|
||||
MCF_SDRAMC_CS1CFG = 0x0800001A; /* SDRAM CS1 configuration (128Mbytes 0800_0000 - 0FFF_FFFF) */
|
||||
MCF_SDRAMC_CS2CFG = 0x1000001A; /* SDRAM CS2 configuration (128Mbytes 1000_0000 - 07FF_FFFF) */
|
||||
MCF_SDRAMC_CS3CFG = 0x1800001A; /* SDRAM CS3 configuration (128Mbytes 1800_0000 - 1FFF_FFFF) */
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
MCF_SDRAMC_SDCFG1 = MCF_SDRAMC_SDCFG1_WTLAT(3) /* Write latency */
|
||||
| MCF_SDRAMC_SDCFG1_REF2ACT(8) /* Refresh to Active Delay */
|
||||
| MCF_SDRAMC_SDCFG1_PRE2ACT(2) /* Precharge to Active Delay */
|
||||
| MCF_SDRAMC_SDCFG1_ACT2RW(2) /* Active to Read/Write Delay */
|
||||
| MCF_SDRAMC_SDCFG1_RDLAT(6) /* Read CAS latency */
|
||||
| MCF_SDRAMC_SDCFG1_SWT2RD(3) /* Single Write to Read/Write/Precharge delay */
|
||||
| MCF_SDRAMC_SDCFG1_SRD2RW(7); /* Single Read to Read/Write/Precharge delay */
|
||||
|
||||
MCF_SDRAMC_SDCFG2 = MCF_SDRAMC_SDCFG2_BL(7) /* Burst Length */
|
||||
| MCF_SDRAMC_SDCFG2_BRD2WT(7) /* Burst Read to Write delay */
|
||||
| MCF_SDRAMC_SDCFG2_BWT2RW(6) /* Burst Write to Read/Write/Precharge delay */
|
||||
| MCF_SDRAMC_SDCFG2_BRD2PRE(4); /* Burst Read to Read/Precharge delay */
|
||||
|
||||
#ifdef _NOT_USED_
|
||||
MCF_SDRAMC_SDCFG1 = 0x73622830; /* SDCFG1 */
|
||||
MCF_SDRAMC_SDCFG2 = 0x46770000; /* SDCFG2 */
|
||||
#endif /* _NOT_USED_ */
|
||||
|
||||
MCF_SDRAMC_SDCR = MCF_SDRAMC_SDCR_IPALL /* initiate Precharge All command */
|
||||
| MCF_SDRAMC_SDCR_RCNT(13) /* Refresh Count (= (x + 1) * 64 */
|
||||
| MCF_SDRAMC_SDCR_MUX(1) /* Muxing control */
|
||||
| MCF_SDRAMC_SDCR_DDR
|
||||
| MCF_SDRAMC_SDCR_CKE
|
||||
| MCF_SDRAMC_SDCR_MODE_EN;
|
||||
|
||||
MCF_SDRAMC_SDMR = MCF_SDRAMC_SDMR_CMD /* Generate an LMR/LEMR command */
|
||||
| MCF_SDRAMC_SDMR_AD(0) /* Address */
|
||||
| MCF_SDRAMC_SDMR_BNKAD(1); /* LEMR */
|
||||
MCF_SDRAMC_SDMR = MCF_SDRAMC_SDMR_CMD /* Generate an LMR/LEMR command */
|
||||
| MCF_SDRAMC_SDMR_AD(0x123)
|
||||
| MCF_SDRAMC_SDMR_BNKAD(0); /* LMR */
|
||||
|
||||
#ifdef _NOT_USED_
|
||||
MCF_SDRAMC_SDCR = 0xE10D0002; /* SDCR + IPALL */
|
||||
MCF_SDRAMC_SDMR = 0x40010000; /* SDMR (write to LEMR) */
|
||||
MCF_SDRAMC_SDMR = 0x048D0000; /* SDRM (write to LMR) */
|
||||
#endif /* _NOT_USED_ */
|
||||
MCF_SDRAMC_SDCR = 0xE10D0002; /* SDCR + IPALL */
|
||||
MCF_SDRAMC_SDCR = 0xE10D0004; /* SDCR + IREF (first refresh) */
|
||||
MCF_SDRAMC_SDCR = 0xE10D0004; /* SDCR + IREF (second refresh) */
|
||||
MCF_SDRAMC_SDMR = 0x008D0000; /* SDMR (write to LMR) */
|
||||
MCF_SDRAMC_SDCR = 0x710D0F00; /* SDCR (lock SDMR and enable refresh) */
|
||||
|
||||
xprintf("finished\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
xprintf("skipped. Already initialized (running from RAM)\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize FlexBus chip select registers
|
||||
*/
|
||||
void init_fbcs()
|
||||
{
|
||||
xprintf("FlexBus chip select registers initialization: ");
|
||||
|
||||
/* Flash */
|
||||
MCF_FBCS0_CSAR = 0xE0000000; /* flash base address */
|
||||
MCF_FBCS0_CSCR = MCF_FBCS_CSCR_PS_16 |
|
||||
MCF_FBCS_CSCR_WS(4)|
|
||||
MCF_FBCS_CSCR_AA;
|
||||
MCF_FBCS0_CSMR = MCF_FBCS_CSMR_BAM_8M |
|
||||
MCF_FBCS_CSMR_V; /* 8 MByte on */
|
||||
|
||||
MCF_FBCS1_CSAR = 0xFFF00000; /* ATARI I/O ADRESS */
|
||||
MCF_FBCS1_CSCR = MCF_FBCS_CSCR_PS_16 /* 16BIT PORT */
|
||||
| MCF_FBCS_CSCR_WS(8) /* DEFAULT 8WS */
|
||||
| MCF_FBCS_CSCR_AA; /* AA */
|
||||
MCF_FBCS1_CSMR = MCF_FBCS_CSMR_BAM_1M | MCF_FBCS_CSMR_V;
|
||||
|
||||
MCF_FBCS2_CSAR = 0xF0000000; // NEUER I/O ADRESS-BEREICH
|
||||
MCF_FBCS2_CSCR = MCF_FBCS_CSCR_PS_32 // 32BIT PORT
|
||||
| MCF_FBCS_CSCR_WS(8) // DEFAULT 4WS
|
||||
| MCF_FBCS_CSCR_AA; // AA
|
||||
MCF_FBCS2_CSMR = (MCF_FBCS_CSMR_BAM_128M // F000'0000-F7FF'FFFF
|
||||
| MCF_FBCS_CSMR_V);
|
||||
|
||||
MCF_FBCS3_CSAR = 0xF8000000; // NEUER I/O ADRESS-BEREICH
|
||||
MCF_FBCS3_CSCR = MCF_FBCS_CSCR_PS_16 // 16BIT PORT
|
||||
| MCF_FBCS_CSCR_AA; // AA
|
||||
MCF_FBCS3_CSMR = (MCF_FBCS_CSMR_BAM_64M // F800'0000-FBFF'FFFF
|
||||
| MCF_FBCS_CSMR_V);
|
||||
|
||||
MCF_FBCS4_CSAR = 0x40000000; // VIDEO RAM BEREICH, #FB_CS3 WIRD NICHT BENÜTZT, DECODE DIREKT AUF DEM FPGA
|
||||
MCF_FBCS4_CSCR = MCF_FBCS_CSCR_PS_32 // 32BIT PORT
|
||||
| MCF_FBCS_CSCR_BSTR // BURST READ ENABLE
|
||||
| MCF_FBCS_CSCR_BSTW; // BURST WRITE ENABLE
|
||||
MCF_FBCS4_CSMR = MCF_FBCS_CSMR_BAM_1G // 4000'0000-7FFF'FFFF
|
||||
| MCF_FBCS_CSMR_V;
|
||||
|
||||
xprintf("finished\r\n");
|
||||
}
|
||||
|
||||
|
||||
void wait_pll(void)
|
||||
{
|
||||
uint32_t trgt = MCF_SLT0_SCNT - 100000;
|
||||
do
|
||||
{
|
||||
;
|
||||
} while ((* (volatile int16_t *) 0xf0000800 < 0) && MCF_SLT0_SCNT > trgt);
|
||||
}
|
||||
|
||||
static volatile uint8_t *pll_base = (volatile uint8_t *) 0xf0000600;
|
||||
|
||||
void init_pll(void)
|
||||
{
|
||||
xprintf("FPGA PLL initialization: ");
|
||||
|
||||
wait_pll();
|
||||
* (volatile uint16_t *) (pll_base + 0x48) = 27; /* loopfilter r */
|
||||
|
||||
wait_pll();
|
||||
* (volatile uint16_t *) (pll_base + 0x08) = 1; /* charge pump 1 */
|
||||
|
||||
wait_pll();
|
||||
* (volatile uint16_t *) (pll_base + 0x00) = 12; /* N counter high = 12 */
|
||||
|
||||
wait_pll();
|
||||
* (volatile uint16_t *) (pll_base + 0x40) = 12; /* N counter low = 12 */
|
||||
|
||||
wait_pll();
|
||||
* (volatile uint16_t *) (pll_base + 0x114) = 1; /* ck1 bypass */
|
||||
|
||||
wait_pll();
|
||||
* (volatile uint16_t *) (pll_base + 0x118) = 1; /* ck2 bypass */
|
||||
|
||||
wait_pll();
|
||||
* (volatile uint16_t *) (pll_base + 0x11c) = 1; /* ck3 bypass */
|
||||
|
||||
wait_pll();
|
||||
* (volatile uint16_t *) (pll_base + 0x10) = 1; /* ck0 high = 1 */
|
||||
|
||||
wait_pll();
|
||||
* (volatile uint16_t *) (pll_base + 0x50) = 1; /* ck0 low = 1 */
|
||||
|
||||
wait_pll();
|
||||
* (volatile uint16_t *) (pll_base + 0x144) = 1; /* M odd division */
|
||||
|
||||
wait_pll();
|
||||
* (volatile uint16_t *) (pll_base + 0x44) = 1; /* M low = 1 */
|
||||
|
||||
wait_pll();
|
||||
* (volatile uint16_t *) (pll_base + 0x04) = 145; /* M high = 145 = 146 MHz */
|
||||
|
||||
wait_pll();
|
||||
|
||||
* (volatile uint8_t *) 0xf0000800 = 0; /* set */
|
||||
|
||||
xprintf("finished\r\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* INIT VIDEO DDR RAM
|
||||
*/
|
||||
|
||||
#define NOP() __asm__ __volatile__("nop\n\t" : : : "memory")
|
||||
|
||||
void init_video_ddr(void) {
|
||||
xprintf("init video RAM: ");
|
||||
|
||||
* (volatile uint16_t *) 0xf0000400 = 0xb; /* set cke = 1, cs=1, config = 1 */
|
||||
NOP();
|
||||
|
||||
_VRAM = 0x00050400; /* IPALL */
|
||||
NOP();
|
||||
|
||||
_VRAM = 0x00072000; /* load EMR pll on */
|
||||
NOP();
|
||||
|
||||
_VRAM = 0x00070122; /* load MR: reset pll, cl=2, burst=4lw */
|
||||
NOP();
|
||||
|
||||
_VRAM = 0x00050400; /* IPALL */
|
||||
NOP();
|
||||
|
||||
_VRAM = 0x00060000; /* auto refresh */
|
||||
NOP();
|
||||
|
||||
_VRAM = 0x00060000; /* auto refresh */
|
||||
NOP();
|
||||
|
||||
_VRAM = 0000070022; /* load MR dll on */
|
||||
NOP();
|
||||
|
||||
* (uint32_t *) 0xf0000400 = 0x01070002; /* fifo on, refresh on, ddrcs und cke on, video dac on */
|
||||
|
||||
xprintf("finished\r\n");
|
||||
}
|
||||
|
||||
|
||||
#define PCI_MEMORY_OFFSET (0x80000000)
|
||||
#define PCI_MEMORY_SIZE (0x40000000)
|
||||
#define PCI_IO_OFFSET (0xD0000000)
|
||||
#define PCI_IO_SIZE (0x10000000)
|
||||
|
||||
/*
|
||||
* INIT PCI
|
||||
*/
|
||||
void init_PCI(void) {
|
||||
xprintf("PCI BUS controller initialization: ");
|
||||
|
||||
MCF_PCIARB_PACR = MCF_PCIARB_PACR_INTMPRI
|
||||
+ MCF_PCIARB_PACR_EXTMPRI(0x1F)
|
||||
+ MCF_PCIARB_PACR_INTMINTEN
|
||||
+ MCF_PCIARB_PACR_EXTMINTEN(0x1F);
|
||||
|
||||
// Setup burst parameters
|
||||
MCF_PCI_PCICR1 = MCF_PCI_PCICR1_CACHELINESIZE(4) + MCF_PCI_PCICR1_LATTIMER(32);
|
||||
MCF_PCI_PCICR2 = MCF_PCI_PCICR2_MINGNT(16) + MCF_PCI_PCICR2_MAXLAT(16);
|
||||
|
||||
// Turn on error signaling
|
||||
MCF_PCI_PCIICR = MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_REE + 32;
|
||||
MCF_PCI_PCIGSCR |= MCF_PCI_PCIGSCR_SEE;
|
||||
|
||||
/* Configure Initiator Windows */
|
||||
/* initiator window 0 base / translation adress register */
|
||||
MCF_PCI_PCIIW0BTAR = (PCI_MEMORY_OFFSET + ((PCI_MEMORY_SIZE -1) >> 8)) & 0xffff0000;
|
||||
|
||||
/* initiator window 1 base / translation adress register */
|
||||
MCF_PCI_PCIIW1BTAR = (PCI_IO_OFFSET + ((PCI_IO_SIZE - 1) >> 8)) & 0xffff0000;
|
||||
|
||||
/* initiator window 2 base / translation address register */
|
||||
MCF_PCI_PCIIW2BTAR = 0L; /* not used */
|
||||
|
||||
/* initiator window configuration register */
|
||||
MCF_PCI_PCIIWCR = MCF_PCI_PCIIWCR_WINCTRL0_MEMRDLINE + MCF_PCI_PCIIWCR_WINCTRL1_IO;
|
||||
|
||||
/* reset PCI devices */
|
||||
MCF_PCI_PCIGSCR &= ~MCF_PCI_PCIGSCR_PR;
|
||||
|
||||
xprintf("finished\r\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* probe for UPC720101 (USB)
|
||||
*/
|
||||
void test_upd720101(void)
|
||||
{
|
||||
xprintf("UDP720101 USB controller initialization: ");
|
||||
|
||||
/* select UPD720101 AD17 */
|
||||
MCF_PCI_PCICAR = MCF_PCI_PCICAR_E +
|
||||
MCF_PCI_PCICAR_DEVNUM(17) +
|
||||
MCF_PCI_PCICAR_FUNCNUM(0) +
|
||||
MCF_PCI_PCICAR_DWORD(0);
|
||||
|
||||
if (* (uint32_t *) PCI_IO_OFFSET == 0x33103500)
|
||||
{
|
||||
MCF_PCI_PCICAR = MCF_PCI_PCICAR_E +
|
||||
MCF_PCI_PCICAR_DEVNUM(17) +
|
||||
MCF_PCI_PCICAR_FUNCNUM(0) +
|
||||
MCF_PCI_PCICAR_DWORD(57);
|
||||
|
||||
//* (uint8_t *) PCI_IO_OFFSET = 0x20; // commented out (hangs currently)
|
||||
}
|
||||
else
|
||||
{
|
||||
MCF_PSC0_PSCTB_8BIT = 'NOT ';
|
||||
|
||||
MCF_PCI_PCICAR = MCF_PCI_PCICAR_DEVNUM(17) +
|
||||
MCF_PCI_PCICAR_FUNCNUM(0) +
|
||||
MCF_PCI_PCICAR_DWORD(57);
|
||||
}
|
||||
xprintf("finished\r\n");
|
||||
}
|
||||
|
||||
static bool i2c_transfer_finished(void)
|
||||
{
|
||||
if (MCF_I2C_I2SR & MCF_I2C_I2SR_IIF)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void wait_i2c_transfer_finished(void)
|
||||
{
|
||||
waitfor(100000, i2c_transfer_finished); /* wait until interrupt bit has been set */
|
||||
MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF; /* clear interrupt bit (byte transfer finished */
|
||||
}
|
||||
|
||||
static bool i2c_bus_free(void)
|
||||
{
|
||||
return (MCF_I2C_I2SR & MCF_I2C_I2SR_IBB);
|
||||
}
|
||||
|
||||
/*
|
||||
* TFP410 (DVI) on
|
||||
*/
|
||||
void dvi_on(void) {
|
||||
uint8_t receivedByte;
|
||||
uint8_t dummyByte; /* only used for a dummy read */
|
||||
int num_tries = 0;
|
||||
|
||||
xprintf("DVI digital video output initialization: ");
|
||||
|
||||
MCF_I2C_I2FDR = 0x3c; /* divide system clock by 1280: 100kHz standard */
|
||||
|
||||
do {
|
||||
/* disable all i2c interrupt routing targets */
|
||||
MCF_I2C_I2ICR = 0x0; //~(MCF_I2C_I2ICR_IE | MCF_I2C_I2ICR_RE | MCF_I2C_I2ICR_TE | MCF_I2C_I2ICR_BNBE);
|
||||
|
||||
/* disable i2c, disable i2c interrupts, slave, receive, i2c = acknowledge, no repeat start */
|
||||
MCF_I2C_I2CR = 0x0;
|
||||
|
||||
/* repeat start, transmit acknowledge */
|
||||
MCF_I2C_I2CR = MCF_I2C_I2CR_RSTA | MCF_I2C_I2CR_TXAK;
|
||||
|
||||
receivedByte = MCF_I2C_I2DR; /* read a byte */
|
||||
MCF_I2C_I2SR = 0x0; /* clear status register */
|
||||
MCF_I2C_I2CR = 0x0; /* disable i2c */
|
||||
|
||||
MCF_I2C_I2ICR = MCF_I2C_I2ICR_IE; /* route i2c interrupts to cpu */
|
||||
/* i2c enable, master mode, transmit acknowledge */
|
||||
MCF_I2C_I2CR = MCF_I2C_I2CR_IEN | MCF_I2C_I2CR_MSTA | MCF_I2C_I2CR_MTX;
|
||||
|
||||
MCF_I2C_I2DR = 0x7a; /* send data: address of TFP410 */
|
||||
wait_i2c_transfer_finished();
|
||||
|
||||
if (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK) /* next try if no acknowledge */
|
||||
continue;
|
||||
|
||||
MCF_I2C_I2DR = 0x00; /* send data: SUB ADRESS 0 */
|
||||
wait_i2c_transfer_finished();
|
||||
|
||||
MCF_I2C_I2CR |= MCF_I2C_I2CR_RSTA; /* repeat start */
|
||||
MCF_I2C_I2DR = 0x7b; /* begin read */
|
||||
|
||||
wait_i2c_transfer_finished();
|
||||
if (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK) /* next try if no acknowledge */
|
||||
continue;
|
||||
|
||||
MCF_I2C_I2CR &= 0xef; //~MCF_I2C_I2CR_MTX; /* switch to receive mode */
|
||||
dummyByte = MCF_I2C_I2DR; /* dummy read */
|
||||
|
||||
wait_i2c_transfer_finished();
|
||||
|
||||
MCF_I2C_I2CR |= MCF_I2C_I2CR_TXAK; /* transmit acknowledge enable */
|
||||
receivedByte = MCF_I2C_I2DR; /* read a byte */
|
||||
|
||||
wait_i2c_transfer_finished();
|
||||
|
||||
MCF_I2C_I2CR = MCF_I2C_I2CR_IEN; /* stop */
|
||||
|
||||
dummyByte = MCF_I2C_I2DR; // dummy read
|
||||
|
||||
if (receivedByte != 0x4c)
|
||||
continue;
|
||||
|
||||
MCF_I2C_I2CR = 0x0; // stop
|
||||
MCF_I2C_I2SR = 0x0; // clear sr
|
||||
|
||||
waitfor(10000, i2c_bus_free);
|
||||
|
||||
MCF_I2C_I2CR = 0xb0; // on tx master
|
||||
MCF_I2C_I2DR = 0x7A;
|
||||
|
||||
wait_i2c_transfer_finished();
|
||||
|
||||
if (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK)
|
||||
continue;
|
||||
|
||||
MCF_I2C_I2DR = 0x08; // SUB ADRESS 8
|
||||
|
||||
wait_i2c_transfer_finished();
|
||||
|
||||
MCF_I2C_I2DR = 0xbf; // ctl1: power on, T:M:D:S: enable
|
||||
|
||||
wait_i2c_transfer_finished();
|
||||
|
||||
MCF_I2C_I2CR = 0x80; // stop
|
||||
dummyByte = MCF_I2C_I2DR; // dummy read
|
||||
MCF_I2C_I2SR = 0x0; // clear sr
|
||||
|
||||
waitfor(10000, i2c_bus_free);
|
||||
|
||||
MCF_I2C_I2CR = 0xb0;
|
||||
MCF_I2C_I2DR = 0x7A;
|
||||
|
||||
wait_i2c_transfer_finished();
|
||||
|
||||
if (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK)
|
||||
continue;
|
||||
|
||||
MCF_I2C_I2DR = 0x08; // SUB ADRESS 8
|
||||
|
||||
wait_i2c_transfer_finished();
|
||||
|
||||
MCF_I2C_I2CR |= 0x4; // repeat start
|
||||
MCF_I2C_I2DR = 0x7b; // beginn read
|
||||
|
||||
wait_i2c_transfer_finished();
|
||||
|
||||
if (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK)
|
||||
continue;
|
||||
|
||||
MCF_I2C_I2CR &= 0xef; // switch to rx
|
||||
dummyByte = MCF_I2C_I2DR; // dummy read
|
||||
|
||||
wait_i2c_transfer_finished();
|
||||
MCF_I2C_I2CR |= 0x08; // txak=1
|
||||
|
||||
wait(50);
|
||||
|
||||
receivedByte = MCF_I2C_I2DR;
|
||||
|
||||
wait_i2c_transfer_finished();
|
||||
|
||||
MCF_I2C_I2CR = 0x80; // stop
|
||||
|
||||
dummyByte = MCF_I2C_I2DR; // dummy read
|
||||
num_tries++;
|
||||
} while ((receivedByte != 0xbf) && (num_tries < 10));
|
||||
|
||||
if (num_tries >= 10) {
|
||||
xprintf("FAILED!\r\n");
|
||||
} else {
|
||||
xprintf("finished\r\n");
|
||||
}
|
||||
UNUSED(dummyByte);
|
||||
// Avoid warning
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* AC97
|
||||
*/
|
||||
void init_ac97(void) {
|
||||
// PSC2: AC97 ----------
|
||||
int i;
|
||||
int zm;
|
||||
int va;
|
||||
int vb;
|
||||
int vc;
|
||||
|
||||
xprintf("AC97 sound chip initialization: ");
|
||||
MCF_PAD_PAR_PSC2 = MCF_PAD_PAR_PSC2_PAR_RTS2_RTS // PSC2=TX,RX BCLK,CTS->AC'97
|
||||
| MCF_PAD_PAR_PSC2_PAR_CTS2_BCLK
|
||||
| MCF_PAD_PAR_PSC2_PAR_TXD2
|
||||
| MCF_PAD_PAR_PSC2_PAR_RXD2;
|
||||
MCF_PSC2_PSCMR1 = 0x0;
|
||||
MCF_PSC2_PSCMR2 = 0x0;
|
||||
MCF_PSC2_PSCIMR = 0x0300;
|
||||
MCF_PSC2_PSCSICR = 0x03; //AC97
|
||||
MCF_PSC2_PSCRFCR = 0x0f000000;
|
||||
MCF_PSC2_PSCTFCR = 0x0f000000;
|
||||
MCF_PSC2_PSCRFAR = 0x00F0;
|
||||
MCF_PSC2_PSCTFAR = 0x00F0;
|
||||
|
||||
for (zm = 0; zm < 100000; zm++) // wiederholen bis synchron
|
||||
{
|
||||
MCF_PSC2_PSCCR = 0x20;
|
||||
MCF_PSC2_PSCCR = 0x30;
|
||||
MCF_PSC2_PSCCR = 0x40;
|
||||
MCF_PSC2_PSCCR = 0x05;
|
||||
|
||||
// MASTER VOLUME -0dB
|
||||
MCF_PSC2_PSCTB_AC97 = 0xE0000000; //START SLOT1 + SLOT2, FIRST FRAME
|
||||
MCF_PSC2_PSCTB_AC97 = 0x02000000; //SLOT1:WR REG MASTER VOLUME adr 0x02
|
||||
|
||||
for (i = 2; i < 13; i++)
|
||||
{
|
||||
MCF_PSC2_PSCTB_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0
|
||||
}
|
||||
|
||||
// read register
|
||||
MCF_PSC2_PSCTB_AC97 = 0xc0000000; //START SLOT1 + SLOT2, FIRST FRAME
|
||||
MCF_PSC2_PSCTB_AC97 = 0x82000000; //SLOT1:master volume
|
||||
|
||||
for (i = 2; i < 13; i++)
|
||||
{
|
||||
MCF_PSC2_PSCTB_AC97 = 0x00000000; //SLOT2-12:RD REG ALLES 0
|
||||
}
|
||||
wait(50);
|
||||
|
||||
va = MCF_PSC2_PSCTB_AC97;
|
||||
if ((va & 0x80000fff) == 0x80000800) {
|
||||
vb = MCF_PSC2_PSCTB_AC97;
|
||||
vc = MCF_PSC2_PSCTB_AC97;
|
||||
|
||||
/* FIXME: that looks more than suspicious (Fredi?) */
|
||||
/* fixed with parentheses to avoid compiler warnings, but this looks still more than wrong to me */
|
||||
if (((va & 0xE0000fff) == 0xE0000800) & (vb == 0x02000000) & (vc == 0x00000000)) {
|
||||
goto livo;
|
||||
}
|
||||
}
|
||||
}
|
||||
uart_out_word(' NOT');
|
||||
livo:
|
||||
// AUX VOLUME ->-0dB
|
||||
MCF_PSC2_PSCTB_AC97 = 0xE0000000; //START SLOT1 + SLOT2, FIRST FRAME
|
||||
MCF_PSC2_PSCTB_AC97 = 0x16000000; //SLOT1:WR REG AUX VOLUME adr 0x16
|
||||
MCF_PSC2_PSCTB_AC97 = 0x06060000; //SLOT1:VOLUME
|
||||
for (i = 3; i < 13; i++) {
|
||||
MCF_PSC2_PSCTB_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0
|
||||
}
|
||||
|
||||
// line in VOLUME +12dB
|
||||
MCF_PSC2_PSCTB_AC97 = 0xE0000000; //START SLOT1 + SLOT2, FIRST FRAME
|
||||
MCF_PSC2_PSCTB_AC97 = 0x10000000; //SLOT1:WR REG MASTER VOLUME adr 0x02
|
||||
for (i = 2; i < 13; i++) {
|
||||
MCF_PSC2_PSCTB_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0
|
||||
}
|
||||
// cd in VOLUME 0dB
|
||||
MCF_PSC2_PSCTB_AC97 = 0xE0000000; //START SLOT1 + SLOT2, FIRST FRAME
|
||||
MCF_PSC2_PSCTB_AC97 = 0x12000000; //SLOT1:WR REG MASTER VOLUME adr 0x02
|
||||
for (i = 2; i < 13; i++) {
|
||||
MCF_PSC2_PSCTB_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0
|
||||
}
|
||||
// mono out VOLUME 0dB
|
||||
MCF_PSC2_PSCTB_AC97 = 0xE0000000; //START SLOT1 + SLOT2, FIRST FRAME
|
||||
MCF_PSC2_PSCTB_AC97 = 0x06000000; //SLOT1:WR REG MASTER VOLUME adr 0x02
|
||||
MCF_PSC2_PSCTB_AC97 = 0x00000000; //SLOT1:WR REG MASTER VOLUME adr 0x02
|
||||
for (i = 3; i < 13; i++) {
|
||||
MCF_PSC2_PSCTB_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0
|
||||
}
|
||||
MCF_PSC2_PSCTFCR |= MCF_PSC_PSCTFCR_WFR; //set EOF
|
||||
MCF_PSC2_PSCTB_AC97 = 0x00000000; //last data
|
||||
xprintf(" finished\r\n");
|
||||
}
|
||||
|
||||
/* Symbols from the linker script */
|
||||
|
||||
extern uint8_t _STRAM_END[];
|
||||
#define STRAM_END ((uint32_t)_STRAM_END)
|
||||
|
||||
extern uint8_t _FIRETOS[];
|
||||
#define FIRETOS ((uint32_t)_FIRETOS) /* where FireTOS is stored in flash */
|
||||
|
||||
extern uint8_t _BAS_LMA[];
|
||||
#define BAS_LMA ((uint32_t)_BAS_LMA) /* where the BaS is stored in flash */
|
||||
|
||||
extern uint8_t _BAS_IN_RAM[];
|
||||
#define BAS_IN_RAM ((uint32_t)_BAS_IN_RAM) /* where the BaS is run in RAM */
|
||||
|
||||
extern uint8_t _BAS_SIZE[];
|
||||
#define BAS_SIZE ((uint32_t)_BAS_SIZE) /* size of the BaS, in bytes */
|
||||
|
||||
void initialize_hardware(void) {
|
||||
/* used in copy loop */
|
||||
uint32_t *src; /* src address to read from flash */
|
||||
uint32_t *end; /* end address to read from flash */
|
||||
uint32_t *dst; /* destination address to copy to */
|
||||
|
||||
/* Test for FireTOS switch: DIP switch #5 up */
|
||||
if (!(DIP_SWITCH & (1 << 6))) {
|
||||
/* Minimal hardware initialization */
|
||||
init_gpio();
|
||||
init_serial();
|
||||
init_slt();
|
||||
init_fbcs();
|
||||
init_ddram();
|
||||
init_fpga();
|
||||
/* FireTOS seems to have trouble to initialize the ST-RAM by itself, so... */
|
||||
/* Validate ST RAM */
|
||||
* (volatile uint32_t *) 0x42e = STRAM_END; /* phystop TOS system variable */
|
||||
* (volatile uint32_t *) 0x420 = 0x752019f3; /* memvalid TOS system variable */
|
||||
* (volatile uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */
|
||||
* (volatile uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */
|
||||
|
||||
/* Jump into FireTOS */
|
||||
typedef void void_func(void);
|
||||
void_func* FireTOS = (void_func*)FIRETOS;
|
||||
FireTOS(); // Should never return
|
||||
return;
|
||||
}
|
||||
|
||||
init_gpio();
|
||||
init_serial();
|
||||
init_slt();
|
||||
init_fbcs();
|
||||
init_ddram();
|
||||
init_PCI();
|
||||
init_fpga();
|
||||
init_pll();
|
||||
init_video_ddr();
|
||||
dvi_on();
|
||||
test_upd720101();
|
||||
//video_1280_1024();
|
||||
init_ac97();
|
||||
|
||||
/* copy the BaS code contained in flash to its final location */
|
||||
src = (uint32_t *)BAS_LMA;
|
||||
end = (uint32_t *)(BAS_LMA + BAS_SIZE);
|
||||
dst = (uint32_t *)BAS_IN_RAM;
|
||||
|
||||
/* The linker script will ensure that the Bas size
|
||||
* is a multiple of the following.
|
||||
*/
|
||||
while (src < end)
|
||||
{
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
/* we have copied a code area, so flush the caches */
|
||||
flush_and_invalidate_caches();
|
||||
|
||||
/* jump into the BaS in RAM */
|
||||
extern void BaS(void);
|
||||
BaS();
|
||||
}
|
||||
17
i2cspi_BaS_gcc/sources/unicode.c
Normal file
17
i2cspi_BaS_gcc/sources/unicode.c
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <ff.h>
|
||||
|
||||
#if _USE_LFN != 0
|
||||
|
||||
#if _CODE_PAGE == 932
|
||||
#include "cc932.c"
|
||||
#elif _CODE_PAGE == 936
|
||||
#include "cc936.c"
|
||||
#elif _CODE_PAGE == 949
|
||||
#include "cc949.c"
|
||||
#elif _CODE_PAGE == 950
|
||||
#include "cc950.c"
|
||||
#else
|
||||
#include "ccsbcs.c"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
31
i2cspi_BaS_gcc/sources/wait.c
Normal file
31
i2cspi_BaS_gcc/sources/wait.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* wait.c
|
||||
*
|
||||
* Created on: 10.12.2012
|
||||
* Author: mfro
|
||||
*
|
||||
* This file is part of BaS_gcc.
|
||||
*
|
||||
* BaS_gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BaS_gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright 2010 - 2012 F. Aschwanden
|
||||
* Copyright 2011 - 2012 V. Riviere
|
||||
* Copyright 2012 M. Froeschle
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <MCF5475.h>
|
||||
|
||||
#include <wait.h>
|
||||
Reference in New Issue
Block a user