Changeset - e0a38751daed
[Not reviewed]
default
0 3 0
Ethan Zonca - 10 years ago 2014-08-23 23:01:14
ez@ethanzonca.com
Display moved to states, refactor test to displaylogo
3 files changed with 88 insertions and 45 deletions:
0 comments (0 inline, 0 general)
main.c
Show inline comments
 
#include "main.h"
 
#include "stm32l100c_discovery.h"
 
#include "ssd1306.h"
 
 
// USB includes
 
#include "hw_config.h"
 
#include "usb_lib.h"
 
#include "usb_desc.h"
 
#include "usb_pwr.h"
 
 
#define LED_POWER GPIOB,GPIO_Pin_9
 
#define LED_STAT  GPIOA,GPIO_Pin_15
 
 
#define MAX_CS GPIOB,GPIO_Pin_12
 
 
// TODO: Grab buttonpresses with interrupts
 
#define SW_BTN  GPIOB, GPIO_Pin_3
 
#define SW_UP   GPIOB, GPIO_Pin_7
 
#define SW_DOWN GPIOB, GPIO_Pin_6
 
#define SW_LEFT GPIOB, GPIO_Pin_5
 
#define SW_RIGHT GPIOB, GPIO_Pin_4
 
 
// USB Supporting Vars
 
extern __IO uint8_t Receive_Buffer[64];
 
extern __IO  uint32_t Receive_length ;
 
extern __IO  uint32_t length ;
 
uint8_t Send_Buffer[64];
 
uint32_t packet_sent=1;
 
uint32_t packet_receive=1;
 
 
 
char* itoa(int16_t i, char b[]){
 
    char const digit[] = "0123456789";
 
    char* p = b;
 
    if(i<0){
 
        *p++ = '-';
 
        i *= -1;
 
    }
 
    uint16_t shifter = i;
 
    do{ //Move to where representation ends
 
        ++p;
 
        shifter = shifter/10;
 
    }while(shifter);
 
    *p = '\0';
 
    do{ //Move back, inserting digits as you go
 
        *--p = digit[i%10];
 
        i = i/10;
 
    }while(i);
 
    return b;
 
}
 
 
char* itoa_fp(int16_t i, uint8_t frac, char b[]){
 
    char const digit[] = "0123456789";
 
 
    // set p to beginning of char array
 
    char* p = b;
 
 
    // If negative, set current char to '-' and inc, unnegate number
 
    if(i<0){
 
        *p++ = '-';
 
        i *= -1;
 
    }
 
 
    // Init shifter to numeric value
 
    uint16_t shifter = i;
 
    uint16_t frac_shifter = frac;
 
 
    // Iterate through 10s places, incrementing text pointer as we go
 
    do{ 
 
        ++p;
 
        shifter = shifter/10;
 
    }while(shifter);
 
    
 
    ++p; // increment for decimal point
 
 
    do{
 
        ++p;
 
        frac_shifter = frac_shifter/10;
 
    }while(frac_shifter);
 
        
 
 
    // Null-terminate the string
 
    *p = '\0';
 
 
    // Go backwards and write out fractional digits 
 
    do{ 
 
        *--p = digit[frac%10];
 
        frac = frac/10;
 
    }while(frac);
 
 
    *--p = '.'; // insert decimal point
 
 
    // Go backwards and write out remaining digits 
 
    do{ 
 
        *--p = digit[i%10];
 
        i = i/10;
 
    }while(i);
 
    return b;
 
}
 
 
 
static __IO uint32_t TimingDelay;
 
 
// Move to header file
 
void init_gpio();
 
void init_spi();
 
void process();
 
void machine();
 
 
int main(void)
 
