Subversion Repositories freemyipod

Rev

Rev 489 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 489 Rev 492
Line 30... Line 30...
30
static struct dma_lli lcd_lli[(LCD_WIDTH * LCD_HEIGHT - 1) / 0xfff]
30
static struct dma_lli lcd_lli[(LCD_WIDTH * LCD_HEIGHT - 1) / 0xfff]
31
    IDATA_ATTR __attribute__((aligned(16)));
31
    IDATA_ATTR __attribute__((aligned(16)));
32
 
32
 
33
static uint16_t lcd_color IDATA_ATTR;
33
static uint16_t lcd_color IDATA_ATTR;
34
 
34
 
-
 
35
static struct mutex lcd_mutex;
-
 
36
 
35
 
37
 
36
void lcd_init()
38
void lcd_init()
37
{
39
{
38
}
40
}
39
 
41
 
Line 55... Line 57...
55
int lcd_get_format()
57
int lcd_get_format()
56
{
58
{
57
    return LCD_FORMAT;
59
    return LCD_FORMAT;
58
}
60
}
59
 
61
 
-
 
62
static void lcd_send_cmd(uint16_t cmd) ICODE_ATTR __attribute__((noinline));
60
static void lcd_send_cmd(uint16_t cmd)
63
static void lcd_send_cmd(uint16_t cmd)
61
{
64
{
62
    while (LCDSTATUS & 0x10);
65
    while (LCDSTATUS & 0x10);
63
    LCDWCMD = cmd;
66
    LCDWCMD = cmd;
64
}
67
}
65
 
68
 
-
 
69
static void lcd_send_data(uint16_t data) ICODE_ATTR __attribute__((noinline));
66
static void lcd_send_data(uint16_t data)
70
static void lcd_send_data(uint16_t data)
67
{
71
{
68
    while (LCDSTATUS & 0x10);
72
    while (LCDSTATUS & 0x10);
69
    LCDWDATA = data;
73
    LCDWDATA = (data & 0xff) | ((data & 0x7f00) << 1);
70
}
74
}
71
 
75
 
72
void lcd_shutdown()
76
void lcd_shutdown()
73
{
77
{
74
}
78
}
75
 
79
 
76
bool displaylcd_busy()
80
bool displaylcd_busy()
77
{
81
{
78
    return DMAC0C0CONFIG & 1;
82
    return DMAC0C4CONFIG & 1;
79
}
83
}
80
 
84
 
81
bool displaylcd_safe()
85
bool displaylcd_safe()
82
{
86
{
83
    return !(DMAC0C0CONFIG & 1);
87
    return !(DMAC0C4CONFIG & 1);
84
}
88
}
85
 
89
 
-
 
90
void displaylcd_sync() ICODE_ATTR;
86
void displaylcd_sync()
91
void displaylcd_sync()
87
{
92
{
-
 
93
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
88
    while (displaylcd_busy()) sleep(100);
94
    while (displaylcd_busy()) sleep(100);
-
 
95
    mutex_unlock(&lcd_mutex);
89
}
96
}
90
 
97
 
91
void displaylcd(unsigned int startx, unsigned int endx,
98
void displaylcd_setup(unsigned int startx, unsigned int endx,
92
                unsigned int starty, unsigned int endy, void* data, int color)
99
                      unsigned int starty, unsigned int endy) ICODE_ATTR;
-
 
100
void displaylcd_setup(unsigned int startx, unsigned int endx,
-
 
101
                      unsigned int starty, unsigned int endy)
