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.
Revision 66:468a11f05580, committed 2014-08-31
- Comitter:
- WiredHome
- Date:
- Sun Aug 31 14:37:37 2014 +0000
- Parent:
- 62:ba5d33438fda
- Child:
- 67:9f834f0ff97d
- Commit message:
- Increase the SPI clock rate by splitting the write from the read to better match the RA8875 display capabilities.
Changed in this revision
| RA8875.cpp | Show annotated file Show diff for this revision Revisions of this file |
| RA8875.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/RA8875.cpp Sun Aug 17 15:38:51 2014 +0000
+++ b/RA8875.cpp Sun Aug 31 14:37:37 2014 +0000
@@ -241,6 +241,7 @@
{
for (int i=0; i<METRICCOUNT; i++)
metrics[i] = 0;
+ idlecounter = 0;
}
@@ -252,13 +253,18 @@
metrics[method] = elapsed;
}
+void RA8875::CountIdleTime(uint32_t t)
+{
+ idlecounter += t;
+}
void RA8875::ReportPerformance(Serial & pc)
{
pc.printf("\r\nPerformance Metrics\r\n");
for (int i=0; i<METRICCOUNT; i++) {
pc.printf("%10d uS %s\r\n", metrics[i], metricsName[i]);
- }
+ }
+ pc.printf("Idle Counter: %u\r\n", idlecounter);
}
#endif
@@ -355,12 +361,41 @@
unsigned char data;
select(true);
- spiwrite(0xC0);
+ spiwrite(0xC0); // These two bits are for the special "Status Read" [STSR]
data = spiread();
select(false);
return data;
}
+/// @todo add a timeout and return false, but how long
+/// to wait since some operations can be very long.
+bool RA8875::_WaitWhileBusy(uint8_t mask)
+{
+ int i = 20000/POLLWAITuSec; // 20 msec max
+
+ while (i-- && ReadStatus() & mask)
+ wait_us(POLLWAITuSec);
+ if (i)
+ return true;
+ else
+ return false;
+}
+
+/// @todo add a timeout and return false, but how long
+/// to wait since some operations can be very long.
+bool RA8875::_WaitWhileReg(uint8_t reg, uint8_t mask)
+{
+ int i = 20000/POLLWAITuSec; // 20 msec max
+
+ while (i-- && ReadCommand(reg) & mask)
+ wait_us(POLLWAITuSec);
+ if (i)
+ return true;
+ else
+ return false;
+}
+
+
dim_t RA8875::fontwidth(void)
{
@@ -599,8 +634,7 @@
WriteCommand(0x02); // RA8875 Internal Fonts
select(true);
WriteData(c);
- while (ReadStatus() & 0x80)
- wait_us(POLLWAITuSec); // Chk_Busy();
+ _WaitWhileBusy(0x80);
select(false);
}
}
@@ -657,8 +691,7 @@
while (*string != '\0') {
WriteData(*string);
++string;
- while (ReadStatus() & 0x80)
- wait_us(POLLWAITuSec); // Chk_Busy();
+ _WaitWhileBusy(0x80);
}
select(false);
#endif
@@ -729,8 +762,7 @@
{
PERFORMANCE_RESET;
WriteCommand(0x8E, (region == ACTIVEWINDOW) ? 0xC0 : 0x80);
- while (ReadCommand(0x8E) & 0x80)
- wait_us(POLLWAITuSec);
+ _WaitWhileReg(0x8E, 0x80);
REGISTERPERFORMANCE(PRF_CLS);
return noerror;
}
@@ -854,8 +886,7 @@
unsigned char drawCmd = 0x00; // Line
WriteCommand(0x90, drawCmd);
WriteCommand(0x90, 0x80 + drawCmd); // Start drawing.
- while (ReadCommand(0x90) & 0x80) // await completion.
- wait_us(POLLWAITuSec);
+ _WaitWhileReg(0x90, 0x80);
}
REGISTERPERFORMANCE(PRF_DRAWLINE);
return noerror;
@@ -897,8 +928,7 @@
drawCmd |= 0x20;
WriteCommand(0x90, drawCmd);
WriteCommand(0x90, 0x80 + drawCmd); // Start drawing.
- while (ReadCommand(0x90) & 0x80) // await completion.
- wait_us(POLLWAITuSec);
+ _WaitWhileReg(0x90, 0x80);
}
REGISTERPERFORMANCE(PRF_DRAWRECTANGLE);
return noerror;
@@ -950,9 +980,7 @@
drawCmd |= 0x40;
WriteCommand(0xA0, drawCmd);
WriteCommand(0xA0, 0x80 + drawCmd); // Start drawing.
- while (ReadCommand(0xA0) & 0x80) { // await completion.
- wait_us(POLLWAITuSec);
- }
+ _WaitWhileReg(0xA0, 0x80);
}
REGISTERPERFORMANCE(PRF_DRAWROUNDEDRECTANGLE);
return ret;
@@ -1001,8 +1029,7 @@
drawCmd |= 0x20;
WriteCommand(0x90, drawCmd);
WriteCommand(0x90, 0x80 + drawCmd); // Start drawing.
- while (ReadCommand(0x90) & 0x80) // await completion.
- wait_us(POLLWAITuSec);
+ _WaitWhileReg(0x90, 0x80);
}
REGISTERPERFORMANCE(PRF_DRAWTRIANGLE);
return ret;
@@ -1042,8 +1069,7 @@
drawCmd |= 0x20;
WriteCommand(0x90, drawCmd);
WriteCommand(0x90, 0x40 + drawCmd); // Start drawing.
- while (ReadCommand(0x90) & 0x40) // await completion.
- wait_us(POLLWAITuSec);
+ _WaitWhileReg(0x90, 0x40);
}
REGISTERPERFORMANCE(PRF_DRAWCIRCLE);
return ret;
@@ -1083,8 +1109,7 @@
drawCmd |= 0x40;
WriteCommand(0xA0, drawCmd);
WriteCommand(0xA0, 0x80 + drawCmd); // Start drawing.
- while (ReadCommand(0xA0) & 0x80) // await completion.
- wait_us(POLLWAITuSec);
+ _WaitWhileReg(0xA0, 0x80);
}
REGISTERPERFORMANCE(PRF_DRAWELLIPSE);
return ret;
@@ -1093,6 +1118,8 @@
RetCode_t RA8875::frequency(unsigned long Hz)
{
+ spiwritefreq = Hz;
+ spireadfreq = Hz/2;
spi.frequency(Hz);
// __ ___
// Clock ___A Rising edge latched
@@ -1265,7 +1292,9 @@
unsigned char retval;
unsigned char data = 0;
+ spi.frequency(spireadfreq);
retval = spi.write(data);
+ spi.frequency(spiwritefreq);
return retval;
}
@@ -1280,7 +1309,7 @@
RetCode_t RA8875::init(int width, int height, int color_bpp)
{
Backlight_u8(0);
- WriteCommand(0x88, 0x0a); // PLLC1 - Phase Lock Loop registers
+ WriteCommand(0x88, 0x0B); // PLLC1 - Phase Lock Loop registers
wait_ms(1);
WriteCommand(0x89, 0x02);
wait_ms(1);
--- a/RA8875.h Sun Aug 17 15:38:51 2014 +0000
+++ b/RA8875.h Sun Aug 31 14:37:37 2014 +0000
@@ -85,7 +85,6 @@
///
/// @todo Add Scroll support for text.
/// @todo Improve sync between internal and external font support - cursor, window, scroll.
-/// @todo Find out why it can't shift frequency after constructor runs.
/// @todo Add Hardware reset signal.
/// @todo Add Keypad Support.
/// @todo Add high level objects - x-y graph, meter, others... but these will
@@ -1200,17 +1199,23 @@
/// Set the SPI port frequency (in Hz).
///
- /// @note attempts to call this API at runtime, with the display
- /// already online, cause the system to lockup.
- /// Investigation continues.
+ /// This uses the mbed SPI driver, and is therefore dependent on
+ /// its capabilities. The RA8875 can accept writes via SPI faster
+ /// than a read can be performed. The frequency set by this API
+ /// is for the SPI writes. It will automatically reduce the SPI
+ /// clock rate when a read is performed, and restore it for the
+ /// next write.
///
- /// This uses the mbed SPI driver, and is therefore dependent on
- /// its capabilities. Limited tests were performed for the display
- /// in the range of 1,000,000 to 10,000,000 Hz. The display was
- /// a bit erratic above 5,000,000 Hz, so this became the default,
- /// even though it might have been the bench-level wiring that posed
- /// the limit.
+ /// @note The primary effect of this is to recover more CPU cycles
+ /// for your application code. Keep in mind that when more than
+ /// one command is sent to the display controller, that it
+ /// will wait for the controller to finish the prior command.
+ /// In this case, the performance is limited by the RA8875.
///
+ /// @param Hz is the frequency in Hz, tested range includes the
+ /// range from 1,000,000 (1MHz) to 10,000,000 (10 MHz). Values
+ /// outside this range will be accepted, but operation may
+ /// be unreliable.
/// @returns success/failure code. @see RetCode_t.
///
RetCode_t frequency(unsigned long Hz = RA8875_DEFAULT_SPI_FREQ);
@@ -1220,6 +1225,12 @@
/// Clear the performance metrics to zero.
void ClearPerformance();
+ /// Count idle time.
+ ///
+ /// @param t is the amount of idle time to accumulate.
+ ///
+ void CountIdleTime(uint32_t t);
+
/// Report the performance metrics for drawing functions using
/// the available serial channel.
///
@@ -1337,6 +1348,23 @@
///
RetCode_t select(bool chipsel);
+ /// Wait while the status register indicates the controller is busy.
+ ///
+ /// @param mask is the mask of bits to monitor.
+ /// @returns true if a normal exit.
+ /// @returns false if a timeout exit.
+ ///
+ bool _WaitWhileBusy(uint8_t mask);
+
+ /// Wait while the the register anded with the mask is true.
+ ///
+ /// @param reg is the register to monitor
+ /// @param mask is the bit mask to monitor
+ /// @returns true if it was a normal exit
+ /// @returns false if it was a timeout that caused the exit.
+ ///
+ bool _WaitWhileReg(uint8_t reg, uint8_t mask);
+
/// The most primitive - to write a data value to the SPI interface.
///
/// @param data is the value to write.
@@ -1356,6 +1384,8 @@
unsigned char spiread();
SPI spi; ///< spi port
+ unsigned long spiwritefreq; ///< saved write freq
+ unsigned long spireadfreq; ///< saved read freq
DigitalOut cs; ///< chip select pin, assumed active low
DigitalOut res; ///< reset pin, assumed active low
const unsigned char * font; ///< reference to an external font somewhere in memory
@@ -1378,6 +1408,7 @@
METRICCOUNT
} method_e;
unsigned long metrics[METRICCOUNT];
+ unsigned long idlecounter;
void RegisterPerformance(method_e method);
Timer performance;
#endif