{
 
 
    // Init clocks
 
    SystemInit();
 
 
    init_gpio();
 
 
    // Init USB
 
    //Set_USBClock();
 
    //USB_Interrupts_Config();
 
    //USB_Init();
 
 
    GPIO_SetBits(LED_POWER);
 
 
    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);
 
    GPIO_SetBits(LED_POWER);
 
    Delay(500);
 
    GPIO_ResetBits(LED_POWER);
 
 
    init_spi();
 
 
    ssd1306_Init();
 
    ssd1306_block_write();
 
    ssd1306_DrawString("therm 0.1", 0, 40);
 
    ssd1306_DrawString("Status: Idle", 2, 40);
 
  //  ssd1306_block_write();
 
    ssd1306_test();
 
 
 
    uint8_t toggle = 0;
 
 
    int16_t temp = -231;
 
 
    while(1)
 
    {
 
        //ssd1306_block_write();
 
 
        // Process sensor inputs [TODO: 5hz?]
 
        process();
 
 
        // Run state machine [TODO: 50hz?]
 
        machine(); 
 
        // probably just passed the actual port
 
 
        // TODO: Grab buttonpresses with interrupts
 
        uint8_t sw_btn = GPIO_ReadInputDataBit(SW_BTN);
 
        //uint8_t sw_btn = GPIO_ReadInputDataBit(SW_BTN);
 
        //uint8_t sw_up = GPIO_ReadInputDataBit(SW_UP);
 
        //uint8_t sw_down = GPIO_ReadInputDataBit(SW_DOWN);
 
        //uint8_t sw_left = GPIO_ReadInputDataBit(SW_LEFT);
 
        //uint8_t sw_right = GPIO_ReadInputDataBit(SW_RIGHT);
 
 
        if(!sw_btn) {
 
            GPIO_ToggleBits(LED_STAT);
 
            if(!toggle) {
 
                GPIO_SetBits(GPIOB, GPIO_Pin_13);
 
                toggle = ! toggle;
 
            }
 
            else  {
 
                GPIO_ResetBits(GPIOB, GPIO_Pin_13);
 
                toggle = ! toggle;
 
            }    
 
        }
 
 
        GPIO_SetBits(LED_POWER);
 
        Delay(50);
 
        GPIO_ResetBits(LED_POWER);
 
        Delay(50);
 
    }
 
}
 
 
int32_t temp = 0;
 
int32_t setpoint = 0;
 
int32_t p = 1;
 
int32_t i = 1;
 
int32_t d = 1;
 
 
 
// Process things
 
void process()
 
