Changeset - 7476de768f19
[Not reviewed]
default
0 4 0
Ethan Zonca - 10 years ago 2014-07-10 23:02:21
ez@ethanzonca.com
Refactor of oled driver
4 files changed with 114 insertions and 133 deletions:
0 comments (0 inline, 0 general)
libraries/oleddrv/bsp.h
Show inline comments
 
@@ -49,19 +49,19 @@ D1/Data 3  4  D0/Clk
 
#define   IsLedOn()       (!(GPIOA->ODR & GPIO_Pin_8))
 
#define   LED_ON()        GPIOA->BRR = GPIO_Pin_8
 
#define   LED_OFF()       GPIOA->BSRR = GPIO_Pin_8
 
#define   ToggleLED()     if(GPIOA->ODR & GPIO_Pin_8){GPIOA->BRR = GPIO_Pin_8;}\
 
                          else{GPIOA->BSRR = GPIO_Pin_8;}
 
#define   GSel1_High()    GPIOB->BSRR = GPIO_Pin_9
 
#define   GSel1_Low()     GPIOB->BRR = GPIO_Pin_9
 
 
#define   MMA_SLEEP()     GPIOB->BRR = GPIO_Pin_11
 
#define   MMA_WAKEUP()    GPIOB->BSRR = GPIO_Pin_11
 
#define   Is_MMA_WAKEUP() (GPIOB->ODR & GPIO_Pin_11)
 
 
#define   DMA_SSD_1303    DMA1_Channel5
 
#define   DMA_Handler_SSD_1303    DMA1_Channel5_IRQHandler
 
#define   DMA_SSD_1306    DMA1_Channel5
 
#define   DMA_Handler_SSD_1306    DMA1_Channel5_IRQHandler
 
 
 
#define   Is_Enc_Key_Down()    (!(GPIOA->IDR & GPIO_Pin_0))
 
 
#endif
main.c
Show inline comments
 
#include "main.h"
 
#include "stm32l100c_discovery.h"
 
#include "ssd1306.h"
 
 
#define LED_POWER GPIOB,GPIO_Pin_9
 
#define LED_STAT  GPIOA,GPIO_Pin_15
 
 
static __IO uint32_t TimingDelay;
 
 
void init_gpio();
 
void init_spi();
 
 
/* Main */
 
int main(void)
 
{
 
 
    // Hopefully init clocks
 
    // Init clocks
 
    SystemInit();
 
    RCC_ClocksTypeDef RCC_Clocks;
 
 
    //SysTick end of count event each 1ms
 
    RCC_GetClocksFreq(&RCC_Clocks);
 
    SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
 
 
    GPIO_ResetBits(LED_STAT);
 
    Delay(100);
 
 
    init_gpio();
 
    init_spi();
 
 
    //SSD1302_Init();
 
    //ssd1306_Init();
 
    //SSD1303_DrawPoint(3,3,1);
 
    //SSD1303_DrawPoint(5,5,0);
 
 
    GPIO_SetBits(LED_POWER);
 
    Delay(500);
 
    GPIO_ResetBits(LED_POWER);
 
 
    while(1)
 
    {  
 
        /* Turn on LD0 Blue LED during 1s each time User button is pressed */
 
        //STM_EVAL_LEDOn(LED4);
 
        GPIO_SetBits(LED_POWER);
 
        //STM_EVAL_LEDOn(LED3);
 
 
        /* wait for 1s */
 
        Delay(150);
 
 
        /* Turn off LD4 Blue LED after 1s each time User button is pressed */
 
        //STM_EVAL_LEDOff(LED4);
 
        GPIO_ResetBits(LED_POWER);
 
        Delay(150);
 
    }
 
}
 
 
/**
 
  * @brief  Inserts a delay time.
 
  * @param  nTime: specifies the delay time length, in 1 ms.
 
  * @retval None
 
  */
 
void Delay(__IO uint32_t nTime)
 
{
 
  TimingDelay = nTime;
 
 
  while(TimingDelay != 0);
 
}
 
 
/**
 
  * @brief  Decrements the TimingDelay variable.
 
  * @param  None
 
  * @retval None
 
  */
 
