OpenCores
URL https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.storage/] [sdram2hibi/] [1.0/] [drv/] [sdram_drv.c] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
// **************************************************************************
2
// File             : sdram_drv.c
3
// Authors          : Antti Kojo
4
// Date             : 12.06.2009
5
// Decription       : SDRAM contoller driver for eCos
6
// Version history  : 12.06.2009    ank    Original version
7
// **************************************************************************
8
 
9
#include <cyg/kernel/kapi.h>
10
#include <cyg/hal/hal_intr.h>
11
#include <assert.h>
12
#include "tut_n2h_regs.h"
13
#include "sdram_drv.h"
14
#include "N2H_registers_and_macros.h"
15
#include "types.h"
16
#include "comm.h"
17
 
18
#define SDRAM_CONFIG_SENDBUF_SIZE      (4)
19
#define SDRAM_READ_CONFIG_WORDS        (4)
20
#define SDRAM_WRITE_CONFIG_WORDS       (3)
21
 
22
/* config word positions */
23
#define SDRAM_ADDR_CONFIG              (0)
24
#define DATA_AMOUNT_CONFIG             (1)
25
#define RCV_HIBI_ADDR_CONFIG           (2)
26
 
27
/* This function must be provided by the application.
28
   Function is called when data has been received. */
29
extern void sdram_rx_end(uint32* data, uint32 data_length);
30
 
31
 
32
/* Semaphore for SDRAM configuration */
33
cyg_sem_t sdram_conf_sem;
34
 
35
// CPU's base address
36
static uint32 own_hibi_base_address;
37
static uint32 mem_ctrl_offset;
38
static uint32 sdram_hibi_address;
39
 
40
// channels for receiving data from SDRAM
41
struct sN2H_ChannelInfo* sdram_conf_channel;
42
struct sN2H_ChannelInfo* sdram_data_channel;
43
 
44
/* This function is called after interrupt when mem_ctrl_offset
45
   or data has been received from SDRAM */
46
void sdram_rx_handler(uint32* data, uint32 data_length, uint32 received_address) {
47
 
48
    if( received_address == own_hibi_base_address + SDRAM_CONF_CHANNEL_ADDR ) {
49
 
50
        mem_ctrl_offset = data[0];
51
        cyg_semaphore_post(&sdram_conf_sem);
52
 
53
    } else if ( received_address == own_hibi_base_address + SDRAM_DATA_CHANNEL_ADDR ) {
54
 
55
        sdram_rx_end( data, data_length/AMOUNT_UNIT_IN_BYTES );
56
    }
57
}
58
 
59
 
60
/* Init semaphore and reserve N2H channels for HIBI addresses */
61
void sdram_init(const uint32 sdram_hibi_addr) {
62
 
63
    printf("[sdram] Initializing..\n");
64
    sdram_hibi_address = sdram_hibi_addr;
65
    cyg_semaphore_init(&sdram_conf_sem, 0);
66
    own_hibi_base_address = GetHibiBaseAddr();
67
 
68
    sdram_conf_channel = N2H_ReserveChannel(AMOUNT_UNIT_IN_BYTES, sdram_rx_handler,
69
                                            false, false, SDRAM_CONF_CHANNEL_ADDR);
70
 
71
    sdram_data_channel = N2H_ReserveChannel(AMOUNT_UNIT_IN_BYTES, sdram_rx_handler,
72
                                            false, false, SDRAM_DATA_CHANNEL_ADDR);
73
 
74
    printf("[sdram] Initialization done!\n");
75
}
76
 
77
 
