Subdirectory provided by Embedded Artists

Dependencies:   DM_FATFileSystem DM_HttpServer DM_USBHost EthernetInterface USBDevice mbed-rpc mbed-rtos mbed-src

Dependents:   lpc4088_displaymodule_hello_world_Sept_2018

Fork of DMSupport by Embedded Artists

DMBoard.cpp

Committer:
embeddedartists
Date:
2014-12-03
Revision:
3:2fa7755f2cef
Parent:
2:887c6b45e7fa
Child:
4:6fdcdf7aff8d

File content as of revision 3:2fa7755f2cef:

/*
 *  Copyright 2014 Embedded Artists AB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "mbed.h"
#include "DMBoard.h"
#include "InternalEEPROM.h"

#if defined(DM_BOARD_USE_TOUCH)
  #include "AR1021.h"
#endif

/******************************************************************************
 * Defines and typedefs
 *****************************************************************************/

#if defined(DM_BOARD_DISABLE_STANDARD_PRINTF)
class DevNull : public Stream {
 
public:
    DevNull(const char *name=NULL) : Stream(name) {}
 
protected:
    virtual int _getc()      {return 0;}
    virtual int _putc(int c) {return c;}
};
 
static DevNull null("null");
#endif

/******************************************************************************
 * Local variables
 *****************************************************************************/

/******************************************************************************
 * Private Functions
 *****************************************************************************/

DMBoard::DMBoard() : 
    _initialized(false),
#if defined(DM_BOARD_USE_MCI_FS)
    _mcifs("mci", P4_16),
#endif
#if defined(DM_BOARD_USE_QSPI_FS)
    _qspifs("qspi"),
#endif
#if defined(DM_BOARD_USE_TOUCH)
    _touch(NULL),
#endif
    _buzzer(P1_5),
    _button(p23),
    _led1(LED1),
    _led2(LED2),
    _led3(LED3),
    _led4(LED4)
{
}

DMBoard::~DMBoard()
{
#if defined(DM_BOARD_USE_TOUCH)
  if (_touch != NULL) {
    delete _touch;
    _touch = NULL;
  }
#endif
}

DMBoard::BoardError DMBoard::readConfiguration()
{
  InternalEEPROM mem;
  mem.init();
  
  uint8_t* buff = (uint8_t*)malloc(mem.memorySize());
  mem.read(0, 0, buff, mem.memorySize());
  mem.powerDown();
#if 0  
  uint8_t* p = buff;
  _logger.printf("\n-------\nBEFORE:\n-------\n");
  for (int i = 0; i < 63; i++) {
    for (int j = 0; j < 4; j++) {
      _logger.printf("0x%04x  %02x %02x %02x %02x %02x %02x %02x %02x  %02x %02x %02x %02x %02x %02x %02x %02x\n",
        i,
        p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],
        p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);
      p += 16;
    }
    _logger.printf("\n");
  }
  
  // find first non-zero page and write to that
  for (int page = 0; page < mem.numPages(); page++) {
    bool zeroPage = true;
    for (int i = 0; i < mem.pageSize(); i++) {
      if (buff[i + page*mem.pageSize()] != 0) {
        zeroPage = false;
        break;
      }
    }
    if (zeroPage) {
      _logger.printf("Will fill page 0x%04x (%d) with 0x00..0x3f\n", page, page);
      p = buff;
      for (int i = 0; i < mem.pageSize(); i++) {
        *p++ = i;
      }
      mem.write(page, 0, buff, mem.pageSize());
      memset(buff, 0, mem.memorySize());
      mem.read(0, 0, buff, mem.memorySize());
      p = buff;
      _logger.printf("\n-------\nAFTER:\n-------\n");
      for (int i = 0; i < 63; i++) {
        for (int j = 0; j < 4; j++) {
          _logger.printf("0x%04x  %02x %02x %02x %02x %02x %02x %02x %02x  %02x %02x %02x %02x %02x %02x %02x %02x\n",
            i,
            p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],
            p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);
          p += 16;
        }
        _logger.printf("\n");
      }
      break;
    }
  }  
#endif
  return Ok;
}

