diff --git a/ion/src/device/device.cpp b/ion/src/device/device.cpp index e7202dd73..4208795f8 100644 --- a/ion/src/device/device.cpp +++ b/ion/src/device/device.cpp @@ -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 diff --git a/ion/src/device/display.cpp b/ion/src/device/display.cpp index 3f8ef2e95..d10ede737 100644 --- a/ion/src/device/display.cpp +++ b/ion/src/device/display.cpp @@ -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; } } diff --git a/ion/src/device/display.h b/ion/src/device/display.h index 634b59449..f42185304 100644 --- a/ion/src/device/display.h +++ b/ion/src/device/display.h @@ -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))); } }