Merge "[ion/device] Migrate to 16-bits FSMC"

This commit is contained in:
Romain Goyet
2016-11-09 21:46:51 +01:00
committed by Gerrit
3 changed files with 81 additions and 61 deletions

View File

@@ -69,13 +69,14 @@ void Ion::Device::initClocks() {
// Peripheral clocks
// AHB1 bus
// Our peripherals are using GPIO A, B, C and D.
// Our peripherals are using GPIO A, B, C, D and E.
// We're not using the CRC nor DMA engines.
class RCC::AHB1ENR ahb1enr(0); // Reset value
ahb1enr.setGPIOAEN(true);
ahb1enr.setGPIOBEN(true);
ahb1enr.setGPIOCEN(true);
ahb1enr.setGPIODEN(true);
ahb1enr.setGPIOEEN(true);
RCC.AHB1ENR()->set(ahb1enr);
// APB1 bus

View File

@@ -37,8 +37,8 @@ namespace Device {
void init() {
// Turn on the reset pin
GPIOB.MODER()->setMode(13, GPIO::MODER::Mode::Output);
GPIOB.ODR()->set(13, true);
GPIOE.MODER()->setMode(9, GPIO::MODER::Mode::Output);
GPIOE.ODR()->set(9, true);
msleep(120);
@@ -53,41 +53,52 @@ void initGPIO() {
GPIOA.MODER()->setMode(2, GPIO::MODER::Mode::AlternateFunction);
GPIOA.MODER()->setMode(3, GPIO::MODER::Mode::AlternateFunction);
GPIOA.MODER()->setMode(4, GPIO::MODER::Mode::AlternateFunction);
GPIOA.MODER()->setMode(5, GPIO::MODER::Mode::AlternateFunction);
GPIOB.MODER()->setMode(14, GPIO::MODER::Mode::AlternateFunction);
GPIOB.MODER()->setMode(12, GPIO::MODER::Mode::AlternateFunction);
GPIOC.MODER()->setMode(3, GPIO::MODER::Mode::AlternateFunction);
GPIOC.MODER()->setMode(4, GPIO::MODER::Mode::AlternateFunction);
GPIOC.MODER()->setMode(5, GPIO::MODER::Mode::AlternateFunction);
GPIOC.MODER()->setMode(6, GPIO::MODER::Mode::AlternateFunction);
GPIOC.MODER()->setMode(11, GPIO::MODER::Mode::AlternateFunction);
GPIOC.MODER()->setMode(12, GPIO::MODER::Mode::AlternateFunction);
GPIOD.MODER()->setMode(0, GPIO::MODER::Mode::AlternateFunction);
GPIOD.MODER()->setMode(1, GPIO::MODER::Mode::AlternateFunction);
GPIOD.MODER()->setMode(4, GPIO::MODER::Mode::AlternateFunction);
GPIOD.MODER()->setMode(5, GPIO::MODER::Mode::AlternateFunction);
GPIOD.MODER()->setMode(7, GPIO::MODER::Mode::AlternateFunction);
GPIOD.MODER()->setMode(9, GPIO::MODER::Mode::AlternateFunction);
GPIOD.MODER()->setMode(10, GPIO::MODER::Mode::AlternateFunction);
GPIOD.MODER()->setMode(11, GPIO::MODER::Mode::AlternateFunction);
GPIOD.MODER()->setMode(14, GPIO::MODER::Mode::AlternateFunction);
GPIOD.MODER()->setMode(15, GPIO::MODER::Mode::AlternateFunction);
GPIOD.MODER()->setMode(2, GPIO::MODER::Mode::AlternateFunction);
GPIOE.MODER()->setMode(10, GPIO::MODER::Mode::AlternateFunction);
GPIOE.MODER()->setMode(11, GPIO::MODER::Mode::AlternateFunction);
GPIOE.MODER()->setMode(12, GPIO::MODER::Mode::AlternateFunction);
GPIOE.MODER()->setMode(13, GPIO::MODER::Mode::AlternateFunction);
GPIOE.MODER()->setMode(14, GPIO::MODER::Mode::AlternateFunction);
GPIOE.MODER()->setMode(15, GPIO::MODER::Mode::AlternateFunction);
/* More precisely, we want to use the FSMC alternate function.
* Oddly enough, this isn't always the same AF number. That equals to:
* AF12 for PA2,3,4,5
* AF10 for PB14
* AF12 for PC3,4,5
* AF10 for PC6,11,12
* AF10 for PD2 */
/* More precisely, we want to use the FSMC alternate function. In our case,
* it is always Alternate Function number 12. */
GPIOA.AFR()->setAlternateFunction(2, GPIO::AFR::AlternateFunction::AF12);
GPIOA.AFR()->setAlternateFunction(3, GPIO::AFR::AlternateFunction::AF12);
GPIOA.AFR()->setAlternateFunction(4, GPIO::AFR::AlternateFunction::AF12);
GPIOA.AFR()->setAlternateFunction(5, GPIO::AFR::AlternateFunction::AF12);
GPIOB.AFR()->setAlternateFunction(14, GPIO::AFR::AlternateFunction::AF10);
GPIOB.AFR()->setAlternateFunction(12, GPIO::AFR::AlternateFunction::AF12);
GPIOC.AFR()->setAlternateFunction(3, GPIO::AFR::AlternateFunction::AF12);
GPIOC.AFR()->setAlternateFunction(4, GPIO::AFR::AlternateFunction::AF12);
GPIOC.AFR()->setAlternateFunction(5, GPIO::AFR::AlternateFunction::AF12);
GPIOC.AFR()->setAlternateFunction(6, GPIO::AFR::AlternateFunction::AF10);
GPIOC.AFR()->setAlternateFunction(11, GPIO::AFR::AlternateFunction::AF10);
GPIOC.AFR()->setAlternateFunction(12, GPIO::AFR::AlternateFunction::AF10);
GPIOD.AFR()->setAlternateFunction(0, GPIO::AFR::AlternateFunction::AF12);
GPIOD.AFR()->setAlternateFunction(1, GPIO::AFR::AlternateFunction::AF12);
GPIOD.AFR()->setAlternateFunction(4, GPIO::AFR::AlternateFunction::AF12);
GPIOD.AFR()->setAlternateFunction(5, GPIO::AFR::AlternateFunction::AF12);
GPIOD.AFR()->setAlternateFunction(7, GPIO::AFR::AlternateFunction::AF12);
GPIOD.AFR()->setAlternateFunction(9, GPIO::AFR::AlternateFunction::AF12);
GPIOD.AFR()->setAlternateFunction(10, GPIO::AFR::AlternateFunction::AF12);
GPIOD.AFR()->setAlternateFunction(11, GPIO::AFR::AlternateFunction::AF12);
GPIOD.AFR()->setAlternateFunction(14, GPIO::AFR::AlternateFunction::AF12);
GPIOD.AFR()->setAlternateFunction(15, GPIO::AFR::AlternateFunction::AF12);
GPIOD.AFR()->setAlternateFunction(2, GPIO::AFR::AlternateFunction::AF10);
GPIOE.AFR()->setAlternateFunction(10, GPIO::AFR::AlternateFunction::AF12);
GPIOE.AFR()->setAlternateFunction(11, GPIO::AFR::AlternateFunction::AF12);
GPIOE.AFR()->setAlternateFunction(12, GPIO::AFR::AlternateFunction::AF12);
GPIOE.AFR()->setAlternateFunction(13, GPIO::AFR::AlternateFunction::AF12);
GPIOE.AFR()->setAlternateFunction(14, GPIO::AFR::AlternateFunction::AF12);
GPIOE.AFR()->setAlternateFunction(15, GPIO::AFR::AlternateFunction::AF12);
}
void initFSMC() {
@@ -104,14 +115,14 @@ void initFSMC() {
// Control register
FSMC.BCR(4)->setMWID(FSMC::BCR::MWID::EIGHT_BITS);
FSMC.BCR(4)->setWREN(true);
FSMC.BCR(4)->setMBKEN(true);
FSMC.BCR(FSMCMemoryBank)->setMWID(FSMC::BCR::MWID::SIXTEEN_BITS);
FSMC.BCR(FSMCMemoryBank)->setWREN(true);
FSMC.BCR(FSMCMemoryBank)->setMBKEN(true);
// Timing register
FSMC.BTR(4)->setADDSET(0);
FSMC.BTR(4)->setDATAST(0);
FSMC.BTR(4)->setBUSTURN(0);
FSMC.BTR(FSMCMemoryBank)->setADDSET(6);
FSMC.BTR(FSMCMemoryBank)->setDATAST(6);
FSMC.BTR(FSMCMemoryBank)->setBUSTURN(6);
}
void initPanel() {
@@ -180,20 +191,14 @@ void setDrawingArea(KDRect r) {
}
void pushPixels(const KDColor * pixels, size_t numberOfPixels) {
uint8_t * bytePixelPointer = (uint8_t *)pixels;
size_t i = 2*numberOfPixels;
while (i--) {
*DataAddress = *bytePixelPointer++;
while (numberOfPixels--) {
*DataAddress = *pixels++;
}
}
void pushColor(KDColor color, size_t numberOfPixels) {
uint8_t firstByte = color;
uint8_t secondByte = (color >> 8);
size_t i = numberOfPixels;
while (i--) {
*DataAddress = firstByte;
*DataAddress = secondByte;
while (numberOfPixels--) {
*DataAddress = color;
}
}

View File

@@ -11,22 +11,30 @@ namespace Ion {
namespace Display {
namespace Device {
/* Pin | Role | Mode | Function
* -----+-------------------+-----------------------+----------
* PA2 | LCD D4 | Alternate Function 12 | FMSC_D4
/* Pin | Role | Mode | Function | Note
* -----+-------------------+-----------------------+----------|
* PA2 | LCD D4 | Alternate Function 12 | FSMC_D4 |
* PA3 | LCD D5 | Alternate Function 12 | FSMC_D5
* PA4 | LCD D6 | Alternate Function 12 | FSMC_D6
* PA5 | LCD D7 | Alternate Function 12 | FSMC_D7
* PB13 | LCD reset | Output |
* PB14 | LCD D0 | Alternate Function 12 | FSMC_D0
* PC3 | LCD data/command | Alternate Function 12 | FSMC_A0
* PC4 | LCD chip select | Alternate Function 12 | FSMC_NE4
* PC5 | LCD read signal | Alternate Function 12 | FSMC_NOE
* PC6 | LCD D1 | Alternate Function 12 | FSMC_D7
* PC9 | LCD backlight | Alternate Function 12 | TIM3_CH4
* PC11 | LCD D2 | Alternate Function 12 | FSMC_D2
* PC12 | LCD D3 | Alternate Function 12 | FSMC_D3
* PD2 | LCD write signal | Alternate Function 12 | FSMC_NWE
* PB12 | LCD D13 | Alternate Function 12 | FSMC_D13 |
* PD0 | LCD D2 | Alternate Function 12 | FSMC_D2
* PD1 | LCD D3 | Alternate Function 12 | FSMC_D3
* PD4 | LCD read signal | Alternate Function 12 | FSMC_NOE
* PD5 | LCD write signal | Alternate Function 12 | FSMC_NWE
* PD7 | LCD chip select | Alternate Function 12 | FSMC_NE1 | Memory bank 1
* PD9 | LCD D14 | Alternate Function 12 | FSMC_D14
* PD10 | LCD D15 | Alternate Function 12 | FSMC_D15
* PD11 | LCD data/command | Alternate Function 12 | FSMC_A16 | Data/Command is address bit 16
* PD14 | LCD D0 | Alternate Function 12 | FSMC_D0
* PD15 | LCD D1 | Alternate Function 12 | FSMC_D1
* PE9 | LCD reset | Output |
* PE10 | LCD D7 | Alternate Function 12 | FSMC_D7
* PE11 | LCD D8 | Alternate Function 12 | FSMC_D8
* PE12 | LCD D9 | Alternate Function 12 | FSMC_D9
* PE13 | LCD D10 | Alternate Function 12 | FSMC_D10
* PE14 | LCD D11 | Alternate Function 12 | FSMC_D11
* PE15 | LCD D12 | Alternate Function 12 | FSMC_D12
*/
void init();
@@ -40,7 +48,7 @@ void setDrawingArea(KDRect r);
void pushPixels(const KDColor * pixels, size_t numberOfPixels);
void pushColor(KDColor color, size_t numberOfPixels);
enum class Command : uint8_t {
enum class Command : uint16_t {
Nop = 0x00,
Reset = 0x01,
SleepIn = 0x10,
@@ -71,8 +79,14 @@ enum class Command : uint8_t {
PumpRatioControl = 0xF7,
};
static volatile Command * const CommandAddress = (Command *)0x6C000000;
static volatile uint8_t * const DataAddress = (uint8_t *)0x6C000001;
constexpr static int FSMCMemoryBank = 1;
constexpr static int FSMCDataCommandAddressBit = 16;
constexpr static uint32_t FSMCBaseAddress = 0x60000000;
constexpr static uint32_t FSMCBankAddress = FSMCBaseAddress + (FSMCMemoryBank-1)*0x04000000;
static volatile Command * const CommandAddress = (Command *)(FSMCBankAddress);
static volatile uint16_t * const DataAddress = (uint16_t *)(FSMCBankAddress | (1<<(FSMCDataCommandAddressBit+1)));
}
}