Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Memory25L16_fast USBDevice mbed
Fork of BlackBoard_Firmware_MVP by
BB_Basic.cpp
- Committer:
- Xinda
- Date:
- 2018-07-07
- Revision:
- 12:fbb1dd0586e1
- Parent:
- 10:1f96f0cce2a0
- Child:
- 13:f7445faded6a
File content as of revision 12:fbb1dd0586e1:
/******************************************************************************
* S O N D E R
* Copyright 2016 (C) Sonder Design Pty Ltd - All Rights Reserved
* Unauthorised copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
*****************************************************************************/
/*
This is the first implementation of a functional firmware. It allows the user to change the Display layout and type. Improvements for later
versions will include usb keyboard support
*/
#include "mbed.h"
#include "USBHID.h"
#include "Memory.h"
#include "VKCodes.h"
//Spi port for epd. on black board P0_21, P1_21, P1_20. on QSB P0_21,P0_22,P1_15
#define EPDSPI P0_21,P0_22,P1_20
//Spi port for memory. on black board P0_9,P0_8,P0_10, P1_20. on QSB P0_9,P0_8,P0_10
#define MEMSPI P0_9,P0_8,P0_10
#define SLOTSIZE 0x50000
#define TNF 0x02
#define TFE 0x01
#define RNE 0x04
/******************************************************************************
* Definitiontions
*/
//Constants for black board
DigitalOut cs_mem(P0_2); //Set up memory's Chip Select pin BB:P0_2 QSB:P0_16 spi0
DigitalOut cs_epd(P1_23); //Set up epd's Chip Select pin BB:P1_23 QSB:P0_11 spi1
DigitalOut TconEn(P0_5); //Tcon Enable pin, open drain must invert
DigitalOut start(P0_14);
DigitalIn TCbusy(P0_4); //Tcon busy line P0_4
DigitalOut trigger(P1_19);
DigitalOut myled(P0_23);
DigitalOut SRclk(P0_15); //Shift register clk signal
DigitalOut SRlat (P1_22); //Shift register output latch
DigitalOut SRds(P1_14); //Shiftreg data pin
DigitalIn E(P1_13); //Definne row row A input pin
DigitalIn D(P0_7); //Definne row row B input pin
DigitalIn C(P1_28); //Definne row row C input pin
DigitalIn B(P1_31); //Definne row row D input pin
DigitalIn A(P1_29); //Definne row row E input pin
DigitalIn modC(P0_11); //Definne row mod C input pin BB:P0_11 QSB:P0_1
DigitalIn modB(P0_12); //Definne row mod B input pin
DigitalIn modA(P0_13); //Definne row mod A input pin
Serial pc (P0_19,P0_18); //Setup a real serial port
Memory mem(P0_2); //Create a new memory manager with chip select on P0_2
USBHID hid(64, 8,0x1234,0x3241); //Create a HID conection with and 64 byte input and 8 byte output report, PID0x1234 VID 3241
volatile int *PIN39IOREG = (int *)0x4004403C;
int reportLength = 64; //The length of the report recieved
//Codes to send to the pc
int readyAndWaiting []= {2,0x25,0,0,0,0,0,0};
int busy []= {2,0x50,0,0,0,0,0,0};
int readyForComand []= {2,0x75,0,0,0,0,0,0};
int GlobalAddress = 0; //The last adress written to plus one
int lastErasedBlock =0; //The Adress of the last erases block
int currentName = 0; //The position in the nameList of the curret layout
char nameList[16][5]; //A list of all the Layouts in memory, each name is 5 bytes long
//Locations in memory were the 16 layouts can be stored
const int slots [] = {0*SLOTSIZE,1*SLOTSIZE, 2*SLOTSIZE,3*SLOTSIZE, 4*SLOTSIZE, 5*SLOTSIZE, 6*SLOTSIZE, 7*SLOTSIZE, 8*SLOTSIZE, 9*SLOTSIZE,10*SLOTSIZE,11*SLOTSIZE,12*SLOTSIZE};
bool erasedSlots[]= {true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false};
int keybuffer[10][2]; //A buffer for storing key presses (mod key plus key)
int scanCode [5][14]= { //This 2D array maps key scan codes to letter codes
{VK_OEM_3, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0, VK_OEM_MINUS, VK_OEM_PLUS, VK_BACK},
{VK_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P},
{KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J, KEY_K, KEY_L, VK_OEM_1},
{KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M, VK_LSHIFT,VK_CONTROL,VK_LMENU},
{VK_F1, VK_F2,VK_F3,VK_F4, VK_SPACE, VK_TAB, VK_BACK, VK_RSHIFT,VK_LWIN,VK_RMENU}
};
/******************************************************************************
* prototype Functions
*/
short bitDouble(int);
/******************************************************************************
* Set up Functions
*/
char check(int depth) //Check availible memory
{
char c;
char *ptr = new char;
//pc.printf("stack at %p, heap at %p\n", &c, ptr);
//pc.printf("sh,%i,%i\n", &c, ptr);
pc.printf("mem size = %p\n", &c-ptr);
//if (depth <= 0) return;
// check(depth-1);
free(ptr);
return 1;
}
/**
* Set up the memory SPI
*/
SPI setupSPI()
{
SPI my_spi(MEMSPI); // mosi, miso, sclk
//cs_mem = 1; // Chip must be deselected
my_spi.format(8,3); // Setup the spi for 8 bit data, low steady state clock,
my_spi.frequency(10000000); // second edge capture, with a 1MHz clock rate, Will work up to 20MHz
return my_spi;
}
/*** My method to mywrite to RAM ***/
void mywrite (unsigned char data) {
// First don't mywrite to the FIFO buffer if it is full
while (!(LPC_SSP0->SR & TNF)) // While TNF-Bit = 0 (FIFO full)...
; // Wait
LPC_SSP0->DR = data; // mywrite to FIFO buffer
}
/**
* Setup USB HID, usefull for later not used in this iterarion
*/
/*USBHID setupUSB()
{
USBHID hid(64, 8,0x1234,0x3241); //Create a HID conection with and 64 byte input and 8 byte output report, PID0x1234 VID 3241
return hid;
}*/
/******************************************************************************
* USB Functions
*/
/**
* checks the usb recive buffer, if it contains data it is coppired to USBDataBuffer and returns 1
* if the empty return -1;
*/
int readUSB(int USBDataBuffer[])
{
HID_REPORT recv_report;
if(hid.readNB(&recv_report)) { //Check if there is a received report
//printf("\n");
for(int i = 0; i<recv_report.length; i++) { //Store the report in a locat array
//printf(" %x", recv_report.data[i]);
USBDataBuffer[i] = recv_report.data[i];
}
return 1;
} else {
return -1;
}
}
/**
* usbSend, send an eight byte report over usb
*/
void sendUSB(int usbReport[])
{
//pc.printf("\nS: %x",usbReport[1]);
HID_REPORT send_report;
send_report.length = 8;
send_report.data[0] = usbReport[0];
send_report.data[1] = usbReport[1]; //comand byte
send_report.data[2] = usbReport[2];
send_report.data[3] = usbReport[3];
send_report.data[4] = usbReport[4];
send_report.data[5] = usbReport[5];
send_report.data[6] = usbReport[6];
send_report.data[7] = usbReport[7];
hid.send(&send_report);
}
/******************************************************************************
* Keyboard Functions
*/
/**
* keyScan(int keyBuffer[][]). Sacns the keyboard matrix and stores any keypresses in the 2D keyBuffer
* If a key press was detected it returns the most recent key press, otherwise it returns 0
*/
int keyScan()
{
//Initialise and set Up code
int counter=0; //Keubuffer index counter
int rowNum = 0;
int code =0; //the return value, the last key pushed
/*Clear the keybuffer*/
for(int i = 0; i<10; i++) {
keybuffer[i][0]=0;
keybuffer[i][1]=0;
}
int noCols = 16; //number of bits to be shifted
int t = 1000; //wait time in uS. This is the period in us of the shift register clock
SRclk=0;
SRlat = 0;
SRds =1; //Set first bit high
for (int col = 0; col<noCols; col++) { //Loop through one shifit reg
SRclk = 1; //clock in current bit // __ __
wait_us(t/2); //SRclk__| |_..._| |_
SRds = 0; //set dext bit low // ___
wait_us(t/2); //SRds | |___..._____
SRclk=0; // _ _
SRlat = 1; //latch all data out //SRlat____| |_...___| |_
wait_us(t/2); //
SRlat=0;
/*
Check if a button has been pressed by scaning the rows
Generates a unique code depending on which button has been pressed
The code is looked up in the scanCode Array
*/
if(A>0) {
//pc.printf("A\n");
rowNum = 0;
code = scanCode[rowNum][col];
keybuffer[counter][1]= code;
counter++;
}
if(B>0) {
//pc.printf("B\n");
rowNum = 1;
code = scanCode[rowNum][col];
keybuffer[counter][1]= code;
counter++;
}
if(C>0) {
//pc.printf("C\n");
rowNum = 2;
code = scanCode[rowNum][col];
keybuffer[counter][1]= code;
counter++;
}
if(D>0) {
//pc.printf("D\n");
rowNum = 3;
code = scanCode[rowNum][col];
keybuffer[counter][1]= code;
counter++;
}
if(E>0) {
//pc.printf("E\n");
rowNum = 4;
code = scanCode[rowNum][col];
keybuffer[counter][1]= code;
counter++;
}
/*Scan the mod keys and assign them to the mod column of key buffer in the from zero up*/
if(col>0) {
counter=0;
if(modC>0) {
rowNum = 0;
code = scanCode[rowNum][col];
keybuffer[counter][0]= code;
}
if(modB>0) {
rowNum = 0;
code = scanCode[rowNum][col];
keybuffer[counter][0]= code;
}
if(modA>0) {
rowNum = 0;
code = scanCode[rowNum][col];
keybuffer[counter][0]= code;
}
}
}
return code;
}
/**
* int sendKey(int mod, int key). Sends a keypress to the pc over usb
*/
void sendKey(int mod, int key)
{
int temp[]= {0x01,mod,key,0,0,0,0,0};
sendUSB(temp);
}
/**
* int sendKey(int mod, int key). Sends a keypress to the pc over usb
*/
void sendKeyXinda(int keylocation1, int keylocation2, int keylocation3, int keylocation4, int keylocation5, int keylocation6, int keylocation7)
{
int temp[]= {0x01,keylocation1,keylocation2,keylocation3,keylocation4,keylocation5,keylocation6,keylocation7};
sendUSB(temp);
}
/**
* keyCheck(), scanss the keys and sends the keypress to the pc over usb
*/
void keyCheck()
{
//pc.printf("KeyCheck\n");
if (keyScan()>0) { //check if keyScan returned key presss
//pc.printf("\nKey scan|n");
int countpos =0;
while(keybuffer[countpos][1]>0) { //While there are keypresses in the buffer
pc.printf("%i",keybuffer[countpos][1]);
pc.printf(" ");
sendKey(keybuffer[countpos][0],keybuffer[countpos][1]);//Send key press
countpos++;
myled=0;
}
}
}
/**
* testKey(), a test function from Xinda for debugging the connection between Newreadjson and BB_Basic according to the setting from CtrlCenter
*/
void testKey()
{
pc.printf("\ntestKey function simulate keyboard event, starts in 2 sec(s)\n");
wait_ms(1000); //give user some time to move the cursor to where they want to type
pc.printf("\ntestKey function simulate keyboard event, starts in 1 sec(s)\n");
wait_ms(1000);
pc.printf("\ntestKey function start! typing...\n");
sendKeyXinda(0,80,80,80,80,80,80); // Input Chinese: Francisco is Sonder's mascot
wait_ms(10);
sendKeyXinda(1,80,80,80,80,80,80); // Ctrl+V according to the Ctrl Center setting
wait_ms(10);
sendKeyXinda(2,80,80,80,80,80,80); // Open Google Chrome in local
wait_ms(10);
sendKeyXinda(0,1,80,80,80,80,80); // Chinese lyric, <Above the Moon> or korean, depends on the layout(cmd.exe or Google chrome)
pc.printf("\ntestKey function end!\n");
}
/******************************************************************************
* Memory control funtions
*/
/**
* Writes the contense of USBDataBuffer to memoryBuffer, starting at bufferIndex
* returns the index of the last written byte+1;
*/
int appendBuffer(int USBDataBuffer[], char memoryBuffer[], int bufferIndex)
{
//printf("\n");
int posIndex=0;
for(int i = 0; i < 64; i++) {
memoryBuffer[bufferIndex+i]=USBDataBuffer[i];
posIndex++;
}
return (bufferIndex+posIndex);
}
/**
*Sends the ready and waiting signall and loops untill data is recieved.
*Recieved data is stored in the USBDataBuffer
*/
void waitForData(int USBDataBuffer[])
{
sendUSB(readyAndWaiting);
while (readUSB(USBDataBuffer)<1) {
sendUSB(readyAndWaiting);
}
}
/**
* Reads 'length' elements into a short array starting at the 24bit Address.
*If length is greater than BufferSize (3840 bytes) the function will terminate
*and return the start address. tyhe eighteight bit data read from memory is
doubled to sixteen bits for the display. eg 0b1010 =>0b11001100
*/
int readData(short value [], int Address, int length, int doubleSelect)
{
//if(length>bufferSize) {
//printf("\nLength %i exceeds Max Length\n",length);
//return Address;
//}
int temp = 0;
short temp1 = 0;
cs_mem = 1; //Ensure cs is deselected
//wait_us(10);
cs_mem = 0; //memory is selected
mywrite(0x03); //Send read command
mywrite(Address>>16); //Send high address byte
mywrite(Address>>8); //Send mid address byte
mywrite(Address); //Send low address byte
for(int i =0; i <length; i++) {
mywrite(dummy);//Send dummy byte to read out value ate Address
while (LPC_SSP0->SR & RNE)
temp = LPC_SSP0->DR;
//pc.printf("Temp: %X, ", temp);
temp1 = bitDouble(temp);
value[i]= temp1;
//printf(" %X",value[i]);
Address++;
}
cs_mem = 1;
return Address; //Return the address of the next unread byte
}
/**
* receives 64 packets over usb and stores them in memooryBuffer. When memory Buffer is full it is
* written to memory at address. This is repeated 336 times to write a whole image to memory.
* returns the next availible adsress;
*/
int writeImage(SPI my_spi,int Address)
{
Timer t;
t.start(); //Start the timer
pc.printf("\nAddress: %i\n", Address);
int USBDataBuffer [64]; //Creat a buffer for recived data
char memoryBuffer [bufferSize]; //Create a memory buffer, to be sent to flash
int bufferIndex = 0; //points to the next available possition in memory
int startAddress = Address;
int imageSize = 310200; //The number of bytes to write, 86272 for 9.8"
while (Address<startAddress+imageSize) {
//waitForData(USBDataBuffer); //Waits untill data is recieved on usb, puts it in USBDataBuffer
while(bufferIndex<bufferSize) {
waitForData(USBDataBuffer);
bufferIndex=appendBuffer(USBDataBuffer, memoryBuffer, bufferIndex); //Appends USBDataBuffer onto memoryBuffer
}
bufferIndex=0;
//Checks if the block has been erased. only virgin bytes can be written to, so if a block has not been errased it is write
//protected. this erases a block before writung to it if nessisary.
int currentSlot = Address/SLOTSIZE;
if (erasedSlots[currentSlot]) {
Address = mem.writeData(memoryBuffer, Address, bufferSize);
} else {
pc.printf("\nCan not write to unerased slot. %X", Address);
Address = mem.writeData(memoryBuffer, Address, bufferSize);
}
}
pc.printf("\n pinnished writing");
t.stop();
pc.printf("\nwrite image %i", t.read_ms());
t.reset();
return Address;
}
/**
* Writes a single memorybuffer to memory
* receives 64 packets over usb and stores them in memooryBuffer. When memory Buffer is full it is
* written to memory at address.
* returns the next availible adsress;
*/
int writeFrame(SPI my_spi,int Address)
{
int USBDataBuffer [64]; //Creat a buffer for recived data
char memoryBuffer [bufferSize]; //Create a memory buffer, to be sent to flash
int bufferIndex = 0; //points to the next available possition in memory
Timer t;
t.start(); //Start the timer
waitForData(USBDataBuffer); //Waits untill data is recieved on usb, puts it in USBDataBuffer
t.stop();
while(bufferIndex<bufferSize) {
bufferIndex=appendBuffer(USBDataBuffer, memoryBuffer, bufferIndex); //Appends USBDataBuffer onto memoryBuffer
t.start();
waitForData(USBDataBuffer);
t.stop();
}
//Checks if the block has been erased. only virgin bytes can be written to, so if a block has not been errased it is write
//protected. this erases a block before writung to it if nessisary.
int currentSlot = Address/SLOTSIZE;
pc.printf("\nCurrent slot: %i", currentSlot);
if (erasedSlots[currentSlot]) {
pc.printf("\nNE");
Address = mem.writeData(memoryBuffer, Address, bufferSize);
} else {
pc.printf("\nCan not write to unerased slot.");
}
//t.stop();
pc.printf("\nWait1 Wate2-4 %i", t.read_ms());
t.reset();
return Address;
}
/**
* Sends a report containing a the name of the layout stored at a given slot
*/
void getLayoutName(int slot)
{
int temp [] = {0x31,slot,nameList[slot][0],nameList[slot][1],nameList[slot][2],nameList[slot][3],nameList[slot][4],0};
sendUSB(temp);
pc.printf("\nSlot %d = %c%c%c%c%c",slot, nameList[slot][0],nameList[slot][1],nameList[slot][2],nameList[slot][3],nameList[slot][4]);
}
/**
* Sends three reports containing the list of layout names stored in memory.
*/
void getNameList()
{
for(int slot =0; slot< 16; slot++) {
getLayoutName(slot);
}
}
/**
* Sends the name of the Current layout
*/
void getCurrentLayout()
{
getLayoutName(currentName);
}
/**
* Writes the name of a given layout to the top memory address in its reserved block
* name[] is a 5 bytes char array with the most significant byte at name[0]
*/
void nameBlock(char name[], int slot)
{
//char temp[]= {name};
pc.printf("write name");
mem.writeData(name, slots[slot]+0x1ff00, 5);
pc.printf("\nName Done");
}
/**
* Reads memory to find the names of the layouts stored. puts the names into nameList
*/
void populateNameList()
{
for(int slot=0; slot<16; slot++) {
short name[5];
mem.readData(name, slots[slot]+0x1FF00, 5); //Read five bytes from the end of a slot into the name array
for( int i = 0; i<5; i++) {
nameList[slot][i]=name[i];
}
}
}
/**
* Prepares the memory for a new Layout, writes the layout's name, and erases the blocks
*/
void prepImage(int slot, char name[])
{
pc.printf("\nSlot: %i, %i", slot, slots[slot]);
mem.blockErase(slots[slot]); //erase the bottom block of the slot
mem.blockErase(slots[slot]+0x10000); //erase the middle block of the slot
mem.blockErase(slots[slot]+0x20000); //erase the top block of the slot
mem.blockErase(slots[slot]+0x30000); //erase the top block of the slot
mem.blockErase(slots[slot]+0x40000); //erase the top block of the slot
pc.printf("\nWorking");
//nameBlock(name, slots[slot]/*+0x1FFF9*/); //Write the name of the layout to memory
erasedSlots[slot]=true; //Mark the erased slot as true
pc.printf("\nFin Working");
populateNameList();
}
/******************************************************************************
* Display control funtions
*/
/*###### EPD Set Up ######*/
//Sets up the EPD spi pins
SPI setupEPD()
{
pc.printf("\nEpd setup");
/////Setup the spi link with the EDP////
SPI epd_spi(EPDSPI); //SPI setup: mosi, miso, sclk
// Setup the spi for 16 bit data, low steady state clock,
// second edge capture, with a 5MHz clock rate
epd_spi.format(16,0);
epd_spi.frequency(10000000);
return epd_spi;
}
/******************************************************************************
* ITE driver Functions
*/
/*###### Wait for LCD ######*/
//delay until the hardware ready pin on LCD is set
void waitForLCD()
{
myled=1;
while(TCbusy==0) {
wait_us(1);
}
myled=0;
}
/*###### Mirror the bits in a int ######*/
int reverse(int in)
{
int out=0;
out|=in&128;
out|=in&64;
out|=in&32;
out|=in&16;
out|=in&8;
out|=in&4;
out|=in&2;
out|=in&1;
return out;
}
/*###### Double the number of bits (up to 16)in an int eg: 1010 => 11001100 ######*/
/*short bitDouble(int in)
{
short out=0;
int y = 0;
for(int i =0; i<8; i++) {
y = 1<<i;
if((in&y)>0) {
out=out|(3<<(2*i));
}
}
return out;
}*/
short bitDouble(int in)
{
short out=0;
//1
out=out|(3*(in&1));
//2
out=out|((in&2)*6);
//4
out=out|((in&4)*12);
//8
out=out|((in&8)*24);
//16
out=out|((in&16)*48);
//32
out=out|((in&32)*96);
//64
out=out|((in&64)*192);
//128
out=out|((in&128)*384);
return out;
}
/*###### Send Comands ######*/
//send a comand to the LCD
void sendComand(SPI my_spi, int comand)
{
waitForLCD();
cs_epd = 0; // Bring chip select low
//Send write commandpreamble 0x6000
my_spi.write(0x6000);
//Send command
my_spi.write(comand);
cs_epd = 1;
}
/*###### Send N Data ######*/
//send some 16 bit words to the LCD
//data[] is an int array containg wordsN number of words
void sendNData(SPI my_spi,int data[], int wordsN) //for ints
{
waitForLCD();
cs_epd = 0; // Bring chip select low
//Send write data preamble 0x0000
mywrite(0x0000);
//Send data
for (int i =0; i<wordsN; i++) {
mywrite(data[i]);
//pc.printf("%x ",data[i]);
waitForLCD();
}
cs_epd = 1; // Bring chip select high to stop writing
}
/*###### Send N Data ######*/
//send some 16 bit words to the LCD
//data[] is an short array containg wordsN number of 16 bit words
void sendNData(short data[], int wordsN) //for shorts
{
waitForLCD();
cs_epd = 0; // Bring chip select low
//Send write data preamble 0x0000
mywrite(0x0000);
//Send data
for (int i =0; i<wordsN; i++) {
mywrite(data[i]);
//pc.printf("%x ",data[i]);
waitForLCD();
}
cs_epd = 1; // Bring chip select high to stop writing
}
/////////////////////////////////////////////////Register comands
//Read one register value
// reg_Add: address of the register you want to read.
//
int* readReg(SPI my_spi, int reg_Add)
{
int myval[3]; //Read data buffer
cs_epd = 0; // Bring chip select low
//Send write commandpreamble 0x6000
my_spi.write(0x6000);
//Send read reg command 0x0010
my_spi.write(0x0010);
cs_epd = 1; // Bring chip select high to stop writing
waitForLCD();
cs_epd = 0; // Bring chip select low
//Send write data preamble 0x0000
my_spi.write(0x0000);
//Send register address 0x1100
my_spi.write(reg_Add);
cs_epd = 1; // Bring chip select high to stop writing
waitForLCD();
cs_epd=0;
//Send read data preamble 0x0000 ?0x0010?
my_spi.write(0x1000);//endian swap
myval[0]=my_spi.write(00);
myval[1]=my_spi.write(00);
myval[2]=my_spi.write(00);
cs_epd = 1; // Bring chip select high to stop writing
pc.printf("\n\rRef:%x %x %x %x",reg_Add,myval[0],myval[1],myval[2]);
//=====Print data=======
return myval;
}
/*###### Write Register ######*/
//Writes to one register
//wirtes reg_data to the registor at adress reg_Add
void writeReg(SPI my_spi, int reg_Add, int reg_data)
{
cs_epd = 0; // Bring chip select low
//Send write commandpreamble 0x6000
my_spi.write(0x6000);
//Send write reg command 0x0011
my_spi.write(0x0011);
cs_epd = 1; // Bring chip select high to stop writing
waitForLCD();
cs_epd = 0; // Bring chip select low
//Send write data preamble 0x0000
my_spi.write(0x0000);
//Send register address
my_spi.write(reg_Add);
cs_epd = 1; // Bring chip select high to stop writing
waitForLCD();
cs_epd = 0; // Bring chip select low
//Send write data preamble 0x0000
my_spi.write(0x0000);
//Send register data
my_spi.write(reg_data);
cs_epd = 1; // Bring chip select high to stop writing
}
/*###### Read Status ######*/
//Reads the staus register of the LCD
//returns 20 16bit words stored in the myval array.
void readStatus(SPI my_spi, int* myval)
{
//my_spi.format(16,0); // Setup the spi for 16 bit data, low steady state clock,
//my_spi.frequency(1000000); // second edge capture, with a 5Hz clock rate
//int myval[20]; //Read data buffer
cs_epd = 0; // Bring chip select low
pc.printf("chec ");
waitForLCD();
pc.printf("check1 ");
//Send write commandpreamble 0x6000
my_spi.write(0x6000);
pc.printf("check2 ");
waitForLCD();
//Send read status comand 0x0302 Section 2.1 in programing guide
my_spi.write(0x0302);
cs_epd = 1; // Bring chip select high to stop writing
waitForLCD();
cs_epd=0;
//Send read data preamble 0x0000 ?0x0010?
my_spi.write(0x1000);//endian swap
waitForLCD();
//Read the result into the data buffer
for(int i = 0; i<20; i++) {
waitForLCD();
mywrite(00);//Send dummy byte to read out value ate Address
while (LPC_SSP0->SR & RNE)
myval[i]= LPC_SSP0->DR;//Read from data register
}
cs_epd = 1; // Bring chip select high to stop writing
//=====Print data to the terminal=======
pc.printf("\n\rStatus: ");
for(int i = 0; i< 20; i++) {
pc.printf("\n\r %x", myval[i]);
}
int imHi = myval[3];
imHi = imHi<<16;
int imaddress = myval[4]|imHi;
pc.printf("Panel(W,H) = (%d,%d)\r\nImage Buffer Address = %X\r\n",myval[1], myval[2],imaddress);
//pc.printf("Image Buffer Address = %X\r\n",imaddress);
}
/*###### Set Image buffer adress ######*/
//sets the bottom adress where new image buffer will be written to and the display will be read from
//imBufAddress is a 16bit address
void setImBufAddress(SPI my_spi, int imBufAddress)
{
int ImBufAdReg = 0x208; //Image buffer maddress register
int addL = imBufAddress&0xffff;
writeReg(my_spi, ImBufAdReg, addL); //Write the low side of the address
int addH = (imBufAddress >> 16)&0xffff;
writeReg(my_spi, ImBufAdReg+2, addH); //Write the high side of the address
}
/*###### Burst write Memory ######*/
//Fast write comand to send data to the LCD buffer
//writeBuffer: short buffer contsaning data to write
//mem_Add: address on the TCON to save the datat to
//write_Size: size of the writeBuffer
void burst_write_Memory(SPI my_spi, short *writeBuffer, int mem_Add, int write_Size)
{
sendComand(my_spi, 0x0014); //Send bst write
//int params []= {mem_Add&0xFFFF,(mem_Add>>16)&0xFFFF,write_Size&0xFFFF,(write_Size>>16)&0xFFFF,}; //Split the parameters into 16bit words
//sendNData(params, 4); //Send paramerters
waitForLCD();
cs_epd=0;
mywrite(0x0000);
waitForLCD();
mywrite(mem_Add&0xFFFF);
cs_epd=1;
waitForLCD();
cs_epd=0;
mywrite(0x0000);
waitForLCD();
mywrite((mem_Add>>16)&0xFFFF);
cs_epd=1;
waitForLCD();
cs_epd=0;
mywrite(0x0000);
waitForLCD();
mywrite(write_Size&0xFFFF);
cs_epd=1;
waitForLCD();
cs_epd=0;
mywrite(0x0000);
waitForLCD();
mywrite((write_Size>>16)&0xFFFF);
cs_epd=1;
waitForLCD();
cs_epd = 0; // Bring chip select low
//Send write data preamble 0x0000
mywrite(0x0000);
//Send data
for(int i = 0; i< 100; i++) {
for(int h = 0; h< write_Size; h++) {
waitForLCD();
mywrite(writeBuffer[h]);
pc.printf(".");
}
}
sendComand(my_spi, 0x0015); //Send burst access stop comand
}
/*###### Burst Read Memory ######*/
//Fast write comand to read data from the TCON
//readBuffer: short buffer contsaning data that was read
//mem_Add: address on the TCON to read the data from
//read_Size: size of the readBuffer
void burst_read_Memory(SPI my_spi, int *readBuffer, int mem_Add, int read_Size)
{
pc.printf("check1");
//Send burst reag trigger comand 0x0012
sendComand(my_spi, 0x0012); // Bring chip select high to stop writing
waitForLCD();
pc.printf("Check4");
cs_epd = 0; // Bring chip select low
//Send write data preamble 0x0000
my_spi.write(0x0000);
//Send memory address low side
my_spi.write(mem_Add);
//Send memory address high side
my_spi.write(mem_Add>>16);
cs_epd = 1;
waitForLCD();
cs_epd = 0; // Bring chip select low
//Send write data preamble 0x0000
my_spi.write(0x0000);
//Send memory size low side
my_spi.write(read_Size);
//Send memory address high side
my_spi.write(read_Size>>16);
cs_epd = 1;
waitForLCD();
cs_epd = 0; // Bring chip select low
//Send write commandpreamble 0x6000
my_spi.write(0x6000);
waitForLCD();
//Send burst read start comand 0x0013
my_spi.write(0x0013);
cs_epd = 1; // Bring chip select high to stop writing
waitForLCD();
cs_epd=0;
//Send read data preamble 0x0000 ?0x0010?
my_spi.write(0x1000);//endian swap
waitForLCD();
//Read the result into the data buffer
for(int i = 0; i<read_Size; i++) {
waitForLCD();
readBuffer[i]=my_spi.write(00); //send Dummy Byte to rede out data
}
cs_epd = 1; // Bring chip select high to stop writing
sendComand(my_spi, 0x0015); //Send burst access stop comand
}
/////////////////////////////////////////////////////////image comands
//
/**
* loads image data into the tcon
* ediantype 0/1 xxxxxxx1
* pixel format bits per pixel 00=2 11=8 xxxxxx01
* rotate 0,90, 270 xxxxxx10
* im_buffer start of the local image buffer. data to send to the display
* imbuffer size, lenght of the buffer
* imPosX, imPosY, the position on the display to place the image
* height, width, the size in pixels of the image.
*/
void load_full_image(SPI my_spi, int endianType, int pixFormat, int rotate, short im_buffer[], int imbufferSize, int imPosX, int imPosY, int width, int height)
{
//Write image buffer address
//setImBufAddress(0x3dbe90); //adress from readdata() dat[2] and data[3]
//pc.printf("\nwidth: %d\nHeight: %d", width, height);
//Write load image comand 0x0020
sendComand(my_spi, 0x0020);
int param[] = {(endianType<<8)|(pixFormat<<4)|rotate};
sendNData(my_spi, param,1);
//Write load image AREA comand 0x0021
//sendComand(0x0021);
//Send load parameters
//int img_param[] = {(endianType<<8)|(pixFormat<<4)|rotate, imPosX, imPosY, width, height};
//sendNData(img_param,5);
int count =0;
int line=0;
//send image data one word at a time
waitForLCD();
//cs_epd = 0; // Bring chip select low
//Send write data preamble 0x0000
//mywrite(0x0000);
//Send data
sendNData(im_buffer, imbufferSize);
cs_epd=1;
//pc.printf("\ncheck1");
//send load image end coand
sendComand(my_spi, 0x0022);
}
//Display bitmap on EPD
/**
* * xstart, ystart, the position on the display to place the image
* height, width, the size in pixels of the image.
* mode: bits per pixel 0 =2bbp, 1=3bpp, 2=4bpp, 3=5-8bpp
*/
void displayIamge(SPI my_spi, int xstart, int ystart, int height, int width, int mode)
{
waitForLCD();
//Write display image comand 0x0034
sendComand(my_spi, 0x0034);
//Send parameters
//t.attach_us(&ledon,5000);
int params[] = {xstart, ystart, width, height, mode};
trigger = 1;
sendNData(my_spi, params,5);
}
/*###### Write Line ######*/
//Write a single line To the TCON buffer
void writeLine(SPI my_spi, int lineNum, short lineBuffer[], int size)//Writes one line to the display memory.
{
int displayAddress = lineNum*0x960+0x3DBE90; //set the address that the line will be stored in
//pc.printf("\n\rline: %X Line Nume: %d", displayAddress, lineNum);
setImBufAddress(my_spi, displayAddress); //0x3DBE90 adress from readdata() dat[2] and data[3]
load_full_image(my_spi, 0,0,0, lineBuffer, size, 0,0, size,1);
//readReg(my_spi, 0x208); //read the image base adress
}
/*###### EPD Write ######*/
//Update the whole display with data from memory, starting at the
//address: the adress in eeprom to read from
int EPD_Write(int address)
{
Timer t;
pc.printf("\nAddress: %i", address);
t.start(); //Start the timer
//Setup the SPIs
SPI epd_spi = setupEPD(); //Creat a new SPI object to comunicate with the EPD
int vaule[20];
readStatus(epd_spi, vaule);
//Create local variables
int lineLengh = 300; //the length of the display in 16 bit wordswords,
int imageLength = 1034;
short sixtyBytes[lineLengh*2]; //Create a line buffer
//int line = 0; //counter to keep track of the current line
//int frameLine = 0; //counter to keep track of the line in the current frame
//led=!led;
//Begin SPI comunication
// for old Tcon
/*cs_epd=1; //EPD chip deselected
TconEn =1; //Tcon ON set High
wait_ms(120); //delay 120ms
cs_epd=0; //Select the Tcon chip
wait_ms(1); //delay 1ms
//Write Header
epd_spi.write(0x06);
epd_spi.write(0xa0);
wait_ms(120); //delay 120ms*/
//loop throug all lines lines
for(int j=0; j<imageLength; j++) {
//pc.printf("\n");
readData(sixtyBytes, address+(j*lineLengh), lineLengh,0); //Read the line, putt them in buffer return the next address to read from. Since mem reads 8bit data, we need double line length for 16bit display
//Halve the resolution by doubling bit length
/*for(int i=0; i<lineLengh; i++) {
int low = sixtyBytes[i];
low = bitDouble(low);
sixtyBytes[i]=(low);
}*/
//pc.printf("ÿup");
writeLine(epd_spi,j,sixtyBytes,lineLengh);
if(j%100==0) {
keyCheck();
}
}
t.stop();
displayIamge(epd_spi,0,0,1034,2400,2);
for(int i = 0; i<1034; i++) {
readData(sixtyBytes, address+(i*lineLengh), lineLengh-250,0); //Read the line, putt them in buffer return the next address to read from. Since mem reads 8bit data, we need double line length for 16bit display
//Halve the resolution by doubling bit length
/*for(int i=0; i<lineLengh; i++) {
int low = sixtyBytes[i];
low = bitDouble(low);
sixtyBytes[i]=(low);
}*/
writeLine(epd_spi,i,sixtyBytes,lineLengh-250);
}
displayIamge(epd_spi,0,0,1034,400,2);
printf("\ntime = %i ", t.read_ms());
t.reset();
printf("\ndone = ");
return 1;
}
/*###### EPD Write ######*/
//Update the whole display with data from a reserved slot
int EPD_Swap(int slot)
{
pc.printf("\nslots: %i, %X", slot,slots[slot]);
return EPD_Write(slots[slot]);
}
/*******************************************************
* Main Function
*/
int main()
{
Timer t;
pc.baud(115200);
int USBDataBuffer[64];
SPI mem_spi = setupSPI(); //Creates an SPI object to comunicate with the external memory
populateNameList(); //Reads the names of layouts stored in external memory into RAM
while(1) {
//pc.printf("Loop");
trigger=0;
sendUSB(readyForComand); //Tell pc that read for data
keyCheck(); //Scan the key matrix for key press and send to the pc
pc.printf(".");
sendUSB(readyForComand);
if (readUSB(USBDataBuffer)>0) { //If a coamd received
pc.printf("\nSwitch %i",USBDataBuffer[1]);
char temp[] = {USBDataBuffer[3],USBDataBuffer[4],USBDataBuffer[5],USBDataBuffer[6],USBDataBuffer[7]};
switch(USBDataBuffer[1]) {
case 0x10: //If the recieved data is a write instruction
GlobalAddress = writeFrame(mem_spi, USBDataBuffer[2]*65536+USBDataBuffer[3]*256+USBDataBuffer[4]); //Write the following data to the memory at 24 bit address usbDatabuffer[2-4]
break;
case 0x11:
pc.printf("\nPrep write");
prepImage(USBDataBuffer[2], temp);//Prepare a slot in memory for an image
break;
case 0x12:
pc.printf("\nImage write");
writeImage(mem_spi, USBDataBuffer[2]*65536+USBDataBuffer[3]*256+USBDataBuffer[4]);//Write the next 86400 bytes of data to the memory starting at 24 bit address usbDatabuffer[2-4]
break;
case 0x20: //If the recieved comand is a read instruction
//mem.readData(mem_spi, memoryBuffer, USBDataBuffer[2], USBDataBuffer[3]);//read(spi, destination[], address, length)
//pc.printf(" \n---EPD UPDATE--- %i",USBDataBuffer[2]*65536+USBDataBuffer[3]*256+USBDataBuffer[4]);
EPD_Write(USBDataBuffer[2]*65536+USBDataBuffer[3]*256+USBDataBuffer[4]);
break;
case 0x21: //If the recieved comand is a swap instruction
EPD_Swap(USBDataBuffer[2]);
break;
case 0x30: //If the recieved comand is a request for the cutrrent name
populateNameList();
getNameList();
break;
case 0x35: //If the recieved comand is a request for all the names
getCurrentLayout();
break;
case 0xF0:
testKey(); // If received command is a request of keypress debugging. Xinda Debug version of keyCheck
break;
default:
pc.printf("\nfail! [%x %x %x %x %x %x %x %x]",USBDataBuffer[0],USBDataBuffer[1],USBDataBuffer[2],USBDataBuffer[3],USBDataBuffer[4],USBDataBuffer[5],USBDataBuffer[6],USBDataBuffer[7]);
}
}
//pc.printf("\n%d", t.read_us());
t.reset();
}
}
