marco valli / TFT_ILI9163C

Dependents:   TFTLCDSCREEN Pong_ILI9163C

Fork of TFT_ILI9163C by _ peu605

Revision:
2:6c1fadae252f
Parent:
1:c271e7e2e330
Child:
3:254e799c24ca
--- a/TFT_ILI9163C.cpp	Thu Jan 22 12:16:31 2015 +0000
+++ b/TFT_ILI9163C.cpp	Mon Jan 26 10:39:12 2015 +0000
@@ -15,216 +15,47 @@
 	: Adafruit_GFX(_TFTWIDTH,_TFTHEIGHT) , SPI(mosi,miso,sclk,NC), _cs(cs), _dc(dc) {
 		
 		_resetPinName = reset;
+		init(cs, dc);
 }
 
 TFT_ILI9163C::TFT_ILI9163C(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc) 
 	: Adafruit_GFX(_TFTWIDTH,_TFTHEIGHT) , SPI(mosi,miso,sclk,NC), _cs(cs), _dc(dc) {
 		
-		_resetPinName = NC;
+		TFT_ILI9163C(mosi, miso, sclk, cs, dc, NC);
 }
 
-
 //Serial pc(SERIAL_TX, SERIAL_RX);
 
 // F411RE specific
-#if defined(__F411RE__)
-inline void TFT_ILI9163C::waitSpiFree() {
-	
-	while ((spi_ptr->SR & SPI_SR_TXE) == 0);
-	while ((spi_ptr->SR & SPI_SR_BSY) != 0);
-}
-
-
-inline void TFT_ILI9163C::writecommand(uint8_t c){
-	
-	spi_ptr->CR1 &= ~SPI_CR1_DFF;
-	
-	_dc = 0;
-	_cs = 0;
-	
-	spi_ptr->DR = c;
-	
-	waitSpiFree();
-	_cs = 1;
-}
-
-
-inline void TFT_ILI9163C::writedata(uint8_t c){
-	
-	spi_ptr->CR1 &= ~SPI_CR1_DFF;
-	
-	_dc = 1;
-	_cs = 0;
-	
-	spi_ptr->DR = c;
-	
-	waitSpiFree();
-	_cs = 1;
-} 
-
-
-inline void TFT_ILI9163C::writedata16(uint16_t d){
+#if defined(TARGET_NUCLEO_F411RE)
+void TFT_ILI9163C::init(PinName cs, PinName dc){
 	
-	spi_ptr->CR1 |= SPI_CR1_DFF;
-	
-	_dc = 1;
-	_cs = 0;
-	
-	spi_ptr->DR = d;
-	
-	waitSpiFree();
-	_cs = 1;
-}
-
-
-inline void TFT_ILI9163C::writedata32(uint16_t d1, uint16_t d2){
-	
-	spi_ptr->CR1 |= SPI_CR1_DFF;
-	
-	_dc = 1;
-	_cs = 0;
-	
-	spi_ptr->DR = d1;
-	while ((spi_ptr->SR & SPI_SR_TXE) == 0);
-	spi_ptr->DR = d2;
-	
-	waitSpiFree();
-	_cs = 1;
-}
-
-
-inline void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) {
-	
-	if (len < 0) {
-		len = -len;
-	}
-
-	spi_ptr->CR1 |= SPI_CR1_DFF;
-	
-	_dc = 1;
-	_cs = 0;
+	SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
+		
+    uint32_t cs_port_index = (uint32_t) cs >> 4;
+    uint32_t dc_port_index = (uint32_t) dc >> 4;
+    
+	 //set cs/dc port addresses and masks
+    cs_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (cs_port_index << 10));
+    cs_reg_mask = 1 << ((uint32_t) cs & 0xf);
+    dc_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (dc_port_index << 10));
+    dc_reg_mask = 1 << ((uint32_t) dc & 0xf);
+    
+    // set bit band addresses
+//  GPIO_TypeDef *cs_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (cs_port_index << 10));
+//  GPIO_TypeDef *dc_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (dc_port_index << 10));
+//  uint8_t cs_port_bit = (uint32_t) cs & 0xf;
+//  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));
+	bb_spi_dff = BITBAND_PERIPH(&spi_ptr->CR1, MASK_TO_BITNUM(SPI_CR1_DFF));
 	
 #if defined(__F411RE_DMA__)