{
 
// Read temperature and update global temp vars
 
int16_t temp = 0;
 
uint8_t temp_frac = 0;
 
void update_temp() {
 
    // Assert CS
 
    GPIO_ResetBits(MAX_CS);
 
    Delay(1);
 
 
    // This may not clock at all... might need to send 16 bits first
 
    SPI_I2S_SendData(SPI2, 0xAAAA); // send dummy data
 
    //SPI_I2S_SendData(SPI2, 0xAA); // send dummy data
 
    uint16_t temp_pre = SPI_I2S_ReceiveData(SPI2);
 
 
    if(temp_pre & 0b0000000000000010) {
 
        ssd1306_DrawString("Fatal Error", 3, 35);
 
    }
 
    else if(temp_pre & 0b0000000000000001) {
 
        ssd1306_DrawString("TC Fault", 3, 35);
 
    }
 
    else {
 
        ssd1306_DrawString("TempSense OK", 3, 35);
 
    }
 
 
    uint8_t sign = temp >> 15;// top bit is sign
 
 
 
    temp_pre = temp_pre >> 2; // Drop 2 lowest bits
 
    uint8_t frac = temp_pre & 0b11; // get fractional part
 
    frac *= 25; // each bit is .25 a degree, up to fixed point
 
    temp_frac = temp_pre & 0b11; // get fractional part
 
    temp_frac *= 25; // each bit is .25 a degree, up to fixed point
 
    temp_pre = temp_pre >> 2; // Drop 2 fractional bits 
 
 
    int16_t temp = 0;
 
    if(sign) {
 
        temp = -temp_pre;
 
    }
 
    else {
 
        temp = temp_pre;
 
    }
 
 
    // Deassert CS
 
    Delay(1);
 
    GPIO_SetBits(MAX_CS);
 
}
 
 
    if(temp > 0) {
 
        GPIO_SetBits(LED_STAT);
 
    }
 
    char tempstr[9];
 
    itoa(temp_pre, tempstr);
 
    ssd1306_DrawString("Temp: ", 1, 40);
 
    ssd1306_DrawString("    ", 1, 70);
 
    ssd1306_DrawString(tempstr, 1, 70);
 
    itoa(frac, tempstr);
 
    ssd1306_DrawString("  ", 1, 90);
 
    ssd1306_DrawString(tempstr, 1, 90);
 
 
int32_t setpoint = 0;
 
int32_t p = 1;
 
int32_t i = 1;
 
int32_t d = 1;
 
 
 
// Process things
 
void process()
 
{
 
    update_temp(); // Read MAX31855
 
 
    // TODO: Add calibration offset (linear)
 
 
    // Perform PID calculations
 
    //if(
 
    GPIO_SetBits(LED_STAT);
 
 
    // Write output to SSR
 
}
 
 
 
 
enum state {
 
    STATE_IDLE = 0,
 
    STATE_SETP,
 
    STATE_SETI,
 
    STATE_SETD,
 
 
    STATE_PREHEAT_BREW,
 
    STATE_MAINTAIN_BREW,
 
    STATE_PREHEAT_STEAM,
 
    STATE_MAINTAIN_STEAM,
 
};
 
 
 
uint8_t state = STATE_IDLE;
 
 
// State machine
 
void machine()
 
{
 
    
 
    uint8_t last_state = state;
 
 
    switch(state)
 
    {
 
        // Idle state
 
        case STATE_IDLE:
 
        {
 
            // Write text to OLED
 
            // [ therm :: idle ]
 
            ssd1306_DrawString("therm :: idle ", 0, 40);
 
 
            ssd1306_drawlogo();
 
            char tempstr[9];
 
            itoa_fp(temp, temp_frac, tempstr);
 
            ssd1306_DrawString("Temp: ", 2, 40);
 
            ssd1306_DrawString("    ", 2, 70);
 
            ssd1306_DrawString(tempstr, 2, 72);
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_SETP;
 
            }
 
 
            // Event Handler
 
            // N/A
 
 
        } break;
 
 
        case STATE_SETP:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set p ]
 
            // [ p = 12         ]
 
            ssd1306_DrawString("therm :: set p", 0, 40);
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_SETI;
 
            }
 
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 
 
        case STATE_SETI:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set i ]
 
            // [ i = 12         ]
 
            ssd1306_DrawString("therm :: set i", 0, 40);
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_SETD;
 
            }
 
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 
 
        case STATE_SETD:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set d ]
 
            // [ d = 12         ]
 
            ssd1306_DrawString("therm :: set d", 0, 40);
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_IDLE;
 
            }
 
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 
 
        case STATE_PREHEAT_BREW:
 
        {
 
            // Write text to OLED
 
            // [ therm : preheating brew ]
 
            // [ 30 => 120 C             ]
 
            ssd1306_DrawString("therm :: Bpreheat", 0, 40);
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_IDLE;
 
            }
 
 
            // Event Handler
 
            if(temp >= setpoint) {
 
                state = STATE_MAINTAIN_BREW;
 
            }
 
 
 
        } break;
 
 
        case STATE_MAINTAIN_BREW:
 
        {
 
            // Write text to OLED
 
            // [ therm : ready to brew ]
 
            // [ 30 => 120 C           ]
 
            ssd1306_DrawString("therm :: Bready", 0, 40);
 
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_IDLE;
 
            }
 
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 
 
        case STATE_PREHEAT_STEAM:
 
        {
 
            // Write text to OLED
 
            // [ therm : preheating steam ]
 
            // [ 30 => 120 C           ]
 
            ssd1306_DrawString("therm :: Spreheat", 0, 40);
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_IDLE;
 
            }
 
 
            // Event Handler
 
            if(temp >= setpoint) {
 
                state = STATE_MAINTAIN_STEAM;
 
            }
 
 
 
        } break;
 
 
        case STATE_MAINTAIN_STEAM:
 
        {
 
            // Write text to OLED
 
            // [ therm : ready to steam ]
 
            // [ 30 => 120 C            ]
 
            ssd1306_DrawString("therm :: Sready", 0, 40);
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_IDLE;
 
            }
 
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 
 
 
        // Something is terribly wrong
 
        default:
 
        {
 
            ssd1306_DrawString("therm :: BAD BAD", 0, 40);
 
            state = STATE_IDLE;
 
 
        } break;
 
            
 
    }
 
 
    if(last_state != state) {
 
        // Clear screen on state change
 
        ssd1306_block_write();
 
    }
 
}
 
 
 