78
/* Send configuration words to SDRAM controller. */
79
uint32 sdram_config( const uint32 sdram_byte_addr,
80
                     const uint32 words,
81
                     const uint8  operation,
82
                     const uint32 read_chn_addr,
83
                     const uint32 row_count_and_stride) {
84
 
85
    const uint32 sdram_word_addr = ( sdram_byte_addr / AMOUNT_UNIT_IN_BYTES );
86
 
87
    uint32 cnf_addr;
88
    uint32 snd_amount;
89
    uint32 sendbuf[ SDRAM_CONFIG_SENDBUF_SIZE ];
90
 
91
    /* Adapt to read/write request */
92
    cnf_addr = sdram_hibi_address;
93
    if( operation == SDRAM_WRITE_OPERATION ) {
94
 
95
        cnf_addr = sdram_hibi_address + 1;
96
    }
97
 
98
    do {
99
 
100
        /* Send request (own hibi address) */
101
        sendbuf[ 0 ] = (own_hibi_base_address+SDRAM_CONF_CHANNEL_ADDR);
102
        HIBI_TX((uint8*)sendbuf, AMOUNT_UNIT_IN_BYTES, cnf_addr, HIBI_TRANSFER_TYPE_MESSAGE);
103
 
104
        /* Wait for an answer (interrupt) */
105
        cyg_semaphore_wait(&sdram_conf_sem);
106
 
107
    } while( mem_ctrl_offset == 0 ); /* Keep sending requests until we get
108
                                        legal mem_ctrl_offset value */
109
 
110
    /* Compute SDRAM configuration register base
111
    Base address is the same as read request address*/
112
    cnf_addr = sdram_hibi_address + mem_ctrl_offset;
113
 
114
    /* The two first words are always the same for reads and writes
115
       (SDRAM address and word count) */
116
    sendbuf[ SDRAM_ADDR_CONFIG ] = sdram_word_addr;
117
    sendbuf[ DATA_AMOUNT_CONFIG ] = words;
118
 
119
    /* Three in default, but +1 for reads */
120
    snd_amount = SDRAM_WRITE_CONFIG_WORDS;
121
 
122
    /* Send own hibi channel addr for read */
123
    if( operation == SDRAM_READ_OPERATION ) {
124
 
125
        sendbuf[ RCV_HIBI_ADDR_CONFIG ] = read_chn_addr;
126
        snd_amount = SDRAM_READ_CONFIG_WORDS;
127
    }
128
 
129
    /* row_count_and_stride is used when reading/writing rectangular areas in memory */
130
    sendbuf[ snd_amount-1 ] = row_count_and_stride;
131
 
132
    /* Send config words to SDRAM controller */
133
    HIBI_TX((uint8*)sendbuf, snd_amount*AMOUNT_UNIT_IN_BYTES, cnf_addr, HIBI_TRANSFER_TYPE_MESSAGE);
134
 
135
    /* Return valid write address to caller */
136
    return cnf_addr;
137
 
138
}
139
 
140
/* This function writes data to SDRAM */
141
bool sdram_write( uint32* const src,
142
                  const uint32 sdram_addr,
143
                  const uint32 words ) {
144
 
145
    uint32 write_addr = 0;
146
 
147
    /* config SDRAM controller for writing */
148
    write_addr = sdram_config( sdram_addr,
149
                               words,
150
                               SDRAM_WRITE_OPERATION,
151
                               0,    /* Not used when writing */
152
 
153
 
154
    /* SDRAM configuration failed? */
155
    if( write_addr == 0 ) {
156
        return FALSE;
157
    }
158
 
159
    /* Send data to SDRAM controller */
160
    HIBI_TX((uint8*)src, words*AMOUNT_UNIT_IN_BYTES, write_addr, HIBI_TRANSFER_TYPE_DATA);
161
 
162
    return TRUE;
163
}
164
 
165
 
166
 
167
/* This function reads data from SDRAM (non-blocking) */
168
void sdram_read( const uint32 sdram_addr,
169
                 const uint32 words ) {
170
 
171
    /* Resize N2H channel to match the amount of data to be received */
172
    N2H_ResizeChannel(sdram_data_channel, words*AMOUNT_UNIT_IN_BYTES);
173
 
174
    /* configure SDRAM controller for reading */
175
    sdram_config( sdram_addr,
176
                  words,
177
                  SDRAM_READ_OPERATION,
178
                  (own_hibi_base_address+SDRAM_DATA_CHANNEL_ADDR),
179
                  0);            /* Reading linear memory area */
180
 
181
 
182
 
183
    /* Reading has started */
184
    return;
185
}
186
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.