marco valli / TFT_ILI9163C

Dependents:   TFTLCDSCREEN Pong_ILI9163C

Fork of TFT_ILI9163C by _ peu605

Revision:
6:83f3605478ab
Parent:
5:836673938ba7
--- a/TFT_ILI9163C.cpp	Tue Jan 27 06:23:31 2015 +0000
+++ b/TFT_ILI9163C.cpp	Wed Jan 28 13:35:18 2015 +0000
@@ -28,7 +28,7 @@
 //Serial pc(SERIAL_TX, SERIAL_RX);
 
 // F411RE specific
-#if defined(TARGET_NUCLEO_F411RE)
+#if defined(TARGET_NUCLEO_F411RE) | defined(TARGET_NUCLEO_F302R8)
 void TFT_ILI9163C::init(PinName cs, PinName dc){
 	
 	SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
@@ -49,13 +49,15 @@
 //  uint8_t dc_port_bit = (uint32_t) dc & 0xf;
 //	bb_cs_port = BITBAND_PERIPH(&cs_port_reg->ODR, cs_port_bit);
 //	bb_dc_port = BITBAND_PERIPH(&dc_port_reg->ODR, dc_port_bit);
-    
+
 	bb_spi_txe = BITBAND_PERIPH(&spi_ptr->SR, MASK_TO_BITNUM(SPI_SR_TXE));
 	bb_spi_bsy = BITBAND_PERIPH(&spi_ptr->SR, MASK_TO_BITNUM(SPI_SR_BSY));
 	bb_spi_spe = BITBAND_PERIPH(&spi_ptr->CR1, MASK_TO_BITNUM(SPI_CR1_SPE));
+#if defined(TARGET_NUCLEO_F411RE)
 	bb_spi_dff = BITBAND_PERIPH(&spi_ptr->CR1, MASK_TO_BITNUM(SPI_CR1_DFF));
-	
-#if defined(__F411RE_DMA__)
+#endif
+
+#if defined(__NUCLEO_DMA__) & defined(TARGET_NUCLEO_F411RE)
 	// init DMA
 	hdma.Init.Direction = DMA_MEMORY_TO_PERIPH;
 	hdma.Init.PeriphInc = DMA_PINC_DISABLE;
@@ -90,7 +92,7 @@
 		hdma.Init.Channel = DMA_CHANNEL_2;	// DMA_CHANNEL5, DMA_CHANNEL7
         __DMA2_CLK_ENABLE();
     }
-    
+	
     HAL_DMA_Init(&hdma);
 
 	// set SPI DR ss Peripheral address
@@ -99,28 +101,60 @@
 	// set bit band addresses
 	bb_spi_txdmaen = BITBAND_PERIPH(&spi_ptr->CR2, MASK_TO_BITNUM(SPI_CR2_TXDMAEN));
 	bb_dma_sxcr_en = BITBAND_PERIPH(&hdma.Instance->CR, MASK_TO_BITNUM(DMA_SxCR_EN));
+	
+#elif defined(__NUCLEO_DMA__) & defined(TARGET_NUCLEO_F302R8)
+	// init DMA
+	hdma.Init.Direction = DMA_MEMORY_TO_PERIPH;
+	hdma.Init.PeriphInc = DMA_PINC_DISABLE;
+	hdma.Init.MemInc = DMA_MINC_DISABLE;
+	hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+	hdma.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
+	hdma.Init.Mode = DMA_NORMAL;
+	hdma.Init.Priority = DMA_PRIORITY_MEDIUM;
+	
+    if(_spi.spi == SPI_2){
+        hdma.Instance = DMA1_Channel5;
+        __DMA1_CLK_ENABLE();
+    } else if(_spi.spi == SPI_3){
+        hdma.Instance = DMA1_Channel3;
+        __DMA1_CLK_ENABLE();
+    }
+    
+    HAL_DMA_Init(&hdma);
+
+	// set SPI DR ss Peripheral address
+	hdma.Instance->CPAR = (uint32_t) &spi_ptr->DR;
+	
+	// set bit band addresses
+	bb_spi_txdmaen = BITBAND_PERIPH(&spi_ptr->CR2, MASK_TO_BITNUM(SPI_CR2_TXDMAEN));
+	bb_dma_sxcr_en = BITBAND_PERIPH(&hdma.Instance->CCR, MASK_TO_BITNUM(DMA_CCR_EN));
 #endif
 }
+
 inline void TFT_ILI9163C::selectSlave() {
 //	_cs = 0;							// Use DigitalOut
 //	*bb_cs_port = 0;					// Use bit band
 	cs_port_reg->BSRRH = cs_reg_mask;	// Use BSRR register
 }
+
 inline void TFT_ILI9163C::deselectSlave() {
 //	_cs = 1;
 //	*bb_cs_port = 1;
 	cs_port_reg->BSRRL = cs_reg_mask;
 }
+
 inline void TFT_ILI9163C::setCommandMode() {
 //	_dc = 0;
 //	*bb_dc_port = 0;
 	dc_port_reg->BSRRH = dc_reg_mask;
 }
+
 inline void TFT_ILI9163C::setDataMode() {
 //	_dc = 1;
 //	*bb_dc_port = 1;
 	dc_port_reg->BSRRL = dc_reg_mask;
 }
+
 inline void TFT_ILI9163C::waitSpiFree() {
 	
 //	SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
@@ -139,6 +173,7 @@
 	while (*bb_spi_txe == 0);
 }
 