/**
 
  * @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)
 
{
 
    SPI_InitTypeDef  SPI_InitStructure;
 
 
    // OLED IC
 
    SPI_Cmd(SPI1, DISABLE); 
 
    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_4;
 
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
 
    SPI_InitStructure.SPI_CRCPolynomial = 7;
 
    SPI_Init(SPI1, &SPI_InitStructure);
 
    SPI_Cmd(SPI1, ENABLE);           /* Enable the SPI  */   
 
 
 
    // MAX IC
 
    SPI_Cmd(SPI2, DISABLE); 
 
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
 
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
 
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; // Andysworkshop
 
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // From andysworkshop
 
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // same
 
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
 
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
 
    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;
 
 
  // 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 
 
                          |GPIO_Pin_9;
 
  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(GPIOB, &GPIO_InitStruct);
 
 
  /*Configure GPIO pin : PA */
 
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15;
ssd1306.c
Show inline comments
 
@@ -559,167 +559,167 @@ const char fontData[240][5] =
 
    {0x7F,0x09,0x09,0x09,0x06},         //   ( 48)  P - 0x0050 Latin Capital Letter P
 
    {0x3E,0x41,0x51,0x21,0x5E},         //   ( 49)  Q - 0x0051 Latin Capital Letter Q
 
    {0x7F,0x09,0x19,0x29,0x46},         //   ( 50)  R - 0x0052 Latin Capital Letter R
 
    {0x46,0x49,0x49,0x49,0x31},         //   ( 51)  S - 0x0053 Latin Capital Letter S
 
    {0x01,0x01,0x7F,0x01,0x01},         //   ( 52)  T - 0x0054 Latin Capital Letter T
 
    {0x3F,0x40,0x40,0x40,0x3F},         //   ( 53)  U - 0x0055 Latin Capital Letter U
 
    {0x1F,0x20,0x40,0x20,0x1F},         //   ( 54)  V - 0x0056 Latin Capital Letter V
 
    {0x3F,0x40,0x38,0x40,0x3F},         //   ( 55)  W - 0x0057 Latin Capital Letter W
 
    {0x63,0x14,0x08,0x14,0x63},         //   ( 56)  X - 0x0058 Latin Capital Letter X
 
    {0x07,0x08,0x70,0x08,0x07},         //   ( 57)  Y - 0x0059 Latin Capital Letter Y
 
    {0x61,0x51,0x49,0x45,0x43},         //   ( 58)  Z - 0x005A Latin Capital Letter Z
 
    {0x00,0x7F,0x41,0x41,0x00},         //   ( 59)  [ - 0x005B Left Square Bracket
 
    {0x02,0x04,0x08,0x10,0x20},         //   ( 60)  \ - 0x005C Reverse Solidus
 
    {0x00,0x41,0x41,0x7F,0x00},         //   ( 61)  ] - 0x005D Right Square Bracket
 
    {0x04,0x02,0x01,0x02,0x04},         //   ( 62)  ^ - 0x005E Circumflex Accent
 
    {0x40,0x40,0x40,0x40,0x40},         //   ( 63)  _ - 0x005F Low Line
 
    {0x01,0x02,0x04,0x00,0x00},         //   ( 64)  ` - 0x0060 Grave Accent
 
    {0x20,0x54,0x54,0x54,0x78},         //   ( 65)  a - 0x0061 Latin Small Letter A
 
    {0x7F,0x48,0x44,0x44,0x38},         //   ( 66)  b - 0x0062 Latin Small Letter B
 
    {0x38,0x44,0x44,0x44,0x20},         //   ( 67)  c - 0x0063 Latin Small Letter C
 
    {0x38,0x44,0x44,0x48,0x7F},         //   ( 68)  d - 0x0064 Latin Small Letter D
 
    {0x38,0x54,0x54,0x54,0x18},         //   ( 69)  e - 0x0065 Latin Small Letter E
 
    {0x08,0x7E,0x09,0x01,0x02},         //   ( 70)  f - 0x0066 Latin Small Letter F
 
    {0x06,0x49,0x49,0x49,0x3F},         //   ( 71)  g - 0x0067 Latin Small Letter G
 
    {0x7F,0x08,0x04,0x04,0x78},         //   ( 72)  h - 0x0068 Latin Small Letter H
 
    {0x00,0x44,0x7D,0x40,0x00},         //   ( 73)  i - 0x0069 Latin Small Letter I
 
    {0x20,0x40,0x44,0x3D,0x00},         //   ( 74)  j - 0x006A Latin Small Letter J
 
    {0x7F,0x10,0x28,0x44,0x00},         //   ( 75)  k - 0x006B Latin Small Letter K
 
    {0x00,0x41,0x7F,0x40,0x00},         //   ( 76)  l - 0x006C Latin Small Letter L
 
    {0x7C,0x04,0x18,0x04,0x7C},         //   ( 77)  m - 0x006D Latin Small Letter M
 
    {0x7C,0x08,0x04,0x04,0x78},         //   ( 78)  n - 0x006E Latin Small Letter N
 
    {0x38,0x44,0x44,0x44,0x38},         //   ( 79)  o - 0x006F Latin Small Letter O
 
    {0x7C,0x14,0x14,0x14,0x08},         //   ( 80)  p - 0x0070 Latin Small Letter P
 
    {0x08,0x14,0x14,0x18,0x7C},         //   ( 81)  q - 0x0071 Latin Small Letter Q
 
    {0x7C,0x08,0x04,0x04,0x08},         //   ( 82)  r - 0x0072 Latin Small Letter R
 
    {0x48,0x54,0x54,0x54,0x20},         //   ( 83)  s - 0x0073 Latin Small Letter S
 
    {0x04,0x3F,0x44,0x40,0x20},         //   ( 84)  t - 0x0074 Latin Small Letter T
 
    {0x3C,0x40,0x40,0x20,0x7C},         //   ( 85)  u - 0x0075 Latin Small Letter U
 
    {0x1C,0x20,0x40,0x20,0x1C},         //   ( 86)  v - 0x0076 Latin Small Letter V
 
    {0x3C,0x40,0x30,0x40,0x3C},         //   ( 87)  w - 0x0077 Latin Small Letter W
 
    {0x44,0x28,0x10,0x28,0x44},         //   ( 88)  x - 0x0078 Latin Small Letter X
 
    {0x0C,0x50,0x50,0x50,0x3C},         //   ( 89)  y - 0x0079 Latin Small Letter Y
 
    {0x44,0x64,0x54,0x4C,0x44},         //   ( 90)  z - 0x007A Latin Small Letter Z
 
    {0x00,0x08,0x36,0x41,0x00},         //   ( 91)  { - 0x007B Left Curly Bracket
 
    {0x00,0x00,0x7F,0x00,0x00},         //   ( 92)  | - 0x007C Vertical Line
 
    {0x00,0x41,0x36,0x08,0x00},         //   ( 93)  } - 0x007D Right Curly Bracket
 
    {0x02,0x01,0x02,0x04,0x02},         //   ( 94)  ~ - 0x007E Tilde
 
    {0x08,0x14,0x2A,0x14,0x22},         //   ( 95) << - 0x00AB Left-Pointing Double Angle Quotation Mark
 
    {0x00,0x02,0x05,0x02,0x00},         //   ( 96)    - 0x00B0 Degree Sign
 
    {0x44,0x44,0x5F,0x44,0x44},         //   ( 97) +- - 0x00B1 Plus-Minus Sign
 
    {0x7E,0x20,0x20,0x10,0x3E},         //   ( 98)  u - 0x00B5 Micro Sign
 
    {0x22,0x14,0x2A,0x14,0x08},         //   ( 99) >> - 0x00BB Right-Pointing Double Angle Quotation Mark
 
    {0x30,0x48,0x45,0x40,0x20},         //   (100)  ? - 0x00BF Inverted Question Mark
 
    {0x22,0x14,0x08,0x14,0x22},         //   (101)  x - 0x00D7 Multiplcation Sign
 
    {0x08,0x08,0x2A,0x08,0x08},         //   (102)  + - 0x00F7 Division Sign
 
    {0x18,0x14,0x08,0x14,0x0C},         //   (103)    - 0x221E Infinity
 
    {0x44,0x4A,0x4A,0x51,0x51},         //   (104)  < - 0x2264 Less-Than or Equal to
 
    {0x51,0x51,0x4A,0x4A,0x44},         //   (105)  > - 0x2265 Greater-Than or Equal to
 
    {0x54,0x14,0x64,0x08,0x70},         //   (106)  .: - RF Symbol
 
    {0x70,0x7C,0x72,0x7C,0x70},         //   (107)  ^ - Lock symbol
 
    {0x70,0x5C,0x52,0x54,0x70},         //   (108)  / - Unlock symbol
 
    {0x0C,0x1E,0x3C,0x1E,0x0C},         //   (109)  <3 - Heart Symbol
 
    {0x18,0x22,0xFF,0x12,0x0C},         //   (110)  U - USB Symbol
 
};
 
 
 
