📄 display_driver.txt
字号:
895. g_ddi_display_VideoMode = DDI_DISPLAY_VSYNC_MODE;
896.
897. // Wait for the first VSYNC pulse
898. WaitForControllerVsync();
899. }
900. else if( DDI_DISPLAY_ASYNC_MODE == VideoMode && DDI_DISPLAY_ASYNC_MODE != g_ddi_display_VideoMode )
901. {
902. // Disable the vector
903. hw_icoll_EnableVector(GPIO_VSYNC_IRQ_VECTOR, false);
904.
905. // Release the GPIO
906. ddi_gpio_UnlockPin(GPIO_VSYNC_IRQ_PIN);
907.
908. WriteDirect(CMD_MODE, 0x0b); // Frame Cycle Control
909. WriteDirect(DATA_MODE, 0);
910. // Stop the controller from generating the VSYNC signal
911. WriteDirect(CMD_MODE, 0x02); // LCD Driving Waveform Control
912. WriteDirect(DATA_MODE, LCDDrivingWaveformControl.V); // Disable sync output
913.
914. g_ddi_display_VideoMode = DDI_DISPLAY_ASYNC_MODE;
915. }
916. else
917. {
918. ret = ERROR_DDI_DISPLAY_CONTROLLER_VIDEO_MODE_UNSUPPORTED;
919. }
920.
921. return ret;
922. }
923. #endif
924. */
925. ////////////////////////////////////////////////////////////////////////////////
926. //! \fn static void SendControllerOutputEnable(bool bOn)
927. //!
928. //! \brief Turns the display on or off
929. //!
930. //! \fntype Function
931. //!
932. //! \param[in] bOn - true to turn on the display, false to turn it off
933. //!
934. //! This function sends commands to the controller to enable the output of the
935. //! display.
936. //!
937. ////////////////////////////////////////////////////////////////////////////////
938. static void SendControllerOutputEnable(bool bOn)
939. {
940. Hx8347aDisplayControl DisplayControl = { 0x0034 };
941.
942. if( bOn )
943. {
944. DisplayControl.B.D1 = 1 ;
945. WriteDirect(CMD_MODE, 0x26); // Display Control
946. WriteDirect(DATA_MODE, DisplayControl.V); // Enable output
947. }
948. else
949. {
950. //diable diaplay
951. DisplayControl.B.D1 = 0 ; //diable diaplay
952. WriteDirect(CMD_MODE, 0x26); // Display Control
953. WriteDirect(DATA_MODE, DisplayControl.V); // Disable output
954. }
955.
956.
957. // Enable or disable the backlight PWM as necessary
958. if( bOn )
959. HW_PWM_CTRL_SET(1 << DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL);
960. else
961. HW_PWM_CTRL_CLR(1 << DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL);
962. }
963.
964.
965. ////////////////////////////////////////////////////////////////////////////////
966. //! \brief Enters/exits low power mode
967. //!
968. //! \fntype Function
969. //!
970. //! \param[in] bOn - true to set low power mode, false to exit low power mode
971. //!
972. //! When entering low power mode, the LCDIF block is put into reset. This
973. //! should make the display controller go into reset as well. The backlight is
974. //! also disabled at this time. When exiting low power mode, the LCDIF is
975. //! reinitialized and the controller init sequence is sent again. The
976. //! application code must set the brightness and output enable after coming out
977. //! of low power mode.
978. //!
979. ////////////////////////////////////////////////////////////////////////////////
980. static void SetControllerLowPowerMode(bool bOn)
981. {
982. if( bOn )
983. {
984. SendControllerOutputEnable(false);
985. ddi_lcdif_Shutdown(true);
986. }
987. else
988. {
989. #ifdef DEBUG
990. RtStatus_t ret = SUCCESS;
991. #endif
992. hw_lcdif_Init_t LcdifInit;
993.
994. // Get the LCDIF init struct to send to the LCDIF DDI init function
995. #ifdef DEBUG
996. ret =
997. #endif
998. ddi_display_controller_GetLcdifInitStruct(&LcdifInit, g_ddi_display_eBitmapType);
999. #ifdef DEBUG
1000. assert(!ret);
1001. #endif
1002.
1003. // Run the low level init on the LCDIF
1004. #ifdef DEBUG
1005. ret =
1006. #endif
1007. ddi_lcdif_Init(&LcdifInit, g_ddi_display_pDmaDescChain, g_ddi_display_NumDmaDesc);
1008. #ifdef DEBUG
1009. assert(!ret);
1010. #endif
1011.
1012. #if defined(RTOS_THREADX)
1013. ddi_lcdif_RegisterCompletionCallback(&g_ddi_display_DmaCompletionCallback);
1014. #endif
1015. // Init the display controller, use last set width/height
1016. #ifdef DEBUG
1017. ret =
1018. #endif
1019. ddi_display_controller_SendCommand(DDI_DISPLAY_CONTROLLER_INIT,
1020. g_ddi_display_eBitmapType,
1021. g_ddi_display_u16ScreenWidth,
1022. g_ddi_display_u16ScreenHeight);
1023. #ifdef DEBUG
1024. assert(!ret);
1025. #endif
1026.
1027. }
1028. }
1029.
1030. ////////////////////////////////////////////////////////////////////////////////
1031. //! \fn static void SetPwmBrightness(uint32_t u32Percentage)
1032. //!
1033. //! \brief Sets the specified brightness percentage on the display
1034. //!
1035. //! \fntype Function
1036. //!
1037. //! \param[in] u32Percentage - Percent total brightness from 0 -> 100
1038. //!
1039. //! Sets the PWM backlight control channel according to the given brightness
1040. //! percentage value.
1041. //!
1042. ////////////////////////////////////////////////////////////////////////////////
1043. static void SetPwmBrightness(uint32_t u32Percentage)
1044. {
1045. uint32_t u32InactivePeriod;
1046.
1047. // Set the raw values in the PWM registers
1048. if( u32Percentage > 100 )
1049. u32Percentage = 100;
1050.
1051. // Calc the pulse width
1052. u32InactivePeriod = ((BACKLIGHT_PWM_PERIOD * MIN_BRIGHTNESS_PERCENTAGE)/100) +
1053. (( ((BACKLIGHT_PWM_PERIOD * (MAX_BRIGHTNESS_PERCENTAGE - MIN_BRIGHTNESS_PERCENTAGE))/100)
1054. * u32Percentage)/100);
1055.
1056. // Scale the range 0->100% down to 0->70% to protect the hardware
1057. BF_CS2n(PWMn_ACTIVE, DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL,
1058. ACTIVE, 0,// BACKLIGHT_PWM_PERIOD,
1059. INACTIVE, u32InactivePeriod);
1060.
1061. // Have to write the period register to apply the changes
1062. HW_PWMn_PERIOD_SET(DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL, 0);
1063. }
1064.
1065.
1066. ////////////////////////////////////////////////////////////////////////////////
1067. //! \fn static RtStatus_t SendControllerRegion(uint32_t u32XDst, uint32_t u32YDst, uint32_t *pu32Width, uint32_t *pu32Height, ddi_display_Rotation_t eRotation)
1068. //!
1069. //! \brief Sets up the region on the controller where pixels are to be placed
1070. //!
1071. //! \fntype Function
1072. //!
1073. //! \param[in] u32XDst - X coordinate of upper left corner of the destination region
1074. //! \param[in] u32YDst - Y coordinate of upper left corner of the destination region
1075. //! \param[in] pu32Width - Width of the destination region
1076. //! \param[in] pu32Height - Height of the destination region
1077. //! \param[in] eRotation - Desired orientation of the display
1078. //!
1079. //! This function sends commands to the controller to set up the destination
1080. //! region (or "box") where pixels are to be placed. The rotation is specified
1081. //! here as well as with the SendControllerRotation function because some
1082. //! controllers handle rotation on a per region basis.
1083. //!
1084. //! \retval SUCCESS No error
1085. //!
1086. //! \retval ERROR_DDI_DISPLAY_CONTROLLER_ROTATION - The specified rotation is
1087. //! not supported by the controller
1088. //!
1089. //! \retval ERROR_DDI_DISPLAY_PLACEMENT - There was an error placing the given
1090. //! region on the display that clipping could not compensate for.
1091. //!
1092. ////////////////////////////////////////////////////////////////////////////////
1093. static RtStatus_t SendControllerRegion(uint32_t u32XDst, uint32_t u32YDst,
1094. uint32_t *pu32Width, uint32_t *pu32Height,
1095. ddi_display_Rotation_t eRotation)
1096. {
1097. uint32_t u32TotalWidth = g_ddi_display_u16ScreenWidth;
1098. uint32_t u32TotalHeight = g_ddi_display_u16ScreenHeight;
1099. RtStatus_t ret = SUCCESS;
1100.
1101. uint16_t u16SourceWinStart_high;
1102. uint16_t u16SourceWinStart_low;
1103. uint16_t u16SourceWinStop_high;
1104. uint16_t u16SourceWinStop_low;
1105.
1106. uint16_t u16GateWinStart_high;
1107. uint16_t u16GateWinStart_low;
1108. uint16_t u16GateWinStop_high;
1109. uint16_t u16GateWinStop_low;
1110.
1111. // Check for zero sized region
1112. if( !*pu32Width || !*pu32Height
1113. || u32XDst >= u32TotalWidth
1114. || u32YDst >= u32TotalHeight )
1115. {
1116. return ERROR_DDI_DISPLAY_PLACEMENT;
1117. }
1118.
1119. // Check for clipping
1120. if( u32XDst + *pu32Width > u32TotalWidth)
1121. {
1122. // FIXME - Must do a DrawRegion type xfer for this
1123. // since the clipped pixels will not be contiguous
1124. return ERROR_DDI_DISPLAY_PLACEMENT;
1125. }
1126.
1127. // Check for clipping
1128. if( u32YDst + *pu32Height > u32TotalHeight )
1129. {
1130. // Fix clipping region
1131. *pu32Height = u32TotalHeight - u32YDst;
1132. }
1133.
1134. // Gate/Source diagram
1135. //
1136. // 240
1137. // S719 S0
1138. // ---------------------
1139. // | | G0
1140. // | |
1141. // | |
1142. // | |
1143. // | |
1144. // | |
1145. // | | 320
1146. // | |
1147. // | |
1148. // | |
1149. // | |
1150. // | |
1151. // | | G319
1152. // ---------------------
1153. // |Ribbon cable |
1154. // ---------------
1155. //
1156. switch(eRotation)
1157. {//11 03 12 00
1158. case DDI_DISPLAY_ROTATION_NONE:
1159. u16SourceWinStart_high=(uint16_t)(((u32XDst)&0x0000FF00)>>8);
1160. u16SourceWinStart_low=(uint16_t)((u32XDst)&0x000000FF);
1161. u16SourceWinStop_high=(uint16_t)(((u32XDst + *pu32Width - 1)&0x0000FF00)>>8);
1162. u16SourceWinStop_low=(uint16_t)((u32XDst + *pu32Width - 1)&0x000000FF);
1163.
1164. u16GateWinStart_high=(uint16_t)(((u32YDst)&0x0000FF00)>>8);
1165. u16GateWinStart_low=(uint16_t)((u32YDst)&0x000000FF);
1166. u16GateWinStop_high=(uint16_t)(((u32YDst + *pu32Height - 1)&0x0000FF00)>>8);
1167. u16GateWinStop_low=(uint16_t)((u32YDst + *pu32Height - 1)&0x000000FF);
1168. break;
1169. case DDI_DISPLAY_ROTATION_90:
1170. u16SourceWinStart_high=(uint16_t)(((u32XDst)&0x0000FF00)>>8);
1171. u16SourceWinStart_low=(uint16_t)((u32XDst)&0x000000FF);
1172. u16SourceWinStop_high=(uint16_t)(((u32XDst + *pu32Width - 1)&0x0000FF00)>>8);
1173. u16SourceWinStop_low=(uint16_t)((u32XDst + *pu32Width - 1)&0x000000FF);
1174.
1175. u16GateWinStart_high=(uint16_t)(((u32YDst)&0x0000FF00)>>8);
1176. u16GateWinStart_low=(uint16_t)((u32YDst)&0x000000FF);
1177. u16GateWinStop_high=(uint16_t)(((u32YDst + *pu32Height - 1)&0x0000FF00)>>8);
1178. u16GateWinStop_low=(uint16_t)((u32YDst + *pu32Height - 1)&0x000000FF);
1179. break;
1180. case DDI_DISPLAY_ROTATION_180:
1181. u16SourceWinStart_high=(uint16_t)(((u32XDst)&0x0000FF00)>>8);
1182. u16SourceWinStart_low=(uint16_t)((u32XDst)&0x000000FF);
1183. u16SourceWinStop_high=(uint16_t)(((u32XDst + *pu32Width - 1)&0x0000FF00)>>8);
1184. u16SourceWinStop_low=(uint16_t)((u32XDst + *pu32Width - 1)&0x000000FF);
1185.
1186. u16GateWinStart_high=(uint16_t)(((u32YDst)&0x0000FF00)>>8);
1187. u16GateWinStart_low=(uint16_t)((u32YDst)&0x000000FF);
1188. u16GateWinStop_high=(uint16_t)(((u32YDst + *pu32Height - 1)&0x0000FF00)>>8);
1189. u16GateWinStop_low=(uint16_t)((u32YDst + *pu32Height - 1)&0x000000FF);
1190. break;
1191. case DDI_DISPLAY_ROTATION_270:
1192. u16SourceWinStart_high=(uint16_t)(((u32XDst)&0x0000FF00)>>8);
1193. u16SourceWinStart_low=(uint16_t)((u32XDst)&0x000000FF);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -