1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-07-01 01:26:43 +03:00

make udc work

This commit is contained in:
Bas Wijnen 2009-09-29 23:48:33 +02:00
parent 20d15f0745
commit 431b38acb9
11 changed files with 139 additions and 90 deletions

View File

@ -73,11 +73,13 @@ static void setup ():
char const *decode_kbd = "0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*() T\n[],.-=/\\;|`'UDLREIKBPFZMS{}CA\":"
Kernel::Num start ():
// Set up lcd first
Kernel::schedule ()
kdebug ("init started\n")
setup ()
kdebug ("init set up\n")
while true:
kdebug ("init waiting\n")
Kernel::wait ()
kdebug ("init done waiting\n")
switch Kernel::recv.protected_data.value ():
case KBD:
unsigned code = Kernel::recv.data[0].l

View File

@ -130,14 +130,13 @@ class Udc:
char configuration
unsigned size
char const *ptr
unsigned send_next (unsigned old_csr)
unsigned vendor (unsigned old_csr, Setup *s)
unsigned get_descriptor (unsigned old_csr, unsigned type, unsigned idx, unsigned len)
bool vendor (Setup *s)
bool get_descriptor (unsigned type, unsigned idx, unsigned len)
bool handle_setup (Setup *s)
public:
void init ()
void log (unsigned c)
void interrupt ()
unsigned handle_setup (unsigned old_csr, Setup *s)
Udc::Device const Udc::device_descriptor = { sizeof (Device), Device::Type, 0x200, 0, 0, 0, max_packet_size0, 0x601a, 0x4740, 0x100, 1, 2, 0, 1 }
Udc::my_config const Udc::config_descriptor = {
@ -150,6 +149,7 @@ Udc::my_config const Udc::config_descriptor = {
Udc::String <7> const Udc::s_manufacturer = { sizeof (String <7>), String <7>::Type, { 'I', 'n', 'g', 'e', 'n', 'i', 'c' } }
Udc::String <22> const Udc::s_product = { sizeof (String <22>), String <22>::Type, { 'J', 'Z', '4', '7', '4', '0', ' ', 'U', 'S', 'B', ' ', 'B', 'o', 'o', 't', ' ', 'D', 'e', 'v', 'i', 'c', 'e'} }
void Udc::init ():
kdebug ("udc: init\n")
state = IDLE
configuration = 0
size = 0
@ -162,36 +162,32 @@ void Udc::init ():
UDC_INTRUSB = UDC_INTR_RESET
// enable interrupts on endpoint 0.
UDC_INTRINE |= 1 << 0
UDC_INDEX = 0
unsigned Udc::send_next (unsigned old_csr):
for unsigned i = 0; size > 0 && i < max_packet_size0; ++i, --size:
// Use 8-bit transfers to avoid problems with alignment.
REG8 (UDC_FIFO_EP0) = *ptr++
if size:
state = TX
return (old_csr | UDC_CSR0_INPKTRDY) & ~UDC_CSR0_DATAEND
else:
state = IDLE
return old_csr | UDC_CSR0_INPKTRDY
unsigned Udc::vendor (unsigned old_csr, Setup *s):
bool Udc::vendor (Setup *s):
kdebug ("udc: vendor\n")
if s->request_type & 0x80:
ptr = "abcdefgh"
kdebug ("udc: vendorsend\n")
static char const *name = "abcdefgh"
ptr = name
size = 8
return send_next (old_csr)
return old_csr
state = TX
return true
kdebug ("udc: vendorrecv\n")
return true
unsigned Udc::get_descriptor (unsigned old_csr, unsigned type, unsigned idx, unsigned len):
bool Udc::get_descriptor (unsigned type, unsigned idx, unsigned len):
kdebug ("udc: getdesc\n")
switch type:
case Configuration::Type:
if idx != 1:
return old_csr | UDC_CSR0_SENDSTALL
return false
ptr = reinterpret_cast <char const *> (&config_descriptor)
size = (len < sizeof (config_descriptor) ? len : sizeof (config_descriptor))
break
case Device::Type:
if idx != 0:
return old_csr | UDC_CSR0_SENDSTALL
return false
ptr = reinterpret_cast <char const *> (&device_descriptor)
size = (len < sizeof (device_descriptor) ? len : sizeof (device_descriptor))
break
@ -207,13 +203,23 @@ unsigned Udc::get_descriptor (unsigned old_csr, unsigned type, unsigned idx, uns
size = (len < sizeof (s_product) ? len : sizeof (s_product))
break
default:
return old_csr | UDC_CSR0_SENDSTALL
return false
break
default:
return old_csr | UDC_CSR0_SENDSTALL
return send_next (old_csr)
return false
state = TX
return true
unsigned Udc::handle_setup (unsigned old_csr, Setup *s):
bool Udc::handle_setup (Setup *s):
kdebug ("udc: setup: type=")
kdebug_num (s->request_type)
kdebug ("; request=")
kdebug_num (s->request)
kdebug ("; value=")
kdebug_num (s->value)
kdebug ("; index=")
kdebug_num (s->index)
kdebug ("\n")
switch s->request_type:
case STANDARD_TO_DEVICE:
switch s->request:
@ -222,49 +228,55 @@ unsigned Udc::handle_setup (unsigned old_csr, Setup *s):
break
case SET_CONFIGURATION:
if s->value >= 2:
return old_csr | UDC_CSR0_SENDSTALL
return false
configuration = s->value
break
case SET_INTERFACE:
if s->value != 0:
return old_csr | UDC_CSR0_SENDSTALL
return false
break
default:
return old_csr | UDC_CSR0_SENDSTALL
return false
break
case STANDARD_FROM_DEVICE:
switch s->request:
case GET_STATUS:
ptr = "\0\0"
size = (s->length < 2 ? s->length : 2)
return send_next (old_csr)
state = TX
break
case GET_DESCRIPTOR:
return get_descriptor (old_csr, (s->value >> 8) & 0xff, s->value & 0xff, s->length)
return get_descriptor ((s->value >> 8) & 0xff, s->value & 0xff, s->length)
case GET_CONFIGURATION:
ptr = &configuration
size = (s->length < 1 ? s->length : 1)
return send_next (old_csr)
state = TX
break
case GET_INTERFACE:
ptr = "\0"
size = (s->length < 1 ? s->length : 1)
return send_next (old_csr)
state = TX
break
default:
return old_csr | UDC_CSR0_SENDSTALL
return false
break
case VENDOR_TO_DEVICE:
case VENDOR_FROM_DEVICE:
return vendor (old_csr, s)
return vendor (s)
default:
return old_csr | UDC_CSR0_SENDSTALL
return old_csr
return false
return true
void Udc::interrupt ():
kdebug ("udc: inter\n")
unsigned i = UDC_INTRUSB
if i & UDC_INTR_RESET:
kdebug ("udc: reset\n")
state = IDLE
return
i = UDC_INTRIN
if i & (1 << 0):
kdebug ("udc: ep0\n")
// Interrupt on endpoint 0.
unsigned csr = UDC_CSR0
if csr & UDC_CSR0_SENTSTALL:
@ -275,39 +287,68 @@ void Udc::interrupt ():
state = IDLE
switch state:
case IDLE:
kdebug ("udc: idle\n")
if !(csr & UDC_CSR0_OUTPKTRDY):
break
csr |= UDC_CSR0_SVDOUTPKTRDY | UDC_CSR0_DATAEND
return
kdebug ("udc: packet\n")
union { unsigned d[2]; Setup s; } packet
packet.d[0] = UDC_FIFO_EP0
packet.d[1] = UDC_FIFO_EP0
csr = handle_setup (csr, &packet.s)
UDC_CSR0 = csr
break
packet.d[0] = UDC_FIFO (0)
packet.d[1] = UDC_FIFO (0)
UDC_CSR0 = csr | UDC_CSR0_DATAEND | UDC_CSR0_SVDOUTPKTRDY
if !handle_setup (&packet.s):
csr |= UDC_CSR0_SENDSTALL
break
if size == 0:
return
// Fall through.
case TX:
UDC_CSR0 = send_next (UDC_CSR0 | UDC_CSR0_DATAEND)
kdebug ("udc: send next:")
unsigned i
for i = 0; (size & ~3) > 0 && i < max_packet_size0; i += 4, size -= 4:
for unsigned i = 0; i < 4; ++i:
kdebug_num (ptr[i], 2)
UDC_FIFO (0) = *(unsigned *)ptr
ptr += 4
for ; size > 0 && i < max_packet_size0; ++i, --size:
kdebug_num (*ptr, 2)
UDC_FIFO8 (0) = *ptr++
kdebug ("\n")
if i == max_packet_size0:
csr |= UDC_CSR0_INPKTRDY
else:
state = IDLE
csr |= UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
break
case RX:
// Not supported.
UDC_CSR0 |= UDC_CSR0_SENDSTALL
csr |= UDC_CSR0_SVDOUTPKTRDY | UDC_CSR0_SENDSTALL
state = IDLE
break
UDC_CSR0 = csr
void Udc::log (unsigned c):
kdebug ("udc: log\n")
Kernel::Num start ():
map_udc ()
Udc udc
kdebug ("udc: start\n")
udc.init ()
kdebug ("udc: done init\n")
Kernel::Cap logcap = Kernel::my_receiver.create_capability (Init::LOG)
kdebug ("udc: made cap\n")
__asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory")
kdebug ("udc: registered cap\n")
Kernel::register_interrupt (IRQ_UDC)
kdebug ("udc: registered interrupt\n")
while true:
kdebug ("udc: waiting\n")
Kernel::wait ()
switch Kernel::recv.protected_data.l:
case IRQ_UDC:
udc.interrupt ()
Kernel::register_interrupt (IRQ_UDC)
break
case Init::LOG:
udc.log (Kernel::recv.data[0].l)

View File

@ -21,38 +21,36 @@
static void log_message (char const *prefix, unsigned target, unsigned pdata, kCapability::Context *c):
if !dbg_code.l:
dbg_log (prefix)
dbg_log (": ")
dbg_log (": caller=")
dbg_log_num ((unsigned)old_current)
dbg_log (" > ")
dbg_log ("; target=")
dbg_log_num (target)
dbg_log (":")
dbg_log ("; pdata=")
dbg_log_num (pdata)
dbg_log ("/")
dbg_log_num (c->data[0].l)
dbg_log (" ")
dbg_log ("; data=")
dbg_log_num (c->data[0].h)
dbg_log (":")
dbg_log_num (c->data[0].l)
dbg_log (",")
dbg_log_num (c->data[1].l)
dbg_log (" ")
dbg_log_num (c->data[1].h)
dbg_log (",")
dbg_log_num (pdata)
dbg_log (";")
dbg_log (":")
dbg_log_num (c->data[1].l)
if c->reply.valid ():
dbg_log ("; reply target=")
dbg_log_num ((unsigned)c->reply->target)
dbg_log (":")
dbg_log ("; pdata=")
dbg_log_num (c->reply->protected_data.l)
dbg_log (",")
if c->arg.valid ():
dbg_log ("; arg target=")
dbg_log_num ((unsigned)c->arg->target)
dbg_log (":")
dbg_log ("; pdata=")
dbg_log_num (c->arg->protected_data.l)
dbg_log ("\n")
void kThread::raise (unsigned code, unsigned data):
dpanic (code, "raise")
dbg_log ("raise ")
dbg_log_num ((unsigned)current)
dbg_log_num ((unsigned)old_current)
dbg_log_char ('/')
if code < Kernel::NUM_EXCEPTION_CODES:
dbg_log (Kernel::exception_name[code])
@ -853,7 +851,7 @@ static void kernel_invoke (unsigned target, Kernel::Num protected_data, kCapabil
return
void invoke (kReceiverP target, Kernel::Num protected_data, kCapability::Context *c):
log_message ("invoke", (unsigned)target, protected_data.l, c)
//log_message ("invoke", (unsigned)target, protected_data.l, c)
if (unsigned)target & ~KERNEL_MASK:
// This is not a kernel capability: send a message to the receiver.
if must_wait:

View File

@ -43,9 +43,11 @@
#define CP0_ENTRY_HI 10
#define CP0_COMPARE 11
#define CP0_STATUS 12
#define CP0_INT_CTL 12, 1
#define CP0_CAUSE 13
#define CP0_EPC 14
#define CP0_P_R_ID 15
#define CP0_EBASE 15, 1
#define CP0_CONFIG 16
#define CP0_CONFIG1 16, 1
#define CP0_CONFIG2 16, 2

View File

@ -59,12 +59,16 @@ static void init_idle ():
directory = idle_memory.arch.directory
static void init_cp0 ():
// Set timer to a defined value
cp0_set (CP0_COMPARE, 1000000)
// Reset timer
cp0_set0 (CP0_COUNT)
// Use the interrupt vector for interrupts
// Disable watchpoint interrupts.
cp0_set0 (CP0_WATCH_LO)
// Use the interrupt vector for interrupts; clear interrupt pending flags.
cp0_set (CP0_CAUSE, 1 << 23)
// Disable interrupts and set interrupt vectors to normal.
cp0_set0 (CP0_STATUS)
// Reset exception base address.
cp0_set0 (CP0_EBASE)
// Use non-vectored interrupts.
cp0_set0 (CP0_INT_CTL)
// clear the tlb, hardwire page 0 to 0xffffffff
// and soft-wire it to (0x294 << 20) + (0x290 << 10)
@ -231,8 +235,6 @@ void init (unsigned mem):
dbg_code = 0
#endif
must_wait = false
// Disable interrupts and set interrupt vectors to normal.
cp0_set (CP0_STATUS, 0x00404304)
// Initialize kernel variables to empty.
unsigned count = init_memory (mem)
// initialize system control coprocessor.
@ -266,6 +268,7 @@ void init (unsigned mem):
// Initialize board-specific things.
board_init ()
intc_unmask_irq (TIMER_INTERRUPT)
// Say we're handling an exception. Since we're going to enter the idle task, allow access to cp0.
// All interrupts enter the CPU through the interrupt controller at IP2, so enable that.

View File

@ -228,9 +228,7 @@ kThread *exception ():
dpanic (0, "no log capability provided")
break
break
if dbg_cap.valid ():
dbg_log_char (current->arch.a[1])
break
dbg_log_char (current->arch.a[1])
#endif
break
case 10:

View File

@ -33,9 +33,9 @@ void board_init ():
gpio_as_gpio (3, 0x05fc0000)
tcu_stop_counter (0)
tcu_select_extalclk (0)
tcu_select_clk_div1 (0)
tcu_select_clk_div4 (0)
tcu_disable_pwm_output (0)
tcu_set_full_data (0, JZ_EXTAL / HZ)
tcu_set_full_data (0, JZ_EXTAL / HZ / 4)
tcu_mask_half_match_irq (0)
tcu_clear_full_match_flag (0)
tcu_unmask_full_match_irq (0)

View File

@ -22,7 +22,7 @@
#define __JZ4740_HH__
// Main clock, for cpu, serial port, and with divisors for most other hardware
#define JZ_EXTAL 3686400 /* 3.6864 MHz */
#define JZ_EXTAL 12000000 /* 3.6864 MHz */
// RTC clock
#define RTC_CLOCK 32768 /* 32.768 KHz */
// Interrupt source used for system timer
@ -1883,17 +1883,16 @@ void cdelay (unsigned cs):
#define UDC_TESTMODE REG8 (UDC_BASE + 0x0f) // USB test mode 8-bit
#define UDC_CSR0 REG8 (UDC_BASE + 0x12) // EP0 CSR 8-bit
#define UDC_INMAXP REG16 (UDC_BASE + 0x10) // EP1-2 IN Max Pkt Size 16-bit
#define UDC_INCSR REG16 (UDC_BASE + 0x12) // EP1-2 IN CSR LSB 8/16bit
#define UDC_INCSRH REG8 (UDC_BASE + 0x13) // EP1-2 IN CSR MSB 8-bit
#define UDC_OUTMAXP REG16 (UDC_BASE + 0x14) // EP1 OUT Max Pkt Size 16-bit
#define UDC_OUTCSR REG16 (UDC_BASE + 0x16) // EP1 OUT CSR LSB 8/16bit
#define UDC_OUTCSRH REG8 (UDC_BASE + 0x17) // EP1 OUT CSR MSB 8-bit
#define UDC_OUTCOUNT REG16 (UDC_BASE + 0x18) // bytes in EP0/1 OUT FIFO 16-bit
#define UDC_INMAXP(ep) REG16 (UDC_BASE + 0x100 + 0x10 * (ep) + 0x10) // EP1-2 IN Max Pkt Size 16-bit
#define UDC_INCSR(ep) REG16 (UDC_BASE + 0x100 + 0x10 * (ep) + 0x12) // EP1-2 IN CSR LSB 8/16bit
#define UDC_INCSRH(ep) REG8 (UDC_BASE + 0x100 + 0x10 * (ep) + 0x13) // EP1-2 IN CSR MSB 8-bit
#define UDC_OUTMAXP(ep) REG16 (UDC_BASE + 0x100 + 0x10 * (ep) + 0x14) // EP1 OUT Max Pkt Size 16-bit
#define UDC_OUTCSR(ep) REG16 (UDC_BASE + 0x100 + 0x10 * (ep) + 0x16) // EP1 OUT CSR LSB 8/16bit
#define UDC_OUTCSRH(ep) REG8 (UDC_BASE + 0x100 + 0x10 * (ep) + 0x17) // EP1 OUT CSR MSB 8-bit
#define UDC_OUTCOUNT(ep) REG16 (UDC_BASE + 0x100 + 0x10 * (ep) + 0x18) // bytes in EP0/1 OUT FIFO 16-bit
#define UDC_FIFO_EP0 REG32 (UDC_BASE + 0x20)
#define UDC_FIFO_EP1 REG32 (UDC_BASE + 0x24)
#define UDC_FIFO_EP2 REG32 (UDC_BASE + 0x28)
#define UDC_FIFO(ep) REG32 (UDC_BASE + 0x20 + 4 * (ep))
#define UDC_FIFO8(ep) REG8 (UDC_BASE + 0x20 + 4 * (ep))
#define UDC_EPINFO REG32 (UDC_BASE + 0x78) // Endpoint information
#define UDC_RAMINFO REG32 (UDC_BASE + 0x79) // RAM information
@ -2354,7 +2353,7 @@ static void pll_init ():
cfcr = CPM_CPCCR_CLKOEN | (n2FR[1] << CPM_CPCCR_CDIV_BIT) | (n2FR[PHM_DIV] << CPM_CPCCR_HDIV_BIT) | (n2FR[PHM_DIV] << CPM_CPCCR_PDIV_BIT) | (n2FR[PHM_DIV] << CPM_CPCCR_MDIV_BIT) | (n2FR[PHM_DIV] << CPM_CPCCR_LDIV_BIT)
pllout2 = (cfcr & CPM_CPCCR_PCS) ? 252000000 : (252000000 / 2)
CPM_UHCCDR = pllout2 / 48000000 - 1
nf = 252000000 * 2 / 12000000
nf = 252000000 * 2 / JZ_EXTAL
plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | (0 << CPM_CPPCR_PLLN_BIT) | (0 << CPM_CPPCR_PLLOD_BIT) | (0x20 << CPM_CPPCR_PLLST_BIT) | CPM_CPPCR_PLLEN
CPM_CPCCR = cfcr
CPM_CPPCR = plcr1

View File

@ -21,6 +21,7 @@
#include <fstream>
#include <sstream>
#include <iostream>
#include <iomanip>
asm volatile (".section .rodata\n"
".globl stage1\n"
@ -165,8 +166,12 @@ void nanonote::boot (std::string const &data, unsigned load, unsigned start):
send_file (load, data.size (), data.data ())
request (VR_FLUSH_CACHES)
request (VR_PROGRAM_START2, start)
sleep (1)
get_cpu_info ()
std::cerr << "info: " << cpu_info << std::endl
std::cerr << "info: ";
for unsigned i = 0; i < cpu_info.size (); ++i:
std::cerr << std::setfill ('0') << std::setw (2) << std::hex << (cpu_info[i] & 0xff);
std::cerr << std::endl
int main (int argc, char **argv):
if argc != 3:

View File

@ -54,4 +54,3 @@ void board_init ():
ost_set_count (0, 1)
ost_set_mode (0, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL)
ost_enable_channel (0)
intc_unmask_irq (IRQ_OST0)

View File

@ -58,7 +58,9 @@ void panic_impl (unsigned n, unsigned line, char const *name, char const *messag
#ifndef NDEBUG
// If a log capability is registered, run its owner.
if dbg_cap.valid () && dbg_cap->target->owner:
#ifndef USE_SERIAL
dbg_cap->target->owner->run ()
#endif
// Use the (now running) log thread to display the message.
dbg_log ("Panic: caller = ")
dbg_log_num ((unsigned)old_current)