void TimingDelay_Decrement(void)
 
{
 
  if (TimingDelay != 0x00)
 
  { 
 
    TimingDelay--;
 
  }
 
}
 
 
 
 
void init_spi(void) {
 
void init_spi(void)
 
{
 
    SPI_InitTypeDef  SPI_InitStructure;
 
 
    // OLED IC
 
    SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
 
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
 
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
 
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
 
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
 
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
 
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
 
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
 
    SPI_InitStructure.SPI_CRCPolynomial = 7;
 
@@ -105,42 +96,32 @@ void init_spi(void) {
 
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
 
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
 
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
 
    SPI_InitStructure.SPI_CRCPolynomial = 7;
 
    SPI_Init(SPI2, &SPI_InitStructure);
 
    SPI_Cmd(SPI2, ENABLE);           /* Enable the SPI */
 
}
 
 
void init_gpio(void) {
 
 
 GPIO_InitTypeDef GPIO_InitStruct;
 
 
  /** Configure pins as 
 
        * Analog 
 
        * Input 
 
        * Output
 
        * EVENT_OUT
 
        * EXTI
 
  */
 
 
  /*Enable or disable the APB peripheral clock */
 
 
 
 
  // Enable SPI clocks
 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
 
 
  // Enable GPIO clocks
 
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOB|RCC_AHBPeriph_GPIOA, ENABLE);
 
 
  // Enable DMA clocks (Is AHB even the right thing???)
 
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // EMZ TODO get the right ones
 
 
  /*Configure GPIO pin : PC */
 
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
 
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
 
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
 
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
 
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_400KHz;
 
  GPIO_Init(GPIOC, &GPIO_InitStruct);
 
 
  /*Configure GPIO pin : PB */
 
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_10|GPIO_Pin_12 
ssd1306.c
Show inline comments
 
/*******************************************************************************
 
* File Name          : SSD1303.c
 
* File Name          : ssd1306.c
 
* Author             : lxyppc
 
* Version            : V1.0
 
* Date               : 10-01-21
 
* Description        : SSD1303 operations
 
*                      the SSH1101A is compatible with SSD1303
 
* Description        : ssd1306 operations
 
*                      the SSH1101A is compatible with ssd1306
 
*******************************************************************************/
 
 
/* Includes ------------------------------------------------------------------*/
 
#include "stm32l100c_discovery.h"
 
#include "bsp.h"
 
#include "ssd1306.h"
 
#include "DrawText.h"
 
 
/* Private typedef -----------------------------------------------------------*/
 
/* Private define ------------------------------------------------------------*/
 
#define   SSD1303_PAGE_NUMBER           8
 
#define   SSD1303_COLUMN_NUMBER         128
 
#define   SSD1303_COLUMN_MARGIN_START   2
 
#define   SSD1303_COLUMN_MARGIN_END     2
 
#define   SSD1303_X_PIXEL   128
 
#define   SSD1303_Y_PIXEL   64
 
#define   SSD1306_PAGE_NUMBER           8
 
#define   SSD1306_COLUMN_NUMBER         128
 
#define   SSD1306_COLUMN_MARGIN_START   2
 
#define   SSD1306_COLUMN_MARGIN_END     2
 
#define   SSD1306_X_PIXEL   128
 
#define   SSD1306_Y_PIXEL   64
 
 
/* Private macro -------------------------------------------------------------*/
 
#define   SSD1303_Buffer    (_SSD1303_Buffer + SSD1303_COLUMN_MARGIN_START)
 
#define   ssd1306_Buffer    (_SSD1306_Buffer + SSD1306_COLUMN_MARGIN_START)
 
 
/* Private variables ---------------------------------------------------------*/
 
static  uint8_t  _SSD1303_Buffer[SSD1303_COLUMN_NUMBER*SSD1303_PAGE_NUMBER + SSD1303_COLUMN_MARGIN_START + SSD1303_COLUMN_MARGIN_END] = {0};
 
static  uint8_t  _SSD1306_Buffer[SSD1306_COLUMN_NUMBER*SSD1306_PAGE_NUMBER + SSD1306_COLUMN_MARGIN_START + SSD1306_COLUMN_MARGIN_END] = {0};
 
static  uint8_t  pageIndex = 0;
 
static  uint8_t  iS_SSD_On = 0;
 
static  uint8_t  pre_on = 0;
 
static  uint8_t  curContrast = 0xCC;
 
static  uint8_t  lastContrast = 0xCC;
 
 
/* Private function prototypes -----------------------------------------------*/
 
void  WriteCommand(unsigned char command);
 
void  WriteData(unsigned char data);
 
void  OnPageTransferDone(void);
 
unsigned long SSD1303_OFF(void);
 
unsigned long SSD1303_ON(void);
 
unsigned char* SSD1303_GetBuffer()
 
unsigned long ssd1306_OFF(void);
 
unsigned long ssd1306_ON(void);
 
unsigned char* ssd1306_GetBuffer()
 
{
 
  return SSD1303_Buffer;
 
  return ssd1306_Buffer;
 
}
 
/*******************************************************************************
 
* Function Name  : WriteCommand
 
* Description    : Write command to the SSD1303
 
* Description    : Write command to the ssd1306
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
void WriteCommand(unsigned char command)
 
{
 
  SSD_A0_Low();
 
  SPI_SendByte(command);
 
  SPI_Wait();
 
}
 
 
/*******************************************************************************
 
* Function Name  : WriteData
 
* Description    : Write data to the SSD1303
 
* Description    : Write data to the ssd1306
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
void WriteData(unsigned char data)
 
{
 
  SSD_A0_High();
 
  SPI_SendByte(data);
 
  SPI_Wait();
 
}
 
 
/*******************************************************************************
 
* Function Name  : SSD1303_Init
 
* Description    : Initialize the SSD1303
 
* Function Name  : ssd1306_Init
 
* Description    : Initialize the ssd1306
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
void SSD1303_Init(void)
 
void ssd1306_Init(void)
 
{
 
 
  /* Generate a reset */
 
  SSD_Reset_Low();
 
  uint32_t i;
 
  for(i=5000; i>1; i--) 
 
  SSD_Reset_High();
 
  
 
  /*************************************************
 
  // SSD1303 Initialization Command
 
  // ssd1306 Initialization Command
 
  *************************************************/
 
  // Lower Column Address
 
  WriteCommand(0x00); /* Set Lower Column Address */
 
  GPIO_SetBits(GPIOA,GPIO_Pin_15);
 
  // High Column Address
 
  WriteCommand(0x10); /* Set Higher Column Address*/
 
  // Display Start Line
 
  WriteCommand(0x40); /* Set Display Start Line */
 
#ifdef    DEBUG_BOARD
 
  curContrast = lastContrast = 0x30;
 
#else
 
  curContrast = lastContrast = 0xCF;
 
@@ -146,391 +146,391 @@ void SSD1303_Init(void)
 
  WriteCommand(0xc8);/* Set COM scan direction */
 
  
 
  // For SSD1306 Set the address mode
 
  WriteCommand(0x20);/* Set address mode */
 
  WriteCommand(0x00);/* Set address mode horizontal */
 
  
 
  // Set the page start address
 
  WriteCommand(0xb0);
 
  WriteCommand(0x00);
 
  WriteCommand(0x10);
 
  
 
  /* Turn on the controller */
 
  pre_on = SSD1303_ON();
 
  pre_on = ssd1306_ON();
 
//  // Set Charge pump
 
//  WriteCommand(0x8D); /* Set Charge pump */
 
//  WriteCommand(0x14); /* 0x14=ON, 0x10=Off */
 
//  
 
//  // Turn on the display
 
//  WriteCommand(0xaf);
 
}
 
 
/*******************************************************************************
 
* Function Name  : SSD1303_TurnOff
 
* Description    : Turn off the SSD1303 controller
 
* Function Name  : ssd1306_TurnOff
 
* Description    : Turn off the ssd1306 controller
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
unsigned long SSD1303_TurnOff(void)
 
unsigned long ssd1306_TurnOff(void)
 
{
 
  pre_on = 0;
 
  return iS_SSD_On;
 
}
 
 
/*******************************************************************************
 
* Function Name  : SSD1303_TurnOn
 
* Description    : Turn off the SSD1303 controller
 
* Function Name  : ssd1306_TurnOn
 
* Description    : Turn off the ssd1306 controller
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
unsigned long SSD1303_TurnOn(void)
 
unsigned long ssd1306_TurnOn(void)
 
{
 
  pre_on = 1;
 
  return iS_SSD_On;
 
}
 
 
/*******************************************************************************
 
* Function Name  : SSD1303_SetContrast
 
* Description    : Set the SSD1303 contrast
 
* Function Name  : ssd1306_SetContrast
 
* Description    : Set the ssd1306 contrast
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
unsigned char SSD1303_SetContrast(unsigned char contrast)
 
unsigned char ssd1306_SetContrast(unsigned char contrast)
 
{
 
  curContrast = contrast;
 
  return lastContrast;
 
}
 
 
/*******************************************************************************
 
* Function Name  : SSD1303_GetContrast
 
* Description    : Get the SSD1303 contrast
 
* Function Name  : ssd1306_GetContrast
 
* Description    : Get the ssd1306 contrast
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
unsigned char SSD1303_GetContrast()
 
unsigned char ssd1306_GetContrast()
 
{
 
  return lastContrast;
 
}
 
 
/*******************************************************************************
 
* Function Name  : SSD1303_OFF
 
* Description    : Turn off the SSD1303 controller
 
* Function Name  : ssd1306_OFF
 
* Description    : Turn off the ssd1306 controller
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
unsigned long SSD1303_OFF(void)
 
unsigned long ssd1306_OFF(void)
 
{
 
  if(iS_SSD_On){
 
#ifdef  DEBUG_UI
 
    uint32_t i = 0;
 
    for(i=0;i<SSD1303_COLUMN_NUMBER*SSD1303_PAGE_NUMBER;i++){
 
      SSD1303_Buffer[i] = 0;
 
    for(i=0;i<ssd1306_COLUMN_NUMBER*SSD1306_PAGE_NUMBER;i++){
 
      ssd1306_Buffer[i] = 0;
 
    }
 
#else
 
    // Turn off the display
 
    WriteCommand(0xae);
 
    
 
    // Set Charge pump
 
    WriteCommand(0x8D); /* Set Charge pump */
 
    WriteCommand(0x10); /* 0x14=ON, 0x10=Off */
 
#endif
 
    iS_SSD_On = 0;
 
  }
 
  return iS_SSD_On;
 
}
 
 
 
