|
1 | 1 | #include "drivers/display/display.h" |
| 2 | +#include "drivers/display/sharp_ls013b7dh01/sharp_ls013b7dh01.h" |
| 3 | +#include "system/logging.h" |
| 4 | +#include "util/reverse.h" |
| 5 | +#include "FreeRTOS.h" |
| 6 | +#include "semphr.h" |
| 7 | + |
| 8 | +#include "bf0_hal.h" |
| 9 | + |
| 10 | +#define SPI_APB_CLOCK 48000000 |
| 11 | +#define SPI_FREQ 1000000 |
| 12 | + |
| 13 | +static SPI_HandleTypeDef spi = { |
| 14 | + .core = CORE_ID_HCPU, |
| 15 | + .Instance = SPI1, |
| 16 | + .State = HAL_SPI_STATE_RESET, |
| 17 | + .Init = { |
| 18 | + .Direction = SPI_DIRECTION_1LINE, |
| 19 | + .Mode = SPI_MODE_MASTER, |
| 20 | + .DataSize = SPI_DATASIZE_8BIT, |
| 21 | + .CLKPhase = SPI_PHASE_1EDGE, |
| 22 | + .CLKPolarity = SPI_POLARITY_LOW, |
| 23 | + .BaudRatePrescaler = (SPI_APB_CLOCK + SPI_FREQ / 2) / SPI_FREQ, |
| 24 | + .FrameFormat = SPI_FRAME_FORMAT_SPI, |
| 25 | + .SFRMPol = SPI_SFRMPOL_HIGH, |
| 26 | + }, |
| 27 | +}; |
| 28 | + |
| 29 | +static SemaphoreHandle_t s_sem; |
| 30 | + |
| 31 | +#define DISPLAY_SELECT() HAL_GPIO_WritePin(hwp_gpio1, 29, GPIO_PIN_SET) |
| 32 | +#define DISPLAY_DESELECT() HAL_GPIO_WritePin(hwp_gpio1, 29, GPIO_PIN_RESET) |
2 | 33 |
|
3 | 34 | uint32_t display_baud_rate_change(uint32_t new_frequency_hz) { |
4 | 35 | return new_frequency_hz; |
5 | 36 | } |
6 | 37 |
|
7 | 38 | void display_init(void) { |
| 39 | + GPIO_InitTypeDef gpio_init; |
| 40 | + |
| 41 | + HAL_PIN_Set(PAD_PA29, GPIO_A29, PIN_NOPULL, 1); |
| 42 | + HAL_PIN_Set(PAD_PA24, SPI1_DIO, PIN_PULLDOWN, 1); |
| 43 | + HAL_PIN_Set(PAD_PA28, SPI1_CLK, PIN_NOPULL, 1); |
| 44 | + |
| 45 | + gpio_init.Pin = 29; |
| 46 | + gpio_init.Mode = GPIO_MODE_OUTPUT; |
| 47 | + gpio_init.Pull = GPIO_NOPULL; |
| 48 | + HAL_GPIO_Init(hwp_gpio1, &gpio_init); |
| 49 | + |
| 50 | + DISPLAY_DESELECT(); |
| 51 | + |
| 52 | + HAL_RCC_EnableModule(RCC_MOD_SPI1); |
| 53 | + |
| 54 | + if (HAL_SPI_Init(&spi) != HAL_OK) { |
| 55 | + PBL_LOG(LOG_LEVEL_ERROR, "spi init err!"); |
| 56 | + return; |
| 57 | + } |
| 58 | + |
| 59 | + vSemaphoreCreateBinary(s_sem); |
| 60 | + |
| 61 | + display_clear(); |
8 | 62 | } |
9 | 63 |
|
10 | 64 | void display_clear(void) { |
| 65 | + HAL_StatusTypeDef ret; |
| 66 | + uint8_t buf[2]; |
| 67 | + |
| 68 | + buf[0] = 0x20U; |
| 69 | + buf[1] = 0x00U; |
| 70 | + |
| 71 | + DISPLAY_SELECT(); |
| 72 | + ret = HAL_SPI_Transmit(&spi, buf, 2, 1000); |
| 73 | + if (ret != HAL_OK) { |
| 74 | + PBL_LOG(LOG_LEVEL_ERROR, "SPI transmit error"); |
| 75 | + return; |
| 76 | + } |
| 77 | + DISPLAY_DESELECT(); |
11 | 78 | } |
12 | 79 |
|
13 | 80 | bool display_update_in_progress(void) { |
| 81 | + if (xSemaphoreTake(s_sem, 0) == pdTRUE) { |
| 82 | + xSemaphoreGive(s_sem); |
| 83 | + return false; |
| 84 | + } |
| 85 | + |
14 | 86 | return true; |
15 | 87 | } |
16 | 88 |
|
17 | 89 | void display_update(NextRowCallback nrcb, UpdateCompleteCallback uccb) { |
| 90 | + DisplayRow row; |
| 91 | + HAL_StatusTypeDef ret; |
| 92 | + uint8_t buf[DISP_DMA_BUFFER_SIZE_BYTES]; |
| 93 | + |
| 94 | + xSemaphoreTake(s_sem, portMAX_DELAY); |
| 95 | + |
| 96 | + DISPLAY_SELECT(); |
| 97 | + |
| 98 | + buf[0] = 0x80U; |
| 99 | + ret = HAL_SPI_Transmit(&spi, buf, 1, HAL_MAX_DELAY); |
| 100 | + if (ret != HAL_OK) { |
| 101 | + PBL_LOG(LOG_LEVEL_ERROR, "SPI transmit error"); |
| 102 | + goto exit; |
| 103 | + } |
| 104 | + |
| 105 | + while (nrcb(&row)) { |
| 106 | + buf[0] = reverse_byte(row.address + 1); |
| 107 | + for (size_t i = 0; i < DISP_LINE_BYTES; i++) { |
| 108 | + buf[i + 1] = reverse_byte(row.data[i]); |
| 109 | + } |
| 110 | + buf[1 + DISP_LINE_BYTES] = 0x00U; |
| 111 | + |
| 112 | + ret = HAL_SPI_Transmit(&spi, buf, DISP_LINE_BYTES + 2, HAL_MAX_DELAY); |
| 113 | + if (ret != HAL_OK) { |
| 114 | + PBL_LOG(LOG_LEVEL_ERROR, "SPI transmit error"); |
| 115 | + goto exit; |
| 116 | + } |
| 117 | + } |
| 118 | + |
| 119 | + buf[0] = 0x00U; |
| 120 | + ret = HAL_SPI_Transmit(&spi, buf, 1, HAL_MAX_DELAY); |
| 121 | + if (ret != HAL_OK) { |
| 122 | + PBL_LOG(LOG_LEVEL_ERROR, "SPI transmit error"); |
| 123 | + goto exit; |
| 124 | + } |
| 125 | + |
| 126 | +exit: |
| 127 | + DISPLAY_DESELECT(); |
| 128 | + |
| 129 | + uccb(); |
| 130 | + |
| 131 | + xSemaphoreGive(s_sem); |
18 | 132 | } |
19 | 133 |
|
20 | 134 | void display_pulse_vcom(void) { |
|
0 commit comments