RM67162调试案例

#include “nrf_drv_spi.h”
#include “nrf_gpio.h”

#include “dxc_hal.h”
#include “dxc_halLcd.h”
#include “drv_rm67162.h”

///
#if 0

// 高速 SPI, 最高可以达到 32Mbps
static const nrfx_spim_t oled_spi = NRFX_SPIM_INSTANCE(3);

// @brief 初始化flash 硬件接口
static void rm6716x_spi_init(void)
{
nrfx_spim_config_t spi_config = NRFX_SPIM_DEFAULT_CONFIG;
spi_config.ss_pin = RM6716X_SPI_CSN_PIN;
spi_config.sck_pin = RM6716X_SPI_SCK_PIN;
spi_config.mosi_pin = RM6716X_SPI_MOSI_PIN;
spi_config.miso_pin = RM6716X_SPI_MISO_PIN;

spi_config.irq_priority = NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY;
spi_config.frequency = NRF_SPIM_FREQ_8M;
spi_config.mode = NRF_SPIM_MODE_0;
spi_config.bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST;

//nrf_gpio_cfg_output(RM6716X_SPI_CSN_PIN);
//rm6716x_spi_csn_set();
// 阻塞模式
APP_ERROR_CHECK(nrfx_spim_init(&oled_spi, &spi_config, NULL, NULL));

}

// @brief 传送数据,必须为阻塞模式
// @param in 输入数据;inLen 输入数据长度
// @param out 输出数据;outLen 输出数据长度
void rm6716x_transfer(const uint8_t* in, uint8_t inLen, uint8_t* out, uint8_t outLen)
{
ret_code_t ret;
nrfx_spim_xfer_desc_t spim_desc;

spim_desc.p_rx_buffer = out;
spim_desc.rx_length = outLen;
spim_desc.p_tx_buffer = in;
spim_desc.tx_length = inLen;

//rm6716x_spi_csn_clr();
ret = nrfx_spim_xfer(&oled_spi, &spim_desc, 0);
//rm6716x_spi_csn_set();
APP_ERROR_CHECK(ret);

}

#else

/**< SPI instance. */
static const nrf_drv_spi_t oled_spi = NRF_DRV_SPI_INSTANCE(0);

// @brief 初始化 spi
static void rm6716x_spi_init(void)
{
const nrf_drv_spi_config_t spi_config = {
.ss_pin = NRF_DRV_SPI_PIN_NOT_USED,
.sck_pin = RM6716X_SPI_SCK_PIN,
.mosi_pin = RM6716X_SPI_MOSI_PIN,
.miso_pin = RM6716X_SPI_MISO_PIN,

    .irq_priority = APP_IRQ_PRIORITY_MID,
    .orc          = 0xFF, 
    .frequency    = NRF_DRV_SPI_FREQ_8M,
    .mode         = NRF_DRV_SPI_MODE_0,
    .bit_order    = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST,
};

nrf_gpio_cfg_output(RM6716X_SPI_CSN_PIN);
rm6716x_spi_csn_set();

APP_ERROR_CHECK(nrf_drv_spi_init(&oled_spi, &spi_config, NULL, NULL));

}

// @brief 传送数据,必须为阻塞模式
// @param in 输入数据;inLen 输入数据长度
// @param out 输出数据;outLen 输出数据长度
void rm6716x_transfer(const uint8_t* in, uint8_t inLen, uint8_t* out, uint8_t outLen)
{
ret_code_t ret;

ret = nrf_drv_spi_transfer(&oled_spi, in, inLen, out, outLen);
APP_ERROR_CHECK(ret);

}
#endif

///
// @brief 设置命令模式
static __INLINE void rm6716x_set_command_mode(void)
{
nrf_gpio_pin_clear(RM6716X_CMD_DATA_PIN);
delay_us(22);
}

// @brief 设置数据模式
static __INLINE void rm6716x_set_data_mode(void)
{
nrf_gpio_pin_set(RM6716X_CMD_DATA_PIN);
delay_us(22);
}