void setStartPage(unsigned char d)
 
{
 
    WriteCommand(0xB0|d);       // Set Page Start Address for Page Addressing Mode
 
                                // Default => 0xB0 (0x00)
 
}
 
/* Below are functions used to configure the OLED */
 
void setStartColumn(unsigned char d)
 
{
 
    WriteCommand(0x00+d%16);    // Set Lower Column Start Address for Page Addressing Mode
 
    WriteCommand(0x10+d/16);    // Set Higher Column Start Address for Page Addressing Mode
 
                                // Default => 0x10
 
}
 
 
 
const uint8_t row[4][32] = { 
 
 
 
{0x00,0x00,0x01,0x03,0x07,0x0F,0x1E,0x3C,0x3C,0x7C,0x7C,0x7C,0xFC,0xFF,0xFF,0xFC,0xFC,0xFC,0xFC,0xFF,0x7F,0x7F,0x7F,0x3C,0x3C,0x1C,0x0C,0x06,0x03,0x01,0x00,0x00},
 
 
{0x0F,0x7F,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x3F,0x3F,0x7F,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x7F,0x0F},
 
 
{0xF0,0xFE,0xFF,0xFF,0xFF,0xC7,0x00,0x00,0x00,0x00,0x87,0xC7,0xC7,0xFF,0xFF,0x00,0x00,0x00,0x00,0x87,0x87,0xC7,0xC3,0x03,0x07,0x07,0x0F,0x7F,0xFF,0xFF,0xFE,0xF0},
 
 
{0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFC,0xFE,0xFE,0xFE,0xFF,0xFF,0xFF,0x1F,0x1F,0x1F,0x1F,0xFF,0xFE,0xFE,0xFE,0xFC,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00},
 
 
 
 
 
};
 
 
void ssd1306_test()
 
