aboutsummaryrefslogtreecommitdiff
path: root/example-fs-bb48
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2016-05-30 14:39:02 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2016-05-30 14:39:02 +0900
commitb90e58f763bd277b7a5285601a34818f44f2b01c (patch)
tree4535e6abc8b77d58215796c240489e7dbf499b44 /example-fs-bb48
parent8209f3875510d1990142a367c8bab6164c2f82cc (diff)
Move CHIP specific things to mcu/
Diffstat (limited to 'example-fs-bb48')
-rw-r--r--example-fs-bb48/Makefile7
-rw-r--r--example-fs-bb48/adc_kl27z.c320
-rw-r--r--example-fs-bb48/command.c7
-rw-r--r--example-fs-bb48/sample.ld8
-rw-r--r--example-fs-bb48/sys.c414
-rw-r--r--example-fs-bb48/sys.h41
-rw-r--r--example-fs-bb48/usb_kl27z.c1034
-rw-r--r--example-fs-bb48/usb_lld.h6
8 files changed, 16 insertions, 1821 deletions
diff --git a/example-fs-bb48/Makefile b/example-fs-bb48/Makefile
index 52782cc..06a68bd 100644
--- a/example-fs-bb48/Makefile
+++ b/example-fs-bb48/Makefile
@@ -6,7 +6,12 @@ PROJECT = sample
CHOPSTX = ..
LDSCRIPT= sample.ld
-CSRC = sample.c sys.c usb_kl27z.c usb-cdc.c adc_kl27z.c command.c
+CSRC = sample.c usb-cdc.c command.c
+CHIP=mkl27z
+
+USE_SYS = yes
+USE_USB = yes
+USE_ADC = yes
###################################
CROSS = arm-none-eabi-
diff --git a/example-fs-bb48/adc_kl27z.c b/example-fs-bb48/adc_kl27z.c
deleted file mode 100644
index de482bb..0000000
--- a/example-fs-bb48/adc_kl27z.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * adc_kl27z.c - ADC driver for KL27Z
- * In this ADC driver, there are NeuG specific parts.
- * It only records lower 8-bit of 16-bit data.
- * You need to modify to use this as generic ADC driver.
- *
- * Copyright (C) 2016 Flying Stone Technology
- * Author: NIIBE Yutaka <gniibe@fsij.org>
- *
- * This file is a part of Chopstx, a thread library for embedded.
- *
- * Chopstx 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.
- *
- * Chopstx 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 this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As additional permission under GNU GPL version 3 section 7, you may
- * distribute non-source form of the Program without the copy of the
- * GNU GPL normally required by section 4, provided you inform the
- * receipents of GNU GPL by a written offer.
- *
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <chopstx.h>
-#include <mcu/kl_sim.h>
-
-struct DMAMUX {
- volatile uint32_t CHCFG0;
- volatile uint32_t CHCFG1;
- volatile uint32_t CHCFG2;
- volatile uint32_t CHCFG3;
-};
-static struct DMAMUX *const DMAMUX = (struct DMAMUX *const)0x40021000;
-
-#define INTR_REQ_DMA0 0
-
-struct DMA {
- volatile uint32_t SAR;
- volatile uint32_t DAR;
- volatile uint32_t DSR_BCR;
- volatile uint32_t DCR;
-};
-static struct DMA *const DMA0 = (struct DMA *const)0x40008100;
-static struct DMA *const DMA1 = (struct DMA *const)0x40008110;
-
-
-/* We don't use ADC interrupt. Just for reference. */
-#define INTR_REQ_ADC 15
-
-struct ADC {
- volatile uint32_t SC1[2];/* Status and Control Registers 1 */
- volatile uint32_t CFG1; /* Configuration Register 1 */
- volatile uint32_t CFG2; /* Configuration Register 2 */
- volatile uint32_t R[2]; /* Data Result Register */
-
- /* Compare Value Registers 1, 2 */
- volatile uint32_t CV1;
- volatile uint32_t CV2;
-
- volatile uint32_t SC2; /* Status and Control Register 2 */
- volatile uint32_t SC3; /* Status and Control Register 3 */
-
- volatile uint32_t OFS; /* Offset Correction Register */
- volatile uint32_t PG; /* Plus-Side Gain Register */
- volatile uint32_t MG; /* Minus-Side Gain Register */
-
- /* Plus-Side General Calibration Value Registers */
- volatile uint32_t CLPD;
- volatile uint32_t CLPS;
- volatile uint32_t CLP4;
- volatile uint32_t CLP3;
- volatile uint32_t CLP2;
- volatile uint32_t CLP1;
- volatile uint32_t CLP0;
- uint32_t rsvd0;
- /* Minus-Side General Calibration Value Registers */
- volatile uint32_t CLMD;
- volatile uint32_t CLMS;
- volatile uint32_t CLM4;
- volatile uint32_t CLM3;
- volatile uint32_t CLM2;
- volatile uint32_t CLM1;
- volatile uint32_t CLM0;
-};
-static struct ADC *const ADC0 = (struct ADC *const)0x4003B000;
-
-/* SC1 */
-#define ADC_SC1_DIFF (1 << 5)
-#define ADC_SC1_AIEN (1 << 6)
-#define ADC_SC1_COCO (1 << 7)
-#define ADC_SC1_TEMPSENSOR 26
-#define ADC_SC1_BANDGAP 27
-#define ADC_SC1_ADCSTOP 31
-
-/* CFG1 */
-#define ADC_CLOCK_SOURCE_ASYNCH (3 << 0)
-#define ADC_MODE_16BIT (3 << 2)
-#define ADC_ADLSMP_SHORT (0 << 4)
-#define ADC_ADLSMP_LONG (1 << 4)
-#define ADC_ADIV_1 (0 << 5)
-#define ADC_ADIV_8 (3 << 5)
-#define ADC_ADLPC_NORMAL (0 << 7)
-#define ADC_ADLPC_LOWPOWER (1 << 7)
-/**/
-#define ADC_CLOCK_SOURCE ADC_CLOCK_SOURCE_ASYNCH
-#define ADC_MODE ADC_MODE_16BIT
-#define ADC_ADLSMP ADC_ADLSMP_SHORT
-#define ADC_ADIV ADC_ADIV_1
-#define ADC_ADLPC ADC_ADLPC_LOWPOWER
-
-/* CFG2 */
-#define ADC_ADLSTS_DEFAULT 0 /* 24 cycles if CFG1.ADLSMP=1, 4 if not. */
-#define ADC_ADHSC_NORMAL (0 << 2)
-#define ADC_ADHSC_HIGHSPEED (1 << 2)
-#define ADC_ADACK_DISABLE (0 << 3)
-#define ADC_ADACK_ENABLE (1 << 3)
-#define ADC_MUXSEL_A (0 << 4)
-#define ADC_MUXSEL_B (1 << 4)
-/**/
-#define ADC_ADLSTS ADC_ADLSTS_DEFAULT
-#define ADC_ADHSC ADC_ADHSC_NORMAL
-#define ADC_ADACKEN ADC_ADACK_ENABLE
-#define ADC_MUXSEL ADC_MUXSEL_A
-
-/* SC2 */
-#define ADC_SC2_REFSEL_DEFAULT 1 /* Internal Voltage Reference??? */
-#define ADC_SC2_DMAEN (1 << 2)
-#define ADC_SC2_ACREN (1 << 3)
-#define ADC_SC2_ACFGT (1 << 4)
-#define ADC_SC2_ACFE (1 << 5)
-#define ADC_SC2_ADTRG (1 << 6) /* For hardware trigger */
-
-/* SC3 */
-#define ADC_SC3_AVGS11 0x03
-#define ADC_SC3_AVGE (1 << 2)
-#define ADC_SC3_ADCO (1 << 3)
-#define ADC_SC3_CALF (1 << 6)
-#define ADC_SC3_CAL (1 << 7)
-
-#define ADC_DMA_SLOT_NUM 40
-
-/*
- * Buffer to save ADC data.
- */
-uint32_t adc_buf[64];
-
-static const uint32_t adc0_sc1_setting = ADC_SC1_TEMPSENSOR;
-
-static chopstx_intr_t adc_intr;
-
-struct adc_internal {
- uint32_t buf[64];
- uint8_t *p;
- int phase : 8;
- int count : 8;
-};
-struct adc_internal adc;
-
-/*
- * Initialize ADC module, do calibration.
- *
- * This is called by MAIN, only once, hopefully before creating any
- * other threads (to be accurate).
- *
- * We configure ADC0 to kick DMA0, configure DMA0 to kick DMA1.
- * DMA0 records output of ADC0 to the ADC.BUF.
- * DMA1 kicks ADC0 again to get another value.
- *
- * ADC0 --[finish conversion]--> DMA0 --[Link channel 1]--> DMA1
- */
-int
-adc_init (void)
-{
- uint32_t v;
-
- /* Enable ADC0 and DMAMUX clock. */
- SIM->SCGC6 |= (1 << 27) | (1 << 1);
- /* Enable DMA clock. */
- SIM->SCGC7 |= (1 << 8);
-
- /* ADC0 setting for calibration. */
- ADC0->CFG1 = ADC_CLOCK_SOURCE | ADC_MODE | ADC_ADLSMP | ADC_ADIV | ADC_ADLPC;
- ADC0->CFG2 = ADC_ADLSTS | ADC_ADHSC | ADC_ADACKEN | ADC_MUXSEL;
- ADC0->SC2 = ADC_SC2_REFSEL_DEFAULT;
- ADC0->SC3 = ADC_SC3_CAL | ADC_SC3_CALF | ADC_SC3_AVGE | ADC_SC3_AVGS11;
-
- /* Wait ADC completion */
- while ((ADC0->SC1[0] & ADC_SC1_COCO) == 0)
- if ((ADC0->SC3 & ADC_SC3_CALF) != 0)
- /* Calibration failure */
- return -1;
-
- if ((ADC0->SC3 & ADC_SC3_CALF) != 0)
- /* Calibration failure */
- return -1;
-
- /* Configure PG by the calibration values. */
- v = ADC0->CLP0 + ADC0->CLP1 + ADC0->CLP2 + ADC0->CLP3 + ADC0->CLP4 + ADC0->CLPS;
- ADC0->PG = 0x8000 | (v >> 1);
-
- /* Configure MG by the calibration values. */
- v = ADC0->CLM0 + ADC0->CLM1 + ADC0->CLM2 + ADC0->CLM3 + ADC0->CLM4 + ADC0->CLMS;
- ADC0->MG = 0x8000 | (v >> 1);
-
- ADC0->SC1[0] = ADC_SC1_ADCSTOP;
-
- /* DMAMUX setting. */
- DMAMUX->CHCFG0 = (1 << 7) | ADC_DMA_SLOT_NUM;
-
- /* DMA0 initial setting. */
- DMA0->SAR = (uint32_t)&ADC0->R[0];
-
- /* DMA1 initial setting. */
- DMA1->SAR = (uint32_t)&adc0_sc1_setting;
- DMA1->DAR = (uint32_t)&ADC0->SC1[0];
-
- chopstx_claim_irq (&adc_intr, INTR_REQ_DMA0);
- return 0;
-}
-
-/*
- * Start using ADC.
- */
-void
-adc_start (void)
-{
- ADC0->CFG1 = ADC_CLOCK_SOURCE | ADC_MODE | ADC_ADLSMP | ADC_ADIV | ADC_ADLPC;
- ADC0->CFG2 = ADC_ADLSTS | ADC_ADHSC | ADC_ADACKEN | ADC_MUXSEL;
- ADC0->SC2 = ADC_SC2_REFSEL_DEFAULT | ADC_SC2_DMAEN;
- ADC0->SC3 = 0;
-}
-
-/*
- * Kick getting data for COUNT times.
- * Data will be saved in ADC_BUF starting at OFFSET.
- */
-static void
-adc_start_conversion_internal (int count)
-{
- /* DMA0 setting. */
- DMA0->DAR = (uint32_t)&adc.buf[0];
- DMA0->DSR_BCR = 4 * count;
- DMA0->DCR = (1 << 31) | (1 << 30) | (1 << 29) | (0 << 20) | (1 << 19)
- | (0 << 17) | (1 << 7) | (2 << 4) | (1 << 2);
-
- /* Kick DMA1. */
- DMA1->DSR_BCR = 4 * count;
- DMA1->DCR = (1 << 30) | (1 << 29) | (0 << 19) | (0 << 17) | (1 << 16) | (1 << 7);
-}
-
-
-/*
- * Kick getting data for COUNT times.
- * Data will be saved in ADC_BUF starting at OFFSET.
- */
-void
-adc_start_conversion (int offset, int count)
-{
- adc.p = (uint8_t *)&adc_buf[offset];
- adc.phase = 0;
- adc.count = count;
- adc_start_conversion_internal (count);
-}
-
-
-static void
-adc_stop_conversion (void)
-{
- ADC0->SC1[0] = ADC_SC1_ADCSTOP;
-}
-
-/*
- * Stop using ADC.
- */
-void
-adc_stop (void)
-{
- SIM->SCGC6 &= ~(1 << 27);
-}
-
-/*
- * Return 0 on success.
- * Return 1 on error.
- */
-int
-adc_wait_completion (void)
-{
- while (1)
- {
- int i;
-
- /* Wait DMA completion */
- chopstx_poll (NULL, 1, &adc_intr);
-
- DMA0->DSR_BCR = (1 << 24);
- DMA1->DSR_BCR = (1 << 24);
-
- adc_stop_conversion ();
-
- for (i = 0; i < adc.count; i++)
- *adc.p++ = (uint8_t)adc.buf[i];
-
- if (++adc.phase >= 4)
- break;
-
- adc_start_conversion_internal (adc.count);
- }
-
- return 0;
-}
diff --git a/example-fs-bb48/command.c b/example-fs-bb48/command.c
index 6556bc7..15df6dd 100644
--- a/example-fs-bb48/command.c
+++ b/example-fs-bb48/command.c
@@ -7,8 +7,13 @@
#include "adc.h"
static int adc_initialized = 0;
#endif
-#include "sys.h"
#include "board.h"
+#ifdef MCU_KINETIS_L
+#include "mcu/sys-mkl27z.h"
+#else
+#include "mcu/sys-stm32.h"
+#undef STM32F10X_MD /* Prepare for high density device, too. */
+#endif
struct command_table
{
diff --git a/example-fs-bb48/sample.ld b/example-fs-bb48/sample.ld
index 5a728a6..fa75271 100644
--- a/example-fs-bb48/sample.ld
+++ b/example-fs-bb48/sample.ld
@@ -29,10 +29,10 @@ SECTIONS
KEEP(*(.sys.version))
KEEP(*(.sys.board_info))
KEEP(*(.sys.vectors))
- build/sys.o(.text)
- build/sys.o(.text.*)
- build/sys.o(.rodata)
- build/sys.o(.rodata.*)
+ build/sys-*.o(.text)
+ build/sys-*.o(.text.*)
+ build/sys-*.o(.rodata)
+ build/sys-*.o(.rodata.*)
. = ALIGN(1024);
KEEP(*(.flash_config))
KEEP(*(.fixed_function.reset))
diff --git a/example-fs-bb48/sys.c b/example-fs-bb48/sys.c
deleted file mode 100644
index f0a0402..0000000
--- a/example-fs-bb48/sys.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * sys.c - First pages for MKL27Z256.
- *
- * Copyright (C) 2016 Flying Stone Technology
- * Author: NIIBE Yutaka <gniibe@fsij.org>
- *
- * Copying and distribution of this file, with or without modification,
- * are permitted in any medium without royalty provided the copyright
- * notice and this notice are preserved. This file is offered as-is,
- * without any warranty.
- *
- *
- * First two pages of Flash ROM is difficult to use because of
- * predefined purposes. It's defined as a default vector page and
- * a flash configuration page.
- *
- * We put something useful to those two pages, together with the
- * data for predefined purposes.
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include "board.h"
-
-#define ADDR_VECTORS (0x00000900)
-#define ADDR_SCR_VTOR 0xe000ed08
-
-static void __attribute__ ((naked,section(".fixed_function.reset")))
-reset (void)
-{
- uint32_t r3 = ADDR_SCR_VTOR;
-
- asm volatile ("str %2, [%0]\n\t" /* Set SCR->VTOR */
- "ldr %0, [%2]\n\t" /* Stack address */
- "msr MSP, %0\n\t" /* Exception handler stack. */
- "ldr %0, [%2, #4]\n\t" /* The entry address */
- "bx %0\n\t" /* Jump to the entry */
- ".align 2"
- : "=r" (r3)
- : "0" (r3), "r" (ADDR_VECTORS)
- : "memory");
-
- /* Never reach here. */
-}
-
-
-static uint32_t
-stack_entry[] __attribute__ ((section(".first_page.first_words"),used)) = {
- /* Since MSP are soon modified in RESET, we put 0 here. */
- 0,
- (uint32_t)reset,
-};
-
-#include "mcu/clk_gpio_init-kl.c"
-
-static void
-set_led (int on)
-{
- if (on)
- GPIOB->PCOR = (1 << 0); /* PTB0: Clear: Light on */
- else
- GPIOB->PSOR = (1 << 0); /* PTB0: Set : Light off */
-}
-
-/*
- * Here comes other SYS routines and data.
- */
-
-const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = {
- 3*2+2, /* bLength */
- 0x03, /* bDescriptorType = STRING_DESCRIPTOR */
- /* sys version: "3.0" */
- '3', 0, '.', 0, '0', 0,
-};
-
-static const uint8_t board_name_string[] = BOARD_NAME;
-
-const uint8_t __attribute__((section(".sys.board_info")))
-*const sys_board_name = board_name_string;
-
-const uint32_t __attribute__((section(".sys.board_info")))
-sys_board_id = BOARD_ID;
-
-typedef void (*handler)(void);
-
-handler sys_vector[] __attribute__ ((section(".sys.vectors"))) = {
- clock_init,
- gpio_init,
- (handler)set_led,
- NULL,
-};
-
-static uint32_t
-flash_config[] __attribute__ ((section(".flash_config"),used)) = {
- 0xffffffff, 0xffffffff, /* Comparison Key */
- 0xffffffff, /* Protection bytes */
- 0xffff3ffe, /* FSEC=0xfe, FOPT=0x3f */
- /* FOPT=0x3f:
- * BOOTSRC_SEL=00: Boot from flash
- */
- /* FSEC=0xfe:
- * unsecure
- */
-};
-
-
-/*
- * Flash memory routine
- */
-struct FTFA {
- volatile uint8_t FSTAT;
- volatile uint8_t FCNFG;
- volatile uint8_t FSEC;
- volatile uint8_t FOPT;
- /* Note: addressing (3,2,1,0, 7,6,5,4, B,A,9,8) */
- /* Use Bx macro. */
- volatile uint8_t FCCO[12];
- /* Note: addressing (3,2,1,0). Use Bx macro. */
- volatile uint8_t FPROT[4];
-};
-static struct FTFA *const FTFA = (struct FTFA *const)0x40020000;
-
-#define FSTAT_CCIF 0x80
-#define B3 0
-#define B2 1
-#define B1 2
-#define B0 3
-#define B7 4
-#define B6 5
-#define B5 6
-#define B4 7
-#define BB 8
-#define BA 9
-#define B9 10
-#define B8 11
-
-uint32_t __attribute__ ((naked,section(".fixed_function.flash_do_internal")))
-flash_do_internal (void)
-{
-#ifdef ORIGINAL_IN_C
- uint8_t r;
-
- asm volatile ("cpsid i" : : : "memory");
- FTFA->FSTAT |= FSTAT_CCIF;
- while (((r = FTFA->FSTAT) & FSTAT_CCIF) == 0)
- ;
- r &= ~FSTAT_CCIF;
- asm volatile ("cpsie i" : : : "memory");
-
- return (uint32_t)r;
-#else
- register unsigned int r0 asm ("r0");
- register unsigned int r1 asm ("r1") = (unsigned int)FTFA;
- register unsigned int r2 asm ("r2") = FSTAT_CCIF;
-
- asm volatile ("cpsid i\n\t"
- "ldrb %0, [%1]\n\t"
- "orr %0, %2\n\t"
- "strb %0, [%1]\n"
- "0:\t"
- "ldrb %0, [%1]\n\t"
- "uxtb %0, %0\n\t"
- "tst %0, %2\n\t"
- "beq 0b\n\t"
- "cpsie i\n\t"
- "bic %0, %2\n\t"
- "bx lr"
- : "=r" (r0)
- : "r" (r1), "r" (r2)
- : "memory");
- return r0;
-#endif
-}
-
-/*
- * Let execute flash command.
- * Since the code should be on RAM, we copy the code onto stack
- * and let it go.
- */
-uint32_t __attribute__ ((naked,section(".fixed_function.flash_do")))
-flash_do (void)
-{
- register unsigned int r0 asm ("r0");
- register unsigned int r1 asm ("r1");
- register unsigned int r2 asm ("r2");
- register unsigned int r3 asm ("r3") = (unsigned int)flash_do_internal&~3;
- /* Address of Thumb code &1 == 1, so, we clear the last bits. ------^ */
-
- asm volatile ("sub sp, #32\n\t"
- "mov %1, sp\n\t"
- "mov %2, #0\n"
- "0:\t"
- "cmp %2, #32\n\t"
- "beq 1f\n\t"
- "ldr %0, [%3, %2]\n\t"
- "str %0, [%1, %2]\n\t"
- "add %2, #4\n\t"
- "b 0b\n"
- "1:\t"
- "add %1, #1\n\t" /* Thumb code requires LSB=1. */
- "mov %3, lr\n\t"
- "blx %1\n\t"
- "add sp, #32\n\t"
- "bx %3"
- : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
- : "3" (r3));
-}
-
-#define FLASH_COMMAND_PROGRAM_LONGWORD 0x06
-#define FLASH_COMMAND_ERASE_FLASH_SECTOR 0x09
-
-int __attribute__ ((naked,section(".fixed_function.flash_erase_page")))
-flash_erase_page (uint32_t addr)
-{
-#ifdef ORIGINAL_IN_C
- FTFA->FCCO[B0] = FLASH_COMMAND_ERASE_FLASH_SECTOR;
- FTFA->FCCO[B3] = (addr >> 0) & 0xff;
- FTFA->FCCO[B2] = (addr >> 8) & 0xff;
- FTFA->FCCO[B1] = (addr >> 16) & 0xff;
- flash_do ();
-#else
- register unsigned int r0 asm ("r0") = addr;
- register unsigned int r1 asm ("r1");
- register unsigned int r2 asm ("r2") = FLASH_COMMAND_ERASE_FLASH_SECTOR;
- register unsigned int r3 asm ("r3") = (unsigned int)FTFA;
-
- asm volatile ("strb %2, [%3, #7]\n\t"
- "strb %0, [%3, #4]\n\t"
- "lsr %0, #8\n\t"
- "strb %0, [%3, #5]\n\t"
- "lsr %0, #8\n\t"
- "strb %0, [%3, #6]\n\t"
- "b flash_do"
- : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
- : "0" (r0), "2" (r2), "3" (r3));
-#endif
-}
-
-int __attribute__ ((naked,section(".fixed_function.flash_program_word")))
-flash_program_word (uint32_t addr, uint32_t word)
-{
-#ifdef ORIGINAL_IN_C
- FTFA->FCCO[B0] = FLASH_COMMAND_PROGRAM_LONGWORD;
- FTFA->FCCO[B3] = (addr >> 0) & 0xff;
- FTFA->FCCO[B2] = (addr >> 8) & 0xff;
- FTFA->FCCO[B1] = (addr >> 16) & 0xff;
- FTFA->FCCO[B4] = (word >> 0) & 0xff;
- FTFA->FCCO[B5] = (word >> 8) & 0xff;
- FTFA->FCCO[B6] = (word >> 16) & 0xff;
- FTFA->FCCO[B7] = (word >> 24) & 0xff;
- flash_do ();
-#else
- register unsigned int r0 asm ("r0") = addr;
- register unsigned int r1 asm ("r1") = word;
- register unsigned int r2 asm ("r2") = FLASH_COMMAND_PROGRAM_LONGWORD;
- register unsigned int r3 asm ("r3") = (unsigned int)FTFA;
-
- asm volatile ("strb %2, [%3, #7]\n\t"
- "strb %0, [%3, #4]\n\t"
- "lsr %0, #8\n\t"
- "strb %0, [%3, #5]\n\t"
- "lsr %0, #8\n\t"
- "strb %0, [%3, #6]\n\t"
- "strb %1, [%3, #11]\n\t"
- "lsr %1, #8\n\t"
- "strb %1, [%3, #10]\n\t"
- "lsr %1, #8\n\t"
- "strb %1, [%3, #9]\n\t"
- "lsr %1, #8\n\t"
- "strb %1, [%3, #8]\n\t"
- "b flash_do"
- : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
- : "0" (r0), "1" (r1), "2" (r2), "3" (r3));
-#endif
-}
-
-
-/*
- * CRC32 calculation routines.
- */
-void __attribute__ ((naked,section(".fixed_function.crc32_init")))
-crc32_init (unsigned int *p)
-{
-#ifdef ORIGINAL_IN_C
- *p = 0xffffffff;
-#else
- register unsigned int r3 asm ("r3");
-
- asm volatile ("mov %0, #1\n\t"
- "neg %0, %0\n\t"
- "str %0, [%1]\n\t"
- "bx lr"
- : "=r" (r3)
- : "r" (p)
- : "memory");
-#endif
-}
-
-#ifdef ORIGINAL_IN_C
-const unsigned int *const crc32_table= (const unsigned int *const)0x00000500;
-#endif
-
-void __attribute__ ((naked,section(".fixed_function.crc32_u8")))
-crc32_u8 (unsigned int *p, unsigned char v)
-{
-#ifdef ORIGINAL_IN_C
- *p = crc32_table[(*p & 0xff) ^ v] ^ (*p >> 8);
-#else
- register unsigned int r2 asm ("r2");
- register unsigned int r3 asm ("r3");
-
- asm volatile ("ldrb %2, [%4]\n\t"
- "eor %0, %2\n\t"
- "mov %2, #0xa0\n\t" /* (0x0500 >> 3) */
- "lsl %0, %0, #2\n\t"
- "lsl %2, %2, #3\n\t"
- "add %0, %0, %2\n\t"
- "ldr %2, [%4]\n\t"
- "ldr %1, [%0]\n\t"
- "lsr %2, %2, #8\n\t"
- "eor %2, %1\n\t"
- "str %2, [%4]\n\t"
- "bx lr"
- : "=r" (v), "=r" (r2), "=r" (r3)
- : "0" (v), "r" (p)
- : "memory");
-#endif
-}
-
-void __attribute__ ((naked,section(".fixed_function.crc32_u32")))
-crc32_u32 (unsigned int *p, unsigned int u)
-{
-#ifdef ORIGINAL_IN_C
- crc32_u8 (p, u & 0xff);
- crc32_u8 (p, (u >> 8)& 0xff);
- crc32_u8 (p, (u >> 16)& 0xff);
- crc32_u8 (p, (u >> 24)& 0xff);
-#else
- register unsigned int r3 asm ("r3");
- register unsigned int r4 asm ("r4");
- register unsigned int r5 asm ("r5");
-
- asm volatile ("push {%1, %2, %3, lr}\n\t"
- "mov %2, %0\n\t"
- "mov %3, %5\n\t"
- "uxtb %0, %0\n\t"
- "bl crc32_u8\n\t"
- "lsr %0, %2, #8\n\t"
- "mov %5, %3\n\t"
- "uxtb %0, %0\n\t"
- "bl crc32_u8\n\t"
- "lsr %0, %2, #16\n\t"
- "mov %5, %3\n\t"
- "uxtb %0, %0\n\t"
- "bl crc32_u8\n\t"
- "mov %5, %3\n\t"
- "lsr %0, %2, #24\n\t"
- "bl crc32_u8\n\t"
- "pop {%1, %2, %3, pc}"
- : "=r" (u), "=r" (r3), "=r" (r4), "=r" (r5)
- : "0" (u), "r" (p)
- : "memory");
-#endif
-}
-
-/*
- * Table of CRC32, generated by gen_crc_table.py
- */
-const unsigned int
-crc32_table[256] __attribute__ ((section(".crc32_table"))) = {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
- 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
- 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
- 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
- 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
- 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
- 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
- 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
- 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
- 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
- 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
- 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
- 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
- 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
- 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
- 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
- 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
- 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
- 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
- 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
- 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
- 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
- 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
- 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
- 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
- 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
- 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
- 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
- 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
- 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
- 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
-};
diff --git a/example-fs-bb48/sys.h b/example-fs-bb48/sys.h
deleted file mode 100644
index eed5d92..0000000
--- a/example-fs-bb48/sys.h
+++ /dev/null
@@ -1,41 +0,0 @@
-extern const uint8_t sys_version[8];
-extern const uint32_t sys_board_id;
-extern const char *const sys_board_name;
-
-typedef void (*handler)(void);
-extern handler sys_vector[16];
-
-/*
- * Users can override INLINE by 'attribute((used))' to have an
- * implementation defined.
- */
-#if !defined(INLINE)
-#define INLINE __inline__
-#endif
-
-static INLINE void
-clock_init (void)
-{
- (*sys_vector[0]) ();
-}
-
-static INLINE void
-gpio_init (void)
-{
- (*sys_vector[1]) ();
-}
-
-static inline void
-set_led (int on)
-{
- void (*func) (int) = (void (*)(int))sys_vector[2];
-
- return (*func) (on);
-}
-
-void crc32_init (unsigned int *);
-void crc32_u8 (unsigned int *, unsigned char);
-void crc32_u32 (unsigned int *, unsigned int);
-
-int flash_erase_page (uint32_t addr);
-int flash_program_word (uint32_t addr, uint32_t word);
diff --git a/example-fs-bb48/usb_kl27z.c b/example-fs-bb48/usb_kl27z.c
deleted file mode 100644
index a7b8723..0000000
--- a/example-fs-bb48/usb_kl27z.c
+++ /dev/null
@@ -1,1034 +0,0 @@
-/*
- * usb_kl27z.c - USB driver for KL27Z
- *
- * Copyright (C) 2016 Flying Stone Technology
- * Author: NIIBE Yutaka <gniibe@fsij.org>
- *
- * This file is a part of Chopstx, a thread library for embedded.
- *
- * Chopstx 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.
- *
- * Chopstx 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 this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As additional permission under GNU GPL version 3 section 7, you may
- * distribute non-source form of the Program without the copy of the
- * GNU GPL normally required by section 4, provided you inform the
- * receipents of GNU GPL by a written offer.
- *
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "usb_lld.h"
-
-struct endpoint_ctl {
- uint32_t rx_odd: 1;
- uint32_t tx_odd: 1;
-};
-static struct endpoint_ctl ep[16];
-
-struct USB_CONF {
- const uint8_t PERID; /* Peripheral ID register */
- uint8_t rsvd0[3]; /* */
- const uint8_t IDCOMP; /* Peripheral ID Complement register */
- uint8_t rsvd1[3]; /* */
- const uint8_t REV; /* Peripheral Revision register */
- uint8_t rsvd2[3]; /* */
- volatile uint8_t ADDINFO; /* Peripheral Additional Info register */
-};
-static struct USB_CONF *const USB_CONF = (struct USB_CONF *const) 0x40072000;
-
-struct USB_CTRL0 {
- volatile uint8_t OTGCTL; /* OTG Control register */
-};
-static struct USB_CTRL0 *const USB_CTRL0 = (struct USB_CTRL0 *const)0x4007201c;
-
-struct USB_CTRL1 {
- volatile uint8_t ISTAT; /* Interrupt Status register */
- uint8_t rsvd5[3]; /* */
- volatile uint8_t INTEN; /* Interrupt Enable register */
- uint8_t rsvd6[3]; /* */
- volatile uint8_t ERRSTAT; /* Error Interrupt Status register */
- uint8_t rsvd7[3]; /* */
- volatile uint8_t ERREN; /* Error Interrupt Enable register */
- uint8_t rsvd8[3]; /* */
- volatile uint8_t STAT; /* Status register */
- uint8_t rsvd9[3]; /* */
- volatile uint8_t CTL; /* Control register */
- uint8_t rsvd10[3]; /* */
- volatile uint8_t ADDR; /* Address register */
- uint8_t rsvd11[3]; /* */
- volatile uint8_t BDTPAGE1; /* BDT Page register 1 */
- uint8_t rsvd12[3]; /* */
- volatile uint8_t FRMNUML; /* Frame Number register Low */
- uint8_t rsvd13[3]; /* */
- volatile uint8_t FRMNUMH; /* Frame Number register High */
- uint8_t rsvd14[11]; /* */
- volatile uint8_t BDTPAGE2; /* BDT Page Register 2 */
- uint8_t rsvd15[3]; /* */
- volatile uint8_t BDTPAGE3; /* BDT Page Register 3 */
-};
-static struct USB_CTRL1 *const USB_CTRL1 = (struct USB_CTRL1 *const)0x40072080;
-
-/* Interrupt source bits */
-#define USB_IS_STALL (1 << 7)
-#define USB_IS_RESUME (1 << 5)
-#define USB_IS_SLEEP (1 << 4)
-#define USB_IS_TOKDNE (1 << 3)
-#define USB_IS_SOFTOK (1 << 2)
-#define USB_IS_ERROR (1 << 1)
-#define USB_IS_USBRST (1 << 0)
-
-
-struct USB_ENDPT {
- volatile uint8_t EP; /* Endpoint Control register */
- uint8_t rsvd17[3];
-};
-static struct USB_ENDPT *const USB_ENDPT = (struct USB_ENDPT *const)0x400720c0;
-
-struct USB_CTRL2 {
- volatile uint8_t USBCTRL; /* USB Control register */
- uint8_t rsvd33[3]; /* */
- volatile uint8_t OBSERVE; /* USB OTG Observe register */
- uint8_t rsvd34[3]; /* */
- volatile uint8_t CONTROL; /* USB OTG Control register */
- uint8_t rsvd35[3]; /* */
- volatile uint8_t USBTRC0; /* USB Transceiver Control register 0 */
- uint8_t rsvd36[7]; /* */
- volatile uint8_t USBFRMADJUST; /* Frame Adjut Register */
-};
-static struct USB_CTRL2 *const USB_CTRL2 = (struct USB_CTRL2 *const)0x40072100;
-
-/* Buffer Descriptor */
-struct BD {
- volatile uint32_t ctrl;
- volatile void *buf;
-};
-/*
- uint32_t rsvd0 : 2;
- volatile uint32_t STALL: 1;
- volatile uint32_t DTS: 1;
-
- volatile uint32_t NINC: 1;
- volatile uint32_t KEEP: 1;
- volatile uint32_t DATA01: 1;
- volatile uint32_t OWN: 1;
-
- uint32_t rsvd1: 8;
- volatile uint32_t BC: 10;
- uint32_t rsvd2: 6;
-*/
-#define TOK_PID(ctrl) ((ctrl >> 2) & 0x0f)
-
-extern uint8_t __usb_bdt__;
-
-static struct BD *const BD_table = (struct BD *const)&__usb_bdt__;
-
-static uint8_t setup[8];
-/* bmRequestType, bRequest */
-/* Value: 2-byte */
-/* Index: 2-byte */
-/* Length: 2-byte */
-
-static void
-kl27z_usb_init (void)
-{
- int i;
-
- memset (ep, 0, sizeof (ep));
- memset (BD_table, 0, 16 * 2 * 2 * sizeof (struct BD));
-
- /* D+ pull up */
- USB_CTRL0->OTGCTL = 0x80;
-
- USB_CTRL1->ERREN = 0xff;
-
- USB_CTRL1->BDTPAGE1 = ((uint32_t)BD_table) >> 8;
- USB_CTRL1->BDTPAGE2 = ((uint32_t)BD_table) >> 16;
- USB_CTRL1->BDTPAGE3 = ((uint32_t)BD_table) >> 24;
-
- /* Not suspended, Pull-down disabled. */
- USB_CTRL2->USBCTRL = 0x00;
- /* DP Pullup in non-OTG device mode. */
- USB_CTRL2->CONTROL = 0x10;
-
- /* Disable all endpoints. */
- for (i = 0; i < 16; i++)
- USB_ENDPT[i].EP = 0;
-
- /*
- * Enable USB FS communication module, clearing all ODD-bits
- * for BDT.
- */
- USB_CTRL1->CTL = 0x03;
-
- /* ??? How we can ask re-enumeration? Is only hard RESET enough? */
-}
-
-static void
-kl27z_set_daddr (uint8_t daddr)
-{
- USB_CTRL1->ADDR = daddr;
-}
-
-static void
-kl27z_prepare_ep0_setup (void)
-{
- /* Endpoint 0, TX=0. */
- BD_table[ep[0].rx_odd].ctrl = 0x00080088; /* Len=8, OWN=1, DATA01=0, DTS=1 */
- BD_table[ep[0].rx_odd].buf = setup;
-
- BD_table[!ep[0].rx_odd].ctrl = 0x0000; /* OWN=0 */
- BD_table[!ep[0].rx_odd].buf = NULL;
-}
-
-static void
-kl27z_prepare_ep0_in (const void *buf, uint8_t len, int data01)
-{
- /* Endpoint 0, TX=1 *//* OWN=1, DTS=1 */
- BD_table[2+ep[0].tx_odd].ctrl = (len << 16) | 0x0088 | (data01 << 6);
- BD_table[2+ep[0].tx_odd].buf = (void *)buf;
-}
-
-static void
-kl27z_prepare_ep0_out (void *buf, uint8_t len, int data01)
-{
- /* Endpoint 0, TX=0 *//* OWN=1, DTS=1 */
- BD_table[ep[0].rx_odd].ctrl = (len << 16) | 0x0088 | (data01 << 6);
- BD_table[ep[0].rx_odd].buf = buf;
-}
-
-static int
-kl27z_ep_is_disabled (uint8_t n)
-{
- return (USB_ENDPT[n].EP == 0);
-}
-
-static int
-kl27z_ep_is_stall (uint8_t n)
-{
- return (USB_ENDPT[n].EP & 0x02) >> 1;
-}
-
-static void
-kl27z_ep_stall (uint8_t n)
-{
- USB_ENDPT[n].EP |= 0x02;
-}
-
-static void
-kl27z_ep_clear_stall (uint8_t n)
-{
- USB_ENDPT[n].EP &= ~0x02;
-}
-
-static void
-kl27z_ep_clear_dtog (int rx, uint8_t n)
-{
- uint32_t config;
-
- if (!kl27z_ep_is_stall (n))
- /* Just in case, when the endpoint is active */
- kl27z_ep_stall (n);
-
- if (rx)
- {
- config = BD_table[4*n+ep[n].rx_odd].ctrl;
-
- BD_table[4*n+!ep[n].rx_odd].ctrl &= ~(1 << 6);
- if ((config & 0x0080)) /* OWN already? */
- {
- /*
- * How to update BDT entry which is owned by USBFS seems to
- * be not clearly documented. It would be just OK to update
- * it as long as the endpoint is stalled (BDT entry is
- * actually not in use). We write 0 at first and then write
- * value with OWN, to avoid possible failure.
- */
- BD_table[4*n+ep[n].rx_odd].ctrl = 0;
- BD_table[4*n+ep[n].rx_odd].ctrl = (config & ~(1 << 6));
- }
- }
- else
- {
- config = BD_table[4*n+2+ep[n].tx_odd].ctrl;
-
- BD_table[4*n+2+!ep[n].tx_odd].ctrl &= ~(1 << 6);
- if ((config & 0x0080)) /* OWN already? */
- {
- BD_table[4*n+2+ep[n].tx_odd].ctrl = 0;
- BD_table[4*n+2+ep[n].tx_odd].ctrl = (config & ~(1 << 6));
- }
- }
-
- kl27z_ep_clear_stall (n);
-}
-
-#define USB_MAX_PACKET_SIZE 64 /* For FS device */
-
-enum STANDARD_REQUESTS {
- GET_STATUS = 0,
- CLEAR_FEATURE,
- RESERVED1,
- SET_FEATURE,
- RESERVED2,
- SET_ADDRESS,
- GET_DESCRIPTOR,
- SET_DESCRIPTOR,
- GET_CONFIGURATION,
- SET_CONFIGURATION,
- GET_INTERFACE,
- SET_INTERFACE,
- SYNCH_FRAME,
- TOTAL_REQUEST /* Total number of Standard request */
-};
-
-
-enum FEATURE_SELECTOR {
- ENDPOINT_STALL,
- DEVICE_REMOTE_WAKEUP
-};
-
-
-struct data_ctl {
- uint8_t *addr;
- uint16_t len;
- uint8_t require_zlp;
-};
-
-/* The state machine states of a control pipe */
-enum {
- WAIT_SETUP,
- IN_DATA,
- OUT_DATA,
- LAST_IN_DATA,
- WAIT_STATUS_IN,
- WAIT_STATUS_OUT,
- STALLED,
- PAUSE
-};
-
-struct device_ctl {
- /* control pipe state */
- uint8_t state;
-
- uint32_t tkdone;
- uint32_t reset;
- uint32_t error;
- uint32_t stall;
-
- uint32_t send;
- uint32_t recv;
-
- /* Device specific settings */
- uint8_t configuration;
- uint8_t feature;
-};
-
-static struct device_ctl device_ctl;
-static struct data_ctl data_ctl;
-
-static struct device_ctl *const dev_p = &device_ctl;
-static struct data_ctl *const data_p = &data_ctl;
-
-static void handle_transaction (uint8_t stat);
-
-void
-usb_lld_stall (int n)
-{
- kl27z_ep_stall (n);
-}
-
-
-void
-usb_lld_init (uint8_t feature)
-{
- dev_p->state = WAIT_SETUP;
- dev_p->tkdone = 0;
- dev_p->reset = 0;
- dev_p->error = 0;
- dev_p->stall = 0;
-
- usb_lld_set_configuration (0);
- dev_p->feature = feature;
-
- kl27z_set_daddr (0);
- kl27z_usb_init ();
-
- /* Enable the endpoint 0. */
- USB_ENDPT[0].EP = 0x0d;
-
- /* Clear Interrupt Status Register, and enable interrupt for USB */
- USB_CTRL1->ISTAT = 0xff; /* All clear */
-
- USB_CTRL1->INTEN = USB_IS_STALL | USB_IS_TOKDNE
- | USB_IS_ERROR | USB_IS_USBRST;
-}
-
-void
-usb_interrupt_handler (void)
-{
- uint8_t istat_value = USB_CTRL1->ISTAT;
- uint8_t stat = USB_CTRL1->STAT;
-
- if ((istat_value & USB_IS_USBRST))
- {
- USB_CTRL1->ISTAT = USB_IS_USBRST;
- usb_cb_device_reset ();
- dev_p->reset++;
- }
- else if ((istat_value & USB_IS_ERROR))
- { /* Clear Errors. */
- USB_CTRL1->ERRSTAT = USB_CTRL1->ERRSTAT;
- USB_CTRL1->ISTAT = USB_IS_ERROR;
- /*reset???*/
- dev_p->error++;
- }
- else if ((istat_value & USB_IS_TOKDNE))
- {
- handle_transaction (stat);
- dev_p->tkdone++;
- }
- else if ((istat_value & USB_IS_STALL))
- {
- /* ??? stat includes ep_num in this case ???: No, it doesn't */
-
- if (kl27z_ep_is_stall (0))
- { /* It's endpoint 0, recover from erorr. */
- dev_p->state = WAIT_SETUP;
- kl27z_ep_clear_stall (0);
- kl27z_prepare_ep0_setup ();
- }
-
- USB_CTRL1->ISTAT = USB_IS_STALL;
- dev_p->stall++;
- }
-}
-
-#define DATA0 0
-#define DATA1 1
-
-static void
-handle_datastage_out (uint8_t stat)
-{
- int odd = (stat >> 2)&1;
- int data01 = !((BD_table[odd].ctrl >> 6)&1);
- uint32_t len = (BD_table[odd].ctrl >> 16)&0x3ff;
-
- data_p->len -= len;
- data_p->addr += len;
-
- len = data_p->len;
- if (len > USB_MAX_PACKET_SIZE)
- len = USB_MAX_PACKET_SIZE;
-
- if (data_p->len == 0)
- {
- /* No more data to receive, proceed to send acknowledge for IN. */
- dev_p->state = WAIT_STATUS_IN;
- kl27z_prepare_ep0_in (setup, 0, DATA1);
- }
- else
- {
- dev_p->state = OUT_DATA;
- kl27z_prepare_ep0_out (data_p->addr, len, data01);
- }
-}
-
-static void
-handle_datastage_in (uint8_t stat)
-{
- int odd = (stat >> 2)&1;
- int data01 = !((BD_table[2+odd].ctrl >> 6)&1);
- uint32_t len = USB_MAX_PACKET_SIZE;
-
- if ((data_p->len == 0) && (dev_p->state == LAST_IN_DATA))
- {
- if (data_p->require_zlp)
- {
- data_p->require_zlp = 0;
-
- /* No more data to send. Send empty packet */
- kl27z_prepare_ep0_in (setup, 0, data01);
- }
- else
- {
- /* No more data to send, proceed to receive OUT acknowledge. */
- dev_p->state = WAIT_STATUS_OUT;
- kl27z_prepare_ep0_out (setup, 8, DATA1);
- }
-
- return;
- }
-
- dev_p->state = (data_p->len <= len) ? LAST_IN_DATA : IN_DATA;
-
- if (len > data_p->len)
- len = data_p->len;
-
- kl27z_prepare_ep0_in (data_p->addr, len, data01);
- data_p->len -= len;
- data_p->addr += len;
-}
-
-typedef int (*HANDLER) (uint8_t req, struct req_args *arg);
-
-static int
-std_none (uint8_t req, struct req_args *arg)
-{
- (void)req; (void)arg;
- return USB_UNSUPPORT;
-}
-
-static int
-std_get_status (uint8_t req, struct req_args *arg)
-{
- uint8_t rcp = req & RECIPIENT;
- uint16_t status_info = 0;
-
- if (arg->value != 0 || arg->len != 2 || (arg->index >> 8) != 0
- || USB_SETUP_SET (req))
- return USB_UNSUPPORT;
-
- if (rcp == DEVICE_RECIPIENT)
- {
- if (arg->index == 0)
- {
- /* Get Device Status */
- uint8_t feature = dev_p->feature;
-
- /* Remote Wakeup enabled */
- if ((feature & (1 << 5)))
- status_info |= 2;
- else
- status_info &= ~2;
-
- /* Bus-powered */
- if ((feature & (1 << 6)))
- status_info |= 1;
- else /* Self-powered */
- status_info &= ~1;
-
- return usb_lld_reply_request (&status_info, 2, arg);
- }
- }
- else if (rcp == INTERFACE_RECIPIENT)
- {
- int r;
-
- if (dev_p->configuration == 0)
- return USB_UNSUPPORT;
-
- r = usb_cb_interface (USB_QUERY_INTERFACE, arg);
- if (r != USB_SUCCESS)
- return USB_UNSUPPORT;
-
- return usb_lld_reply_request (&status_info, 2, arg);
- }
- else if (rcp == ENDPOINT_RECIPIENT)
- {
- uint8_t n = (arg->index & 0x0f);
-
- if ((arg->index & 0x70) || n == ENDP0)
- return USB_UNSUPPORT;
-
- if (kl27z_ep_is_disabled (n))
- return USB_UNSUPPORT;
-
- status_info = kl27z_ep_is_stall (n);
- return usb_lld_reply_request (&status_info, 2, arg);
- }
-
- return USB_UNSUPPORT;
-}
-
-static int
-std_clear_feature (uint8_t req, struct req_args *arg)
-{
- uint8_t rcp = req & RECIPIENT;
-
- if (USB_SETUP_GET (req))
- return USB_UNSUPPORT;
-
- if (rcp == DEVICE_RECIPIENT)
- {
- if (arg->len != 0 || arg->index != 0)
- return USB_UNSUPPORT;
-
- if (arg->value == DEVICE_REMOTE_WAKEUP)
- {
- dev_p->feature &= ~(1 << 5);
- return USB_SUCCESS;
- }
- }
- else if (rcp == ENDPOINT_RECIPIENT)
- {
- uint8_t n = (arg->index & 0x0f);
-
- if (dev_p->configuration == 0)
- return USB_UNSUPPORT;
-
- if (arg->len != 0 || (arg->index >> 8) != 0
- || arg->value != ENDPOINT_STALL || n == ENDP0)
- return USB_UNSUPPORT;
-
- if (kl27z_ep_is_disabled (n))
- return USB_UNSUPPORT;
-
- kl27z_ep_clear_dtog ((arg->index & 0x80) == 0, n);
-
- // event??
- return USB_SUCCESS;
- }
-
- return USB_UNSUPPORT;
-}
-
-static int
-std_set_feature (uint8_t req, struct req_args *arg)
-{
- uint8_t rcp = req & RECIPIENT;
-
- if (USB_SETUP_GET (req))
- return USB_UNSUPPORT;
-
- if (rcp == DEVICE_RECIPIENT)
- {
- if (arg->len != 0 || arg->index != 0)
- return USB_UNSUPPORT;
-
- if (arg->value == DEVICE_REMOTE_WAKEUP)
- {
- dev_p->feature |= 1 << 5;
- // event??
- return USB_SUCCESS;
- }
- }
- else if (rcp == ENDPOINT_RECIPIENT)
- {
- uint8_t n = (arg->index & 0x0f);
-
- if (dev_p->configuration == 0)
- return USB_UNSUPPORT;
-
- if (arg->len != 0 || (arg->index >> 8) != 0
- || arg->value != 0 || n == ENDP0)
- return USB_UNSUPPORT;
-
- if (kl27z_ep_is_disabled (n))
- return USB_UNSUPPORT;
-
- kl27z_ep_stall (n);
-
- // event??
- return USB_SUCCESS;
- }
-
- return USB_UNSUPPORT;
-}
-
-static int
-std_set_address (uint8_t req, struct req_args *arg)
-{
- uint8_t rcp = req & RECIPIENT;
-
- if (USB_SETUP_GET (req))
- return USB_UNSUPPORT;
-
- if (rcp == DEVICE_RECIPIENT && arg->len == 0 && arg->value <= 127
- && arg->index == 0 && dev_p->configuration == 0)
- return USB_SUCCESS;
-
- return USB_UNSUPPORT;
-}
-
-static int
-std_get_descriptor (uint8_t req, struct req_args *arg)
-{
- uint8_t rcp = req & RECIPIENT;
-
- if (USB_SETUP_SET (req))
- return USB_UNSUPPORT;
-
- return usb_cb_get_descriptor (rcp, (arg->value >> 8),
- (arg->value & 0xff), arg);
-}
-
-static int
-std_get_configuration (uint8_t req, struct req_args *arg)
-{
- uint8_t rcp = req & RECIPIENT;
-
- (void)arg;
- if (USB_SETUP_SET (req))
- return USB_UNSUPPORT;
-
- if (rcp == DEVICE_RECIPIENT)
- return usb_lld_reply_request (&dev_p->configuration, 1, arg);
-
- return USB_UNSUPPORT;
-}
-
-static int
-std_set_configuration (uint8_t req, struct req_args *arg)
-{
- uint8_t rcp = req & RECIPIENT;
-
- if (USB_SETUP_GET (req))
- return USB_UNSUPPORT;
-
- if (rcp == DEVICE_RECIPIENT && arg->index == 0 && arg->len == 0)
- return usb_cb_handle_event (USB_EVENT_CONFIG, arg->value);
-
- return USB_UNSUPPORT;
-}
-
-static int
-std_get_interface (uint8_t req, struct req_args *arg)
-{
- uint8_t rcp = req & RECIPIENT;
-
- if (USB_SETUP_SET (req))
- return USB_UNSUPPORT;
-
- if (rcp == INTERFACE_RECIPIENT)
- {
- if (arg->value != 0 || (arg->index >> 8) != 0 || arg->len != 1)
- return USB_UNSUPPORT;
-
- if (dev_p->configuration == 0)
- return USB_UNSUPPORT;
-
- return usb_cb_interface (USB_GET_INTERFACE, arg);
- }
-
- return USB_UNSUPPORT;
-}
-
-static int
-std_set_interface (uint8_t req, struct req_args *arg)
-{
- uint8_t rcp = req & RECIPIENT;
-
- if (USB_SETUP_GET (req) || rcp != INTERFACE_RECIPIENT
- || arg->len != 0 || (arg->index >> 8) != 0
- || (arg->value >> 8) != 0 || dev_p->configuration == 0)
- return USB_UNSUPPORT;
-
- return usb_cb_interface (USB_SET_INTERFACE, arg);
-}
-
-
-static void
-handle_setup0 (void)
-{
- struct req_args *arg = (struct req_args *)&setup[2];
- int r = USB_UNSUPPORT;
- HANDLER handler;
-
- data_p->addr = NULL;
- data_p->len = 0;
- data_p->require_zlp = 0;
-
- if ((setup[0] & REQUEST_TYPE) == STANDARD_REQUEST)
- {
- if (setup[1] < TOTAL_REQUEST)
- {
- switch (setup[1])
- {
- case 0: handler = std_get_status; break;
- case 1: handler = std_clear_feature; break;
- case 3: handler = std_set_feature; break;
- case 5: handler = std_set_address; break;
- case 6: handler = std_get_descriptor; break;
- case 8: handler = std_get_configuration; break;
- case 9: handler = std_set_configuration; break;
- case 10: handler = std_get_interface; break;
- case 11: handler = std_set_interface; break;
- default: handler = std_none; break;
- }
-
- r = (*handler) (setup[0], arg);
- }
- }
- else
- r = usb_cb_setup (setup[0], setup[1], arg);
-
- if (r != USB_SUCCESS)
- dev_p->state = STALLED;
- else if (USB_SETUP_SET (setup[0]))
- {
- if (arg->len == 0)
- {
- /* Zero length packet for ACK. */
- kl27z_prepare_ep0_in (setup, 0, DATA1);
- dev_p->state = WAIT_STATUS_IN;
- }
- }
-}
-
-static void
-handle_in0 (uint8_t stat)
-{
- if (dev_p->state == IN_DATA || dev_p->state == LAST_IN_DATA)
- handle_datastage_in (stat);
- else if (dev_p->state == WAIT_STATUS_IN)
- { /* Control WRITE transfer done successfully. */
- uint16_t value = (setup[3]<<8) | setup[2];
-
- if ((setup[1] == SET_ADDRESS) &&
- ((setup[0] & (REQUEST_TYPE | RECIPIENT))
- == (STANDARD_REQUEST | DEVICE_RECIPIENT)))
- {
- kl27z_set_daddr (value);
- usb_cb_handle_event (USB_EVENT_ADDRESS, value);
- ep[0].rx_odd = 0;
- }
- else
- usb_cb_ctrl_write_finish (setup[0], setup[1],
- (struct req_args *)&setup[2]);
-
- dev_p->state = WAIT_SETUP;
- kl27z_prepare_ep0_setup ();
- }
- else
- dev_p->state = STALLED;
-}
-
-static void
-handle_out0 (uint8_t stat)
-{
- if (dev_p->state == IN_DATA || dev_p->state == LAST_IN_DATA)
- /* Host aborts the control READ transfer before finish. */
- dev_p->state = STALLED;
- else if (dev_p->state == OUT_DATA)
- /* It's normal control WRITE transfer. */
- handle_datastage_out (stat);
- else if (dev_p->state == WAIT_STATUS_OUT)
- { /* Control READ transfer done successfully. */
- dev_p->state = WAIT_SETUP;
- kl27z_prepare_ep0_setup ();
- }
- else
- dev_p->state = STALLED;
-}
-
-static void
-handle_transaction (uint8_t stat)
-{
- int odd = (stat >> 2)&1;
- uint8_t ep_num = (stat >> 4);
-
- if (ep_num == 0)
- {
- if ((stat & 0x08) == 0)
- {
- ep[0].rx_odd ^= 1;
- if (TOK_PID (BD_table[odd].ctrl) == 0x0d)
- {
- handle_setup0 ();
- USB_CTRL1->ISTAT = USB_IS_TOKDNE;
- USB_CTRL1->CTL = 0x01; /* Clear TXSUSPENDTOKENBUSY. */
- }
- else
- {
- USB_CTRL1->ISTAT = USB_IS_TOKDNE;
- handle_out0 (stat);
- }
- }
- else
- {
- ep[0].tx_odd ^= 1;
- USB_CTRL1->ISTAT = USB_IS_TOKDNE;
- handle_in0 (stat);
- }
-
- if (dev_p->state == STALLED)
- kl27z_ep_stall (0);
- }
- else
- {
- if ((stat & 0x08) == 0)
- {
- dev_p->recv++;
- ep[ep_num].rx_odd ^= 1;
- usb_cb_rx_ready (ep_num);
- }
- else
- {
- /* XXX: Can be NAK. Check BDT if it's NAK or not. */
-
- dev_p->send++;
- ep[ep_num].tx_odd ^= 1;
- usb_cb_tx_done (ep_num);
- }
-
- USB_CTRL1->ISTAT = USB_IS_TOKDNE;
- }
-}
-
-void
-usb_lld_reset (uint8_t feature)
-{
- dev_p->feature = feature;
- usb_lld_set_configuration (0);
-
- /* Reset USB */
- USB_CTRL2->USBTRC0 = 0xc0;
-
- USB_CTRL1->CTL = 0x00; /* Disable USB FS communication module */
-
- dev_p->state = WAIT_SETUP;
- dev_p->tkdone = 0;
- dev_p->error = 0;
- dev_p->stall = 0;
-
- kl27z_set_daddr (0);
- kl27z_usb_init ();
-
- /* Clear Interrupt Status Register, and enable interrupt for USB */
- USB_CTRL1->ISTAT = 0xff; /* All clear */
-
- USB_CTRL1->INTEN = USB_IS_STALL | USB_IS_TOKDNE
- | USB_IS_ERROR | USB_IS_USBRST;
-}
-
-void
-usb_lld_setup_endpoint (int n, int rx_en, int tx_en)
-{
- if (n == 0)
- {
- /* Enable the endpoint 0. */
- USB_ENDPT[0].EP = 0x0d;
- kl27z_prepare_ep0_setup ();
- }
- else
- {
- /* Enable the endpoint. */
- USB_ENDPT[n].EP = (rx_en << 3)|(tx_en << 2)|0x11;
-
- /* Configure BDT entry so that it starts with DATA0. */
-
- /* RX */
- BD_table[4*n+ep[n].rx_odd].ctrl = 0x0000;
- BD_table[4*n+ep[n].rx_odd].buf = NULL;
- BD_table[4*n+!ep[n].rx_odd].ctrl = 0x0040;
- BD_table[4*n+!ep[n].rx_odd].buf = NULL;
-
- /* TX */
- BD_table[4*n+2+ep[n].tx_odd].ctrl = 0x0000;
- BD_table[4*n+2+ep[n].tx_odd].buf = NULL;
- BD_table[4*n+2+!ep[n].tx_odd].ctrl = 0x0040;
- BD_table[4*n+2+!ep[n].tx_odd].buf = NULL;
- }
-}
-
-
-void
-usb_lld_set_configuration (uint8_t config)
-{
- dev_p->configuration = config;
-}
-
-uint8_t
-usb_lld_current_configuration (void)
-{
- return dev_p->configuration;
-}
-
-void
-usb_lld_set_data_to_recv (void *p, size_t len)
-{
- data_p->addr = (uint8_t *)p;
- data_p->len = len;
- if (len > USB_MAX_PACKET_SIZE)
- len = USB_MAX_PACKET_SIZE;
-
- kl27z_prepare_ep0_out (p, len, DATA1);
- dev_p->state = OUT_DATA;
-}
-
-/*
- * BUF: Pointer to data memory. Data memory should not be allocated
- * on stack when BUFLEN > USB_MAX_PACKET_SIZE.
- *
- * BUFLEN: size of the data.
- */
-int
-usb_lld_reply_request (const void *buf, size_t buflen, struct req_args *a)
-{
- uint32_t len_asked = a->len;
- uint32_t len;
-
- data_p->addr = (void *)buf;
- data_p->len = buflen;
-
- /* Restrict the data length to be the one host asks for */
- if (data_p->len > len_asked)
- data_p->len = len_asked;
-
- data_p->require_zlp = (data_p->len != 0
- && (data_p->len % USB_MAX_PACKET_SIZE) == 0);
-
- if (data_p->len < USB_MAX_PACKET_SIZE)
- {
- len = data_p->len;
- dev_p->state = LAST_IN_DATA;
- }
- else
- {
- len = USB_MAX_PACKET_SIZE;
- dev_p->state = IN_DATA;
- }
-
- if (len)
- kl27z_prepare_ep0_in (data_p->addr, len, DATA1);
-
- data_p->len -= len;
- data_p->addr += len;
-
- return USB_SUCCESS;
-}
-
-void
-usb_lld_rx_enable (int n, void *buf, size_t len)
-{
- int data01 = !((BD_table[4*n+!ep[n].rx_odd].ctrl >> 6)&1);
-
- BD_table[4*n+ep[n].rx_odd].ctrl = (len << 16) | 0x0088 | (data01 << 6);
- BD_table[4*n+ep[n].rx_odd].buf = buf;
-}
-
-int
-usb_lld_rx_data_len (int n)
-{
- return (BD_table[4*n+!ep[n].rx_odd].ctrl >> 16)&0x3ff;
-}
-
-
-void
-usb_lld_tx_enable (uint8_t n, const void *buf, size_t len)
-{
- int data01 = !((BD_table[4*n+2+!ep[n].tx_odd].ctrl >> 6)&1);
-
- BD_table[4*n+2+ep[n].tx_odd].ctrl = (len << 16) | 0x0088 | (data01 << 6);
- BD_table[4*n+2+ep[n].tx_odd].buf = (void *)buf;
-}
-
-int
-usb_lld_tx_result (int ep_num)
-{
- (void)ep_num;
- return 0; /* XXX: return -1 when NAK */
-}
diff --git a/example-fs-bb48/usb_lld.h b/example-fs-bb48/usb_lld.h
index da694a6..b2ce4fb 100644
--- a/example-fs-bb48/usb_lld.h
+++ b/example-fs-bb48/usb_lld.h
@@ -10,12 +10,6 @@
#define ENDP6 ((uint8_t)6)
#define ENDP7 ((uint8_t)7)
-/* EP_TYPE[1:0] EndPoint TYPE */
-#define EP_BULK (0x0000) /* EndPoint BULK */
-#define EP_CONTROL (0x0200) /* EndPoint CONTROL */
-#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */
-#define EP_INTERRUPT (0x0600) /* EndPoint INTERRUPT */
-
enum RECIPIENT_TYPE
{
DEVICE_RECIPIENT, /* Recipient device */