// @brief 发送数据
void rm6716x_write_data(const uint8_t* data, uint16_t dataLen)
{
rm6716x_spi_csn_clr();
rm6716x_set_data_mode();
rm6716x_transfer(data, dataLen, NULL, 0);
rm6716x_spi_csn_set();
}

// @brief 发送命令和数据
void rm6716x_send_command_data(uint8_t cmd, const uint8_t* data, uint16_t dataLen)
{
rm6716x_spi_csn_clr();

// 发送命令
rm6716x_set_command_mode();
rm6716x_transfer(&cmd, 1, NULL, 0);

// 发送数据
if (data && dataLen > 0)
{
    rm6716x_set_data_mode();
    rm6716x_transfer(data, dataLen, NULL, 0);
}

rm6716x_spi_csn_set();

}

// @brief 发送命令和字节
static __INLINE void rm6716x_send_command_byte(uint8_t cmd, uint8_t byte)
{
rm6716x_send_command_data(cmd, &byte, 1);
}

// @brief 发送命令
static __INLINE void rm6716x_write_command(uint8_t cmd)
{
rm6716x_send_command_data(cmd, NULL, 0);
}

///
uint16_t mem_start_address; // 垂直滚动地址
int16_t mem_length = 390; // 内存长(左右长度)
int16_t mem_width = 390; // 内存宽(上下高度)

///
// @brief 接口调试
void rm6716x_who_am_i(void)
{
uint8_t buff[8];

memset(buff, 0, sizeof(buff));
buff[0] = 0x04;
//rm6716x_write_command(0x04);
rm6716x_transfer(buff, 1, &buff[1], 3);

Debug("buff: %02x-%02x-%02x-%02x-%02x-%02x", buff[0], buff[1], buff[2], buff[3], buff[4], buff[5]);

}

// @brief
void rm6716x_x120bln_init(void)
{
uint8_t buff[32];
uint8_t offset;

// 引脚初始化
hal_gpio_cfg_output(RM6716X_POWER_ENABLE_PIN);
hal_gpio_cfg_output(RM6716X_SPI_RESET_PIN);
hal_gpio_cfg_output(RM6716X_CMD_DATA_PIN);

// power enable
hal_gpio_pin_set(RM6716X_POWER_ENABLE_PIN);
delay_ms(15);

// reset
rm6716x_reset();

// 初始化
rm6716x_spi_init();
delay_ms(2);

rm6716x_send_command_byte(0xfe, 0x01); // page 1
rm6716x_send_command_byte(0x6c, 0x0a); // mipi turn off
rm6716x_send_command_byte(0x04, 0xa0);// 开启 spi 写 ram

rm6716x_send_command_byte(0xfe, 0x05);
rm6716x_send_command_byte(0x05, 0x00);

rm6716x_send_command_byte(0xfe, 0x00);
rm6716x_send_command_byte(0x35, 0x00);
rm6716x_send_command_byte(0x36, RM6716X_MADCTL_MY|RM6716X_MADCTL_MX|RM6716X_MADCTL_RGB);
rm6716x_send_command_byte(RM6716X_CMD_SET_BRIGHTNESS, 200);
rm6716x_send_command_byte(0x53, 0x20);
rm6716x_send_command_byte(0xc4, 0x80);
rm6716x_send_command_byte(0x3a, RM6716X_RGB_FORMAT_565);

offset = 0;
buff[offset++] = 0x00;
buff[offset++] = 0x00;
buff[offset++] = 0x01;          // 0x00ef = 239; 319 = 0x013f
buff[offset++] = 0x85;
rm6716x_send_command_data(RM6716X_CMD_COLUMN_ADDR_SET, buff, offset);
offset = 0;
buff[offset++] = 0x00;
buff[offset++] = 0x00;
buff[offset++] = 0x01;          // 0x00ef = 239; 319 = 0x013f
buff[offset++] = 0x85;
rm6716x_send_command_data(RM6716X_CMD_ROW_ADDR_SET, buff, offset);

rm6716x_write_command(0x11);            // sleep out
delay_ms(120);

rm6716x_write_command(0x29);
delay_ms(20);
rm6716x_write_command(0x2C);
delay_ms(20);
rm6716x_show_block_color(0, 0, 389, 389, WHITE);

}