void ssd1306_drawlogo()
 
{
 
    uint8_t i = 0;
 
    setStartPage(3);
 
    setStartColumn(0);
 
    for(i = 0; i<32; i++)
 
    {
 
        WriteData(row[0][i]);
 
    }
 
 
    WriteData(0x00);
 
 
    setStartPage(2);
 
    setStartColumn(0);
 
    for(i = 0; i<32; i++)
 
    {
 
        WriteData(row[1][i]);
 
    }
 
    WriteData(0x00);
 
 
    setStartPage(1);
 
    setStartColumn(0);
 
    for(i = 0; i<32; i++)
 
    {
 
        WriteData(row[2][i]);
 
    }
 
    WriteData(0x00);
 
 
    setStartPage(0);
 
    setStartColumn(0);
 
    for(i = 0; i<32; i++)
 
    {
 
        WriteData(row[3][i]);
 
    }
 
    WriteData(0x00);
 
}
 
 
/* Print a single character from font.cpp */
 
void ssd1306_DrawChar(char ascii, unsigned char row, unsigned char xPos)
 
{
 
    char *srcPointer = 0;
 
    unsigned char i;
 
 
    srcPointer = &fontData[(ascii-32)][0];
 
 
    setStartPage(row);
 
    setStartColumn(xPos);
 
 
    for(i=0;i<5;i++)
 
    {
 
        WriteData(*srcPointer);
 
        srcPointer++;
 
    }
 
    WriteData(0x00);
 
}
 
 
void ssd1306_DrawString(const char *dataPtr, unsigned char row, unsigned char xPos)
 