/*******************************************************************************
 
* Function Name  : SSD1303_ON
 
* Description    : Turn on the SSD1303 controller
 
* Function Name  : ssd1306_ON
 
* Description    : Turn on the ssd1306 controller
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
unsigned long SSD1303_ON(void)
 
unsigned long ssd1306_ON(void)
 
{
 
  if(!iS_SSD_On){
 
#ifdef  DEBUG_UI
 
#else
 
  #ifdef    DEBUG_BOARD
 
  #else
 
    // Set Charge pump
 
    WriteCommand(0x8D); /* Set Charge pump */
 
    WriteCommand(0x14); /* 0x14=ON, 0x10=Off */
 
  #endif
 
    // Turn on the display
 
    WriteCommand(0xaf);
 
#endif
 
    iS_SSD_On = 1;
 
  }
 
  return iS_SSD_On;
 
}
 
 
 
/*******************************************************************************
 
* Function Name  : SSD1303_IsOn
 
* Description    : Check whether the SSD1303 is on or off
 
* Function Name  : ssd1306_IsOn
 
* Description    : Check whether the ssd1306 is on or off
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
unsigned long SSD1303_IsOn(void)
 
unsigned long ssd1306_IsOn(void)
 
{
 
  return iS_SSD_On;
 
}
 
 
/*******************************************************************************
 
* Function Name  : OnPageTransferDone
 
* Description    : Called when each page transfer done
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
void  OnPageTransferDone(void)
 
{
 
  if(pageIndex == SSD1303_PAGE_NUMBER){
 
  if(pageIndex == SSD1306_PAGE_NUMBER){
 
    pageIndex = 0;
 
    return;
 
  }
 
#ifdef    DEBUG_BOARD
 
  WriteCommand(0xb0 + pageIndex);
 
  if(pageIndex == 0){
 
    WriteCommand(0x00);
 
    WriteCommand(0x10);
 
  }
 
  SSD_A0_High();
 
  DMA1_Channel5->CCR &= ((uint32_t)0xFFFFFFFE);
 
  DMA1_Channel5->CNDTR = SSD1303_COLUMN_NUMBER+SSD1303_COLUMN_MARGIN_START + SSD1303_COLUMN_MARGIN_END;
 
  DMA1_Channel5->CMAR = (uint32_t)(SSD1303_Buffer+SSD1303_COLUMN_NUMBER*pageIndex - SSD1303_COLUMN_MARGIN_START);
 
  DMA_SSD_1303->CCR |= ((uint32_t)0x00000001);
 
  DMA1_Channel5->CNDTR = ssd1306_COLUMN_NUMBER+SSD1306_COLUMN_MARGIN_START + SSD1306_COLUMN_MARGIN_END;
 
  DMA1_Channel5->CMAR = (uint32_t)(ssd1306_Buffer+SSD1306_COLUMN_NUMBER*pageIndex - SSD1306_COLUMN_MARGIN_START);
 
  DMA_SSD_1306->CCR |= ((uint32_t)0x00000001);
 
  pageIndex++;
 
#else
 
  SSD_A0_High();
 
  DMA_SSD_1303->CCR &= ((uint32_t)0xFFFFFFFE);
 
  DMA_SSD_1303->CNDTR = SSD1303_COLUMN_NUMBER*SSD1303_PAGE_NUMBER;//+SSD1303_COLUMN_MARGIN_START + SSD1303_COLUMN_MARGIN_END;
 
  DMA_SSD_1303->CMAR = (uint32_t)(SSD1303_Buffer);//+SSD1303_COLUMN_NUMBER*pageIndex);
 
  //DMA_Cmd(DMA_SSD_1303, ENABLE);
 
  DMA_SSD_1303->CCR |= ((uint32_t)0x00000001);
 
  DMA_SSD_1306->CCR &= ((uint32_t)0xFFFFFFFE);
 
  DMA_SSD_1306->CNDTR = SSD1306_COLUMN_NUMBER*SSD1306_PAGE_NUMBER;//+SSD1306_COLUMN_MARGIN_START + SSD1306_COLUMN_MARGIN_END;
 
  DMA_SSD_1306->CMAR = (uint32_t)(ssd1306_Buffer);//+SSD1306_COLUMN_NUMBER*pageIndex);
 
  //DMA_Cmd(DMA_SSD_1306, ENABLE);
 
  DMA_SSD_1306->CCR |= ((uint32_t)0x00000001);
 
//  pageIndex++;
 
  pageIndex = SSD1303_PAGE_NUMBER;
 
  pageIndex = SSD1306_PAGE_NUMBER;
 
#endif
 
}
 
 
/*******************************************************************************
 
* Function Name  : DMA1_Channel5_IRQHandler
 
* Description    : This function handles DMA1 Channel 5 interrupt request.
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
void DMA_Handler_SSD_1303(void) //DMA1_Channel5_IRQHandler(void)
 
void DMA_Handler_SSD_1306(void) //DMA1_Channel5_IRQHandler(void)
 
{
 
  if(DMA_GetITStatus(DMA1_IT_TC5)){
 
    DMA_ClearITPendingBit(DMA1_IT_GL5);
 
    OnPageTransferDone();
 
  }
 
}
 
 
/*******************************************************************************
 
* Function Name  : StartPageTransfer
 
* Description    : Start a new page transfer
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
void StartPageTransfer(void)
 
{
 
  pageIndex = 0;
 
  if(pre_on){
 
    if(iS_SSD_On == 0){
 
      pre_on = SSD1303_ON();
 
      pre_on = ssd1306_ON();
 
    }
 
  }else{
 
    if(iS_SSD_On){
 
      pre_on = SSD1303_OFF();
 
      pre_on = ssd1306_OFF();
 
    }
 
  }
 
  if( curContrast != lastContrast ){
 
    lastContrast = curContrast;
 
    WriteCommand(0x81); /* Set Contrast Control */
 
    WriteCommand(lastContrast); /* 0 ~ 255 0x1f*/
 
  }
 
  
 
  if(iS_SSD_On){
 
    OnPageTransferDone();
 
  }
 
}
 
 
/*******************************************************************************
 
  Display related functions
 
 ******************************************************************************/
 