-	// use DMA, but polling... :-(
-
-	// clear DMA flags
-//	__HAL_DMA_CLEAR_FLAG(&hdma, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma));
-	__HAL_DMA_CLEAR_FLAG(&hdma, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma));
-	
-	hdma.Instance->M0AR = (uint32_t) &d;
-	hdma.Instance->NDTR = len;
-	// enable DMA
-	hdma.Instance->CR |= DMA_SxCR_EN;
-
-	// enable DMA request from 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);
-		
-#else
-	// use software loop, fast enough :-)
-	while (len--) {
-		while ((spi_ptr->SR & SPI_SR_TXE) == 0);
-		spi_ptr->DR = d;
-	}
-#endif
-	
-	waitSpiFree();
-	_cs = 1;
-}
-
-// mbed general
-#else
-inline void TFT_ILI9163C::waitSpiFree() {
-}
-
-inline void TFT_ILI9163C::writecommand(uint8_t c){
-	
-	_dc = 0;
-	_cs = 0;
-	
-	SPI::write(c);
-
-	_cs = 1;
-}
-
-
-inline void TFT_ILI9163C::writedata(uint8_t c){
-	
-	_dc = 1;
-	_cs = 0;
-	
-	SPI::write(c);
-	
-	_cs = 1;
-} 
-
-
-inline void TFT_ILI9163C::writedata16(uint16_t d){
-	
-	_dc = 1;
-	_cs = 0;
-	
-	SPI::write(d >> 8);
-	SPI::write(d & 0xff);
-	
-	_cs = 1;
-}
-
-
-inline void TFT_ILI9163C::writedata32(uint16_t d1, uint16_t d2){
-	
-	_dc = 1;
-	_cs = 0;
-	
-	SPI::write(d1 >> 8);
-	SPI::write(d1 & 0xff);
-	SPI::write(d2 >> 8);
-	SPI::write(d2 & 0xff);
-
-	_cs = 1;
-}
-
-
-inline void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) {
-	
-	if (len < 0) {
-		len = -len;
-	}
-	
-	_dc = 1;
-	_cs = 0;
-	
-	while (len--) {
-		SPI::write(d >> 8);
-		SPI::write(d & 0xff);
-	}
-
-	_cs = 1;
-}
-#endif
-
-
-void TFT_ILI9163C::setBitrate(uint32_t n){
-	SPI::frequency(n);
-}
-
-
-void TFT_ILI9163C::begin(void) {
-	
-	SPI::format(8,0);			// 8 bit spi mode 0
-	SPI::frequency(5000000L);	// 5MHz
-	
-#if defined(__F411RE__)
-	spi_ptr = (SPI_TypeDef*) _spi.spi;
-
-#if defined(__F411RE_DMA__)
+	// init DMA
 	hdma.Init.Direction = DMA_MEMORY_TO_PERIPH;
 	hdma.Init.PeriphInc = DMA_PINC_DISABLE;
 	hdma.Init.MemInc = DMA_MINC_DISABLE;
@@ -263,8 +94,291 @@
 
 	// set SPI DR ss Peripheral address
 	hdma.Instance->PAR = (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->CR, MASK_TO_BITNUM(DMA_SxCR_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;
+//	while ((spi_ptr->SR & SPI_SR_TXE) == 0);
+//	while ((spi_ptr->SR & SPI_SR_BSY) != 0);
+
+	while (*bb_spi_txe == 0);
+	while (*bb_spi_bsy != 0);
+}
+
+inline void TFT_ILI9163C::waitBufferFree() {
+	
+//	SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
+//	while ((spi_ptr->SR & SPI_SR_TXE) == 0);
+
+	while (*bb_spi_txe == 0);
+}
+
+inline void TFT_ILI9163C::set8bitMode() {
+	
+//	SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
+//	spi_ptr->CR1 &= ~(SPI_CR1_SPE | SPI_CR1_DFF);
+//	spi_ptr->CR1 |= SPI_CR1_SPE;
+	
+	*bb_spi_spe = 0;
+	*bb_spi_dff = 0;
+	*bb_spi_spe = 1;
+}
+
+inline void TFT_ILI9163C::set16bitMode() {
+	
+//	SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
+//	spi_ptr->CR1 &= ~SPI_CR1_SPE;
+//	spi_ptr->CR1 |= (SPI_CR1_SPE | SPI_CR1_DFF);
+	
+	*bb_spi_spe = 0;
+	*bb_spi_dff = 1;
+	*bb_spi_spe = 1;
+}
+
+void TFT_ILI9163C::writecommand(uint8_t c){
+	
+	set8bitMode();
+	setCommandMode();
+	selectSlave();
+	
+	SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
+	spi_ptr->DR = c;
+	
+	waitSpiFree();
+	deselectSlave();
+}
+
+
+void TFT_ILI9163C::writedata(uint8_t c){
+	
+	set8bitMode();
+	setDataMode();
+	selectSlave();
+	
+	SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
+	spi_ptr->DR = c;
+	
+	waitSpiFree();
+	deselectSlave();
+} 
+
+
+void TFT_ILI9163C::writedata16(uint16_t d){
+	
+	set16bitMode();
+	setDataMode();
+	selectSlave();
+	
+	SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
+	spi_ptr->DR = d;
+	
+	waitSpiFree();
+	deselectSlave();
+}
+
+
+void TFT_ILI9163C::writedata32(uint16_t d1, uint16_t d2){
+	
+	set16bitMode();
+	setDataMode();
+	selectSlave();
+	
+	SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
+	spi_ptr->DR = d1;
+	waitBufferFree();
+	spi_ptr->DR = d2;
+	
+	waitSpiFree();
+	deselectSlave();
+}
+
+#if defined(__F411RE_DMA__)
+// use DMA, but polling... :-(
+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_TE_FLAG_INDEX(&hdma));
+		__HAL_DMA_CLEAR_FLAG(&hdma, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma));
+		
+		hdma.Instance->M0AR = (uint32_t) &d;
+		hdma.Instance->NDTR = len;
+		
+//		// 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);
+		
+		waitSpiFree();
+		deselectSlave();
+	}
+}
+
+#else
+// use software loop, fast enough :-)
+void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) {
+	
+	len = len < 0 ? -len : len;
+	
+	if (len > 0) {
+		set16bitMode();
+		setDataMode();
+		selectSlave();
+		
+		SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
+		while (len--) {
+			waitBufferFree();
+			spi_ptr->DR = d;
+		}
+		
+		waitSpiFree();
+		deselectSlave();
+	}
+}
 #endif