93
{
102
{
-
 
103
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
94
    displaylcd_sync();
104
    displaylcd_sync();
95
    lcd_send_cmd(0x2a);
105
    lcd_send_cmd(0x2a);
96
    lcd_send_data(((startx & 0x7f00) << 1) | (startx & 0xff));
106
    lcd_send_data(startx);
97
    lcd_send_data(((endx & 0x7f00) << 1) | (endx & 0xff));
107
    lcd_send_data(endx);
98
    lcd_send_cmd(0x2b);
108
    lcd_send_cmd(0x2b);
99
    lcd_send_data(((starty & 0x7f00) << 1) | (starty & 0xff));
109
    lcd_send_data(starty);
100
    lcd_send_data(((endy & 0x7f00) << 1) | (endy & 0xff));
110
    lcd_send_data(endy);
101
    lcd_send_cmd(0x2c);
111
    lcd_send_cmd(0x2c);
-
 
112
}
-
 
113
 
-
 
114
static void displaylcd_dma(void* data, int pixels, bool solid) ICODE_ATTR;
102
    int pixels = (endx - startx + 1) * (endy - starty + 1);
115
static void displaylcd_dma(void* data, int pixels, bool solid)
-
 
116
{
103
    int i;
117
    int i;
104
    bool solid = (int)data == -1;
-
 
105
    if (solid) lcd_color = color;
-
 
106
    for (i = -1; i < (int)ARRAYLEN(lcd_lli) && pixels > 0; i++, pixels -= 0xfff)
118
    for (i = -1; i < (int)ARRAYLEN(lcd_lli) && pixels > 0; i++, pixels -= 0xfff)
107
    {
119
    {
108
        bool last = i + 1 >= ARRAYLEN(lcd_lli) || pixels <= 0xfff;
120
        bool last = i + 1 >= ARRAYLEN(lcd_lli) || pixels <= 0xfff;
109
        struct dma_lli* lli = i < 0 ? (struct dma_lli*)((int)&DMAC0C0LLI) : &lcd_lli[i];
121
        struct dma_lli* lli = i < 0 ? (struct dma_lli*)((int)&DMAC0C4LLI) : &lcd_lli[i];
110
        lli->srcaddr = solid ? &lcd_color : data;
122
        lli->srcaddr = data;
111
        lli->dstaddr = (void*)((int)&LCDWDATA);
123
        lli->dstaddr = (void*)((int)&LCDWDATA);
112
        lli->nextlli = last ? NULL : &lcd_lli[i + 1];
124
        lli->nextlli = last ? NULL : &lcd_lli[i + 1];
113
        lli->control = 0x70240000 | (last ? pixels : 0xfff)
125
        lli->control = 0x70240000 | (last ? pixels : 0xfff)
114
                     | (last ? 0x80000000 : 0) | (solid ? 0 : 0x4000000);
126
                     | (last ? 0x80000000 : 0) | (solid ? 0 : 0x4000000);
115
        data = (void*)(((uint32_t)data) + 0x1ffe);
127
        data = (void*)(((uint32_t)data) + 0x1ffe);
116
    }
128
    }
117
    clean_dcache();
129
    clean_dcache();
118
    DMAC0C0CONFIG = 0x88c1;
130
    DMAC0C4CONFIG = 0x88c1;
-
 
131
}
-
 
132
 
-
 
133
void displaylcd_native(unsigned int startx, unsigned int endx,
-
 
134
                       unsigned int starty, unsigned int endy, void* data)
-
 
135
{
-
 
136
    int pixels = (endx - startx + 1) * (endy - starty + 1);
-
 
137
    if (pixels <= 0) return;
-
 
138
    displaylcd_setup(startx, endx, starty, endy);
-
 
139
    displaylcd_dma(data, pixels, false);
-
 
140
    mutex_unlock(&lcd_mutex);
-
 
141
}
-
 
142
 
-
 
143
void filllcd_native(unsigned int startx, unsigned int endx,
-
 
144
                    unsigned int starty, unsigned int endy, int color)
-
 
145
{
-
 
146
    int pixels = (endx - startx + 1) * (endy - starty + 1);
-
 
147
    if (pixels <= 0) return;
-
 
148
    displaylcd_setup(startx, endx, starty, endy);
-
 
149
    lcd_color = color;
-
 
150
    displaylcd_dma(&lcd_color, pixels, true);
-
 
151
    mutex_unlock(&lcd_mutex);
-
 
152
}
-
 
153
 
-
 
154
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
-
 
155
                       unsigned int height, void* data, unsigned int datax,
-
 
156
                       unsigned int datay, unsigned int stride, bool solid) ICODE_ATTR;
-
 
157
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
-
 
158
                       unsigned int height, void* data, unsigned int datax,
