Line 37... |
Line 37... |
//
|
//
|
//
|
//
|
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
//
|
//
|
//
|
//
|
|
#include "artyboard.h"
|
#include "zipcpu.h"
|
#include "zipcpu.h"
|
#include "zipsys.h"
|
#include "zipsys.h"
|
#include "artyboard.h"
|
|
|
#define sys _sys
|
|
|
void idle_task(void) {
|
void idle_task(void) {
|
while(1)
|
while(1)
|
zip_idle();
|
zip_idle();
|
}
|
}
|
|
|
extern int splash[], mug[];
|
extern short splash[], mug[];
|
|
|
#define OLED_DISPLAYON 0x0af
|
#define OLED_DISPLAYON 0x0af
|
#define MICROSECOND (CLOCKFREQ_HZ/1000000)
|
#define MICROSECOND (CLOCKFREQ_HZ/1000000)
|
#define OLED_DISPLAY_OFF
|
#define OLED_DISPLAY_OFF
|
|
|
Line 138... |
Line 140... |
0x01837D,
|
0x01837D,
|
// disable scrolling
|
// disable scrolling
|
0x02e
|
0x02e
|
};
|
};
|
|
|
|
const int num_init_items = sizeof(init_sequence)/sizeof(init_sequence[0]);
|
|
|
/*
|
/*
|
* oled_init()
|
* oled_init()
|
*
|
*
|
* This initializes and starts up the OLED. While it sounds important, really
|
* This initializes and starts up the OLED. While it sounds important, really
|
* the majority of the work necessary to do this is really captured in the
|
* the majority of the work necessary to do this is really captured in the
|
Line 154... |
Line 158... |
*
|
*
|
*/
|
*/
|
void oled_init(void) {
|
void oled_init(void) {
|
int i;
|
int i;
|
|
|
for(i=0; i<sizeof(init_sequence); i++) {
|
for(i=0; i<num_init_items; i++) {
|
while(OLED_BUSY(sys->io_oled))
|
while(OLED_BUSY(sys->io_oled))
|
;
|
;
|
sys->io_oled.o_ctrl = init_sequence[i];
|
sys->io_oled.o_ctrl = init_sequence[i];
|
}
|
}
|
|
|
Line 266... |
Line 270... |
* clear before sending the image. The biggest difference between the two
|
* clear before sending the image. The biggest difference between the two
|
* approaches is that, when using the DMA, the routine finishes before the
|
* approaches is that, when using the DMA, the routine finishes before the
|
* DMA transfer is complete, whereas the second version of the routine
|
* DMA transfer is complete, whereas the second version of the routine
|
* returns as soon as the image transfer is complete.
|
* returns as soon as the image transfer is complete.
|
*/
|
*/
|
void oled_show_image(int *img) {
|
void oled_show_image(unsigned short *img) {
|
#define USE_DMA
|
|
#ifdef USE_DMA
|
|
zip->z_dma.d_len= 6144;
|
|
zip->z_dma.d_rd = img;
|
|
zip->z_dma.d_wr = (int *)&sys->io_oled.o_data;
|
|
zip->z_dma.d_ctrl = DMAONEATATIME|DMA_CONSTDST|DMA_ONOLED;
|
|
#else
|
|
for(int i=0; i<6144; i++) {
|
for(int i=0; i<6144; i++) {
|
while(OLED_BUSY(sys->io_oled))
|
while(OLED_BUSY(sys->io_oled))
|
;
|
;
|
sys->io_oled.o_data = img[i];
|
sys->io_oled.o_data = (unsigned)img[i];
|
}
|
}
|
#endif
|
|
}
|
}
|
|
|
/*
|
/*
|
* entry()
|
* entry()
|
*
|
*
|
Line 311... |
Line 307... |
if (0) {
|
if (0) {
|
// While this appears to do the task quite nicely, it leaves
|
// While this appears to do the task quite nicely, it leaves
|
// the master_ce line high within the CPU, and so it generates
|
// the master_ce line high within the CPU, and so it generates
|
// a whole lot of debug information in our Verilator simulation,
|
// a whole lot of debug information in our Verilator simulation,
|
// busmaster_tb.
|
// busmaster_tb.
|
int pwrcount = sys->io_pwrcount;
|
int pwrcount = sys->io_b.i_pwrcount;
|
do {
|
do {
|
pwrcount = sys->io_pwrcount;
|
pwrcount = sys->io_b.i_pwrcount;
|
} while((pwrcount>0)&&(pwrcount < CLOCKFREQ_HZ/4));
|
} while((pwrcount>0)&&(pwrcount < CLOCKFREQ_HZ/4));
|
} else {
|
} else {
|
// By using the timer and sleeping instead, the simulator can
|
// By using the timer and sleeping instead, the simulator can
|
// be made to run a *lot* faster, with a *lot* less debugging
|
// be made to run a *lot* faster, with a *lot* less debugging
|
// ... junk.
|
// ... junk.
|
int pwrcount = sys->io_pwrcount;
|
int pwrcount = sys->io_b.i_pwrcount;
|
if ((pwrcount > 0)&&(pwrcount < CLOCKFREQ_HZ/4)) {
|
if ((pwrcount > 0)&&(pwrcount < CLOCKFREQ_HZ/4)) {
|
pwrcount = CLOCKFREQ_HZ/4 - pwrcount;
|
pwrcount = CLOCKFREQ_HZ/4 - pwrcount;
|
timer_delay(pwrcount);
|
timer_delay(pwrcount);
|
}
|
}
|
}
|
}
|
Line 379... |
Line 375... |
// 7. Wait 100ms
|
// 7. Wait 100ms
|
// We already stuffed this command sequence into the oled_init,
|
// We already stuffed this command sequence into the oled_init,
|
// so we're good here.
|
// so we're good here.
|
|
|
while(1) {
|
while(1) {
|
sys->io_ledctrl = 0x0f0;
|
sys->io_b.i_leds = 0x0f0;
|
|
|
sys->io_oled.o_ctrl = OLED_DISPLAYON;
|
sys->io_oled.o_ctrl = OLED_DISPLAYON;
|
|
|
oled_clear();
|
oled_clear();
|
|
|
Line 399... |
Line 395... |
while(OLED_BUSY(sys->io_oled))
|
while(OLED_BUSY(sys->io_oled))
|
;
|
;
|
|
|
// Now ... finally ... we can send our image.
|
// Now ... finally ... we can send our image.
|
oled_show_image(splash);
|
oled_show_image(splash);
|
wait_on_interrupt(SYSINT_DMAC);
|
// wait_on_interrupt(SYSINT_DMAC);
|
|
|
// Wait 25 seconds. The LEDs are for a fun effect.
|
// Wait 25 seconds. The LEDs are for a fun effect.
|
sys->io_ledctrl = 0x0f1;
|
sys->io_b.i_leds = 0x0f1;
|
timer_delay(CLOCKFREQ_HZ*5);
|
timer_delay(CLOCKFREQ_HZ*5);
|
sys->io_ledctrl = 0x0f3;
|
sys->io_b.i_leds = 0x0f3;
|
timer_delay(CLOCKFREQ_HZ*5);
|
timer_delay(CLOCKFREQ_HZ*5);
|
sys->io_ledctrl = 0x0f7;
|
sys->io_b.i_leds = 0x0f7;
|
timer_delay(CLOCKFREQ_HZ*5);
|
timer_delay(CLOCKFREQ_HZ*5);
|
sys->io_ledctrl = 0x0ff;
|
sys->io_b.i_leds = 0x0ff;
|
timer_delay(CLOCKFREQ_HZ*5);
|
timer_delay(CLOCKFREQ_HZ*5);
|
sys->io_ledctrl = 0x0fe;
|
sys->io_b.i_leds = 0x0fe;
|
timer_delay(CLOCKFREQ_HZ*5);
|
timer_delay(CLOCKFREQ_HZ*5);
|
|
|
|
|
// Display a second image.
|
// Display a second image.
|
sys->io_ledctrl = 0x0fc;
|
sys->io_b.i_leds = 0x0fc;
|
oled_show_image(mug);
|
oled_show_image(mug);
|
wait_on_interrupt(SYSINT_DMAC);
|
// wait_on_interrupt(SYSINT_DMAC);
|
|
|
// Leave this one in effect for 5 seconds only.
|
// Leave this one in effect for 5 seconds only.
|
sys->io_ledctrl = 0x0f8;
|
sys->io_b.i_leds = 0x0f8;
|
timer_delay(CLOCKFREQ_HZ*5);
|
timer_delay(CLOCKFREQ_HZ*5);
|
}
|
}
|
|
|
// We'll never get here, so this line is really just for form.
|
// We'll never get here, so this line is really just for form.
|
zip_halt();
|
zip_halt();
|