/*******************************************************************************
 
* Function Name  : SSD1303_DrawBlock
 
* Description    : Draw a block with specify data to SSD1303
 
* Function Name  : ssd1306_DrawBlock
 
* Description    : Draw a block with specify data to ssd1306
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
unsigned long SSD1303_DrawBlock(
 
unsigned long ssd1306_DrawBlock(
 
  Pos_t x,
 
  Pos_t y,
 
  Pos_t cx,
 
  Pos_t cy,
 
  const unsigned char* data)
 
{
 
  if(x >= SSD1303_X_PIXEL)return 0;
 
  if(y >= SSD1303_Y_PIXEL)return 0;
 
  if(x+cx > SSD1303_X_PIXEL ) cx = SSD1303_X_PIXEL - x ;
 
  if(y+cy > SSD1303_Y_PIXEL ) cy = SSD1303_Y_PIXEL - y ;
 
  unsigned char* pStart = SSD1303_Buffer + (y/8)*SSD1303_COLUMN_NUMBER + x;
 
  if(x >= SSD1306_X_PIXEL)return 0;
 
  if(y >= SSD1306_Y_PIXEL)return 0;
 
  if(x+cx > SSD1306_X_PIXEL ) cx = SSD1306_X_PIXEL - x ;
 
  if(y+cy > SSD1306_Y_PIXEL ) cy = SSD1306_Y_PIXEL - y ;
 
  unsigned char* pStart = ssd1306_Buffer + (y/8)*SSD1306_COLUMN_NUMBER + x;
 
  unsigned char offset1 = y%8;
 
  unsigned char offset2 = (cy+y)%8;
 
  if(data){
 
    unsigned char mask1 = (1<<offset1)-1;
 
    unsigned char mask2 = ~((1<<offset2)-1);
 
    cy = (cy+offset1)/8;
 
   
 
    Pos_t i = 0;
 
    for(i=0;i<cx;i++){
 
      Pos_t j = 0;
 
      unsigned short tmp = *pStart & mask1;
 
      for(;j<cy;j++){
 
        tmp |= (((unsigned short)data[j*cx])<<offset1);
 
        *(pStart + j*SSD1303_COLUMN_NUMBER) = tmp;
 
        *(pStart + j*SSD1306_COLUMN_NUMBER) = tmp;
 
        tmp>>=8;
 
      }
 
      if(offset2){
 
        tmp |= ((((unsigned short)data[j*cx])<<offset1) & (~mask2))
 
            | *(pStart + j*SSD1303_COLUMN_NUMBER) & mask2;
 
        *(pStart + j*SSD1303_COLUMN_NUMBER) = tmp;
 
            | *(pStart + j*SSD1306_COLUMN_NUMBER) & mask2;
 
        *(pStart + j*SSD1306_COLUMN_NUMBER) = tmp;
 
      }
 
      data++;
 
      pStart++;
 
    }
 
  }else{
 
    unsigned char mask1 = ~((1<<offset1)-1);
 
    unsigned char mask2 = ((1<<offset2)-1);
 
    cy = (cy+offset1)/8;
 
 
    Pos_t i = 0;
 
    for(i=0;i<cx;i++){
 
      Pos_t j = 1;
 
      *pStart ^= mask1;
 
      for(;j<cy;j++){
 
        *(pStart + j*SSD1303_COLUMN_NUMBER) ^= 0xFF;
 
        *(pStart + j*SSD1306_COLUMN_NUMBER) ^= 0xFF;
 
      }
 
      if(offset2){
 
        *(pStart + j*SSD1303_COLUMN_NUMBER) ^= mask2;
 
        *(pStart + j*SSD1306_COLUMN_NUMBER) ^= mask2;
 
      }
 
      pStart++;
 
    }
 
  }
 
  
 
  
 
//  if(!offset){
 
//    for(Pos_t i=0;i<cx;i++){
 
//      unsigned char tmp;
 
//      Pos_t j = 0;
 
//      for(;j<cy/8;j++){
 
//        tmp = data[i+j*cx];
 
//        *(pStart + j*SSD1303_COLUMN_NUMBER + i + x) = tmp;
 
//        *(pStart + j*ssd1306_COLUMN_NUMBER + i + x) = tmp;
 
//      }
 
//      if(cy&0x7){
 
//        unsigned char mask1 = (1<<(cy&7)) - 1;
 
//        unsigned char mask2 = 0xFF - mask1;
 
//        tmp = (data[i+j*cx] & mask1)
 
//            | (*(pStart + j*SSD1303_COLUMN_NUMBER + i + x) & mask2);
 
//        *(pStart + j*SSD1303_COLUMN_NUMBER + i + x) = tmp;
 
//            | (*(pStart + j*ssd1306_COLUMN_NUMBER + i + x) & mask2);
 
//        *(pStart + j*ssd1306_COLUMN_NUMBER + i + x) = tmp;
 
//      }
 
//    }
 
//  }else{
 
//    for(Pos_t i=0;i<cx;i++){
 
//      unsigned short tmp;
 
//      for(Pos_t j=0;j<cy/8;j++){
 
//        if(j == 0){
 
//          // First line
 
//          tmp = *(pStart + j*SSD1303_COLUMN_NUMBER + i + x) & mask;
 
//          tmp = *(pStart + j*ssd1306_COLUMN_NUMBER + i + x) & mask;
 
//        }
 
//        tmp |= (((unsigned short)data[i+j*cx])<<offset);
 
//        *(pStart + j*SSD1303_COLUMN_NUMBER + i + x) = tmp;
 
//        *(pStart + j*ssd1306_COLUMN_NUMBER + i + x) = tmp;
 
//        tmp>>=8;
 
//        if(j == (cy/8)-1){
 
//          // Last line
 
//          *(pStart + (j+1)*SSD1303_COLUMN_NUMBER + i + x) &= ~mask;
 
//          *(pStart + (j+1)*SSD1303_COLUMN_NUMBER + i + x) |= tmp;
 
//          *(pStart + (j+1)*ssd1306_COLUMN_NUMBER + i + x) &= ~mask;
 
//          *(pStart + (j+1)*ssd1306_COLUMN_NUMBER + i + x) |= tmp;
 
//        }
 
//      }
 
//    }
 
//  }
 
  
 
  return 0;
 
}
 
 
/*******************************************************************************
 
* Function Name  : SSD1303_DrawPoint
 
* Description    : Draw a point with specify data to SSD1303
 
* Function Name  : ssd1306_DrawPoint
 
* Description    : Draw a point with specify data to ssd1306
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
unsigned long SSD1303_DrawPoint(
 
unsigned long ssd1306_DrawPoint(
 
  Pos_t x,
 
  Pos_t y,
 
  Color_t color)
 
{
 
  if(x >= SSD1303_X_PIXEL)return 0;
 
  if(y >= SSD1303_Y_PIXEL)return 0;
 
  unsigned char* pStart = SSD1303_Buffer + (y/8)*SSD1303_COLUMN_NUMBER + x;
 
  if(x >= SSD1306_X_PIXEL)return 0;
 
  if(y >= SSD1306_Y_PIXEL)return 0;
 
  unsigned char* pStart = ssd1306_Buffer + (y/8)*SSD1306_COLUMN_NUMBER + x;
 
  unsigned char mask = 1<<(y%8);
 
  if(color){
 
    *pStart |= mask;
 
  }else{
 
    *pStart &= ~mask;
 
  }
 
  return 0;
 
}
 
 
/*******************************************************************************
 
* Function Name  : SSD1303_ReadPoint
 
* Description    : Read a point from SSD1303
 
* Function Name  : ssd1306_ReadPoint
 
* Description    : Read a point from ssd1306
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
unsigned long SSD1303_ReadPoint(
 
unsigned long ssd1306_ReadPoint(
 
  Pos_t x,
 
  Pos_t y)
 
{
 
  unsigned char* pStart = SSD1303_Buffer + (y/8)*SSD1303_COLUMN_NUMBER + x;
 
  unsigned char* pStart = ssd1306_Buffer + (y/8)*SSD1306_COLUMN_NUMBER + x;
 
  unsigned char mask = 1<<(y%8);
 
  return *pStart&mask ? 1 : 0;
 
}
 
 
/*******************************************************************************
 
* Function Name  : SSD1303_ClearScreen
 
* Function Name  : ssd1306_ClearScreen
 
* Description    : Clear the screen contents
 
* Input          : None
 
* Output         : None
 
* Return         : None
 
*******************************************************************************/
 