-
 
159
                       unsigned int datay, unsigned int stride, bool solid)
-
 
160
{
-
 
161
    int pixels = width * height;
-
 
162
    if (pixels <= 0) return;
-
 
163
    displaylcd_setup(x, x + width - 1, y, y + height - 1);
-
 
164
    int corrsize = width * 3;
-
 
165
    signed char* corr = (signed char*)malloc(corrsize);
-
 
166
    if (!corr)
-
 
167
    {
-
 
168
        mutex_unlock(&lcd_mutex);
-
 
169
        return;
-
 
170
    }
-
 
171
    memset(corr, 0, corrsize);
-
 
172
    unsigned char* in = (unsigned char*)data + (stride * datay + datax) * 3;
-
 
173
    for (y = 0; y < height; y++)
-
 
174
    {
-
 
175
        int i;
-
 
176
        signed char* corrptr = corr;
-
 
177
        signed char lastcorr[3] = {0};
-
 
178
        for (x = 0; x < width; x++)
-
 
179
        {
-
 
180
            unsigned int pixel = 0;
-
 
181
            signed char* lastcorrptr = lastcorr;
-
 
182
            int orig = *in++ + *corrptr + *lastcorrptr;
-
 
183
            orig = MAX(0, MIN(255, orig));
-
 
184
            unsigned int real = orig >> 3;
-
 
185
            pixel |= real << 11;
-
 
186
            int err = orig - ((real << 3) | (real >> 2));
-
 
187
            *corrptr++ = (*lastcorrptr >> 1) + err >> 2;
-
 
188
            *lastcorrptr++ = err >> 1;
-
 
189
            orig = *in++ + *corrptr + *lastcorrptr;
-
 
190
            orig = MAX(0, MIN(255, orig));
-
 
191
            real = orig >> 2;
-
 
192
            pixel |= real << 5;
-
 
193
            err = orig - ((real << 2) | (real >> 4));
-
 
194
            *corrptr++ = (*lastcorrptr >> 1) + err >> 2;
-
 
195
            *lastcorrptr++ = err >> 1;
-
 
196
            orig = *in++ + *corrptr + *lastcorrptr;
-
 
197
            orig = MAX(0, MIN(255, orig));
-
 
198
            real = orig >> 3;
-
 
199
            pixel |= real;
-
 
200
            err = orig - ((real << 3) | (real >> 2));
-
 
201
            *corrptr++ = (*lastcorrptr >> 1) + err >> 2;
-
 
202
            *lastcorrptr++ = err >> 1;
-
 
203
            while (LCDSTATUS & 0x10);
-
 
204
            LCDWDATA = pixel;
-
 
205
            if (solid) in -= 3;
-
 
206
        }
-
 
207
        if (solid) in += stride * 3;
-
 
208
        else in += (stride - width) * 3;
-
 
209
    }
-
 
210
    free(corr);
-
 
211
    mutex_unlock(&lcd_mutex);
-
 
212
}
-
 
213
 
-
 
214
void displaylcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height,
-
 
215
                void* data, unsigned int datax, unsigned int datay, unsigned int stride)
-
 
216
{
-
 
217
    displaylcd_dither(x, y, width, height, data, datax, datay, stride, false);
-
 
218
}
-
 
219
 
-
 
220
void filllcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int color)
-
 
221
{
-
 
222
    if (width * height <= 0) return;
-
 
223
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
-
 
224
    lcd_color = color;
-
 
225
    displaylcd_dither(x, y, width, height, &lcd_color, 0, 0, 0, true);
-
 
226
    mutex_unlock(&lcd_mutex);
119
}
227
}
120
 
228
 
121
void INT_DMAC0C0()
229
void INT_DMAC0C4()
122
{
230
{
123
    DMAC0INTTCCLR = 1;
231
    DMAC0INTTCCLR = 0x10;
124
    lcdconsole_callback();
232
    lcdconsole_callback();
125
}
233
}
126
 
234
 
127
int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
235
int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
128
    ICODE_ATTR __attribute__((naked, noinline));
236
    ICODE_ATTR __attribute__((naked, noinline));