#include "includes.h"
static volatile bool qspi_xfer_done;
static void qspi_event_handler(nrfx_qspi_evt_t event, void * p_context)
{
qspi_xfer_done = true; //设置SPIM传输完成
}
static void config_qspi_pin_high_drive(void)
{
nrf_gpio_cfg(
AM_OLED_CLK_PIN,
NRF_GPIO_PIN_DIR_INPUT,
NRF_GPIO_PIN_INPUT_CONNECT,
NRF_GPIO_PIN_PULLDOWN,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_SENSE_HIGH);
nrf_gpio_cfg(
AM_OLED_CS_PIN,
NRF_GPIO_PIN_DIR_INPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_NOPULL,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE);
nrf_gpio_cfg(
AM_OLED_D0_PIN,
NRF_GPIO_PIN_DIR_INPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_PULLDOWN,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE);
nrf_gpio_cfg(
AM_OLED_D1_PIN,
NRF_GPIO_PIN_DIR_INPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_PULLDOWN,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE);
nrf_gpio_cfg(
AM_OLED_D2_PIN,
NRF_GPIO_PIN_DIR_INPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_PULLDOWN,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE);
nrf_gpio_cfg(
AM_OLED_D3_PIN,
NRF_GPIO_PIN_DIR_INPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_PULLDOWN,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE);
}
static void bsp_amoled_qspi_init(void)
{
uint32_t err_code;
AMOLED_RST_PIN_INIT();
AMOLED_RST_PIN_H();
nrf_delay_ms(10);
AMOLED_RST_PIN_L();
nrf_delay_ms(10);
AMOLED_RST_PIN_H();
config_qspi_pin_high_drive();
nrf_drv_qspi_config_t config = NRF_DRV_QSPI_DEFAULT_CONFIG;
config.phy_if.sck_freq = 1;
config.pins.csn_pin = AM_OLED_CS_PIN;
config.pins.sck_pin = AM_OLED_CLK_PIN;
config.pins.io0_pin = AM_OLED_D0_PIN;
config.pins.io1_pin = AM_OLED_D1_PIN;
config.pins.io2_pin = AM_OLED_D2_PIN;
config.pins.io3_pin = AM_OLED_D3_PIN;
config.prot_if.dpmconfig = false;
err_code = nrf_drv_qspi_init(&config, qspi_event_handler, NULL);
APP_ERROR_CHECK(err_code);
}
static void bsp_amoled_qspi_write_cmd(uint8_t cmd)
{
uint8_t tx_buf[4];
nrf_qspi_cinstr_conf_t cinstr_cfg =
{
.opcode = 0x02,
.length = NRF_QSPI_CINSTR_LEN_4B,
.io2_level = true,
.io3_level = true,
.wipwait = false,
.wren = false
};
memset(tx_buf, 0, sizeof(tx_buf));
tx_buf[1] = cmd;
APP_ERROR_CHECK(nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, tx_buf, NULL));
}
static void bsp_amoled_qspi_write_reg(uint8_t reg, uint8_t *buf, uint8_t len)
{
uint8_t tx_buf[8];
nrf_qspi_cinstr_len_t cinstr_len;
if(len < 1 || len > 5)
{
return;
}
switch(len)
{
case 1:
cinstr_len = NRF_QSPI_CINSTR_LEN_5B;
break;
case 2:
cinstr_len = NRF_QSPI_CINSTR_LEN_6B;
break;
case 3:
cinstr_len = NRF_QSPI_CINSTR_LEN_7B;
break;
case 4:
cinstr_len = NRF_QSPI_CINSTR_LEN_8B;
break;
case 5:
cinstr_len = NRF_QSPI_CINSTR_LEN_9B;
break;
default:
break;
}
nrf_qspi_cinstr_conf_t cinstr_cfg =
{
.opcode = 0x02,
.length = cinstr_len,
.io2_level = true,
.io3_level = true,
.wipwait = false,
.wren = false
};
memset(tx_buf, 0, sizeof(tx_buf));
tx_buf[1] = reg;
memcpy(&tx_buf[3], buf, len);
APP_ERROR_CHECK(nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, tx_buf, NULL));
}
void bsp_amoled_qspi_write_data(uint32_t addr, uint8_t *buf, uint32_t len)
{
uint32_t time_count = 0;
if(len > 256)
{
return;
}
qspi_xfer_done = false;
APP_ERROR_CHECK(nrf_drv_qspi_write(buf, len, addr));
while(!qspi_xfer_done)
{
nrf_delay_us(1);
if(time_count++ > 10000000ul)
{
NRF_LOG_INFO("bsp_amoled_write_buf: NRF_ERROR_TIMEOUT");
break;
}
}
}
void bsp_amoled_color_fill(uint16_t x1, uint16_t x2, uint16_t y1, uint16_t y2, uint8_t *color_data)
{
uint8_t para1[4] = {0};
uint8_t para2[4] = {0};
uint8_t tx_buf[QSPI_FLASH_PAGE_SIZE] = {0};
uint16_t tx_size;
uint16_t row, col;
uint16_t area_x1, area_x2;
if(x1 >= LCD_DISP_HOR_RES || x2 >= LCD_DISP_HOR_RES || y1 >= LCD_DISP_VER_RES || y2 >= LCD_DISP_VER_RES)
{
return;
}
if(x2 < x1 || y2 < y1)
{
return;
}
row = (y2 - y1 + 1);
col = (x2 - x1 + 1);
//NRF_LOG_INFO("x1:%d, x2:%d, y1:%d, y2:%d, area:%d", x1, x2, y1, y2, row*col);
for(uint8_t i = 0; i < (col + 127)/128; i++)
{
if((i*128 + 128) < col)
{
tx_size = 256;
area_x1 = x1 + i*128;
area_x2 = x1 + i*128 + 128 - 1;
}
else
{
area_x1 = x1 + i*128;
area_x2 = x2;
tx_size = (area_x2 - area_x1 + 1)*2;
}
//NRF_LOG_INFO("x1:%d, x2:%d, y1:%d, y2:%d %d %d", area_x1, area_x2, y1, y2, tx_size, i);
para1[0] = (area_x1 >> 8) & 0x00FF;
para1[1] = area_x1 & 0x00FF;
para1[2] = (area_x2 >> 8) & 0x00FF;
para1[3] = area_x2 & 0x00FF;
para2[0] = (y1 >> 8) & 0x00FF;
para2[1] = y1 & 0x00FF;
para2[2] = (y2 >> 8) & 0x00FF;
para2[3] = y2 & 0x00FF;
bsp_amoled_qspi_write_reg(0x2A, para1, sizeof(para1));
bsp_amoled_qspi_write_reg(0x2B, para2, sizeof(para2));
memcpy(tx_buf, &color_data[256*i], tx_size); /*第0行数据*/
bsp_amoled_qspi_write_data(0x002C00, tx_buf, tx_size);
for(uint16_t j = 1; j < row; j++)
{
memcpy(tx_buf, &color_data[j*col*2 + 256*i], tx_size);
bsp_amoled_qspi_write_data(0x003C00, tx_buf, tx_size);
}
}
}
uint8_t test_buf[368*4*2];
void bsp_amoled_init(void)
{
bsp_amoled_qspi_init();
nrf_delay_ms(10);
bsp_amoled_qspi_write_cmd(0x11);
nrf_delay_ms(10);
uint8_t para3[2] = {0x01, 0xBF};
bsp_amoled_qspi_write_reg(0x44, para3, sizeof(para3));
uint8_t para4[1] = {0x55};
bsp_amoled_qspi_write_reg(0x3A, para4, sizeof(para4)); //0x55, -->565,, 0x77, -->888
uint8_t para6[1] = {0x00};
bsp_amoled_qspi_write_reg(0x35, para6, sizeof(para6));
uint8_t para7[1] = {0x20};
bsp_amoled_qspi_write_reg(0x53, para7, sizeof(para7));
nrf_delay_ms(25);
bsp_amoled_qspi_write_cmd(0x29);
NRF_LOG_INFO("bsp_amoled_init");
memset(test_buf, 0xFF, sizeof(test_buf));
for(uint16_t i = 0; i < 448/4; i++)
{
bsp_amoled_color_fill(0, 367, i*4, i*4+3, (uint8_t *)test_buf);
}
}
// Factory test
// uint8_t para8[2] = {0x5A, 0x5A};
// bsp_amoled_write_reg(0xC0, para8, sizeof(para8));
// uint8_t para9[1] = {0x81};
// bsp_amoled_write_reg(0xBA, para9, sizeof(para9));