void  SSD1303_FillScreen(Color_t color)
 
void  ssd1306_FillScreen(Color_t color)
 
{
 
  unsigned char mask = color ? 0xFF : 0;
 
  unsigned long i = 0;
 
  for(i=0;i<SSD1303_COLUMN_NUMBER*SSD1303_PAGE_NUMBER;i++){
 
    SSD1303_Buffer[i] = mask;
 
  for(i=0;i<SSD1306_COLUMN_NUMBER*SSD1306_PAGE_NUMBER;i++){
 
    ssd1306_Buffer[i] = mask;
 
  }
 
}
 
 
const DeviceProp  SSD1303_Prop =
 
const DeviceProp  ssd1306_Prop =
 
{
 
  .pfnDrawBlok = SSD1303_DrawBlock,
 
  .pfnDrawPoint = SSD1303_DrawPoint,
 
  .pfnDrawBlok = ssd1306_DrawBlock,
 
  .pfnDrawPoint = ssd1306_DrawPoint,
 
  .xPixel = 128,
 
  .yPixel = 64,
 
};
 
ssd1306.h
Show inline comments
 
#ifndef   SSD1303_H
 
#define   SSD1303_H
 
#ifndef   ssd1306_H
 
#define   ssd1306_H
 
#include "DrawText.h"
 
 
void  SSD1303_Init(void);
 
void  ssd1306_Init(void);
 
void  StartPageTransfer(void);
 
extern  const DeviceProp  SSD1303_Prop;
 
unsigned long SSD1303_DrawBlock(Pos_t x, Pos_t y, Pos_t cx, Pos_t cy, const unsigned char* data);
 
unsigned long SSD1303_IsOn(void);
 
unsigned long SSD1303_TurnOff(void);
 
unsigned long SSD1303_TurnOn(void);
 
unsigned char SSD1303_SetContrast(unsigned char contrast);
 
unsigned char SSD1303_GetContrast();
 
unsigned char* SSD1303_GetBuffer();
 
unsigned long SSD1303_DrawPoint(Pos_t x, Pos_t y, Color_t color);
 
extern  const DeviceProp  ssd1306_Prop;
 
unsigned long ssd1306_DrawBlock(Pos_t x, Pos_t y, Pos_t cx, Pos_t cy, const unsigned char* data);
 
unsigned long ssd1306_IsOn(void);
 
unsigned long ssd1306_TurnOff(void);
 
unsigned long ssd1306_TurnOn(void);
 
unsigned char ssd1306_SetContrast(unsigned char contrast);
 
unsigned char ssd1306_GetContrast();
 
unsigned char* ssd1306_GetBuffer();
 
unsigned long ssd1306_DrawPoint(Pos_t x, Pos_t y, Color_t color);
 
 
#endif
0 comments (0 inline, 0 general)