+
+// mbed general
+#else
+void TFT_ILI9163C::init(PinName cs, PinName dc){
+	// nothing here
+}
+
+void TFT_ILI9163C::writecommand(uint8_t c){
+	
+	_dc = 0;
+	_cs = 0;
+	
+	SPI::write(c);
+
+	_cs = 1;
+}
+
+
+void TFT_ILI9163C::writedata(uint8_t c){
+	
+	_dc = 1;
+	_cs = 0;
+	
+	SPI::write(c);
+	
+	_cs = 1;
+} 
+
+
+void TFT_ILI9163C::writedata16(uint16_t d){
+	
+	_dc = 1;
+	_cs = 0;
+	
+	SPI::write(d >> 8);
+	SPI::write(d & 0xff);
+	
+	_cs = 1;
+}
+
+
+void TFT_ILI9163C::writedata32(uint16_t d1, uint16_t d2){
+	
+	_dc = 1;
+	_cs = 0;
+	
+	SPI::write(d1 >> 8);
+	SPI::write(d1 & 0xff);
+	SPI::write(d2 >> 8);
+	SPI::write(d2 & 0xff);
+
+	_cs = 1;
+}
+
+
+void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) {
+	
+	len = len < 0 ? -len : len;
+	
+	if (len > 0) {
+	
+		_dc = 1;
+		_cs = 0;
+		
+		while (len--) {
+			SPI::write(d >> 8);
+			SPI::write(d & 0xff);
+		}
+	
+		_cs = 1;
+	}
+}
+#endif
+
+
+void TFT_ILI9163C::setBitrate(uint32_t n){
+	SPI::frequency(n);
+}
+
+
+void TFT_ILI9163C::begin(void) {
+	
+	SPI::format(8,0);			// 8 bit spi mode 0
+	SPI::frequency(5000000L);	// 5MHz
 	
 	if (_resetPinName != NC) {
 		DigitalOut _reset(_resetPinName);