+#if defined(TARGET_NUCLEO_F411RE)
 inline void TFT_ILI9163C::set8bitMode() {
 	
 //	SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
@@ -174,7 +209,6 @@
 	deselectSlave();
 }
 
-
 void TFT_ILI9163C::writedata(uint8_t c){
 	
 	set8bitMode();
@@ -187,6 +221,71 @@
 	waitSpiFree();
 	deselectSlave();
 } 
+#endif
+
+#if defined(TARGET_NUCLEO_F302R8)
+inline void TFT_ILI9163C::set8bitMode() {
+
+	*bb_spi_spe = 0;
+	SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
+
+	uint16_t tmp = spi_ptr->CR2;
+	tmp &= ~SPI_CR2_DS;
+	tmp |= SPI_DATASIZE_8BIT;
+	spi_ptr->CR2 = tmp;
+
+	*bb_spi_spe = 1;
+}
+
+inline void TFT_ILI9163C::set16bitMode() {
+
+	*bb_spi_spe = 0;
+	SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
+	
+	uint16_t tmp = spi_ptr->CR2;
+	tmp &= ~SPI_CR2_DS;
+	tmp |= SPI_DATASIZE_16BIT;
+	spi_ptr->CR2 = tmp;
+
+	*bb_spi_spe = 1;
+}
+
+void TFT_ILI9163C::writecommand(uint8_t c){
+	
+	set8bitMode();
+	setCommandMode();
+	selectSlave();
+	
+	// Strange behavior :-(
+	// Data packing RM0365 P.816
+	// When the data frame size fits into one byte (less than or equal to 8 bits), data packing is
+	// used automatically when any read or write 16-bit access is performed on the SPIx_DR register.
+	
+    // Force 8-bit access to the data register
+    SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
+    uint8_t *p_spi_dr = (uint8_t*) &spi_ptr->DR;
+    *p_spi_dr = (uint8_t) c;
+	
+	waitSpiFree();
+	deselectSlave();
+}
+
+
+void TFT_ILI9163C::writedata(uint8_t c){
+	
+	set8bitMode();
+	setDataMode();
+	selectSlave();
+	
+    // Force 8-bit access to the data register
+    SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
+    uint8_t *p_spi_dr = (uint8_t*) &spi_ptr->DR;
+    *p_spi_dr = (uint8_t) c;
+	
+	waitSpiFree();
+	deselectSlave();
+} 
+#endif
 
 
 void TFT_ILI9163C::writedata16(uint16_t d){
@@ -218,7 +317,7 @@
 	deselectSlave();
 }
 
-#if defined(__F411RE_DMA__)
+#if defined(__NUCLEO_DMA__) & defined(TARGET_NUCLEO_F411RE)
 // use DMA, but polling... :-(
 void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) {
 	
@@ -238,33 +337,25 @@
 		
 //		// enable DMA
 //		hdma.Instance->CR |= DMA_SxCR_EN;
-//		
 //		// enable DMA request from SPI
 //		SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
 //		spi_ptr->CR2 |= SPI_CR2_TXDMAEN;
-//		
 //		// wait DMA complete
 //		while (hdma.Instance->NDTR);
-//		
 //		// disable SPI-DMA
 //		spi_ptr->CR2 &= ~SPI_CR2_TXDMAEN;
-//		
 //		// disable DMA
 //		hdma.Instance->CR &= ~DMA_SxCR_EN;
 //		while (hdma.Instance->CR & DMA_SxCR_EN);
 		
 		// enable DMA
 		*bb_dma_sxcr_en = 1;
-		
 		// enable DMA request from SPI
 		*bb_spi_txdmaen = 1;
-		
 		// wait DMA complete
 		while (hdma.Instance->NDTR);
-		
 		// disable SPI-DMA
 		*bb_spi_txdmaen = 0;
-		
 		// disable DMA
 		*bb_dma_sxcr_en = 0;
 		while (*bb_dma_sxcr_en);
@@ -273,7 +364,38 @@
 		deselectSlave();
 	}
 }
-
+#elif defined(__NUCLEO_DMA__) & defined(TARGET_NUCLEO_F302R8)
+void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) {
+	
+	len = len < 0 ? -len : len;
+	
+	if (len > 0) {
+		set16bitMode();
+		setDataMode();
+		selectSlave();
+	
+		// clear DMA flags
+		__HAL_DMA_CLEAR_FLAG(&hdma, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma));
+		
+		hdma.Instance->CMAR = (uint32_t) &d;
+		hdma.Instance->CNDTR = len;
+		
+		// enable DMA
+		*bb_dma_sxcr_en = 1;
+		// enable DMA request from SPI
+		*bb_spi_txdmaen = 1;
+		// wait DMA complete
+		while (hdma.Instance->CNDTR);
+		// disable SPI-DMA
+		*bb_spi_txdmaen = 0;
+		// disable DMA
+		*bb_dma_sxcr_en = 0;
+		while (*bb_dma_sxcr_en);
+		
+		waitSpiFree();
+		deselectSlave();
+	}
+}
 #else
 // use software loop, fast enough :-)
 void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) {
@@ -297,7 +419,8 @@
 }
 #endif
 
-// mbed general
+
+// mbed generic
 #else
 void TFT_ILI9163C::init(PinName cs, PinName dc){
 	// nothing here
@@ -413,6 +536,7 @@
 */
 	_Mactrl_Data = 0;	// 0b00000000;
 	_colorspaceData = __COLORSPC;//start with default data;
+	
 	chipInit();
 }