Changeset dce1032b in rtems


Ignore:
Timestamp:
Aug 1, 2011, 1:48:40 PM (9 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.11, 5, master
Children:
bc018b12
Parents:
01f2692e
Message:

2011-08-01 Sebastien Bourdeauducq <sebastien.bourdeauducq@…>

PR 1869/bsps

  • startup/bspclean.c: New file.
  • include/tm27.h: Removed.
  • ChangeLog?, Makefile.am, README, preinstall.am, include/bsp.h, include/system_conf.h, make/custom/milkymist.cfg, startup/linkcmds: Complete BSP for Milkymist One supporting Milkymist SOC 1.0.x. Includes new or updated drivers for:
    • Multi-standard video input (PAL/SECAM/NTSC)
    • Two DMX512 (RS485) ports
    • MIDI IN and MIDI OUT ports
    • VGA output
    • AC'97 audio
    • NOR flash
    • 10/100 Ethernet
    • Memory card (experimental and incomplete)
    • USB host connectors (input devices only)
    • RC5 infrared receiver
    • RS232 debug port
Location:
c/src/lib/libbsp/lm32
Files:
30 added
1 deleted
21 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/lm32/milkymist/ChangeLog

    r01f2692e rdce1032b  
     12011-08-01      Sebastien Bourdeauducq <sebastien.bourdeauducq@gmail.com>
     2
     3        PR 1869/bsps
     4        * startup/bspclean.c: New file.
     5        * include/tm27.h: Removed.
     6        * ChangeLog, Makefile.am, README, preinstall.am, include/bsp.h,
     7        include/system_conf.h, make/custom/milkymist.cfg, startup/linkcmds:
     8        Complete BSP for Milkymist One supporting Milkymist SOC 1.0.x.
     9        Includes new or updated drivers for:
     10          - Multi-standard video input (PAL/SECAM/NTSC)
     11          - Two DMX512 (RS485) ports
     12          - MIDI IN and MIDI OUT ports
     13          - VGA output
     14          - AC'97 audio
     15          - NOR flash
     16          - 10/100 Ethernet
     17          - Memory card (experimental and incomplete)
     18          - USB host connectors (input devices only)
     19          - RC5 infrared receiver
     20          - RS232 debug port
     21
    1222011-02-02      Ralf Corsépius <ralf.corsepius@rtems.org>
    223
     
    1435        include/bsp.h, include/system_conf.h, include/tm27.h,
    1536        make/custom/milkymist.cfg, startup/linkcmds: New files.
    16 
    17 08 / 12 / 2010 : <Yann Sionneau> Added Milkymist BSP
  • c/src/lib/libbsp/lm32/milkymist/Makefile.am

    r01f2692e rdce1032b  
    1111dist_project_lib_DATA = bsp_specs
    1212
    13 include_HEADERS = include/bsp.h
    14 include_HEADERS += include/tm27.h
     13include_HEADERS  = include/bsp.h
     14include_HEADERS += ../../shared/include/coverhd.h
     15include_HEADERS += ../../shared/include/tm27.h
     16
     17include_bsp_HEADERS  = ../../lm32/shared/include/irq.h
     18include_bsp_HEADERS += ../../shared/include/irq-generic.h
     19include_bsp_HEADERS += ../../lm32/shared/milkymist_gpio/milkymist_gpio.h
     20include_bsp_HEADERS += ../../lm32/shared/milkymist_buttons/milkymist_buttons.h
     21include_bsp_HEADERS += ../../lm32/shared/milkymist_ac97/milkymist_ac97.h
     22include_bsp_HEADERS += ../../lm32/shared/milkymist_usbinput/milkymist_usbinput.h
     23include_bsp_HEADERS += ../../lm32/shared/milkymist_pfpu/milkymist_pfpu.h
     24include_bsp_HEADERS += ../../lm32/shared/milkymist_tmu/milkymist_tmu.h
     25include_bsp_HEADERS += ../../lm32/shared/milkymist_memcard/milkymist_memcard.h
     26include_bsp_HEADERS += ../../lm32/shared/milkymist_flash/milkymist_flash.h
     27include_bsp_HEADERS += ../../lm32/shared/milkymist_dmx/milkymist_dmx.h
     28include_bsp_HEADERS += ../../lm32/shared/milkymist_midi/milkymist_midi.h
     29include_bsp_HEADERS += ../../lm32/shared/milkymist_ir/milkymist_ir.h
     30include_bsp_HEADERS += ../../lm32/shared/milkymist_video/milkymist_video.h
     31include_bsp_HEADERS += ../../lm32/shared/milkymist_versions/milkymist_versions.h
    1532
    1633nodist_include_HEADERS = include/bspopts.h
     
    2037noinst_PROGRAMS =
    2138
    22 include_HEADERS += ../../shared/include/coverhd.h
    2339include_HEADERS += include/system_conf.h
    2440
     
    3450
    3551# startup
    36 libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
    37     ../../shared/bsppost.c ../shared/startup/bspstart.c \
    38     ../../shared/bspreset.c ../../shared/bsppretaskinghook.c \
    39     ../../shared/bspgetworkarea.c ../../shared/bootcard.c \
    40     ../../shared/sbrk.c ../../lm32/shared/startup/setvec.c \
    41     ../../shared/gnatinstallhandler.c
     52libbsp_a_SOURCES += startup/bspclean.c
     53libbsp_a_SOURCES += ../../shared/bsplibc.c
     54libbsp_a_SOURCES += ../../shared/bsppost.c
     55libbsp_a_SOURCES += ../shared/startup/bspstart.c
     56libbsp_a_SOURCES += ../../shared/bsppretaskinghook.c
     57libbsp_a_SOURCES += ../../shared/bspgetworkarea.c
     58libbsp_a_SOURCES += ../../shared/bootcard.c
     59libbsp_a_SOURCES += ../../shared/sbrk.c
     60libbsp_a_SOURCES += ../../shared/gnatinstallhandler.c
     61
     62# irq
     63libbsp_a_SOURCES += ../../lm32/shared/irq/irq.c
    4264
    4365# clock
    44 
    4566libbsp_a_SOURCES += ../../lm32/shared/milkymist_clock/ckinit.c
    4667
    4768# console
    48 libbsp_a_SOURCES += ../../lm32/shared/milkymist_console/console.c \
    49     ../../lm32/shared/milkymist_console/uart.c
     69libbsp_a_SOURCES += ../../lm32/shared/milkymist_console/console.c
     70libbsp_a_SOURCES += ../../lm32/shared/milkymist_console/uart.c
     71
    5072# timer
    5173libbsp_a_SOURCES += ../../lm32/shared/milkymist_timer/timer.c
     
    5476libbsp_a_SOURCES += ../../lm32/shared/milkymist_framebuffer/framebuffer.c
    5577
    56 # gpio
     78# GPIO
    5779libbsp_a_SOURCES += ../../lm32/shared/milkymist_gpio/gpio.c
     80
     81# buttons
     82libbsp_a_SOURCES += ../../lm32/shared/milkymist_buttons/buttons.c
     83
     84# ac97
     85libbsp_a_SOURCES += ../../lm32/shared/milkymist_ac97/ac97.c
     86
     87# usbinput
     88libbsp_a_SOURCES += ../../lm32/shared/milkymist_usbinput/usbinput.c
     89
     90# PFPU
     91libbsp_a_SOURCES += ../../lm32/shared/milkymist_pfpu/pfpu.c
     92
     93# TMU
     94libbsp_a_SOURCES += ../../lm32/shared/milkymist_tmu/tmu.c
     95
     96# memory card
     97libbsp_a_SOURCES += ../../lm32/shared/milkymist_memcard/memcard.c
     98
     99# flash
     100libbsp_a_SOURCES += ../../lm32/shared/milkymist_flash/flash.c
     101
     102# DMX
     103libbsp_a_SOURCES += ../../lm32/shared/milkymist_dmx/dmx.c
     104
     105# MIDI
     106libbsp_a_SOURCES += ../../lm32/shared/milkymist_midi/midi.c
     107
     108# IR
     109libbsp_a_SOURCES += ../../lm32/shared/milkymist_ir/ir.c
     110
     111# video input
     112libbsp_a_SOURCES += ../../lm32/shared/milkymist_video/video.c
     113
     114# versions
     115libbsp_a_SOURCES += ../../lm32/shared/milkymist_versions/versions.c
    58116
    59117if HAS_NETWORKING
    60118noinst_PROGRAMS += network.rel
    61 network_rel_SOURCES = ../../lm32/shared/milkymist_networking/network.c \
    62     ../../lm32/shared/milkymist_networking/mm_crc32.c
     119network_rel_SOURCES = ../../lm32/shared/milkymist_networking/network.c
    63120network_rel_CPPFLAGS = $(AM_CPPFLAGS) -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
    64121network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
  • c/src/lib/libbsp/lm32/milkymist/README

    r01f2692e rdce1032b  
    33#
    44
    5 This is a BSP written by Yann Sionneau <yann.sionneau@telecom-sudparis.eu>
    6 as part of Google Summer of Code 2010.
     5Full RTEMS port to the Milkymist One. Supports Milkymist SoC 1.0.x.
    76
    8 This is a BSP to make RTEMS run on Milkymist One board using Milkymist SoC
     7Includes drivers for:
     8- Multi-standard video input (PAL/SECAM/NTSC)
     9- Two DMX512 (RS485) ports
     10- MIDI IN and MIDI OUT ports
     11- VGA output
     12- AC'97 audio
     13- NOR flash
     14- 10/100 Ethernet
     15- Memory card (experimental and incomplete)
     16- USB host connectors (input devices only, using the softusb-input firmware)
     17- RC5 infrared receiver
     18- RS232 debug port
    919
    10 It provides driver for timer, uart, ethernet, framebuffer so far.
    11 
    12 Milkymist SoC is running @ 83 MHz with 128 MB of 32-bit DDR400 SDRAM
    13 The SoC is based on a XC6SLX45 Spartan-6 FPGA running
    14 the LatticeMico32 softcore.
    15 
    16 More informations available at : http://www.milkymist.org/
    17 
    18 Information about the porting can be found in Yann Sionneau's blog
    19 at http://sionneau.net/
    20 
    21 Milkymist is a project leaded by Sebastien Bourdeauducq (aka lekernel)
     20For more information: http://www.milkymist.org/
  • c/src/lib/libbsp/lm32/milkymist/include/bsp.h

    r01f2692e rdce1032b  
    99 *  $Id$
    1010 *
    11  *  Yann Sionneau <yann.sionneau@telecom-sudparis.eu>, (GSoC 2010)
    12  *  Telecom SudParis
     11 *  COPYRIGHT (c) 2011 Sebastien Bourdeauducq
    1312 */
    1413
     
    2322#include <rtems/clockdrv.h>
    2423
    25 
    2624#ifdef __cplusplus
    2725extern "C" {
    2826#endif
    2927
    30 #define BSP_DIRTY_MEMORY 1
    31 
    3228#define BSP_HAS_FRAME_BUFFER 1
    3329
    34 #define GPIO_DRIVER_TABLE_ENTRY { gpio_initialize, \
    35 gpio_open, gpio_close, gpio_read, gpio_write, gpio_control}
    36 
    37   /*
    38    * lm32 requires certain aligment of mbuf because unaligned uint32_t
    39    * accesses are not handled properly.
    40    */
     30/*
     31 * lm32 requires certain aligment of mbuf because unaligned uint32_t
     32 * accesses are not handled properly.
     33 */
    4134
    4235#define CPU_U32_FIX
     
    5144#endif
    5245
    53   /*
    54    *  Simple spin delay in microsecond units for device drivers.
    55    *  This is very dependent on the clock speed of the target.
    56    */
    57 
    58 #define rtems_bsp_delay( microseconds ) \
    59   { \
    60   }
    61 
    62 /* functions */
    63 lm32_isr_entry set_vector(                     /* returns old vector */
    64   rtems_isr_entry     handler,                  /* isr routine        */
    65   rtems_vector_number vector,                   /* vector number      */
    66   int                 type                      /* RTEMS or RAW intr  */
    67 );
    68 
    6946#ifdef __cplusplus
    7047}
     
    7249
    7350#endif
    74 /* end of include file */
  • c/src/lib/libbsp/lm32/milkymist/include/system_conf.h

    r01f2692e rdce1032b  
    11/*  system_conf.h
    22 *  Global System conf
    3  * 
     3 *
    44 *  Milkymist port of RTEMS
    55 *
    6  *  The license and distribution terms for this file may be 
     6 *  The license and distribution terms for this file may be
    77 *  found in the file LICENSE in this distribution or at
    88 *  http://www.rtems.com/license/LICENSE.
     
    1010 *  $Id$
    1111 *
     12 *  COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
    1213 */
    1314
     
    1516#define __SYSTEM_CONFIG_H_
    1617
    17 #define CPU_FREQUENCY (83333333)
    18 #define UART_BAUD_RATE  (115200)
    19 
    20 #define MM_TIMER1_COMPARE (0xe0001024)
    21 #define MM_TIMER1_COUNTER (0xe0001028)
    22 #define MM_TIMER1_CONTROL (0xe0001020)
    23 
    24 #define MM_TIMER0_COMPARE (0xe0001014)
    25 #define MM_TIMER0_COUNTER (0xe0001018)
    26 #define MM_TIMER0_CONTROL (0xe0001010)
    27 
    28 #define TIMER_ENABLE  (0x01)
    29 #define TIMER_AUTORESTART (0x02)
    30 
    31 #define MM_VGA_RESET_MODE (0x01)
    32 #define MM_VGA_RESET  (0xe0003000)
    33 #define MM_VGA_BASEADDRESS (0xe0003024)
     18#define CPU_FREQUENCY           (80000000)
     19#define UART_BAUD_RATE          (115200)
     20
     21/* FML bridge */
     22#define FMLBRG_FLUSH_BASE       (0xc8000000)
     23#define FMLBRG_LINE_LENGTH      (32)
     24#define FMLBRG_LINE_COUNT       (512)
     25
     26/* UART */
     27#define MM_UART_RXTX            (0xe0000000)
     28#define MM_UART_DIV             (0xe0000004)
     29
     30/* Timers */
     31#define MM_TIMER1_COMPARE       (0xe0001024)
     32#define MM_TIMER1_COUNTER       (0xe0001028)
     33#define MM_TIMER1_CONTROL       (0xe0001020)
     34
     35#define MM_TIMER0_COMPARE       (0xe0001014)
     36#define MM_TIMER0_COUNTER       (0xe0001018)
     37#define MM_TIMER0_CONTROL       (0xe0001010)
     38
     39#define TIMER_ENABLE            (0x01)
     40#define TIMER_AUTORESTART       (0x02)
     41
     42/* GPIO */
     43#define MM_GPIO_IN              (0xe0001000)
     44#define MM_GPIO_OUT             (0xe0001004)
     45#define MM_GPIO_INTEN           (0xe0001008)
     46
     47#define GPIO_BTN1               (0x00000001)
     48#define GPIO_BTN2               (0x00000002)
     49#define GPIO_BTN3               (0x00000004)
     50#define GPIO_PCBREV0            (0x00000008)
     51#define GPIO_PCBREV1            (0x00000010)
     52#define GPIO_PCBREV2            (0x00000020)
     53#define GPIO_PCBREV3            (0x00000040)
     54#define GPIO_LED1               (0x00000001)
     55#define GPIO_LED2               (0x00000002)
     56
     57/* System ID and reset */
     58#define MM_SYSTEM_ID            (0xe000103c)
     59
     60/* ICAP */
     61#define MM_ICAP                 (0xe0001034)
     62
     63#define ICAP_READY              (0x01)
     64#define ICAP_CE                 (0x10000)
     65#define ICAP_WRITE              (0x20000)
     66
     67/* VGA */
     68#define MM_VGA_RESET            (0xe0003000)
     69
     70#define MM_VGA_HRES             (0xe0003004)
     71#define MM_VGA_HSYNC_START      (0xe0003008)
     72#define MM_VGA_HSYNC_END        (0xe000300C)
     73#define MM_VGA_HSCAN            (0xe0003010)
     74
     75#define MM_VGA_VRES             (0xe0003014)
     76#define MM_VGA_VSYNC_START      (0xe0003018)
     77#define MM_VGA_VSYNC_END        (0xe000301C)
     78#define MM_VGA_VSCAN            (0xe0003020)
     79
     80#define MM_VGA_BASEADDRESS      (0xe0003024)
    3481#define MM_VGA_BASEADDRESS_ACT  (0xe0003028)
    3582
    36 #define MM_MINIMAC_SETUP  (0xe0009000)
    37 #define MM_MINIMAC_STATE0  (0xe0009008)
    38 #define MM_MINIMAC_ADDR0 (0xe000900C)
    39 #define MM_MINIMAC_COUNT0  (0xe0009010)
    40 
    41 #define MM_MINIMAC_STATE1  (0xe0009014)
    42 #define MM_MINIMAC_ADDR1 (0xe0009018)
    43 #define MM_MINIMAC_COUNT1  (0xe000901C)
    44 
    45 #define MM_MINIMAC_STATE2  (0xe0009020)
    46 #define MM_MINIMAC_ADDR2 (0xe0009024)
    47 #define MM_MINIMAC_COUNT2  (0xe0009028)
    48 
    49 #define MM_MINIMAC_STATE3  (0xe000902C)
    50 #define MM_MINIMAC_ADDR3 (0xe0009030)
    51 #define MM_MINIMAC_COUNT3  (0xe0009034)
    52 
    53 #define MM_MINIMAC_TXREMAINING  (0xe000903C)
    54 #define MM_MINIMAC_TXADR (0xe0009038)
     83#define MM_VGA_BURST_COUNT      (0xe000302C)
     84
     85#define MM_VGA_DDC              (0xe0003030)
     86
     87#define MM_VGA_CLKSEL           (0xe0003034)
     88
     89#define VGA_RESET               (0x01)
     90#define VGA_DDC_SDAIN           (0x1)
     91#define VGA_DDC_SDAOUT          (0x2)
     92#define VGA_DDC_SDAOE           (0x4)
     93#define VGA_DDC_SDC             (0x8)
     94
     95/* Ethernet */
     96#define MM_MINIMAC_SETUP        (0xe0008000)
     97#define MM_MINIMAC_MDIO         (0xe0008004)
     98
     99#define MM_MINIMAC_STATE0       (0xe0008008)
     100#define MM_MINIMAC_COUNT0       (0xe000800C)
     101#define MM_MINIMAC_STATE1       (0xe0008010)
     102#define MM_MINIMAC_COUNT1       (0xe0008014)
     103
     104#define MM_MINIMAC_TXCOUNT      (0xe0008018)
     105
     106#define MINIMAC_RX0_BASE        (0xb0000000)
     107#define MINIMAC_RX1_BASE        (0xb0000800)
     108#define MINIMAC_TX_BASE         (0xb0001000)
     109
     110#define MINIMAC_SETUP_PHYRST    (0x1)
     111
     112#define MINIMAC_STATE_EMPTY     (0x0)
     113#define MINIMAC_STATE_LOADED    (0x1)
     114#define MINIMAC_STATE_PENDING   (0x2)
     115
     116/* AC97 */
     117#define MM_AC97_CRCTL           (0xe0005000)
     118
     119#define AC97_CRCTL_RQEN         (0x01)
     120#define AC97_CRCTL_WRITE        (0x02)
     121
     122#define MM_AC97_CRADDR          (0xe0005004)
     123#define MM_AC97_CRDATAOUT       (0xe0005008)
     124#define MM_AC97_CRDATAIN        (0xe000500C)
     125
     126#define MM_AC97_DCTL            (0xe0005010)
     127#define MM_AC97_DADDRESS        (0xe0005014)
     128#define MM_AC97_DREMAINING      (0xe0005018)
     129
     130#define MM_AC97_UCTL            (0xe0005020)
     131#define MM_AC97_UADDRESS        (0xe0005024)
     132#define MM_AC97_UREMAINING      (0xe0005028)
     133
     134#define AC97_SCTL_EN            (0x01)
     135
     136#define AC97_MAX_DMASIZE        (0x3fffc)
     137
     138/* SoftUSB */
     139#define MM_SOFTUSB_CONTROL      (0xe000f000)
     140
     141#define SOFTUSB_CONTROL_RESET   (0x1)
     142
     143#define MM_SOFTUSB_PMEM_BASE    (0xa0000000)
     144#define MM_SOFTUSB_DMEM_BASE    (0xa0020000)
     145
     146#define SOFTUSB_PMEM_SIZE       (1 << 12)
     147#define SOFTUSB_DMEM_SIZE       (1 << 13)
     148
     149/* PFPU */
     150#define MM_PFPU_CTL             (0xe0006000)
     151#define PFPU_CTL_START          (0x01)
     152#define PFPU_CTL_BUSY           (0x01)
     153
     154#define MM_PFPU_MESHBASE        (0xe0006004)
     155#define MM_PFPU_HMESHLAST       (0xe0006008)
     156#define MM_PFPU_VMESHLAST       (0xe000600C)
     157
     158#define MM_PFPU_CODEPAGE        (0xe0006010)
     159
     160#define MM_PFPU_DREGBASE        (0xe0006400)
     161#define MM_PFPU_CODEBASE        (0xe0006800)
     162
     163#define PFPU_PAGESIZE           (512)
     164#define PFPU_SPREG_COUNT        (2)
     165#define PFPU_REG_X              (0)
     166#define PFPU_REG_Y              (1)
     167
     168/* TMU */
     169#define MM_TMU_CTL              (0xe0007000)
     170#define TMU_CTL_START           (0x01)
     171#define TMU_CTL_BUSY            (0x01)
     172#define TMU_CTL_CHROMAKEY       (0x02)
     173
     174#define MM_TMU_HMESHLAST        (0xe0007004)
     175#define MM_TMU_VMESHLAST        (0xe0007008)
     176#define MM_TMU_BRIGHTNESS       (0xe000700C)
     177#define MM_TMU_CHROMAKEY        (0xe0007010)
     178
     179#define MM_TMU_VERTICESADR      (0xe0007014)
     180#define MM_TMU_TEXFBUF          (0xe0007018)
     181#define MM_TMU_TEXHRES          (0xe000701C)
     182#define MM_TMU_TEXVRES          (0xe0007020)
     183#define MM_TMU_TEXHMASK         (0xe0007024)
     184#define MM_TMU_TEXVMASK         (0xe0007028)
     185
     186#define MM_TMU_DSTFBUF          (0xe000702C)
     187#define MM_TMU_DSTHRES          (0xe0007030)
     188#define MM_TMU_DSTVRES          (0xe0007034)
     189#define MM_TMU_DSTHOFFSET       (0xe0007038)
     190#define MM_TMU_DSTVOFFSET       (0xe000703C)
     191#define MM_TMU_DSTSQUAREW       (0xe0007040)
     192#define MM_TMU_DSTSQUAREH       (0xe0007044)
     193
     194#define MM_TMU_ALPHA            (0xe0007048)
     195
     196/* Memory card */
     197#define MM_MEMCARD_CLK2XDIV     (0xe0004000)
     198
     199#define MM_MEMCARD_ENABLE       (0xe0004004)
     200
     201#define MEMCARD_ENABLE_CMD_TX   (0x1)
     202#define MEMCARD_ENABLE_CMD_RX   (0x2)
     203#define MEMCARD_ENABLE_DAT_TX   (0x4)
     204#define MEMCARD_ENABLE_DAT_RX   (0x8)
     205
     206#define MM_MEMCARD_PENDING      (0xe0004008)
     207
     208#define MEMCARD_PENDING_CMD_TX  (0x1)
     209#define MEMCARD_PENDING_CMD_RX  (0x2)
     210#define MEMCARD_PENDING_DAT_TX  (0x4)
     211#define MEMCARD_PENDING_DAT_RX  (0x8)
     212
     213#define MM_MEMCARD_START        (0xe000400c)
     214
     215#define MEMCARD_START_CMD_RX    (0x1)
     216#define MEMCARD_START_DAT_RX    (0x2)
     217
     218#define MM_MEMCARD_CMD          (0xe0004010)
     219#define MM_MEMCARD_DAT          (0xe0004014)
     220
     221/* DMX */
     222#define MM_DMX_TX(x)            (0xe000c000+4*(x))
     223#define MM_DMX_THRU             (0xe000c800)
     224#define MM_DMX_RX(x)            (0xe000d000+4*(x))
     225
     226/* MIDI */
     227#define MM_MIDI_RXTX            (0xe000b000)
     228#define MM_MIDI_DIVISOR         (0xe000b004)
     229#define MM_MIDI_THRU            (0xe000b008)
     230
     231/* IR */
     232#define MM_IR_RX                (0xe000e000)
     233
     234/* Video input */
     235#define MM_BT656_I2C            (0xe000a000)
     236#define MM_BT656_FILTERSTATUS   (0xe000a004)
     237#define MM_BT656_BASE           (0xe000a008)
     238#define MM_BT656_MAXBURSTS      (0xe000a00c)
     239#define MM_BT656_DONEBURSTS     (0xe000a010)
     240
     241#define BT656_I2C_SDAIN         (0x1)
     242#define BT656_I2C_SDAOUT        (0x2)
     243#define BT656_I2C_SDAOE         (0x4)
     244#define BT656_I2C_SDC           (0x8)
     245
     246#define BT656_FILTER_FIELD1     (0x1)
     247#define BT656_FILTER_FIELD2     (0x2)
     248#define BT656_FILTER_INFRAME    (0x4)
     249
     250/* Interrupts */
     251#define MM_IRQ_UARTRX           (0)
     252#define MM_IRQ_UARTTX           (1)
     253#define MM_IRQ_GPIO             (2)
     254#define MM_IRQ_TIMER0           (3)
     255#define MM_IRQ_TIMER1           (4)
     256#define MM_IRQ_AC97CRREQUEST    (5)
     257#define MM_IRQ_AC97CRREPLY      (6)
     258#define MM_IRQ_AC97DMAR         (7)
     259#define MM_IRQ_AC97DMAW         (8)
     260#define MM_IRQ_PFPU             (9)
     261#define MM_IRQ_TMU              (10)
     262#define MM_IRQ_ETHRX            (11)
     263#define MM_IRQ_ETHTX            (12)
     264#define MM_IRQ_VIDEOIN          (13)
     265#define MM_IRQ_MIDIRX           (14)
     266#define MM_IRQ_MIDITX           (15)
     267#define MM_IRQ_IR               (16)
     268#define MM_IRQ_USB              (17)
     269
     270/* Flash layout */
     271#define FLASH_BASE                      (0x80000000)
     272
     273#define FLASH_OFFSET_STANDBY_BITSTREAM  (0x80000000)
     274
     275#define FLASH_OFFSET_RESCUE_BITSTREAM   (0x800A0000)
     276#define FLASH_OFFSET_RESCUE_BIOS        (0x80220000)
     277#define FLASH_OFFSET_MAC_ADDRESS        (0x802200E0)
     278#define FLASH_OFFSET_RESCUE_SPLASH      (0x80240000)
     279#define FLASH_OFFSET_RESCUE_APP         (0x802E0000)
     280
     281#define FLASH_OFFSET_REGULAR_BITSTREAM  (0x806E0000)
     282#define FLASH_OFFSET_REGULAR_BIOS       (0x80860000)
     283#define FLASH_OFFSET_REGULAR_SPLASH     (0x80880000)
     284#define FLASH_OFFSET_REGULAR_APP        (0x80920000)
     285
     286/* MMIO */
     287#define MM_READ(reg) (*((volatile unsigned int *)(reg)))
     288#define MM_WRITE(reg, val) *((volatile unsigned int *)(reg)) = val
     289
     290/* Flash partitions */
     291
     292#define FLASH_SECTOR_SIZE     (128*1024)
     293
     294#define FLASH_PARTITION_COUNT (5)
     295
     296#define FLASH_PARTITIONS { \
     297  { .start_address = 0x806E0000, .length = 0x0180000 }, \
     298  { .start_address = 0x80860000, .length = 0x0020000 }, \
     299  { .start_address = 0x80880000, .length = 0x00A0000 }, \
     300  { .start_address = 0x80920000, .length = 0x0400000 }, \
     301  { .start_address = 0x80D20000, .length = 0x12E0000 }, \
     302}
    55303
    56304#endif /* __SYSTEM_CONFIG_H_ */
  • c/src/lib/libbsp/lm32/milkymist/make/custom/milkymist.cfg

    r01f2692e rdce1032b  
    1919
    2020# optimize flag: typically -O2
    21 # ATM, doesn't work with optimization levels > 0
    2221CFLAGS_OPTIMIZE_V = -O2 -g
    2322
  • c/src/lib/libbsp/lm32/milkymist/preinstall.am

    r01f2692e rdce1032b  
    4242PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h
    4343
    44 $(PROJECT_INCLUDE)/tm27.h: include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
     44$(PROJECT_INCLUDE)/coverhd.h: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
     45        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
     46PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
     47
     48$(PROJECT_INCLUDE)/tm27.h: ../../shared/include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
    4549        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h
    4650PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h
     51
     52$(PROJECT_INCLUDE)/bsp/irq.h: ../../lm32/shared/include/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     53        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
     54PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
     55
     56$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     57        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-generic.h
     58PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
     59
     60$(PROJECT_INCLUDE)/bsp/milkymist_gpio.h: ../../lm32/shared/milkymist_gpio/milkymist_gpio.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     61        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/milkymist_gpio.h
     62PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/milkymist_gpio.h
     63
     64$(PROJECT_INCLUDE)/bsp/milkymist_buttons.h: ../../lm32/shared/milkymist_buttons/milkymist_buttons.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     65        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/milkymist_buttons.h
     66PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/milkymist_buttons.h
     67
     68$(PROJECT_INCLUDE)/bsp/milkymist_ac97.h: ../../lm32/shared/milkymist_ac97/milkymist_ac97.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     69        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/milkymist_ac97.h
     70PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/milkymist_ac97.h
     71
     72$(PROJECT_INCLUDE)/bsp/milkymist_usbinput.h: ../../lm32/shared/milkymist_usbinput/milkymist_usbinput.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     73        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/milkymist_usbinput.h
     74PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/milkymist_usbinput.h
     75
     76$(PROJECT_INCLUDE)/bsp/milkymist_pfpu.h: ../../lm32/shared/milkymist_pfpu/milkymist_pfpu.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     77        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/milkymist_pfpu.h
     78PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/milkymist_pfpu.h
     79
     80$(PROJECT_INCLUDE)/bsp/milkymist_tmu.h: ../../lm32/shared/milkymist_tmu/milkymist_tmu.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     81        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/milkymist_tmu.h
     82PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/milkymist_tmu.h
     83
     84$(PROJECT_INCLUDE)/bsp/milkymist_memcard.h: ../../lm32/shared/milkymist_memcard/milkymist_memcard.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     85        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/milkymist_memcard.h
     86PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/milkymist_memcard.h
     87
     88$(PROJECT_INCLUDE)/bsp/milkymist_flash.h: ../../lm32/shared/milkymist_flash/milkymist_flash.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     89        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/milkymist_flash.h
     90PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/milkymist_flash.h
     91
     92$(PROJECT_INCLUDE)/bsp/milkymist_dmx.h: ../../lm32/shared/milkymist_dmx/milkymist_dmx.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     93        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/milkymist_dmx.h
     94PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/milkymist_dmx.h
     95
     96$(PROJECT_INCLUDE)/bsp/milkymist_midi.h: ../../lm32/shared/milkymist_midi/milkymist_midi.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     97        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/milkymist_midi.h
     98PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/milkymist_midi.h
     99
     100$(PROJECT_INCLUDE)/bsp/milkymist_ir.h: ../../lm32/shared/milkymist_ir/milkymist_ir.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     101        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/milkymist_ir.h
     102PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/milkymist_ir.h
     103
     104$(PROJECT_INCLUDE)/bsp/milkymist_video.h: ../../lm32/shared/milkymist_video/milkymist_video.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     105        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/milkymist_video.h
     106PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/milkymist_video.h
     107
     108$(PROJECT_INCLUDE)/bsp/milkymist_versions.h: ../../lm32/shared/milkymist_versions/milkymist_versions.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     109        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/milkymist_versions.h
     110PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/milkymist_versions.h
    47111
    48112$(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp)
     
    53117        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bootcard.h
    54118PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bootcard.h
    55 
    56 $(PROJECT_INCLUDE)/coverhd.h: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
    57         $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
    58 PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
    59119
    60120$(PROJECT_INCLUDE)/system_conf.h: include/system_conf.h $(PROJECT_INCLUDE)/$(dirstamp)
  • c/src/lib/libbsp/lm32/milkymist/startup/linkcmds

    r01f2692e rdce1032b  
    1010 */
    1111RamBase = DEFINED(RamBase) ? RamBase : 0x40000000;
    12 RamSize = DEFINED(RamSize) ? RamSize : 64M;
    13 HeapSize = DEFINED(HeapSize) ? HeapSize : 2M;
     12RamSize = DEFINED(RamSize) ? RamSize : 128M;
     13HeapSize = DEFINED(HeapSize) ? HeapSize : 92M;
    1414_StackSize = DEFINED(_StackSize) ? _StackSize : 0x2000;
    1515
    1616PROVIDE (__stack = 0);
    1717MEMORY {
    18         sdram   : ORIGIN = 0x40000000 , LENGTH = 64M
     18        sdram   : ORIGIN = 0x40000000 , LENGTH = 128M
    1919}
    2020SECTIONS
  • c/src/lib/libbsp/lm32/shared/gdbstub/lm32-stub.c

    r01f2692e rdce1032b  
    2525 * SUCH DAMAGE.
    2626 */
     27
     28/* $Id$ */
    2729
    2830#include <bsp.h>
  • c/src/lib/libbsp/lm32/shared/milkymist_ac97/ac97.c

    r01f2692e rdce1032b  
    11/*  ac97.c
    22 *
    3  *  This file is the sound driver for the Milkymist One board
    4  *  It does an OSS style character device in /dev/snd
     3 *  Sound driver for Milkymist SoC
    54 *
    65 *  The license and distribution terms for this file may be
     
    109 *  $Id$
    1110 *
    12  *  COPYRIGHT (c) Yann Sionneau <yann.sionneau@telecom-sudparis.eu> (GSoC 2010)
    13  *  Telecom SudParis
     11 *  COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
    1412 */
    1513
    16 #include <stdlib.h>
    17 #include <stdio.h>
    18 #include <errno.h>
    19 #include <sys/types.h>
    20 #include <pthread.h>
     14#define RTEMS_STATUS_CHECKS_USE_PRINTK
     15
    2116#include <rtems.h>
    2217#include <bsp.h>
     18#include <bsp/irq-generic.h>
     19#include <rtems/libio.h>
     20#include <rtems/status-checks.h>
    2321#include "../include/system_conf.h"
    24 #include <rtems/libio.h>
    25 
    26 #define GPIO_DRIVER_TABLE_ENTRY { ac97_initialize, \
    27 ac97_open, ac97_close, ac97_read, ac97_write, ac97_control}
    28 
    29 #define SND_DEVICE_NAME  "/dev/snd"
    30 
    31 static struct milkymist_ac97 {
    32   rtems_device_minor_number minor;
    33   pthread_mutex_t mutex;
    34 } ac97_driver;
    35 
    36 rtems_device_driver gpio_initialize(
    37 rtems_device_major_number  major,
    38 rtems_device_minor_number  minor,
    39 void *arg)
    40 {
    41   rtems_status_code status;
    42 
    43   printk( "ac97 driver initializing..\n" );
    44 
    45   status = rtems_io_register_name(SND_DEVICE_NAME, major, 0);
    46   if (status != RTEMS_SUCCESSFUL)
    47   {
    48     printk("Error registering /dev/snd ac97 device \n");
    49     rtems_fatal_error_occurred( status );
    50   }
    51   gpio[0].minor = 0;
    52   gpio[0].mutex = PTHREAD_MUTEX_INITIALIZER;
    53 
    54   return RTEMS_SUCCESSFUL;
    55 }
    56 
    57 rtems_device_driver gpio_close(
    58   rtems_device_major_number  major,
    59   rtems_device_minor_number  minor,
     22#include "milkymist_ac97.h"
     23
     24#define SND_DEVICE_NAME "/dev/snd"
     25#define MIXER_DEVICE_NAME "/dev/mixer"
     26
     27static rtems_id cr_write_sem;
     28static rtems_id cr_read_sem;
     29
     30static rtems_isr crrequest_handler(rtems_vector_number n)
     31{
     32  rtems_semaphore_release(cr_write_sem);
     33  lm32_interrupt_ack(1 << MM_IRQ_AC97CRREQUEST);
     34}
     35
     36static rtems_isr crreply_handler(rtems_vector_number n)
     37{
     38  rtems_semaphore_release(cr_read_sem);
     39  lm32_interrupt_ack(1 << MM_IRQ_AC97CRREPLY);
     40}
     41
     42/* queued playback buffers */
     43#define PLAY_Q_SIZE 8
     44#define PLAY_Q_MASK (PLAY_Q_SIZE-1)
     45
     46static struct snd_buffer *play_q[PLAY_Q_SIZE];
     47static int play_produce;
     48static int play_consume;
     49static int play_level;
     50
     51/* buffers played, for application to collect */
     52static rtems_id play_q_done;
     53
     54static void play_start(struct snd_buffer *buf)
     55{
     56  if (buf->nsamples > (AC97_MAX_DMASIZE/4))
     57    buf->nsamples = AC97_MAX_DMASIZE/4;
     58
     59  MM_WRITE(MM_AC97_DADDRESS, (unsigned int)buf->samples);
     60  MM_WRITE(MM_AC97_DREMAINING, buf->nsamples*4);
     61  MM_WRITE(MM_AC97_DCTL, AC97_SCTL_EN);
     62}
     63
     64static rtems_isr pcmplay_handler(rtems_vector_number n)
     65{
     66  lm32_interrupt_ack(1 << MM_IRQ_AC97DMAR);
     67
     68  rtems_message_queue_send(play_q_done, &play_q[play_consume],
     69    sizeof(void *));
     70
     71  play_consume = (play_consume + 1) & PLAY_Q_MASK;
     72  play_level--;
     73
     74  if(play_level > 0)
     75    play_start(play_q[play_consume]);
     76  else
     77    MM_WRITE(MM_AC97_DCTL, 0);
     78}
     79
     80/* queued record buffers */
     81#define RECORD_Q_SIZE 8
     82#define RECORD_Q_MASK (RECORD_Q_SIZE-1)
     83
     84static struct snd_buffer *record_q[RECORD_Q_SIZE];
     85static int record_produce;
     86static int record_consume;
     87static int record_level;
     88
     89/* buffers recorded, for application to collect */
     90static rtems_id record_q_done;
     91
     92static void record_start(struct snd_buffer *buf)
     93{
     94  if (buf->nsamples > (AC97_MAX_DMASIZE/4))
     95    buf->nsamples = AC97_MAX_DMASIZE/4;
     96
     97  MM_WRITE(MM_AC97_UADDRESS, (unsigned int)buf->samples);
     98  MM_WRITE(MM_AC97_UREMAINING, buf->nsamples*4);
     99  MM_WRITE(MM_AC97_UCTL, AC97_SCTL_EN);
     100}
     101
     102static rtems_isr pcmrecord_handler(rtems_vector_number n)
     103{
     104  lm32_interrupt_ack(1 << MM_IRQ_AC97DMAW);
     105
     106  __asm__ volatile( /* Invalidate Level-1 data cache */
     107      "wcsr DCC, r0\n"
     108      "nop\n"
     109    );
     110
     111  rtems_message_queue_send(record_q_done, &record_q[record_consume],
     112    sizeof(void *));
     113
     114  record_consume = (record_consume + 1) & RECORD_Q_MASK;
     115  record_level--;
     116
     117  if(record_level > 0)
     118    record_start(record_q[record_consume]);
     119  else
     120    MM_WRITE(MM_AC97_UCTL, 0);
     121}
     122
     123rtems_device_driver ac97_initialize(
     124  rtems_device_major_number major,
     125  rtems_device_minor_number minor,
    60126  void *arg
    61127)
    62128{
    63   if (pthread_mutex_unlock(&ac97_driver.mutex) == 0){
     129  rtems_status_code sc;
     130  rtems_isr_entry dummy;
     131
     132  sc = rtems_io_register_name(SND_DEVICE_NAME, major, 0);
     133  RTEMS_CHECK_SC(sc, "create snd device");
     134
     135  sc = rtems_io_register_name(MIXER_DEVICE_NAME, major, 1);
     136  RTEMS_CHECK_SC(sc, "create mixer device");
     137
     138  sc = rtems_semaphore_create(
     139    rtems_build_name('C', 'R', 'W', 'S'),
     140    0,
     141    RTEMS_SIMPLE_BINARY_SEMAPHORE,
     142    0,
     143    &cr_write_sem
     144  );
     145  RTEMS_CHECK_SC(sc, "create AC97 register write semaphore");
     146
     147  sc = rtems_semaphore_create(
     148    rtems_build_name('C', 'R', 'R', 'S'),
     149    0,
     150    RTEMS_SIMPLE_BINARY_SEMAPHORE,
     151    0,
     152    &cr_read_sem
     153  );
     154  RTEMS_CHECK_SC(sc, "create AC97 register read semaphore");
     155
     156  sc = rtems_message_queue_create(
     157    rtems_build_name('P', 'L', 'Y', 'Q'),
     158    PLAY_Q_SIZE*2,
     159    sizeof(void *),
     160    0,
     161    &play_q_done
     162  );
     163  RTEMS_CHECK_SC(sc, "create playback done queue");
     164
     165  sc = rtems_message_queue_create(
     166    rtems_build_name('R', 'E', 'C', 'Q'),
     167    RECORD_Q_SIZE*2,
     168    sizeof(void *),
     169    0,
     170    &record_q_done
     171  );
     172  RTEMS_CHECK_SC(sc, "create record done queue");
     173
     174  rtems_interrupt_catch(crrequest_handler, MM_IRQ_AC97CRREQUEST, &dummy);
     175  rtems_interrupt_catch(crreply_handler, MM_IRQ_AC97CRREPLY, &dummy);
     176  rtems_interrupt_catch(pcmplay_handler, MM_IRQ_AC97DMAR, &dummy);
     177  rtems_interrupt_catch(pcmrecord_handler, MM_IRQ_AC97DMAW, &dummy);
     178  bsp_interrupt_vector_enable(MM_IRQ_AC97CRREQUEST);
     179  bsp_interrupt_vector_enable(MM_IRQ_AC97CRREPLY);
     180  bsp_interrupt_vector_enable(MM_IRQ_AC97DMAR);
     181  bsp_interrupt_vector_enable(MM_IRQ_AC97DMAW);
     182
     183  play_produce = 0;
     184  play_consume = 0;
     185  play_level = 0;
     186
     187  record_produce = 0;
     188  record_consume = 0;
     189  record_level = 0;
     190
     191  return RTEMS_SUCCESSFUL;
     192}
     193
     194static rtems_status_code submit_play(struct snd_buffer *buf)
     195{
     196  bsp_interrupt_vector_disable(MM_IRQ_AC97DMAR);
     197  if (play_level == PLAY_Q_SIZE) {
     198    bsp_interrupt_vector_enable(MM_IRQ_AC97DMAR);
     199    return RTEMS_UNSATISFIED;
     200  }
     201  play_q[play_produce] = buf;
     202  play_produce = (play_produce + 1) & PLAY_Q_MASK;
     203  play_level++;
     204
     205  if (play_level == 1)
     206    play_start(buf);
     207
     208  bsp_interrupt_vector_enable(MM_IRQ_AC97DMAR);
     209  return RTEMS_SUCCESSFUL;
     210}
     211
     212static rtems_status_code collect_play(struct snd_buffer **buf)
     213{
     214  size_t s;
     215
     216  return rtems_message_queue_receive(
     217    play_q_done,
     218    buf,
     219    &s,
     220    RTEMS_WAIT,
     221    RTEMS_NO_TIMEOUT
     222  );
     223}
     224
     225static rtems_status_code submit_record(struct snd_buffer *buf)
     226{
     227  bsp_interrupt_vector_disable(MM_IRQ_AC97DMAW);
     228  if (record_level == RECORD_Q_SIZE) {
     229    bsp_interrupt_vector_enable(MM_IRQ_AC97DMAW);
     230    return RTEMS_UNSATISFIED;
     231  }
     232  record_q[record_produce] = buf;
     233  record_produce = (record_produce + 1) & RECORD_Q_MASK;
     234  record_level++;
     235
     236  if (record_level == 1)
     237    record_start(buf);
     238
     239  bsp_interrupt_vector_enable(MM_IRQ_AC97DMAW);
     240  return RTEMS_SUCCESSFUL;
     241}
     242
     243static rtems_status_code collect_record(struct snd_buffer **buf)
     244{
     245  size_t s;
     246
     247  return rtems_message_queue_receive(
     248    record_q_done,
     249    buf,
     250    &s,
     251    RTEMS_WAIT,
     252    RTEMS_NO_TIMEOUT
     253  );
     254}
     255
     256#define CR_TIMEOUT 10
     257
     258static int read_cr(unsigned int adr)
     259{
     260  rtems_status_code sc;
     261
     262  MM_WRITE(MM_AC97_CRADDR, adr);
     263  MM_WRITE(MM_AC97_CRCTL, AC97_CRCTL_RQEN);
     264  sc = rtems_semaphore_obtain(cr_write_sem, RTEMS_WAIT, CR_TIMEOUT);
     265  if (sc != RTEMS_SUCCESSFUL)
     266    return -1;
     267  sc = rtems_semaphore_obtain(cr_read_sem, RTEMS_WAIT, CR_TIMEOUT);
     268  if (sc != RTEMS_SUCCESSFUL)
     269    return -1;
     270  return MM_READ(MM_AC97_CRDATAIN);
     271}
     272
     273static int write_cr(unsigned int adr, unsigned int val)
     274{
     275  rtems_status_code sc;
     276
     277  MM_WRITE(MM_AC97_CRADDR, adr);
     278  MM_WRITE(MM_AC97_CRDATAOUT, val);
     279  MM_WRITE(MM_AC97_CRCTL, AC97_CRCTL_RQEN|AC97_CRCTL_WRITE);
     280  sc = rtems_semaphore_obtain(cr_write_sem, RTEMS_WAIT, CR_TIMEOUT);
     281  if (sc != RTEMS_SUCCESSFUL)
     282    return 0;
     283  return 1;
     284}
     285
     286rtems_device_driver ac97_open(
     287   rtems_device_major_number major,
     288   rtems_device_minor_number minor,
     289   void *arg
     290)
     291{
     292  int codec_id;
     293 
     294  if (minor == 0) {
     295    /* snd */
    64296    return RTEMS_SUCCESSFUL;
    65   }
    66   return RTEMS_UNSATISFIED;
    67 }
    68 
    69 rtems_device_driver gpio_open(
    70   rtems_device_major_number  major,
    71   rtems_device_minor_number  minor,
     297  } else {
     298    /* mixer */
     299    codec_id = read_cr(0x00);
     300    if ((codec_id != 0x0d50) && (codec_id != 0x6150)) {
     301      printk("AC97 codec detection failed\n");
     302      return RTEMS_UNSATISFIED;
     303    }
     304    write_cr(0x02, 0x0000); /* master volume */
     305    write_cr(0x04, 0x0f0f); /* headphones volume */
     306    write_cr(0x18, 0x0000); /* PCM out volume */
     307    write_cr(0x1c, 0x0f0f); /* record gain */
     308
     309    write_cr(0x1a, 0x0505); /* record select: stereo mix */
     310
     311    return RTEMS_SUCCESSFUL;
     312  }
     313}
     314
     315static rtems_status_code ioctl_read_channel(void *buf,
     316  unsigned int chan, int mono)
     317{
     318  unsigned int *val = (unsigned int *)buf;
     319  int codec;
     320  int left, right;
     321
     322  codec = read_cr(chan);
     323  if (codec < 0)
     324    return RTEMS_UNSATISFIED;
     325  if (codec & 0x8000) {
     326    /* muted */
     327    *val = 0;
     328    return RTEMS_SUCCESSFUL;
     329  }
     330  if (mono) {
     331    right = left = 100-(((codec & 0x1f) + 1)*100)/32;
     332  } else {
     333    right = 100-(((codec & 0x1f) + 1)*100)/32;
     334    left = 100-((((codec & 0x1f00) >> 8) + 1)*100)/32;
     335  }
     336  *val = left | (right << 8);
     337  return RTEMS_SUCCESSFUL;
     338}
     339
     340static rtems_status_code ioctl_write_channel(void *buf,
     341  unsigned int chan, int mono)
     342{
     343  unsigned int *val = (unsigned int *)buf;
     344  int left, right;
     345  int codec;
     346  rtems_status_code sc;
     347
     348  left = *val & 0xff;
     349  left = (left*32)/100 - 1;
     350  if(left < 0)
     351    left = 0;
     352
     353  if (mono)
     354    right = 31;
     355  else {
     356    right = (*val >> 8) & 0xff;
     357    right = (right*32)/100 - 1;
     358    if(right < 0)
     359      right = 0;
     360  }
     361
     362  if ((left == 0) && (right == 0))
     363    /* mute */
     364    codec = 0x8000;
     365  else
     366    codec = (31-left) | ((31-right) << 8);
     367
     368  if (!write_cr(chan, codec))
     369    sc = RTEMS_UNSATISFIED;
     370  else
     371    sc = RTEMS_SUCCESSFUL;
     372  return sc;
     373}
     374
     375rtems_device_driver ac97_control(
     376  rtems_device_major_number major,
     377  rtems_device_minor_number minor,
    72378  void *arg
    73379)
    74380{
    75   if (pthread_mutex_trylock(&ac97_driver.mutex) == 0){
    76     return RTEMS_SUCCESSFUL;
    77   }
    78   return RTEMS_UNSATISFIED;
    79 }
    80 
    81 
    82 rtems_device_driver gpio_read(
    83   rtems_device_major_number  major,
    84   rtems_device_minor_number  minor,
    85   void                      *arg
    86 )
    87 {
    88   rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
    89  
    90   return RTEMS_SUCCESSFUL;
    91 }
    92 
    93 rtems_device_driver gpio_write(
    94   rtems_device_major_number  major,
    95   rtems_device_minor_number  minor,
    96   void                      *arg
    97 )
    98 {
    99   rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
    100 
    101   return RTEMS_SUCCESSFUL;
    102 }
    103 
    104 rtems_device_driver gpio_control(
    105   rtems_device_major_number  major,
    106   rtems_device_minor_number  minor,
    107   void                      *arg
    108 )
    109 {
    110381  rtems_libio_ioctl_args_t *args = arg;
    111 
    112   switch( args->command ) {
    113     default:
    114      args->ioctl_return = 0;
    115      break;
    116   }
    117   return RTEMS_SUCCESSFUL;
    118 }
    119 
     382  rtems_status_code sc;
     383
     384  args->ioctl_return = -1;
     385  if(minor == 0) {
     386    /* dsp */
     387    switch (args->command) {
     388      case SOUND_SND_SUBMIT_PLAY:
     389        return submit_play((struct snd_buffer *)args->buffer);
     390      case SOUND_SND_COLLECT_PLAY:
     391        return collect_play((struct snd_buffer **)args->buffer);
     392      case SOUND_SND_SUBMIT_RECORD:
     393        return submit_record((struct snd_buffer *)args->buffer);
     394      case SOUND_SND_COLLECT_RECORD:
     395        return collect_record((struct snd_buffer **)args->buffer);
     396      default:
     397        return RTEMS_UNSATISFIED;
     398    }
     399  } else {
     400    /* mixer */
     401    switch (args->command) {
     402      case SOUND_MIXER_READ(SOUND_MIXER_MIC):
     403        sc = ioctl_read_channel(args->buffer, 0x0e, 1);
     404        if(sc == RTEMS_SUCCESSFUL)
     405          args->ioctl_return = 0;
     406        return sc;
     407      case SOUND_MIXER_READ(SOUND_MIXER_LINE):
     408        sc = ioctl_read_channel(args->buffer, 0x10, 0);
     409        if(sc == RTEMS_SUCCESSFUL)
     410          args->ioctl_return = 0;
     411        return sc;
     412      case SOUND_MIXER_WRITE(SOUND_MIXER_MIC):
     413        sc = ioctl_write_channel(args->buffer, 0x0e, 1);
     414        if(sc == RTEMS_SUCCESSFUL)
     415          args->ioctl_return = 0;
     416        return sc;
     417      case SOUND_MIXER_WRITE(SOUND_MIXER_LINE):
     418        sc = ioctl_write_channel(args->buffer, 0x10, 0);
     419        if(sc == RTEMS_SUCCESSFUL)
     420          args->ioctl_return = 0;
     421        return sc;
     422      default:
     423        return RTEMS_UNSATISFIED;
     424    }
     425  }
     426}
  • c/src/lib/libbsp/lm32/shared/milkymist_clock/ckinit.c

    r01f2692e rdce1032b  
    1414
    1515#include <bsp.h>
     16#include <bsp/irq-generic.h>
    1617#include "../include/system_conf.h"
    1718#include "clock.h"
     
    2223#endif
    2324
    24 static inline int clockread(unsigned int reg)
    25 {
    26   return *((int*)(reg));
    27 }
    28 
    29 static inline void clockwrite(unsigned int reg, int value)
    30 {
    31   *((int*)reg) = value;
    32 }
    33 
    34 /*
    35  *  The interrupt vector number associated with the clock tick device
    36  *  driver.
    37  */
    38 
    39 #define TIMER0_IRQ              (1)
    40 
    41 #define CLOCK_VECTOR    ( TIMER0_IRQ )
    42 #define CLOCK_IRQMASK   ( 1 << CLOCK_VECTOR )
    43 
    4425#define Clock_driver_support_at_tick() \
    4526  do { \
    46     lm32_interrupt_ack(CLOCK_IRQMASK); \
     27    lm32_interrupt_ack(1 << MM_IRQ_TIMER0); \
    4728  } while (0)
    4829
    4930#define Clock_driver_support_install_isr(_new, _old ) \
    5031  do { \
    51           _old = (rtems_isr_entry) set_vector( _new, CLOCK_VECTOR, 1 ); \
     32    rtems_interrupt_catch(_new, MM_IRQ_TIMER0, &_old); \
    5233  } while (0)
    5334
    5435void Clock_driver_support_initialize_hardware(void)
    5536{
    56   clockwrite(MM_TIMER0_COMPARE, (CPU_FREQUENCY / (1000000 / rtems_configuration_get_microseconds_per_tick())));
    57        
    58   clockwrite(MM_TIMER0_COUNTER, 0);
    59   clockwrite(MM_TIMER0_CONTROL, TIMER_ENABLE | TIMER_AUTORESTART);
    60   lm32_interrupt_unmask(CLOCK_IRQMASK);
     37  MM_WRITE(MM_TIMER0_COMPARE,
     38   (CPU_FREQUENCY/(1000000/rtems_configuration_get_microseconds_per_tick())));
     39  MM_WRITE(MM_TIMER0_COUNTER, 0);
     40  MM_WRITE(MM_TIMER0_CONTROL, TIMER_ENABLE | TIMER_AUTORESTART);
     41  bsp_interrupt_vector_enable(MM_IRQ_TIMER0);
    6142}
    6243
    6344void Clock_driver_support_shutdown_hardware(void)
    6445{
    65   lm32_interrupt_mask(CLOCK_IRQMASK);
    66   clockwrite(MM_TIMER0_CONTROL, 0);
     46  bsp_interrupt_vector_disable(MM_IRQ_TIMER0);
     47  MM_WRITE(MM_TIMER0_CONTROL, 0);
    6748}
    6849
    6950#include "../../../shared/clockdrv_shell.h"
    70 
  • c/src/lib/libbsp/lm32/shared/milkymist_console/console.c

    r01f2692e rdce1032b  
    11/*
    2  *  Console driver for Lattice Mico32 (lm32).
     2 *  Console driver for Milkymist
    33 *
    44 *  The license and distribution terms for this file may be
     
    88 *  $Id$
    99 *
    10  *  Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
    11  *  Micro-Research Finland Oy
    12  *
    13  *  COPYRIGHT (c) Yann Sionneau <yann.sionneau@telecom-sudparis.eu>, GSoc 2010
    14  *  Telecom SudParis
     10 *  COPYRIGHT (c) 2010 Sebastien Bourdeauducq
    1511 */
    1612
    17 #define NO_BSP_INIT
     13#include <unistd.h>
     14#include <termios.h>
    1815
    1916#include <rtems.h>
    20 #include <bsp.h>
    2117#include <rtems/libio.h>
    22 
    23 void BSP_uart_polled_write(char ch);
    24 int BSP_uart_polled_read( void );
    25 char BSP_uart_is_character_ready(char *ch);
    26 
    27 /*  console_initialize
    28  *
    29  *  This routine initializes the console IO driver.
    30  *
    31  *  Input parameters: NONE
    32  *
    33  *  Output parameters:  NONE
    34  *
    35  *  Return values:
    36  */
     18#include <rtems/console.h>
     19#include <rtems/termiostypes.h>
     20#include <bsp/irq-generic.h>
     21
     22#include "../include/system_conf.h"
     23#include "uart.h"
     24
     25BSP_output_char_function_type BSP_output_char = BSP_uart_polled_write;
     26BSP_polling_getchar_function_type BSP_poll_char = BSP_uart_polled_read;
     27
     28static struct rtems_termios_tty *tty;
     29
     30static int mmconsole_first_open(int major, int minor, void *arg)
     31{
     32  tty = ((rtems_libio_open_close_args_t *) arg)->iop->data1;
     33  return rtems_termios_set_initial_baud(tty, UART_BAUD_RATE);
     34}
     35
     36static int mmconsole_last_close(int major, int minor, void *arg)
     37{
     38  return 0;
     39}
     40
     41static int mmconsole_set_attributes(int minor, const struct termios *t)
     42{
     43  int baud;
     44
     45  switch (t->c_cflag & CBAUD) {
     46    case B0:
     47      baud = 0;
     48      break;
     49    case B50:
     50      baud = 50;
     51      break;
     52    case B75:
     53      baud = 75;
     54      break;
     55    case B110:
     56      baud = 110;
     57      break;
     58    case B134:
     59      baud = 134;
     60      break;
     61    case B150:
     62      baud = 150;
     63      break;
     64    case B200:
     65      baud = 200;
     66      break;
     67    case B300:
     68      baud = 300;
     69      break;
     70    case B600:
     71      baud = 600;
     72      break;
     73    case B1200:
     74      baud = 1200;
     75      break;
     76    case B1800:
     77      baud = 1800;
     78      break;
     79    case B2400:
     80      baud = 2400;
     81      break;
     82    case B4800:
     83      baud = 4800;
     84      break;
     85    case B9600:
     86      baud = 9600;
     87      break;
     88    case B19200:
     89      baud = 19200;
     90      break;
     91    case B38400:
     92      baud = 38400;
     93      break;
     94    case B57600:
     95      baud = 57600;
     96      break;
     97    case B115200:
     98      baud = 115200;
     99      break;
     100    case B230400:
     101      baud = 230400;
     102      break;
     103    case B460800:
     104      baud = 460800;
     105      break;
     106    default:
     107      baud = -1;
     108      break;
     109  }
     110
     111  if (baud > 0)
     112    MM_WRITE(MM_UART_DIV, CPU_FREQUENCY/baud/16);
     113
     114  return 0;
     115}
     116
     117static ssize_t mmconsole_write(int minor, const char *buf, size_t n)
     118{
     119  rtems_interrupt_level level;
     120
     121  rtems_interrupt_disable(level);
     122  BSP_uart_txbusy = true;
     123  MM_WRITE(MM_UART_RXTX, *buf);
     124  rtems_interrupt_enable(level);
     125  return 0;
     126}
     127
     128static rtems_isr mmconsole_txdone(rtems_vector_number n)
     129{
     130  BSP_uart_txbusy = false;
     131  lm32_interrupt_ack(1 << MM_IRQ_UARTTX);
     132  rtems_termios_dequeue_characters(tty, 1);
     133}
     134
     135static rtems_isr mmconsole_rxdone(rtems_vector_number n)
     136{
     137  char c;
     138  c = MM_READ(MM_UART_RXTX);
     139  lm32_interrupt_ack(1 << MM_IRQ_UARTRX);
     140  rtems_termios_enqueue_raw_characters(tty, &c, 1);
     141}
     142
     143static const rtems_termios_callbacks mmconsole_callbacks = {
     144  .firstOpen = mmconsole_first_open,
     145  .lastClose = mmconsole_last_close,
     146  .pollRead = NULL,
     147  .write = mmconsole_write,
     148  .setAttributes = mmconsole_set_attributes,
     149  .stopRemoteTx = NULL,
     150  .startRemoteTx = NULL,
     151  .outputUsesInterrupts = TERMIOS_IRQ_DRIVEN
     152};
    37153
    38154rtems_device_driver console_initialize(
    39   rtems_device_major_number  major,
    40   rtems_device_minor_number  minor,
    41   void                      *arg
     155  rtems_device_major_number major,
     156  rtems_device_minor_number minor,
     157  void *arg
    42158)
    43159{
    44160  rtems_status_code status;
    45 
    46   printk("console_initialize\n");
    47 
    48   status = rtems_io_register_name(
    49     "/dev/console",
    50     major,
    51     (rtems_device_minor_number) 0
    52   );
    53 
     161  rtems_isr_entry dummy;
     162
     163  rtems_termios_initialize();
     164
     165  status = rtems_io_register_name("/dev/console", major, 0);
    54166  if (status != RTEMS_SUCCESSFUL)
    55167    rtems_fatal_error_occurred(status);
    56168
     169  rtems_interrupt_catch(mmconsole_txdone, MM_IRQ_UARTTX, &dummy);
     170  rtems_interrupt_catch(mmconsole_rxdone, MM_IRQ_UARTRX, &dummy);
     171  bsp_interrupt_vector_enable(MM_IRQ_UARTTX);
     172  bsp_interrupt_vector_enable(MM_IRQ_UARTRX);
     173
    57174  return RTEMS_SUCCESSFUL;
    58175}
    59176
    60 /*  is_character_ready
    61  *
    62  *  This routine returns TRUE if a character is available.
    63  *
    64  *  Input parameters: NONE
    65  *
    66  *  Output parameters:  NONE
    67  *
    68  *  Return values:
    69  */
    70 
    71 bool is_character_ready(
    72   char *ch
    73 )
    74 {
    75   return BSP_uart_is_character_ready(ch);
    76 }
    77 
    78 /*  inbyte
    79  *
    80  *  This routine reads a character from the SOURCE.
    81  *
    82  *  Input parameters: NONE
    83  *
    84  *  Output parameters:  NONE
    85  *
    86  *  Return values:
    87  *    character read from SOURCE
    88  */
    89 
    90 int inbyte( void )
    91 {
    92   /*
    93    *  If polling, wait until a character is available.
    94    */
    95 
    96   return BSP_uart_polled_read();
    97 }
    98 
    99 /*  outbyte
    100  *
    101  *  This routine transmits a character out the SOURCE.  It may support
    102  *  XON/XOFF flow control.
    103  *
    104  *  Input parameters:
    105  *    ch  - character to be transmitted
    106  *
    107  *  Output parameters:  NONE
    108  */
    109 
    110 void outbyte(
    111   char ch
    112 )
    113 {
    114   /*
    115    *  If polling, wait for the transmitter to be ready.
    116    *  Check for flow control requests and process.
    117    *  Then output the character.
    118    */
    119 
    120   BSP_uart_polled_write(ch);
    121 }
    122 
    123 /*
    124  *  Open entry point
    125  */
    126 
    127177rtems_device_driver console_open(
    128178  rtems_device_major_number major,
    129179  rtems_device_minor_number minor,
    130   void                    * arg
    131 )
    132 {
    133   return RTEMS_SUCCESSFUL;
    134 }
    135 
    136 /*
    137  *  Close entry point
    138  */
     180  void  *arg
     181)
     182{
     183  return rtems_termios_open(major, minor, arg, &mmconsole_callbacks);
     184}
    139185
    140186rtems_device_driver console_close(
    141187  rtems_device_major_number major,
    142188  rtems_device_minor_number minor,
    143   void                    * arg
    144 )
    145 {
    146   return RTEMS_SUCCESSFUL;
    147 }
    148 
    149 /*
    150  * read bytes from the serial port. We only have stdin.
    151  */
     189  void *arg
     190)
     191{
     192  return rtems_termios_close(arg);
     193}
    152194
    153195rtems_device_driver console_read(
    154196  rtems_device_major_number major,
    155197  rtems_device_minor_number minor,
    156   void                    * arg
    157 )
    158 {
    159   rtems_libio_rw_args_t *rw_args;
    160   char *buffer;
    161   int maximum;
    162   int count = 0;
    163 
    164   rw_args = (rtems_libio_rw_args_t *) arg;
    165 
    166   buffer = rw_args->buffer;
    167   maximum = rw_args->count;
    168 
    169   for (count = 0; count < maximum; count++) {
    170     buffer[ count ] = inbyte();
    171     if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
    172       buffer[ count++ ]  = '\n';
    173       break;
    174     }
    175   }
    176 
    177   rw_args->bytes_moved = count;
    178   return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
    179 }
    180 
    181 /*
    182  * write bytes to the serial port. Stdout and stderr are the same.
    183  */
     198  void *arg
     199)
     200{
     201  return rtems_termios_read(arg);
     202}
    184203
    185204rtems_device_driver console_write(
    186205  rtems_device_major_number major,
    187206  rtems_device_minor_number minor,
    188   void                    * arg
    189 )
    190 {
    191   int count;
    192   int maximum;
    193   rtems_libio_rw_args_t *rw_args;
    194   char *buffer;
    195 
    196   rw_args = (rtems_libio_rw_args_t *) arg;
    197 
    198   buffer = rw_args->buffer;
    199   maximum = rw_args->count;
    200 
    201   for (count = 0; count < maximum; count++) {
    202     if ( buffer[ count ] == '\n') {
    203       outbyte('\r');
    204     }
    205     outbyte( buffer[ count ] );
    206   }
    207 
    208   rw_args->bytes_moved = maximum;
    209   return 0;
    210 }
    211 
    212 /*
    213  *  IO Control entry point
    214  */
     207  void *arg
     208)
     209{
     210  return rtems_termios_write(arg);
     211}
    215212
    216213rtems_device_driver console_control(
    217214  rtems_device_major_number major,
    218215  rtems_device_minor_number minor,
    219   void                    * arg
    220 )
    221 {
    222   return RTEMS_SUCCESSFUL;
    223 }
    224 
    225 BSP_output_char_function_type BSP_output_char = BSP_uart_polled_write;
    226 BSP_polling_getchar_function_type BSP_poll_char = BSP_uart_polled_read;
     216  void *arg
     217)
     218{
     219  return rtems_termios_ioctl(arg);
     220}
  • c/src/lib/libbsp/lm32/shared/milkymist_console/uart.c

    r01f2692e rdce1032b  
    11/*
    2  *  Uart driver for Lattice Mico32 (lm32) UART
     2 *  Driver for Milkymist UART
    33 *
    44 *  The license and distribution terms for this file may be
     
    88 *  $Id$
    99 *
     10 *  COPYRIGHT (c) 2010 Sebastien Bourdeauducq
    1011 *  COPYRIGHT (c) Yann Sionneau <yann.sionneau@telecom-sudparis.eu> (GSoC 2010)
    1112 *  Telecom SudParis
    1213 */
    1314
     15#include <rtems.h>
     16#include <rtems/libio.h>
    1417#include "../include/system_conf.h"
    1518#include "uart.h"
    16 #include <rtems/libio.h>
    1719
    18 static inline int uartread(unsigned int reg)
    19 {
    20   return *((int*)(reg));
    21 }
    22 
    23 static inline void uartwrite(unsigned int reg, int value)
    24 {
    25   *((int*)(reg)) = value;
    26 }
     20bool BSP_uart_txbusy;
    2721
    2822void BSP_uart_init(int baud)
    2923{
    30 
    31   /* Set baud rate */
    32   uartwrite(MM_UART_DIV, CPU_FREQUENCY/baud/16);
     24  MM_WRITE(MM_UART_DIV, CPU_FREQUENCY/baud/16);
    3325}
    3426
     
    3628{
    3729  int ip;
    38   /* Wait until THR is empty. */
    39   uartwrite(MM_UART_RXTX, ch);
     30  rtems_interrupt_level level;
     31
     32  rtems_interrupt_disable(level);
     33  if (BSP_uart_txbusy) {
     34    /* wait for the end of the transmission by the IRQ-based driver */
     35    do {
     36      lm32_read_interrupts(ip);
     37    } while (!(ip & (1 << MM_IRQ_UARTTX)));
     38    lm32_interrupt_ack(1 << MM_IRQ_UARTTX);
     39  }
     40  MM_WRITE(MM_UART_RXTX, ch);
    4041  do {
    4142    lm32_read_interrupts(ip);
    42   } while (! (ip & MM_IRQ_UARTTX) );
    43   lm32_interrupt_ack(MM_IRQ_UARTTX);
     43  } while (!(ip & (1 << MM_IRQ_UARTTX)));
     44  /* if TX was busy, do not ack the IRQ
     45   * so that the IRQ-based driver ISR is run */
     46  if (!BSP_uart_txbusy)
     47    lm32_interrupt_ack(1 << MM_IRQ_UARTTX);
     48  rtems_interrupt_enable(level);
    4449}
    4550
    46 char BSP_uart_polled_read( void )
     51int BSP_uart_polled_read(void)
    4752{
    4853  int ip;
    49   /* Wait until there is a byte in RBR */
     54  char r;
     55  rtems_interrupt_level level;
     56
     57  rtems_interrupt_disable(level);
    5058  do {
    5159    lm32_read_interrupts(ip);
    52   } while(! (ip & MM_IRQ_UARTRX) );
    53   lm32_interrupt_ack(MM_IRQ_UARTRX);
    54   return (char) uartread(MM_UART_RXTX);
     60  } while (!(ip & (1 << MM_IRQ_UARTRX)));
     61  lm32_interrupt_ack(1 << MM_IRQ_UARTRX);
     62  r = MM_READ(MM_UART_RXTX);
     63  rtems_interrupt_enable(level);
     64
     65  return r;
    5566}
    56 
    57 char BSP_uart_is_character_ready(char *ch)
    58 {
    59   int ip;
    60   lm32_read_interrupts(ip);
    61   if (ip & MM_IRQ_UARTRX)
    62     {
    63       *ch = (char) uartread(MM_UART_RXTX);
    64       lm32_interrupt_ack(MM_IRQ_UARTRX);
    65       return true;
    66     }
    67   *ch = '0';
    68   return false;
    69 }
  • c/src/lib/libbsp/lm32/shared/milkymist_console/uart.h

    r01f2692e rdce1032b  
    1515#define _BSPUART_H
    1616
     17extern bool BSP_uart_txbusy;
     18
    1719void BSP_uart_init(int baud);
    18 
    19 #define MM_UART_RXTX    (0xe0000000)
    20 
    21 #define MM_UART_DIV     (0xe0000004)
    22 
    23 #define MM_IRQ_UARTTX   (0x00000010) /* 4 */
    24 #define MM_IRQ_UARTRX   (0x00000008) /* 3 */
     20void BSP_uart_polled_write(char ch);
     21int BSP_uart_polled_read(void);
    2522
    2623#endif /* _BSPUART_H */
  • c/src/lib/libbsp/lm32/shared/milkymist_framebuffer/framebuffer.c

    r01f2692e rdce1032b  
    1212 *  COPYRIGHT (c) Yann Sionneau <yann.sionneau@telecom-sudparis.eu> (GSoC 2010)
    1313 *  Telecom SudParis
     14 *  Copyright (c) 2011 Sebastien Bourdeauducq
    1415 */
    1516
     
    1819#include <errno.h>
    1920#include <sys/types.h>
    20 #include <pthread.h>
    2121#include <rtems.h>
    2222#include <bsp.h>
     
    2727#define FRAMEBUFFER_DEVICE_NAME "/dev/fb"
    2828
    29 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    30 
    31 static unsigned short int framebufferA[640*480] __attribute__((aligned(32)));
    32 static unsigned short int framebufferB[640*480] __attribute__((aligned(32)));
    33 static unsigned short int framebufferC[640*480] __attribute__((aligned(32)));
    34 
    35 static unsigned short int *frontbuffer = framebufferA;
    36 static unsigned short int *backbuffer = framebufferB;
    37 static unsigned short int *lastbuffer = framebufferC;
    38 
    39 static inline void fb_write(unsigned int reg, int value)
    40 {
    41   *((int*)reg) = value;
    42 }
    43 
    44 static inline int fb_read(unsigned int reg)
    45 {
    46   return *((int*)(reg));
    47 }
    48 
    49 /* screen information for the VGA driver */
    50 static struct fb_var_screeninfo fb_var =
    51 {
     29static unsigned short int framebufferA[1024*768]
     30  __attribute__((aligned(32)));
     31static unsigned short int framebufferB[1024*768]
     32  __attribute__((aligned(32)));
     33static unsigned short int framebufferC[1024*768]
     34  __attribute__((aligned(32)));
     35
     36static unsigned short int *frontbuffer;
     37static unsigned short int *backbuffer;
     38static unsigned short int *lastbuffer;
     39
     40static struct fb_var_screeninfo fb_var = {
    5241  .xres                = 640,
    5342  .yres                = 480,
     
    5544};
    5645
    57 static struct fb_fix_screeninfo fb_fix =
    58 {
    59 // this is initialized at start-up
    60   .smem_len            = 640 * 480 * 2,                      /* buffer size       */
    61 // 2 bytes per pixels
    62   .type                = FB_TYPE_VGA_PLANES,           /* type of display    */
    63   .visual              = FB_VISUAL_TRUECOLOR,        /* color scheme used */
    64   .line_length         = 80                            /* chars per line    */
     46static struct fb_fix_screeninfo fb_fix = {
     47  .smem_len            = 1024 * 768 * 2,
     48  .type                = FB_TYPE_VGA_PLANES,
     49  .visual              = FB_VISUAL_TRUECOLOR,
     50  .line_length         = 80
    6551};
    66 
    6752
    6853static int get_fix_screen_info( struct fb_fix_screeninfo *info )
     
    7863}
    7964
    80 
    81 rtems_device_driver frame_buffer_initialize(
    82 rtems_device_major_number  major,
    83 rtems_device_minor_number  minor,
    84 void *arg)
    85 {
    86   rtems_status_code status;
    87 
    88   printk( "frame buffer driver initializing..\n" );
    89 
    90   fb_fix.smem_start = (volatile char *)frontbuffer;
    91 
    92   fb_write(MM_VGA_BASEADDRESS, (unsigned int)frontbuffer);
    93   fb_write(MM_VGA_RESET, (unsigned int)0);
    94 
    95   /*
    96   * Register the device
    97   */
    98   status = rtems_io_register_name(FRAMEBUFFER_DEVICE_NAME, major, 0);
    99   if (status != RTEMS_SUCCESSFUL)
    100   {
    101     printk("Error registering frame buffer device!\n");
    102     rtems_fatal_error_occurred( status );
    103   }
    104 
    105   printk("VGA: initialized at resolution %dx%d\n", fb_var.xres, fb_var.yres);
    106   printk("VGA: framebuffers at 0x%08x 0x%08x 0x%08x\n",
    107   (unsigned int)frontbuffer, (unsigned int)backbuffer,
    108   (unsigned int)lastbuffer);
    109 
    110   /*
    111   * graphics hardware initialization goes here for non-console
    112   * devices
    113   */
    114   return RTEMS_SUCCESSFUL;
    115 }
    116 
    117 rtems_device_driver frame_buffer_close(
    118   rtems_device_major_number  major,
    119   rtems_device_minor_number  minor,
    120   void *arg
    121 )
    122 {
    123   if (pthread_mutex_unlock(&mutex) == 0){
    124   /* restore previous state.  for VGA this means return to text mode.
    125    * leave out if graphics hardware has been initialized in
    126    * frame_buffer_initialize() */
    127     fb_write(MM_VGA_RESET, MM_VGA_RESET_MODE);
    128     return RTEMS_SUCCESSFUL;
    129   }
    130   return RTEMS_UNSATISFIED;
    131 }
    132 
    133 rtems_device_driver frame_buffer_open(
    134   rtems_device_major_number  major,
    135   rtems_device_minor_number  minor,
    136   void *arg
    137 )
    138 {
    139   if (pthread_mutex_trylock(&mutex) == 0){
    140     fb_write(MM_VGA_RESET, (unsigned int)0);
    141     return RTEMS_SUCCESSFUL;
    142   }
    143   return RTEMS_UNSATISFIED;
    144 }
    145 
    146 static void vga_swap_buffers(void)
     65static void init_buffers(void)
     66{
     67  frontbuffer = framebufferA;
     68  backbuffer = framebufferB;
     69  lastbuffer = framebufferC;
     70}
     71
     72static void swap_buffers(void)
    14773{
    14874  unsigned short int *p;
    14975
    150   /*
    151   * Make sure last buffer swap has been executed.
    152   * Beware, DMA address registers of vgafb are incomplete
    153   * (only LSBs are present) so don't compare them directly
    154   * with CPU pointers.
    155   */
    156   while( fb_read(MM_VGA_BASEADDRESS_ACT) != fb_read(MM_VGA_BASEADDRESS) );
     76  /* Make sure last buffer swap has been executed */
     77  while (MM_READ(MM_VGA_BASEADDRESS_ACT) != MM_READ(MM_VGA_BASEADDRESS));
    15778
    15879  p = frontbuffer;
     
    16283
    16384  fb_fix.smem_start = (volatile char *)backbuffer;
    164 
    165   fb_write(MM_VGA_BASEADDRESS, (unsigned int)frontbuffer);
     85  MM_WRITE(MM_VGA_BASEADDRESS, (unsigned int)frontbuffer);
     86}
     87
     88static void set_video_mode(int mode)
     89{
     90  int hres, vres;
     91 
     92  MM_WRITE(MM_VGA_RESET, VGA_RESET);
     93  hres = vres = 0;
     94  switch(mode) {
     95    case 0: // 640x480, pixel clock: 25MHz
     96      hres = 640;
     97      vres = 480;
     98      MM_WRITE(MM_VGA_HSYNC_START, 656);
     99      MM_WRITE(MM_VGA_HSYNC_END, 752);
     100      MM_WRITE(MM_VGA_HSCAN, 799);
     101      MM_WRITE(MM_VGA_VSYNC_START, 491);
     102      MM_WRITE(MM_VGA_VSYNC_END, 493);
     103      MM_WRITE(MM_VGA_VSCAN, 523);
     104      MM_WRITE(MM_VGA_CLKSEL, 0);
     105      break;
     106    case 1: // 800x600, pixel clock: 50MHz
     107      hres = 800;
     108      vres = 600;
     109      MM_WRITE(MM_VGA_HSYNC_START, 848);
     110      MM_WRITE(MM_VGA_HSYNC_END, 976);
     111      MM_WRITE(MM_VGA_HSCAN, 1040);
     112      MM_WRITE(MM_VGA_VSYNC_START, 637);
     113      MM_WRITE(MM_VGA_VSYNC_END, 643);
     114      MM_WRITE(MM_VGA_VSCAN, 666);
     115      MM_WRITE(MM_VGA_CLKSEL, 1);
     116      break;
     117    case 2: // 1024x768, pixel clock: 65MHz
     118      hres = 1024;
     119      vres = 768;
     120      MM_WRITE(MM_VGA_HSYNC_START, 1048);
     121      MM_WRITE(MM_VGA_HSYNC_END, 1184);
     122      MM_WRITE(MM_VGA_HSCAN, 1344);
     123      MM_WRITE(MM_VGA_VSYNC_START, 771);
     124      MM_WRITE(MM_VGA_VSYNC_END, 777);
     125      MM_WRITE(MM_VGA_VSCAN, 806);
     126      MM_WRITE(MM_VGA_CLKSEL, 2);
     127      break;
     128  }
     129  if((hres != 0) && (vres != 0)) {
     130    MM_WRITE(MM_VGA_HRES, hres);
     131    MM_WRITE(MM_VGA_VRES, vres);
     132    fb_var.xres = hres;
     133    fb_var.yres = vres;
     134    memset(framebufferA, 0, hres*vres*2);
     135    memset(framebufferB, 0, hres*vres*2);
     136    memset(framebufferC, 0, hres*vres*2);
     137    MM_WRITE(MM_VGA_BURST_COUNT, hres*vres/16);
     138    MM_WRITE(MM_VGA_RESET, 0);
     139  } /* otherwise, leave the VGA controller in reset */
     140}
     141
     142rtems_device_driver frame_buffer_initialize(
     143  rtems_device_major_number major,
     144  rtems_device_minor_number minor,
     145  void *arg
     146)
     147{
     148  rtems_status_code status;
     149
     150  init_buffers();
     151  fb_fix.smem_start = (volatile char *)frontbuffer;
     152  MM_WRITE(MM_VGA_BASEADDRESS, (unsigned int)frontbuffer);
     153
     154  status = rtems_io_register_name(FRAMEBUFFER_DEVICE_NAME, major, 0);
     155  if (status != RTEMS_SUCCESSFUL) {
     156    printk("Error registering frame buffer device!\n");
     157    rtems_fatal_error_occurred( status );
     158  }
     159
     160  return RTEMS_SUCCESSFUL;
     161}
     162
     163rtems_device_driver frame_buffer_close(
     164  rtems_device_major_number major,
     165  rtems_device_minor_number minor,
     166  void *arg
     167)
     168{
     169  return RTEMS_SUCCESSFUL;
     170}
     171
     172rtems_device_driver frame_buffer_open(
     173  rtems_device_major_number major,
     174  rtems_device_minor_number minor,
     175  void *arg
     176)
     177{
     178  return RTEMS_SUCCESSFUL;
    166179}
    167180
    168181rtems_device_driver frame_buffer_read(
    169   rtems_device_major_number  major,
    170   rtems_device_minor_number  minor,
    171   void                      *arg
     182  rtems_device_major_number major,
     183  rtems_device_minor_number minor,
     184  void *arg
    172185)
    173186{
    174187  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
    175   rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
    176   memcpy(rw_args->buffer, (const void *) (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved);
     188  rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len)
     189    ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
     190  memcpy(rw_args->buffer, (const void *)(fb_fix.smem_start + rw_args->offset),
     191    rw_args->bytes_moved);
    177192  return RTEMS_SUCCESSFUL;
    178193}
    179194
    180195rtems_device_driver frame_buffer_write(
    181   rtems_device_major_number  major,
    182   rtems_device_minor_number  minor,
    183   void                      *arg
     196  rtems_device_major_number major,
     197  rtems_device_minor_number minor,
     198  void *arg
    184199)
    185200{
    186201  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
    187   rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
    188   memcpy( (void *) (fb_fix.smem_start + rw_args->offset), rw_args->buffer, rw_args->bytes_moved);
     202  rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len)
     203     ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
     204  memcpy((void *)(fb_fix.smem_start + rw_args->offset), rw_args->buffer,
     205    rw_args->bytes_moved);
    189206  return RTEMS_SUCCESSFUL;
    190207}
    191208
    192209rtems_device_driver frame_buffer_control(
    193   rtems_device_major_number  major,
    194   rtems_device_minor_number  minor,
    195   void                      *arg
     210  rtems_device_major_number major,
     211  rtems_device_minor_number minor,
     212  void *arg
    196213)
    197214{
    198215  rtems_libio_ioctl_args_t *args = arg;
    199216
    200   switch( args->command ) {
     217  switch (args->command) {
    201218    case FBIOGET_FSCREENINFO:
    202       args->ioctl_return =  get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer );
    203       break;
     219      args->ioctl_return =
     220        get_fix_screen_info((struct fb_fix_screeninfo *)args->buffer);
     221      return RTEMS_SUCCESSFUL;
    204222    case FBIOGET_VSCREENINFO:
    205       args->ioctl_return =  get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer );
    206       break;
    207     case FBIOPUT_VSCREENINFO:
    208       /* not implemented yet */
     223      args->ioctl_return =
     224        get_var_screen_info((struct fb_var_screeninfo *)args->buffer);
     225      return RTEMS_SUCCESSFUL;
     226    case FBIOSWAPBUFFERS:
     227      swap_buffers();
     228      args->ioctl_return = 0;
     229      return RTEMS_SUCCESSFUL;
     230    case FBIOSETBUFFERMODE:
     231      args->ioctl_return = 0;
     232      switch ((unsigned int)args->buffer) {
     233        case FB_SINGLE_BUFFERED:
     234          init_buffers();
     235          fb_fix.smem_start = (volatile char *)frontbuffer;
     236          MM_WRITE(MM_VGA_BASEADDRESS, (unsigned int)frontbuffer);
     237          return RTEMS_SUCCESSFUL;
     238        case FB_TRIPLE_BUFFERED:
     239          fb_fix.smem_start = (volatile char *)backbuffer;
     240          return RTEMS_SUCCESSFUL;
     241        default:
     242          return RTEMS_UNSATISFIED;
     243      }
     244    case FBIOSETVIDEOMODE:
     245      set_video_mode((int)args->buffer);
     246      return RTEMS_SUCCESSFUL;
     247    default:
    209248      args->ioctl_return = -1;
    210249      return RTEMS_UNSATISFIED;
    211     case FBIOGETCMAP:
    212       /* not implemented yet */
    213       args->ioctl_return = -1;
    214       return RTEMS_UNSATISFIED;
    215       break;
    216     case FBIOPUTCMAP:
    217       /* not implemented yet */
    218       args->ioctl_return = -1;
    219       return RTEMS_UNSATISFIED;
    220       break;
    221     case FBIOSWAPBUFFERS:
    222       vga_swap_buffers();
    223       args->ioctl_return = 0;
    224       break;
    225     case FBIOSETBUFFERMODE:
    226       args->ioctl_return = 0;
    227       switch ( (unsigned int)args->buffer ) {
    228         case FB_SINGLE_BUFFERED:
    229           fb_fix.smem_start = (volatile char *)frontbuffer;
    230           break;
    231         case  FB_TRIPLE_BUFFERED:
    232           fb_fix.smem_start = (volatile char *)backbuffer;
    233           break;
    234         default:
    235           printk("[framebuffer] : error no such buffer mode\n");
    236       }
    237       break;
    238     default:
    239      args->ioctl_return = 0;
    240      break;
    241250  }
    242   return RTEMS_SUCCESSFUL;
    243 }
    244 
     251}
     252
  • c/src/lib/libbsp/lm32/shared/milkymist_gpio/gpio.c

    r01f2692e rdce1032b  
    11/*  gpio.c
    22 *
    3  *  This file is the gpio driver for the Milkymist One board
     3 *  GPIO driver for the Milkymist One board
    44 *
    55 *  The license and distribution terms for this file may be
     
    99 *  $Id$
    1010 *
     11 *  COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
    1112 *  COPYRIGHT (c) Yann Sionneau <yann.sionneau@telecom-sudparis.eu> (GSoC 2010)
    1213 *  Telecom SudParis
    1314 */
     15
     16#define RTEMS_STATUS_CHECKS_USE_PRINTK
    1417
    1518#include <stdlib.h>
     
    1720#include <errno.h>
    1821#include <sys/types.h>
    19 #include <pthread.h>
    2022#include <rtems.h>
     23#include <rtems/status-checks.h>
    2124#include <bsp.h>
     25#include <rtems/libio.h>
    2226#include "../include/system_conf.h"
    23 #include <rtems/libio.h>
     27#include "milkymist_gpio.h"
    2428
    25 #define GPIO_DRIVER_TABLE_ENTRY { gpio_initialize, \
    26 gpio_open, gpio_close, gpio_read, gpio_write, gpio_control}
     29struct milkymist_gpio {
     30  char *name;
     31  unsigned int mask;
     32  bool readonly;
     33};
    2734
    28 #define LED1_DEVICE_NAME  "/dev/led1"
    29 #define LED2_DEVICE_NAME  "/dev/led2"
    30 #define BTN1_DEVICE_NAME  "/dev/btn1"
    31 #define BTN2_DEVICE_NAME  "/dev/btn2"
    32 #define BTN3_DEVICE_NAME  "/dev/btn3"
    33 
    34 static struct milkymist_gpio {
    35   rtems_device_minor_number minor;
    36   unsigned int *address;
    37   unsigned int offset;
    38   uint8_t readonly;
    39   pthread_mutex_t mutex;
    40 } gpio[5];
     35static const struct milkymist_gpio gpio[] = {
     36  {
     37    .name = "/dev/led1",
     38    .mask = GPIO_LED1,
     39    .readonly = false
     40  },
     41  {
     42    .name = "/dev/led2",
     43    .mask = GPIO_LED2,
     44    .readonly = false
     45  },
     46};
    4147
    4248rtems_device_driver gpio_initialize(
    43 rtems_device_major_number  major,
    44 rtems_device_minor_number  minor,
    45 void *arg)
     49  rtems_device_major_number major,
     50  rtems_device_minor_number minor,
     51  void *arg
     52)
    4653{
    47   rtems_status_code status;
     54  rtems_status_code sc;
     55  int i;
    4856
    49   printk( "gpio driver initializing..\n" );
    50 
    51   status = rtems_io_register_name(LED1_DEVICE_NAME, major, 0);
    52   if (status != RTEMS_SUCCESSFUL)
    53   {
    54     printk("Error registering gpio device led1\n");
    55     rtems_fatal_error_occurred( status );
     57  for (i=0;i<sizeof(gpio)/sizeof(struct milkymist_gpio);i++) {
     58    sc = rtems_io_register_name(gpio[i].name, major, i);
     59    RTEMS_CHECK_SC(sc, "create GPIO device");
    5660  }
    57   gpio[0].minor = 0;
    58   gpio[0].readonly = 0;
    59   gpio[0].offset = 0x00000001;
    60   gpio[0].address = (unsigned int *)0xe0001004;
    61   gpio[0].mutex = PTHREAD_MUTEX_INITIALIZER;
    62 
    63   status = rtems_io_register_name(LED2_DEVICE_NAME, major, 1);
    64   if (status != RTEMS_SUCCESSFUL)
    65   {
    66     printk("Error registering gpio device led2\n");
    67     rtems_fatal_error_occurred( status );
    68   }
    69   gpio[1].minor = 1;
    70   gpio[1].readonly = 0;
    71   gpio[1].offset = 0x00000002;
    72   gpio[1].address = (unsigned int *)0xe0001004;
    73   gpio[1].mutex = PTHREAD_MUTEX_INITIALIZER;
    74 
    75   status = rtems_io_register_name(BTN1_DEVICE_NAME, major, 2);
    76   if (status != RTEMS_SUCCESSFUL)
    77   {
    78     printk("Error registering gpio device btn1\n");
    79     rtems_fatal_error_occurred( status );
    80   }
    81   gpio[2].minor = 2;
    82   gpio[2].readonly = 1;
    83   gpio[2].offset = 0x00000001;
    84   gpio[2].address = (unsigned int *)0xe0001000;
    85   gpio[2].mutex = PTHREAD_MUTEX_INITIALIZER;
    86   status = rtems_io_register_name(BTN2_DEVICE_NAME, major, 3);
    87   if (status != RTEMS_SUCCESSFUL)
    88   {
    89     printk("Error registering gpio device btn2\n");
    90     rtems_fatal_error_occurred( status );
    91   }
    92   gpio[3].minor = 3;
    93   gpio[3].readonly = 1;
    94   gpio[3].address = (unsigned int *)0xe0001000;
    95   gpio[3].offset = 0x00000002;
    96   gpio[3].mutex = PTHREAD_MUTEX_INITIALIZER;
    97 
    98   status = rtems_io_register_name(BTN3_DEVICE_NAME, major, 4);
    99   if (status != RTEMS_SUCCESSFUL)
    100   {
    101     printk("Error registering gpio device btn3\n");
    102     rtems_fatal_error_occurred( status );
    103   }
    104 
    105   gpio[4].minor = 4;
    106   gpio[4].readonly = 1;
    107   gpio[4].offset = 0x00000004;
    108   gpio[4].address = (unsigned int *)0xe0001000;
    109   gpio[4].mutex = PTHREAD_MUTEX_INITIALIZER;
    11061
    11162  return RTEMS_SUCCESSFUL;
    11263}
    11364
    114 rtems_device_driver gpio_close(
    115   rtems_device_major_number  major,
    116   rtems_device_minor_number  minor,
     65rtems_device_driver gpio_read(
     66  rtems_device_major_number major,
     67  rtems_device_minor_number minor,
    11768  void *arg
    11869)
    11970{
    120   if (pthread_mutex_unlock(&gpio[minor].mutex) == 0){
     71  unsigned int data;
     72
     73  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
     74
     75  if (rw_args->offset > 0) {
     76    rw_args->bytes_moved = 0;
    12177    return RTEMS_SUCCESSFUL;
    12278  }
    123   return RTEMS_UNSATISFIED;
    124 }
    12579
    126 rtems_device_driver gpio_open(
    127   rtems_device_major_number  major,
    128   rtems_device_minor_number  minor,
    129   void *arg
    130 )
    131 {
    132   if (pthread_mutex_trylock(&gpio[minor].mutex) == 0){
    133     return RTEMS_SUCCESSFUL;
    134   }
    135   return RTEMS_UNSATISFIED;
    136 }
     80  rw_args->bytes_moved = 1;
    13781
     82  if (gpio[minor].readonly)
     83    data = MM_READ(MM_GPIO_IN);
     84  else
     85    data = MM_READ(MM_GPIO_OUT);
    13886
    139 rtems_device_driver gpio_read(
    140   rtems_device_major_number  major,
    141   rtems_device_minor_number  minor,
    142   void                      *arg
    143 )
    144 {
    145   rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
    146   rw_args->bytes_moved = 1;
    147  
    148   if ( *gpio[minor].address & gpio[minor].offset )
    149     *(uint8_t *)rw_args->buffer = 1;
     87  if (data & gpio[minor].mask)
     88    *(uint8_t *)rw_args->buffer = '1';
    15089  else
    151     *(uint8_t *)rw_args->buffer = 0;
    152  
     90    *(uint8_t *)rw_args->buffer = '0';
     91
    15392  return RTEMS_SUCCESSFUL;
    15493}
     
    15796  rtems_device_major_number  major,
    15897  rtems_device_minor_number  minor,
    159   void                      *arg
     98  void *arg
    16099)
    161100{
    162101  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
     102
     103  if (gpio[minor].readonly) {
     104    rw_args->bytes_moved = 0;
     105    return RTEMS_UNSATISFIED;
     106  }
     107
     108  if (rw_args->offset > 0) {
     109    rw_args->bytes_moved = 0;
     110    return RTEMS_SUCCESSFUL;
     111  }
     112
    163113  rw_args->bytes_moved = 1;
    164114
    165   if (gpio[minor].readonly)
    166     return RTEMS_UNSATISFIED;
    167 
    168   if ( *(uint8_t *)rw_args->buffer )
    169     *gpio[minor].address |= gpio[minor].offset;
     115  if (*(uint8_t *)rw_args->buffer == '1')
     116    MM_WRITE(MM_GPIO_OUT, MM_READ(MM_GPIO_OUT)|gpio[minor].mask);
    170117  else
    171     *gpio[minor].address &= ~gpio[minor].offset;
     118    MM_WRITE(MM_GPIO_OUT, MM_READ(MM_GPIO_OUT) & ~gpio[minor].mask);
    172119
    173120  return RTEMS_SUCCESSFUL;
    174121}
    175 
    176 rtems_device_driver gpio_control(
    177   rtems_device_major_number  major,
    178   rtems_device_minor_number  minor,
    179   void                      *arg
    180 )
    181 {
    182   rtems_libio_ioctl_args_t *args = arg;
    183 
    184   switch( args->command ) {
    185     default:
    186      args->ioctl_return = 0;
    187      break;
    188   }
    189   return RTEMS_SUCCESSFUL;
    190 }
    191 
  • c/src/lib/libbsp/lm32/shared/milkymist_networking/network.c

    r01f2692e rdce1032b  
    11/*
    2  *  RTEMS driver for Minimac ethernet IP-core of Milkymist SoC
     2 *  RTEMS driver for Minimac2 ethernet IP-core of Milkymist SoC
    33 *
    44 *  The license and distribution terms for this file may be
     
    1010 *  COPYRIGHT (c) Yann Sionneau <yann.sionneau@telecom-sudparis.eu> (GSoC 2010)
    1111 *  Telecom SudParis, France
     12 *  Copyright (C) 2011 Sebastien Bourdeauducq
    1213 */
    1314
     15#define RTEMS_STATUS_CHECKS_USE_PRINTK
    1416
    1517#include <bsp.h>
    16 #include "../include/system_conf.h"
    17 #include "bspopts.h"
     18#include <bsp/irq-generic.h>
    1819#include <stdio.h>
     20#include <string.h>
    1921#include <rtems/rtems_bsdnet.h>
     22#include <rtems/status-checks.h>
    2023#include <sys/param.h>
    2124#include <sys/mbuf.h>
     
    2326#include <sys/sockio.h>
    2427#include <net/if.h>
     28#include <net/ethernet.h>
    2529#include <netinet/in.h>
    2630#include <netinet/if_ether.h>
    2731#include <rtems.h>
     32#include "bspopts.h"
     33#include "../include/system_conf.h"
    2834#include "network.h"
    2935
    30 unsigned int mm_ether_crc32(const unsigned char *buffer, unsigned int len);
    31 static char rxbuff0[ETHERNET_FRAME_LENGTH] __attribute__((aligned (4)));
    32 static char rxbuff1[ETHERNET_FRAME_LENGTH] __attribute__((aligned (4)));
    33 static char rxbuff2[ETHERNET_FRAME_LENGTH] __attribute__((aligned (4)));
    34 static char rxbuff3[ETHERNET_FRAME_LENGTH] __attribute__((aligned (4)));
    35 
    36 static char *rxbuffs[4] = {rxbuff0, rxbuff1, rxbuff2, rxbuff3};
    37 
    38 static struct minimac_softc minimac_softc;
    39 
    40 static uint32_t rx_slot_state[4] = {MM_MINIMAC_STATE0, MM_MINIMAC_STATE1,
    41                             MM_MINIMAC_STATE2, MM_MINIMAC_STATE3};
    42 
    43 static uint32_t rx_slot_addr[4] = {MM_MINIMAC_ADDR0, MM_MINIMAC_ADDR1,
    44                             MM_MINIMAC_ADDR2, MM_MINIMAC_ADDR3};
    45 
    46 static uint32_t rx_slot_count[4] = {MM_MINIMAC_COUNT0, MM_MINIMAC_COUNT1,
    47                             MM_MINIMAC_COUNT2, MM_MINIMAC_COUNT3};
    48 #ifdef CPU_U32_FIX
    49 
    50 /*
    51  * Routine to align the received packet so that the ip header
    52  * is on a 32-bit boundary. Necessary for cpu's that do not
    53  * allow unaligned loads and stores and when the 32-bit DMA
    54  * mode is used.
    55  *
    56  * Transfers are done on word basis to avoid possibly slow byte
    57  * and half-word writes.
    58  *
    59  * Copied over from sonic.c driver
    60  */
    61 
    62 void ipalign(struct mbuf *m)
    63 {
    64   unsigned int *first, *last, data;
    65   unsigned int tmp = 0;
    66 
    67   if ((((int) m->m_data) & 2) && (m->m_len)) {
    68     last = (unsigned int *) ((((int) m->m_data) + m->m_len + 8) & ~3);
    69     first = (unsigned int *) (((int) m->m_data) & ~3);
    70     tmp = *first << 16;
    71     first++;
    72     do {
    73       data = *first;
    74       *first = tmp | (data >> 16);
    75       tmp = data << 16;
    76       first++;
    77     } while (first <= last);
    78 
    79     m->m_data = (caddr_t)(((int) m->m_data) + 2);
    80   }
    81 }
    82 #endif
    83 
    84 static inline int minimac_read(unsigned int reg)
    85 {
    86   return *((int*)(reg));
    87 }
    88 
    89 static inline void minimac_write(unsigned int reg, int value)
    90 {
    91   *((int*)reg) = value;
    92 }
    93 
    94 int rtems_minimac_driver_attach (struct rtems_bsdnet_ifconfig *config,
     36#define CTS_EVENT             RTEMS_EVENT_1
     37#define RX_EVENT              RTEMS_EVENT_1
     38#define START_TRANSMIT_EVENT  RTEMS_EVENT_2
     39
     40static struct arpcom arpcom;
     41static rtems_id rx_daemon_id;
     42static rtems_id tx_daemon_id;
     43
     44static void minimac_init(void *arg);
     45static int minimac_ioctl(struct ifnet *ifp, ioctl_command_t command,
     46  caddr_t data);
     47static void minimac_start(struct ifnet *ifp);
     48
     49static void rx_daemon(void *arg);
     50static void tx_daemon(void *arg);
     51static rtems_isr rx_interrupt_handler(rtems_vector_number vector);
     52static rtems_isr tx_interrupt_handler(rtems_vector_number vector);
     53
     54static bool validate_mac(const char *m)
     55{
     56  int i;
     57 
     58  for(i=0;i<6;i++)
     59    if((m[i] != 0x00) && (m[i] != 0xff))
     60      return true;
     61  return false;
     62}
     63
     64static const char *get_mac_address(void)
     65{
     66  const char *flash_mac = (const char *)FLASH_OFFSET_MAC_ADDRESS;
     67  static const char fallback_mac[6] = { 0x10, 0xe2, 0xd5, 0x00, 0x00, 0x00 };
     68 
     69  if(validate_mac(flash_mac))
     70    return flash_mac;
     71  else {
     72    printk("Warning: using fallback MAC address\n");
     73    return fallback_mac;
     74  }
     75}
     76
     77int rtems_minimac_driver_attach(struct rtems_bsdnet_ifconfig *config,
    9578  int attaching)
    9679{
    97   struct minimac_softc *sc;
    9880  struct ifnet *ifp;
    99  
    100 
    101   if (!attaching) {
    102     printk ("MINIMAC driver cannot be detached.\n");
     81  rtems_isr_entry dummy;
     82  int i;
     83  static int registered;
     84  uint8_t *tx_buffer = (uint8_t *)MINIMAC_TX_BASE;
     85
     86  if(!attaching) {
     87    printk("Minimac driver cannot be detached.\n");
    10388    return 0;
    10489  }
    10590
    106   sc = &minimac_softc;
    107   ifp = &(sc->arpcom.ac_if);
    108 
    109   if (sc->registered) {
    110     printk ("Driver already in use.\n");
     91  ifp = &(arpcom.ac_if);
     92
     93  if(registered) {
     94    printk("Minimac driver already in use.\n");
    11195    return 0;
    11296  }
    113 
    114   sc->registered = 1;
    115 
    116   /*
    117    *  Mac address of Milkymist One board is 1 by default
    118    */
    119 
    120   sc->arpcom.ac_enaddr[0] = 0x00;
    121   sc->arpcom.ac_enaddr[1] = 0x23;
    122   sc->arpcom.ac_enaddr[2] = 0x8b;
    123   sc->arpcom.ac_enaddr[3] = 0x47;
    124   sc->arpcom.ac_enaddr[4] = 0x86;
    125   sc->arpcom.ac_enaddr[5] = 0x20;
    126   ifp->if_softc = sc;
     97  registered = 1;
     98
     99  memcpy(arpcom.ac_enaddr, get_mac_address(), 6);
    127100  ifp->if_mtu = ETHERMTU;
    128101  ifp->if_unit = 0;
     
    135108  ifp->if_snd.ifq_maxlen = ifqmaxlen;
    136109
    137   if_attach (ifp);
     110  if_attach(ifp);
    138111  ether_ifattach(ifp);
    139   printk("[minimac] Ethernet driver attached\n");
     112
     113  rx_daemon_id = rtems_bsdnet_newproc("mrxd", 4096, rx_daemon, NULL);
     114  tx_daemon_id = rtems_bsdnet_newproc("mtxd", 4096, tx_daemon, NULL);
     115  rtems_interrupt_catch(rx_interrupt_handler, MM_IRQ_ETHRX, &dummy);
     116  rtems_interrupt_catch(tx_interrupt_handler, MM_IRQ_ETHTX, &dummy);
     117 
     118  MM_WRITE(MM_MINIMAC_STATE0, MINIMAC_STATE_LOADED);
     119  MM_WRITE(MM_MINIMAC_STATE1, MINIMAC_STATE_LOADED);
     120
     121  for(i=0;i<7; i++)
     122    tx_buffer[i] = 0x55;
     123  tx_buffer[7] = 0xd5;
     124  MM_WRITE(MM_MINIMAC_SETUP, 0);
     125  rtems_event_send(tx_daemon_id, CTS_EVENT);
     126 
     127  bsp_interrupt_vector_enable(MM_IRQ_ETHRX);
     128  bsp_interrupt_vector_enable(MM_IRQ_ETHTX);
     129
    140130  return 1;
    141131}
     
    143133static void minimac_start(struct ifnet *ifp)
    144134{
    145   struct minimac_softc *sc = ifp->if_softc;
    146   rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
     135  rtems_event_send(tx_daemon_id, START_TRANSMIT_EVENT);
    147136  ifp->if_flags |= IFF_OACTIVE;
    148 //  printk("[minimac] start();\n");
    149 }
    150 
    151 /*
    152  *  Initialize and start the device
    153  */
    154 static void minimac_init (void *arg)
    155 {
    156   struct minimac_softc *sc = arg;
    157   struct ifnet *ifp = &sc->arpcom.ac_if;
    158   unsigned char j;
    159   if (sc->txDaemonTid == 0) {
    160     sc->txDaemonTid = rtems_bsdnet_newproc ("MINIMACtx", 4096, minimac_txDaemon, sc);
    161     sc->rxDaemonTid = rtems_bsdnet_newproc ("MINIMACrx", 4096, minimac_rxDaemon, sc);
    162     set_vector(minimac_rx_interrupt_handler, IRQ_ETHRX, 1);
    163     set_vector(minimac_tx_interrupt_handler, IRQ_ETHTX, 1);
    164     lm32_interrupt_unmask(MM_ETHRX_IRQMASK);
    165     lm32_interrupt_unmask(MM_ETHTX_IRQMASK);
    166   }
    167  
    168   /*   
    169    *  Tell the world that we're running.
     137}
     138
     139static void minimac_init(void *arg)
     140{
     141  struct ifnet *ifp = &arpcom.ac_if;
     142  ifp->if_flags |= IFF_RUNNING;
     143}
     144
     145static void minimac_stop(void)
     146{
     147  struct ifnet *ifp = &arpcom.ac_if;
     148  ifp->if_flags &= ~IFF_RUNNING;
     149}
     150
     151static int minimac_ioctl(struct ifnet *ifp, ioctl_command_t command,
     152  caddr_t data)
     153{
     154  int error;
     155 
     156  error = 0;
     157  switch (command) {
     158    case SIOCGIFADDR:
     159    case SIOCSIFADDR:
     160      ether_ioctl(ifp, command, data);
     161      break;
     162
     163    case SIOCSIFFLAGS:
     164      switch(ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
     165        case IFF_RUNNING:
     166          minimac_stop();
     167          break;
     168        case IFF_UP:
     169          minimac_init(NULL);
     170          break;
     171        case IFF_UP | IFF_RUNNING:
     172          minimac_stop();
     173          minimac_init(NULL);
     174          break;
     175        default:
     176          break;
     177      }
     178      break;
     179
     180    default:
     181      error = EINVAL;
     182      break;
     183  }
     184  return error;
     185}
     186
     187
     188static rtems_isr rx_interrupt_handler(rtems_vector_number vector)
     189{
     190  /* Deassert IRQ line.
     191   * The RX daemon will then read all the slots we marked as empty.
    170192   */
    171   ifp->if_flags |= IFF_RUNNING;
    172 
    173   /*
    174    *  Start the receiver and transmitter
    175    */
    176 
    177   lm32_interrupt_ack( MM_ETHTX_IRQMASK | MM_ETHRX_IRQMASK );
    178   minimac_write(MM_MINIMAC_TXREMAINING, 0);
    179 
    180   for (j = 0 ; j < NB_RX_SLOTS ; j++) {
    181     minimac_write(rx_slot_addr[j], (unsigned int)rxbuffs[j]);
    182     minimac_write(rx_slot_state[j], MINIMAC_STATE_LOADED);
    183   }
    184  
    185 
    186   minimac_write(MM_MINIMAC_SETUP, 0);
    187   rtems_event_send(sc->rxDaemonTid, INTERRUPT_EVENT);
    188 }
    189 
    190 static void minimac_stop (struct minimac_softc *sc)
    191 {
    192   struct ifnet *ifp = &sc->arpcom.ac_if;
    193   unsigned char j;
    194   ifp->if_flags &= ~IFF_RUNNING;
    195 
    196   /*
    197    *  Shuts down receiver and transmitter
    198    */
    199   for (j = 0 ; j < NB_RX_SLOTS ; j++)
    200     minimac_write(rx_slot_state[j], MINIMAC_STATE_EMPTY);
    201   minimac_write(MM_MINIMAC_TXREMAINING, 0);
    202   minimac_write(MM_MINIMAC_SETUP, MINIMAC_SETUP_RXRST | MINIMAC_SETUP_TXRST);
    203 }
    204 
    205 static int minimac_ioctl(struct ifnet *ifp, ioctl_command_t command, caddr_t data)
    206 {
    207 
    208         struct minimac_softc *sc = ifp->if_softc;
    209         int error = 0;
    210         switch (command) {
    211         case SIOCGIFADDR:
    212         case SIOCSIFADDR:
    213                 ether_ioctl (ifp, command, data);
    214                 break;
    215 
    216         case SIOCSIFFLAGS:
    217                 switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
    218                 case IFF_RUNNING:
    219                         minimac_stop (sc);
    220                         break;
    221 
    222                 case IFF_UP:
    223                         minimac_init (sc);
    224                         break;
    225 
    226                 case IFF_UP | IFF_RUNNING:
    227                         minimac_stop (sc);
    228                         minimac_init (sc);
    229                         break;
    230 
    231                 default:
    232                         break;
    233                 }   
    234                 break;
    235 
    236         case SIO_RTEMS_SHOW_STATS:
    237                 minimac_stats (sc);
    238                 break;
    239  
    240         /*
    241          * FIXME: All sorts of multicast commands need to be added here!
    242          */
    243         default:
    244                 error = EINVAL;
    245                 break;
    246         }
    247         return error;
    248 
    249 
    250 }
    251 
    252 rtems_isr minimac_rx_interrupt_handler(rtems_vector_number vector)
    253 {
    254   unsigned int ip;
    255   struct minimac_softc *sc = &minimac_softc;
    256   lm32_read_interrupts(ip);
    257   if (ip & MM_ETHRX_IRQMASK) {
    258     lm32_interrupt_mask(MM_ETHRX_IRQMASK);
    259     rtems_event_send(sc->rxDaemonTid, INTERRUPT_EVENT);
    260     sc->rxInterrupts++; // update stats
    261   }
    262 }
    263 
    264 rtems_isr minimac_tx_interrupt_handler(rtems_vector_number vector)
    265 {
    266   int ip;
    267   struct minimac_softc *sc = &minimac_softc;
    268   lm32_read_interrupts(ip);
    269   if (ip & MM_ETHTX_IRQMASK) {
    270     lm32_interrupt_ack(MM_ETHTX_IRQMASK);
    271     rtems_event_send(sc->txDaemonTid, INTERRUPT_EVENT);
    272     sc->txInterrupts++; // update stats
    273   }
    274 }
    275 
    276 
    277 static void minimac_rxDaemon(void *arg)
    278 {
    279   struct ifnet *ifp = &minimac_softc.arpcom.ac_if;
     193  if(MM_READ(MM_MINIMAC_STATE0) == MINIMAC_STATE_PENDING)
     194    MM_WRITE(MM_MINIMAC_STATE0, MINIMAC_STATE_EMPTY);
     195  if(MM_READ(MM_MINIMAC_STATE1) == MINIMAC_STATE_PENDING)
     196    MM_WRITE(MM_MINIMAC_STATE1, MINIMAC_STATE_EMPTY);
     197
     198  rtems_event_send(rx_daemon_id, RX_EVENT);
     199
     200  lm32_interrupt_ack(1 << MM_IRQ_ETHRX);
     201}
     202
     203static void receive_packet(uint8_t *buffer, int length)
     204{
     205  struct ifnet *ifp = &arpcom.ac_if;
     206  struct mbuf *m;
     207  struct ether_header *eh;
     208  uint32_t computed_crc, net_crc;
     209 
     210  if(length < 64) {
     211    printk("Warning: Ethernet packet too short\n");
     212    return;
     213  }
     214
     215  length -= 4; /* strip CRC */
     216  net_crc = ((uint32_t)buffer[length])
     217    | ((uint32_t)buffer[length+1] << 8)
     218    | ((uint32_t)buffer[length+2] << 16)
     219    | ((uint32_t)buffer[length+3] << 24);
     220  length -= 8; /* strip preamble */
     221  computed_crc = ether_crc32_le(&buffer[8], length) ^ 0xffffffff;
     222  if(computed_crc == net_crc) {
     223    MGETHDR(m, M_WAIT, MT_DATA);
     224    MCLGET(m, M_WAIT);
     225    length -= sizeof(struct ether_header); /* strip Ethernet header */
     226    memcpy(m->m_data, &buffer[8+sizeof(struct ether_header)], length);
     227    m->m_len = m->m_pkthdr.len = length;
     228    m->m_pkthdr.rcvif = ifp;
     229    eh = (struct ether_header *)&buffer[8];
     230    ether_input(ifp, eh, m);
     231  } else
     232    printk("Ethernet CRC error: got %08x expected %08x (len=%d)\n",
     233      net_crc, computed_crc, length);
     234}
     235
     236static void rx_daemon(void *arg)
     237{
    280238  rtems_event_set events;
    281   struct minimac_softc *sc = &minimac_softc;
    282   for (;;) {
    283     uint32_t *buf;
    284     int rxlen;
    285     uint8_t j;
    286     struct mbuf *m;
    287     struct ether_header *eh;
    288     rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
    289     RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &events);
    290     if(minimac_read(MM_MINIMAC_SETUP) & MINIMAC_SETUP_RXRST ) {
    291       printk("Minimac RX FIFO overflow!\n");
    292       minimac_write(MM_MINIMAC_SETUP, 0);
    293       lm32_interrupt_ack(MM_ETHRX_IRQMASK);
    294       lm32_interrupt_unmask(MM_ETHRX_IRQMASK);
    295       sc->txFifoFull++; // update stats
     239 
     240  while(1) {
     241    rtems_bsdnet_event_receive(RX_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT,
     242      RTEMS_NO_TIMEOUT, &events);
     243
     244    if(MM_READ(MM_MINIMAC_STATE0) == MINIMAC_STATE_EMPTY) {
     245      receive_packet((uint8_t *)MINIMAC_RX0_BASE, MM_READ(MM_MINIMAC_COUNT0));
     246      MM_WRITE(MM_MINIMAC_STATE0, MINIMAC_STATE_LOADED);
    296247    }
    297 
    298     for (j = 0 ; j < NB_RX_SLOTS ; j++) {
    299       if (minimac_read(rx_slot_state[j]) == MINIMAC_STATE_PENDING) {
    300         __asm__ volatile( /* Invalidate Level-1 data cache */
    301           "wcsr DCC, r0\n"
    302           "nop\n"
    303         );
    304         rxlen = minimac_read(rx_slot_count[j]);
    305         rxlen -= 8; // we drop the preamble
    306         MGETHDR(m, M_WAIT, MT_DATA);
    307         MCLGET(m, M_WAIT);
    308         m->m_pkthdr.rcvif = ifp;
    309         buf = (uint32_t *) mtod(m, uint32_t*);
    310         memcpy(buf, (uint8_t *)minimac_read(rx_slot_addr[j]) + 8, rxlen);
    311         m->m_len = m->m_pkthdr.len = rxlen - sizeof(uint32_t) - sizeof(struct ether_header);
    312 
    313         minimac_write(rx_slot_state[j], MINIMAC_STATE_EMPTY);
    314         minimac_write(rx_slot_state[j], MINIMAC_STATE_LOADED);
    315         eh = mtod(m, struct ether_header*);
    316         m->m_data += sizeof(struct ether_header);
    317 #ifdef  CPU_U32_FIX
    318         ipalign(m);
    319 #endif
    320         ether_input(ifp, eh, m);
    321       }
     248    if(MM_READ(MM_MINIMAC_STATE1) == MINIMAC_STATE_EMPTY) {
     249      receive_packet((uint8_t *)MINIMAC_RX1_BASE, MM_READ(MM_MINIMAC_COUNT1));
     250      MM_WRITE(MM_MINIMAC_STATE1, MINIMAC_STATE_LOADED);
    322251    }
    323     lm32_interrupt_ack(MM_ETHRX_IRQMASK); // we ack once for all the rx interruptions
    324     lm32_interrupt_unmask(MM_ETHRX_IRQMASK);
    325   }
    326 }
    327 static void minimac_txDaemon(void *arg)
    328 {
    329   struct ifnet *ifp = &minimac_softc.arpcom.ac_if;
     252  }
     253}
     254
     255/* RTEMS apparently doesn't support m_length() ... */
     256static int copy_mbuf_chain(struct mbuf *m, uint8_t *target)
     257{
     258  int len;
     259
     260  len = 0;
     261  while(m != NULL) {
     262    if(m->m_len > 0) {
     263      m_copydata(m, 0, m->m_len, (caddr_t)(target + len));
     264      len += m->m_len;
     265    }
     266    m = m->m_next;
     267  }
     268  return len;
     269}
     270
     271static void send_packet(struct ifnet *ifp, struct mbuf *m)
     272{
     273  unsigned int len;
     274  unsigned int crc;
     275  uint8_t *tx_buffer = (uint8_t *)(MINIMAC_TX_BASE+8);
     276 
     277  len = copy_mbuf_chain(m, tx_buffer);
     278  for(;len<60;len++)
     279    tx_buffer[len] = 0x00; // Padding
     280
     281  crc = ether_crc32_le(tx_buffer, len) ^ 0xffffffff;
     282
     283  tx_buffer[len] = crc & 0xff;
     284  tx_buffer[len+1] = (crc & 0xff00) >> 8;
     285  tx_buffer[len+2] = (crc & 0xff0000) >> 16;
     286  tx_buffer[len+3] = crc >> 24;
     287
     288  len += 4; // We add 4 bytes of CRC32
     289
     290  MM_WRITE(MM_MINIMAC_TXCOUNT, len + 8);
     291}
     292
     293static rtems_isr tx_interrupt_handler(rtems_vector_number vector)
     294{
     295  lm32_interrupt_ack(1 << MM_IRQ_ETHTX);
     296  rtems_event_send(tx_daemon_id, CTS_EVENT);
     297}
     298
     299static void tx_daemon(void *arg)
     300{
     301  struct ifnet *ifp = &arpcom.ac_if;
    330302  rtems_event_set events;
    331303  struct mbuf *m;
    332   int txq;
    333 
    334   for (;;) {
    335     rtems_bsdnet_event_receive (START_TRANSMIT_EVENT | INTERRUPT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events);
    336     for (;;) {
    337       txq = 2048;
    338 
    339       if (txq < ifp->if_mtu)
     304 
     305  while(1) {
     306    rtems_bsdnet_event_receive(START_TRANSMIT_EVENT,
     307      RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events);
     308    while(1) {
     309      IF_DEQUEUE(&ifp->if_snd, m);
     310      if(m == NULL)
    340311        break;
    341 
    342       IF_DEQUEUE(&ifp->if_snd, m);
    343 
    344       if (!m)
    345         break;
    346       minimac_sendpacket(ifp, m);
     312      rtems_bsdnet_event_receive(CTS_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT,
     313        RTEMS_NO_TIMEOUT, &events);
     314      send_packet(ifp, m);
    347315      m_freem(m);
    348316    }
    349   ifp->if_flags &= ~IFF_OACTIVE;
    350   }
    351 }
    352 
    353 static void minimac_stats(struct minimac_softc *sc)
    354 {
    355 
    356 }
    357 
    358 
    359 static void minimac_sendpacket(struct ifnet *ifp, struct mbuf *m)
    360 {
    361   struct mbuf *nm = m;
    362   struct minimac_softc *sc = &minimac_softc;
    363   unsigned int len = 0;
    364   struct mm_packet p;
    365   unsigned int crc;
    366   uint8_t i;
    367   for (i = 0 ; i < 7 ; i++) // Preamble
    368     p.preamble[i] = 0x55;
    369   p.preamble[7] = 0xd5;
    370  
    371   do
    372     {
    373       unsigned int mlen;
    374       mlen = nm->m_len;
    375       if (nm->m_len > 0) {
    376         m_copydata(nm, 0, mlen, p.raw_data + len);
    377         len += nm->m_len;
    378       }
    379 
    380     } while ( (nm = nm->m_next) != 0 );
    381     for ( ; len < 60 ; len++)
    382       p.raw_data[len] = 0x00; // Padding
    383 
    384     crc = mm_ether_crc32((uint8_t *)p.raw_data, len); // CRC32
    385 
    386     p.raw_data[len] = crc & 0xff;
    387     p.raw_data[len+1] = (crc & 0xff00) >> 8;
    388     p.raw_data[len+2] = (crc & 0xff0000) >> 16;
    389     p.raw_data[len+3] = crc >> 24;
    390    
    391     len += 4; // We add 4 bytes of CRC32
    392 
    393     if (len + 8 < 64) {
    394       printk("[minimac] Packet is too small !\n");
    395       sc->txErrors++; // update stats
    396       return;
    397     }
    398    
    399     minimac_write(MM_MINIMAC_TXADR, (unsigned int)&p);
    400     minimac_write(MM_MINIMAC_TXREMAINING, (unsigned int)(len + 8));
    401 }
     317    ifp->if_flags &= ~IFF_OACTIVE;
     318  }
     319}
  • c/src/lib/libbsp/lm32/shared/milkymist_networking/network.h

    r01f2692e rdce1032b  
    1414
    1515
    16 #ifndef _MM_NETWORKING_H_
    17 #define _MM_NETWORKING_H_
    18 
    19 #include "../include/system_conf.h"
    20 
    21 #define IRQ_ETHRX 11
    22 #define IRQ_ETHTX 12
    23 
    24 #define INTERRUPT_EVENT RTEMS_EVENT_1
    25 #define START_TRANSMIT_EVENT  RTEMS_EVENT_2
    26 
    27 #define MINIMAC_STATE_EMPTY (0x0)
    28 #define MINIMAC_STATE_LOADED  (0x1)
    29 #define MINIMAC_STATE_PENDING (0x2)
    30 
    31 #define MINIMAC_SETUP_RXRST (0x1)
    32 #define MINIMAC_SETUP_TXRST (0x2)
    33 
    34 #define NB_RX_SLOTS 4
    35 
    36 #define MM_ETHTX_IRQMASK  (1 << IRQ_ETHTX)
    37 #define MM_ETHRX_IRQMASK  (1 << IRQ_ETHRX)
    38 #define ETHERNET_FRAME_LENGTH 1532
    39 
    40 struct mm_packet {
    41   unsigned char preamble[8];
    42   char raw_data[MLEN];
    43 } __attribute__((aligned(4), packed));
    44 
    45 struct minimac_softc {
    46 
    47   struct arpcom arpcom;
    48   uint8_t registered;
    49 
    50   /*
    51    *  Statistics
    52    */
    53 
    54   rtems_id  rxDaemonTid;
    55   rtems_id  txDaemonTid;
    56 
    57   unsigned long int rxInterrupts;
    58   unsigned long int txInterrupts;
    59   unsigned long int rxedPackets;
    60   unsigned long int txFifoFull;
    61   unsigned long int txErrors;
    62 };
     16#ifndef __MILKYMIST_NETWORKING_H_
     17#define __MILKYMIST_NETWORKING_H_
    6318
    6419int rtems_minimac_driver_attach (struct rtems_bsdnet_ifconfig *, int);
    6520
    66 static void minimac_start(struct ifnet *);
    67 static void minimac_init(void *);
    68 static int minimac_ioctl(struct ifnet *, ioctl_command_t, caddr_t);
    69 static void minimac_stop(struct minimac_softc *);
    70 
    71 static void minimac_txDaemon(void *);
    72 static void minimac_rxDaemon(void *);
    73 static void minimac_sendpacket(struct ifnet *, struct mbuf *);
    74 
    75 static rtems_isr minimac_rx_interrupt_handler (rtems_vector_number);
    76 static rtems_isr minimac_tx_interrupt_handler (rtems_vector_number);
    77 
    78 static void minimac_stats(struct minimac_softc *);
    79 
    8021#endif
  • c/src/lib/libbsp/lm32/shared/milkymist_timer/timer.c

    r01f2692e rdce1032b  
    2626#include "../../shared/clock/clock.h"
    2727
    28 static inline int timerread(unsigned int reg)
    29 {
    30   return *((int*)(reg));
    31 }
    32 
    33 static inline void timerwrite(unsigned int reg, int value)
    34 {
    35   *((int*)reg) = value;
    36 }
    37 
    3828bool benchmark_timer_find_average_overhead;
    3929
    40 void benchmark_timer_initialize( void )
     30void benchmark_timer_initialize(void)
    4131{
    42   timerwrite(MM_TIMER1_COMPARE, 0xffffffff);
    43   timerwrite(MM_TIMER1_COUNTER, 0);
    44   timerwrite(MM_TIMER1_CONTROL, TIMER_ENABLE);
     32  MM_WRITE(MM_TIMER1_COMPARE, 0xffffffff);
     33  MM_WRITE(MM_TIMER1_COUNTER, 0);
     34  MM_WRITE(MM_TIMER1_CONTROL, TIMER_ENABLE);
    4535}
    4636
     
    6050#define LEAST_VALID       4  /* Don't trust a clicks value lower than this */
    6151
    62 uint32_t benchmark_timer_read( void )
     52uint32_t benchmark_timer_read(void)
    6353{
    6454  uint32_t ticks;
    6555  uint32_t total;
    66   ticks = timerread(MM_TIMER1_COUNTER);
     56
     57  ticks = MM_READ(MM_TIMER1_COUNTER);
    6758  if (ticks == 0xffffffff)
    6859    printk("Timer overflow!\n");
     
    7061  total = ticks / (CPU_FREQUENCY / 1000000);
    7162
    72   if ( benchmark_timer_find_average_overhead == true )
     63  if (benchmark_timer_find_average_overhead)
    7364    return total;
    7465  else
    7566  {
    76     if ( total < LEAST_VALID )
     67    if (total < LEAST_VALID)
    7768      return 0;
    7869
    7970    return (total - AVG_OVERHEAD);
    80 
    8171  }
    8272}
  • c/src/lib/libbsp/lm32/shared/start/start.S

    r01f2692e rdce1032b  
    146146.end_clear_bss:
    147147        mvi     r1, 0
     148        be      r4, r0, .no_rescue
     149        mvhi    r1, hi(.rescue_str)
     150        ori     r1, r1, lo(.rescue_str)
     151.no_rescue:
    148152        mvhi    r7, hi(boot_card)
    149153        ori     r7, r7, lo(boot_card)
    150154        call    r7
    151155        # boot_card returns when RTEMS is shutdown
    152 #if ON_SIMULATOR
    153     #if defined(ON_GDB_SIM)
    154         #define SYS_exit        1
    155         mvi     r8, SYS_exit
    156         scall
    157     #else
    158         # on qemu-lm32
    159         #define SYS_CTRL_REG 0xffff0000
    160         mvhi    r7, hi(SYS_CTRL_REG)
    161         ori     r7, r7, lo(SYS_CTRL_REG)
    162         sw      (r7+0), r0
    163     #endif
    164 #endif
    165 
    166156.dead_end:
    167157        bi      .dead_end
    168158
     159.section .rodata
     160.rescue_str:
     161        .ascii "rescue"
     162
  • c/src/lib/libbsp/lm32/shared/startup/bspstart.c

    r01f2692e rdce1032b  
    3636 */
    3737
    38 void bsp_start( void )
     38void bsp_start(void)
    3939{
    40   /* Setup console baud rate which we derive from
    41      Mico System Builder (MSB) generated system_conf.h */
     40  /* Setup console baud rate */
    4241  BSP_uart_init(UART_BAUD_RATE);
    4342}
Note: See TracChangeset for help on using the changeset viewer.