#if defined(DM_BOARD_USE_DISPLAY)
DMBoard::BoardError DMBoard::readDisplayConfiguration(uint8_t** data, uint32_t* size)
{
  uint32_t allocsize = 17*sizeof(uint32_t);
  uint32_t* stuff = (uint32_t*)malloc(allocsize);
  if (stuff == NULL) {
    return MemoryError;
  }
#if defined(DM_BOARD_USE_4_3_DISPLAY_TMP)
  // Temporary setup, for a 4.3" display

  stuff[ 0] = 40,    //horizontalBackPorch == HSYNC back porch
  stuff[ 1] = 5,     //horizontalFrontPorch == HSYNC front porch
  stuff[ 2] = 2,     //hsync  ==  HSYNC width
  stuff[ 3] = 480,   //width == Horizontal active area
  stuff[ 4] = 8,     //verticalBackPorch == VSYNC back porch
  stuff[ 5] = 8,     //verticalFrontPorch == VSYNC front porch
  stuff[ 6] = 2,     //vsync == VSYNC width
  stuff[ 7] = 272,   //height == Vertical display area
  stuff[ 8] = false,
  stuff[ 9] = false,
  stuff[10] = true,
  stuff[11] = true,
  stuff[12] = 1,
  stuff[13] = Display::Resolution_16bit_rgb565;
  stuff[14] = 9000000, //clock or 0 for external
  stuff[15] = 0,       //LcdController::Tft,
  stuff[16] = false;
#else
  // Temporary setup, for a 5" rogin display

  stuff[ 0] = 46,    //horizontalBackPorch == HSYNC back porch
  stuff[ 1] = 20,    //horizontalFrontPorch == HSYNC front porch
  stuff[ 2] = 2,     //hsync  ==  HSYNC width
  stuff[ 3] = 800,   //width == Horizontal active area
  stuff[ 4] = 23,    //verticalBackPorch == VSYNC back porch
  stuff[ 5] = 10,    //verticalFrontPorch == VSYNC front porch
  stuff[ 6] = 3,     //vsync == VSYNC width
  stuff[ 7] = 480,   //height == Vertical display area
  stuff[ 8] = false,
  stuff[ 9] = false,
  stuff[10] = true,
  stuff[11] = true,
  stuff[12] = 1,
  stuff[13] = Display::Resolution_16bit_rgb565;
  stuff[14] = 30000000, //clock or 0 for external
  stuff[15] = 0,        //LcdController::Tft,
  stuff[16] = false;
#endif  
  *data = (uint8_t*)&(stuff[0]);
  *size = allocsize;

  return Ok;
}
#endif

/******************************************************************************
 * Public Functions
 *****************************************************************************/

DMBoard::BoardError DMBoard::init()
{
  BoardError err = Ok;
  if (!_initialized) {
    do {
      // Turn off the buzzer
      _buzzer.period_ms(1);
      _buzzer = 0;
      
      // Make sure the button is configured correctly
      _button.mode(PullUp);
    
      // Turn off all LEDs
      _led1 = 1;
      _led2 = 1;
      _led3 = 0;
      _led4 = 0;

      // Make sure that the logger is always initialized even if
      // other initialization tasks fail
      _logger.init();

#if defined(DM_BOARD_DISABLE_STANDARD_PRINTF)
      // Kill all ouput of calls to printf() so that there is no
      // simultaneous calls into the non-thread-safe standard libraries.
      // User code should use the RtosLogger anyway.
      freopen("/null", "w", stdout);
#endif

#if defined(DM_BOARD_USE_QSPI) || defined(DM_BOARD_USE_QSPI_FS)
      if (SPIFI::instance().init() != SPIFI::Ok) {
        err = SpifiError;
        break;
      }
#endif
      
      readConfiguration();
      
#if defined(DM_BOARD_USE_DISPLAY)
      if (Display::instance().init() != Display::Ok) {
        err = DisplayError;
        break;
      }
#endif
      
#if defined(DM_BOARD_USE_TOUCH)
      //if (... configuration says AR1021...) {
        _touch = new AR1021(P2_27, P2_26, P2_22, P2_23, P2_25);
        if (!_touch->init(Display::instance().width(), Display::instance().height())) {
          err = TouchError;
          break;
        }
      //}
#endif

      
      _initialized = true;
    } while(0);
  }
  return err;
}

void DMBoard::setLED(Leds led, bool on)
{
  switch(led) {
    case Led1:
      _led1 = (on ? 0 : 1);
      break;
    case Led2:
      _led2 = (on ? 0 : 1);
      break;
    case Led3:
      _led3 = (on ? 1 : 0);
      break;
    case Led4:
      _led4 = (on ? 1 : 0);
      break;
  }
}

void DMBoard::buzzer(float value)
{
  if (value < 0) {
    value = 0;
  } else if (value > 1) {
    value = 1;
  }
  _buzzer = value;
}

bool DMBoard::buttonPressed()
{ 
  return _button.read() == 0;
}