// @brief 寄存器初始化
void rm6716x_init(void)
{
// gpio 初始化
//hal_gpio_cfg_output(RM6716X_BACK_LIGHT_PIN);
hal_gpio_cfg_output(RM6716X_POWER_ENABLE_PIN);
hal_gpio_cfg_output(RM6716X_SPI_RESET_PIN);
hal_gpio_cfg_output(RM6716X_CMD_DATA_PIN);

rm6716x_spi_init();
//delay_ms(1);
//nrf_gpio_pin_set(RM6716X_BACK_LIGHT_PIN);
delay_ms(1);
nrf_gpio_pin_clear(RM6716X_SPI_RESET_PIN);
delay_ms(2);
nrf_gpio_pin_set(RM6716X_SPI_RESET_PIN);
delay_ms(2);

// reg config
rm6716x_write_command(RM6716X_CMD_SLEEP_OUT);
delay_ms(10);
//rm6716x_register_init();

}

// @brief 使能电源
void rm6716x_power_enable(void)
{
// 复位引脚拉低
hal_gpio_cfg_output(RM6716X_SPI_RESET_PIN);
hal_gpio_pin_clear(RM6716X_SPI_RESET_PIN);

hal_gpio_cfg_output(RM6716X_CMD_DATA_PIN);

// 电源芯片引脚拉高
hal_gpio_cfg_output(RM6716X_POWER_ENABLE_PIN);
hal_gpio_pin_set(RM6716X_POWER_ENABLE_PIN);

}

// 初始化 spi
void rm6716x_spi_enable(void)
{
rm6716x_spi_init();
}

void rm6716x_reset(void)
{
hal_gpio_cfg_output(RM6716X_SPI_RESET_PIN);
delay_us(20);

nrf_gpio_pin_set(RM6716X_SPI_RESET_PIN);
delay_ms(4);
nrf_gpio_pin_clear(RM6716X_SPI_RESET_PIN);
delay_ms(4);
nrf_gpio_pin_set(RM6716X_SPI_RESET_PIN);
delay_ms(12);

// TE 引脚拉低
//hal_gpio_cfg_output(RM6716X_TE_PIN);
//delay_us(20);
//hal_gpio_pin_set(RM6716X_TE_PIN);

}

// @brief 进入休眠
void rm6716x_enter_sleep(void)
{
rm6716x_write_command(RM6716X_CMD_DISPLAY_OFF);
//delay_ms(10);
rm6716x_write_command(RM6716X_CMD_SLEEP_IN);
// 关背光灯
//nrf_gpio_pin_clear(RM6716X_BACK_LIGHT_PIN);
}

// @brief 退出休眠
void rm6716x_exit_sleep(void)
{
rm6716x_write_command(RM6716X_CMD_SLEEP_OUT);
delay_ms(5);
rm6716x_write_command(RM6716X_CMD_DISPLAY_ON);

// 开背光灯
//nrf_gpio_pin_set(RM6716X_BACK_LIGHT_PIN);

}

// @brief 设置窗口地址
// @param xs,xe 设置列区域(左右),ys,ye 设置行区域(上下);
void rm6716x_set_addr_window(uint16_t xs, uint16_t ys, uint16_t xe, uint16_t ye)
{
uint8_t buff[4];

buff[0] = xs >> 8;
buff[1] = xs;
buff[2] = xe >> 8;
buff[3] = xe;
rm6716x_send_command_data(RM6716X_CMD_COLUMN_ADDR_SET, buff, 4);

buff[0] = ys >> 8;
buff[1] = ys;
buff[2] = ye >> 8;
buff[3] = ye;
rm6716x_send_command_data(RM6716X_CMD_ROW_ADDR_SET, buff, 4);

rm6716x_write_command(RM6716X_CMD_MEM_WRITE);

}