{
 
    char *srcPointer;
 
 
    srcPointer = (char*)dataPtr;
 
    ssd1306_DrawChar(' ',row,xPos); // NBSP must be written first before the string start
 
 
    while(1)
 
    {
 
        ssd1306_DrawChar(*srcPointer,row,xPos);
 
        srcPointer++;
 
        xPos+=6;
 
        if(*srcPointer == 0) break;
 
    }
 
}
ssd1306.h
Show inline comments
 
#ifndef   ssd1306_H
 
#define   ssd1306_H
 
 
typedef unsigned long Pos_t;
 
typedef unsigned long Size_t;
 
typedef unsigned long Color_t;
 
 
typedef   unsigned long  (*pfnDrawBlock_t)(
 
  Pos_t x,
 
  Pos_t y,
 
  Pos_t cx,
 
  Pos_t cy,
 
  const unsigned char* data);
 
typedef   unsigned long  (*pfnDrawPoint_t)(Pos_t x, Pos_t y, Color_t color);
 
 
 
typedef unsigned long(*pfnFontDrawChar)(pfnDrawBlock_t DrawBlock,Pos_t x, Pos_t y, unsigned int ch);
 
 
 
 
 
typedef  struct _DeviceProp
 
{
 
  pfnDrawBlock_t    pfnDrawBlok;
 
  pfnDrawPoint_t    pfnDrawPoint;
 
  Size_t            xPixel;
 
  Size_t            yPixel;
 
}DeviceProp;
 
 
typedef  struct  _Device
 
{
 
  const DeviceProp*   pDevProp;
 
  pfnFontDrawChar     pfnFont;
 
  Pos_t               curX;
 
  Pos_t               curY;
 
}Device;
 
 
 
void  ssd1306_Init(void);
 
void  StartPageTransfer(void);
 
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);
 
void ssd1306_block_write(void);
 
void ssd1306_DrawChar(char ascii, unsigned char row, unsigned char xPos);
 
void ssd1306_DrawString(const char *dataPtr, unsigned char row, unsigned char xPos);
 
void ssd1306_test();
 
void ssd1306_drawlogo();
 
 
#endif
0 comments (0 inline, 0 general)