Wed Mar 18, 2015 5:21 pm
// Happy Birthday Gamebuino !
// Jonne Valola aka "Jonnection"
// Combines parts of Myndale's SD audio streaming demo
// and petit_fs lib demo
#include <TimerOne.h>
#include <petit_fatfs.h>
#define PLAYBACK_FREQ 6552 // was 6552
#define SPEAKER 3
#define BUFFER_SIZE 128
// GAMEBUINO DEFINED PINS
#define PIN_SCE A1 // PC 1 SCR ENABLE
#define PIN_RESET A0 // PC 0 SCR RESET
#define PIN_DC A2 // PC 2 SCR DC
#define PIN_SDIN 11 // PB 3 MOSI - data to screen
#define PIN_SCLK 13 // PB 5 SCK
#define PIN_BACKLIGHT 5 // PD 5 BACKLIGHT
#define PORT_SCLK PORTB
#define SCLK_BIT 5
#define PORT_SDIN PORTB
#define SDIN_BIT 3
#define LCD_C LOW
#define LCD_D HIGH
#define LCD_CMD 0
#define LCD_X 84
#define LCD_Y 48
byte buffer[LCD_X*LCD_Y/8];
unsigned char buffers[2][BUFFER_SIZE];
volatile int currentBuffer = 0;
volatile int bufindex = 0;
volatile boolean blit=false;
volatile unsigned char * currentPtr;
volatile unsigned char * endPtr;
const int chipSelect = 10;
WORD br;
void LcdClear(void)
{
for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
{
LcdWrite(LCD_D, 0x00);
}
}
void LcdInitialise(void)
{
pinMode(PIN_SCE, OUTPUT);
pinMode(PIN_RESET, OUTPUT);
pinMode(PIN_DC, OUTPUT);
pinMode(PIN_SDIN, OUTPUT);
pinMode(PIN_SCLK, OUTPUT);
digitalWrite(PIN_RESET, LOW);
digitalWrite(PIN_RESET, HIGH);
LcdWrite( LCD_CMD, 0x21 ); // LCD Extended Commands.
LcdWrite( LCD_CMD, 0xB9 ); // Set LCD Vop (Contrast). //B1
LcdWrite( LCD_CMD, 0x04 ); // Set Temp coefficent. //0x04
LcdWrite( LCD_CMD, 0x14 ); // LCD bias mode 1:48. //0x13
LcdWrite( LCD_CMD, 0x0C ); // LCD in normal mode. 0x0d for inverse
LcdWrite(LCD_C, 0x20);
LcdWrite(LCD_C, 0x0C);
pinMode(5, OUTPUT); //backlight
digitalWrite(5, HIGH);
}
void LcdWrite(byte dc, byte data) {
digitalWrite(PIN_DC, dc); // select command or data mode
digitalWrite(PIN_SCE, LOW); // enable screen
digitalWrite(SS, HIGH); // disable SD
tx(data); // replace with hardware version from petit_fs demo
digitalWrite(PIN_SCE, HIGH); // disable screen
}
void gotoXY(int x, int y) {
LcdWrite( 0, 0x80 | x); // Column.
LcdWrite( 0, 0x40 | y); // Row.
}
void setup(void)
{
spi_init();
Serial.begin(9600);
Serial.println(F("Starting videoplayer"));
int a = PFFS.begin(10, rx, tx);
Serial.println(F("SD begin succeeded"));
int err = PFFS.open_file("VIDEO.JVD");
if (err) Serial.println(F("Video open failed"));
else Serial.println(F("Video open success"));
if (err==0) {
Serial.println(F("Data file opened"));
pf_read((void *)&buffers[0][0],BUFFER_SIZE,&br);
currentBuffer = 0;
currentPtr = buffers[currentBuffer];
endPtr = currentPtr + BUFFER_SIZE;
pinMode(SPEAKER, OUTPUT);
TCCR2B = (TCCR2B & 0b11111000) | 0x01; // set max PWM frequency
Timer1.initialize(1000000/PLAYBACK_FREQ);
Timer1.attachInterrupt(callback);
}
LcdInitialise();
gotoXY(0,0);
LcdClear();
}
void loop(void)
{
digitalWrite(SS, LOW);
pf_read((void *)&buffers[1][0],BUFFER_SIZE,&br);
digitalWrite(SS, HIGH);
while (currentBuffer != 1) if (blit) blitscreen();
digitalWrite(SS, LOW);
pf_read((void *)&buffers[0][0],BUFFER_SIZE,&br);
digitalWrite(SS, HIGH);
while (currentBuffer != 0) if (blit) blitscreen();
}
void callback()
{
buffer[bufindex] = (*currentPtr++);
bufindex++;
if (bufindex == 504) {
bufindex=0;
blit=true;
}
analogWrite(SPEAKER, (*currentPtr++));
if (currentPtr >= endPtr)
{
currentBuffer = 1-currentBuffer;
currentPtr = buffers[currentBuffer];
endPtr = currentPtr + BUFFER_SIZE;
}
}
byte rx()
{
// The SPI Data Register is a read/write register
// used for data transfer between the Register File and the SPI Shift Register.
// Writing to the register initiates data transmission. Reading the register causes the Shift Register receive buffer to be read.
SPDR = 0xFF; // dummy byte to initiate reading
// loop_until_bit_is_set is an AVR libc macro
// SPSR is SPI status register, SPIF is SPI interrupt flag, that is set after transmission is complete
loop_until_bit_is_set(SPSR, SPIF);
return SPDR; //return the SPDR (= value back from slave)
}
void tx(byte d)
{
SPDR = d;
loop_until_bit_is_set(SPSR, SPIF);
}
void spi_init()
{
pinMode(10, OUTPUT); // 10 = SS = Slave select of SD
pinMode(11, OUTPUT); // MOSI data to SD
pinMode(12, INPUT); // PB 4 - MISO data from SD
pinMode(13, OUTPUT); // SCLK
// SET HARDWARE SPI in Master & enabled
// default speed is Clock/4 = 4 Mhz which is maximum for nokia lcd
SPCR = _BV(MSTR) | _BV(SPE); // Master mode, SPI enable, clock speed MCU_XTAL/4
}
inline void blitscreen()
{
digitalWrite(PIN_DC, HIGH); // select data mode
digitalWrite(PIN_SCE, LOW); // enable screen
digitalWrite(SS, HIGH); // disable SD
for (int i = 0; i < 504; i++)
{
tx(buffer[i]);
}
digitalWrite(PIN_SCE, HIGH); // disable screen
blit=false;
}
Wed Mar 18, 2015 8:03 pm
Wed Mar 18, 2015 8:13 pm
Wed Mar 18, 2015 8:48 pm
Thu Mar 19, 2015 8:40 pm
Fri Mar 20, 2015 7:03 am
Fri Mar 20, 2015 7:48 am
rodot wrote: I would be glad to put it by default on all the Gamebuino I make
Fri Mar 20, 2015 11:31 am
rodot wrote:Hey, that's really awesome !
I've put your nickname in the title and a link to the forum thread in the description, but if you want me to remove it from my YouTube account (as it's not my work) just tell me.
PS: I would be glad to put it by default on all the Gamebuino I make if you add the ability to load the loader when C is pressed ^^
Sun Mar 22, 2015 1:34 pm
Sat Mar 28, 2015 6:47 pm