// @brief 显示一个区块的颜色
bool rm6716x_show_block_color(int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)
{
uint16_t i;
uint16_t length, weight;
uint8_t buff[256];

if (x2 > mem_length - 1)
    x2 = mem_length - 1;
if (y2 > mem_length - 1)
    y2 = mem_length - 1;
if (x1 < 0)
    x1 = 0;
if (y1 < 0)
    y1 = 0;

if ((x1 > x2) || (y1 > y2))
{
    //Log("show block color failed. x1:y1=(%d:%d), x2:y2=(%d:%d)", x1, y1, x2, y2);
    return FALSE;
}

length = x2-x1+1; 
weight = y2-y1+1;

for (i=0; i<=256;) 
{
    buff[i++] = color >> 8;
    buff[i++] = color;
}

// 对某个区域内存进行写
rm6716x_set_addr_window(x1, y1, x2, y2);
for(i=0; i<weight; i++)
{
    if (length < 128)
    {
        rm6716x_write_data(buff, (length << 1));
    }
    else 
    {
        rm6716x_write_data(buff, length);
        rm6716x_write_data(buff, length);
    }
}
rm6716x_write_command(0x2C);
delay_ms(20);
return TRUE;

}

// @brief 显示一张图片的一部分
// @param x1,y1 显示坐标
// @param xoft,yoft 图片显示偏移量
// @return true 成功显示图片;false 失败,没有显示图片
bool rm6716x_show_picture(int16_t x1, int16_t y1, int16_t xoft, int16_t yoft, const uint8_t *data)
{
int16_t i;
int16_t length, width;
uint8_t buf[256];
uint32_t offset = 8;
int16_t xLen, yLen; //

// 如果坐标小于0,需要做偏移
if (x1 < 0)
{
    xoft += (-x1);
    x1 = 0;
}
if (y1 < 0)
{
    yoft += (-y1);
    y1 = 0;
}

length = ((data[2] << 8) | (data[3] & 0xFF));
width = ((data[4] << 8) | (data[5] & 0xFF));
if (xoft > length - 1 || yoft > width - 1)      // 偏移超出图片大小
{
    Log("The error picture position. xoft=%d, yoft=%d, width=%d, length=%d", xoft, yoft, width, length);
    return FALSE;
}

xLen = length - xoft;
yLen = width - yoft;
xoft = 0;
if (x1 + xLen > mem_length - 1)
    xLen = mem_length - x1;
else
    xoft = (length - xLen) * 2;
length <<= 1;
if (y1 + yLen > mem_width - 1)
    yLen = mem_width - y1;
else
    offset += yoft * length;

//Log("x1+xLen-1=%d, %d", x1+xLen-1, y1+yLen-1);
rm6716x_set_addr_window(x1, y1, x1 + xLen - 1, y1 + yLen - 1);
for (i=0; i<yLen; i++)
{
    if (xLen < 128)
    {
        memcpy(buf, &data[offset + xoft], (xLen << 1));
        rm6716x_write_data(buf, (xLen << 1));
    }
    else 
    {
        memcpy(buf, &data[offset + xoft], xLen);
        rm6716x_write_data(buf, xLen);
        memcpy(buf, &data[offset+xLen + xoft], xLen);
        rm6716x_write_data(buf, xLen);
    }
    
    offset += length;
}
return TRUE;

}

// @brief 垂直滚动定义命令
// @param tfix 顶部固定区域;scoll 滚动区域;bfix 底部固定区域
// @note: tfix + scoll + bfix = 320
void rm6716x_vertical_scrolling_defined(uint16_t tfix, uint16_t scoll, uint16_t bfix)
{
uint8_t data[6];

data[0] = tfix >> 8;
data[1] = tfix;
data[2] = scoll >> 8;
data[3] = scoll;
data[4] = bfix >> 8;
data[5] = bfix;
LCD_SendCmdData(RM6716X_CMD_VERTICAL_SCROLLING, data, 6);

}

// @brief 设置垂直滚动起始地址
void rm6716x_set_mem_start_address(uint16_t addr)
{
uint8_t data[2];

if (addr == mem_start_address)
    return;
mem_start_address = addr;
data[0] = addr >> 8;
data[1] = addr;
LCD_SendCmdData(RM6716X_CMD_VER_SCRO_START_ADDR, data, 2);

}

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值