Browse Source

Merge pull request #20 from clockworkpi/develop

Develop devterm-printer now with cjk freetype
GNU 2 years ago
parent
commit
e9d66e78ac

+ 98 - 36
Code/devterm_wiringpi_cpi/gpio/CPi_readall.c

@@ -8,35 +8,35 @@
 
 int bcmToGpioCPi[64] =
 {
-	106,  107,      // 0, 1
-	104, 10,      // 2, 3
-	3, 9,      // 4  5
-	4,  90,      // 6, 7
-	92,  158,      // 8, 9
-	156,  105,      //10,11
-	146,  150,      //12,13
-	81,  80,      //14,15
-
-	82, 83,      //16,17
-	131,  132,      //18,19
-	134,  135,      //20,21
-	89,  88,      //22,23
-	84,  85,      //24,25
-	86, 87,      //26,27
-	112,  113,    //28,29
-	109,   157,    //30,31
-
-	148,  147,      //32,33
-	100,  101,      //34,35
-	102, 103,      //36,37
-	97,  98,      //38,39
-	99,  96,      //40,41
-	110, 111,      //42,43
-	64,  65,      //44,45
-	-1, -1,      //46,47
-
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63	
-}
+	58,  57,	  // 0, 1
+	167, 0, 	 // 2, 3
+	1, 2,	   // 4  5
+	3,	4,		// 6, 7
+	5,	6,		// 8, 9
+	7,	8,		//10,11
+	15,  54,	  //12,13
+	134,  135,		//14,15
+
+	137, 136,	   //16,17
+	139,  138,		//18,19
+	141,  140,		//20,21
+	128,  129,		//22,23
+	130,  131,		//24,25
+	132, 133,	   //26,27
+	9,	201,	//28,29
+	196,   199,    //30,31
+
+	161,  160,		//32,33
+	227,  198,		//34,35
+	163, 166,	   //36,37
+	165,  164,		//38,39
+	228,  224,		//40,41
+	225, 226,	   //42,43
+	56,  55,	  //44,45
+	-1, -1, 	 //46,47
+
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63
+};
 
 #endif
 
@@ -71,7 +71,7 @@ int bcmToGpioCPi[64] =
 	64,  65,      //44,45
 	-1, -1,      //46,47
 
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63	
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63
 };
 
 #endif
@@ -81,32 +81,60 @@ static char *alts [] =
   "IN", "OUT", "ALT2", "ALT3", "ALT4", "ALT5", "ALT6", "OFF"
 } ;
 
+static char* get_pin_name(int pin)
+{
+	static char name[10];
+	char c;
+	int b, d;
+
+	b = pin/32;
+	d = pin % 32;
+
+#ifdef CONFIG_CLOCKWORKPI_A04
+
+	if(b < 6)
+		c = b + 'C';
+	else
+		c = b - 6 + 'L';
+	sprintf(name, "P%c%d", c, d);
+
+#elif defined(CONFIG_CLOCKWORKPI_A06)
+
+	c = d/8 + 'A';
+	sprintf(name, "%d%c%d", b, c, d % 8);
+
+#endif
+	return name;
+}
+
 void CPiReadAll(void)
 {
 	int pin, pin2;
 	int tmp = wiringPiDebug;
 	wiringPiDebug = FALSE;
 
-	printf (" +-----+------+------+---+-----+------+------+---+\n");
-	printf (" | BCM | GPIO | Mode | V | BCM | GPIO | Mode | V |\n");
-	printf (" +-----+------+------+---+-----+------+------+---+\n");
+	printf (" +-----+------+------+------+---+-----+------+------+------+---+\n");
+	printf (" | BCM | GPIO | Name | Mode | V | BCM | GPIO | Name | Mode | V |\n");
+	printf (" +-----+------+------+------+---+-----+------+------+------+---+\n");
 
 	for (pin = 0 ; pin < 23; pin ++) {
 		printf (" | %3d", pin);
 		printf (" | %4d", bcmToGpioCPi[pin]);
+		printf (" | %-4s", get_pin_name(bcmToGpioCPi[pin]));
 		printf (" | %4s", alts [CPi_get_gpio_mode(bcmToGpioCPi[pin])]);
 		printf (" | %d", CPi_digitalRead(bcmToGpioCPi[pin])) ;
 		pin2 = pin + 23;
 		printf (" | %3d", pin2);
 		printf (" | %4d", bcmToGpioCPi[pin2]);
+		printf (" | %-4s", get_pin_name(bcmToGpioCPi[pin2]));
 		printf (" | %4s", alts [CPi_get_gpio_mode(bcmToGpioCPi[pin2])]);
 		printf (" | %d", CPi_digitalRead(bcmToGpioCPi[pin2])) ;
 		printf (" |\n") ;
 	}
 
-	printf (" +-----+------+------+---+-----+------+------+---+\n");
-	printf (" | BCM | GPIO | Mode | V | BCM | GPIO | Mode | V |\n");
-	printf (" +-----+------+------+---+-----+------+------+---+\n");
+	printf (" +-----+------+------+------+---+-----+------+------+------+---+\n");
+	printf (" | BCM | GPIO | Name | Mode | V | BCM | GPIO | Name | Mode | V |\n");
+	printf (" +-----+------+------+------+---+-----+------+------+------+---+\n");
 
 	wiringPiDebug = tmp;
 }
@@ -117,6 +145,38 @@ void CPiReadAllRaw(void)
 	int tmp = wiringPiDebug;
 	wiringPiDebug = FALSE;
 
+#ifdef CONFIG_CLOCKWORKPI_A04
+
+	printf (" +------+------+------+---+------+------+------+---+------+------+------+---+------+------+------+---+------+------+------+---+------+------+------+---+\n");
+	printf (" | GPIO | Name | Mode | V | GPIO | Name | Mode | V | GPIO | Name | Mode | V | GPIO | Name | Mode | V | GPIO | Name | Mode | V | GPIO | Name | Mode | V |\n");
+	printf (" +------+------+------+---+------+------+------+---+------+------+------+---+------+------+------+---+------+------+------+---+------+------+------+---+\n");
+
+	for (pin = 0 ; pin < 27; pin++) {
+		pin2 = pin;
+		for(i = 0; i < 6; i++) {
+			if(CPi_get_gpio_mode(pin2) >= 0) {
+				printf (" | %4d", pin2) ;
+				printf (" | %-4s", get_pin_name(pin2));
+				printf (" | %4s", alts [CPi_get_gpio_mode(pin2)]) ;
+				printf (" | %d", CPi_digitalRead(pin2)) ;
+			} else {
+				printf (" |     ") ;
+				printf (" |     ") ;
+				printf (" |     ") ;
+				printf (" |  ") ;
+			}
+			pin2 += 32;
+			if(i == 1) pin2 += 64;
+		}
+		printf (" |\n") ;
+	}
+
+	printf (" +------+------+------+---+------+------+------+---+------+------+------+---+------+------+------+---+------+------+------+---+------+------+------+---+\n");
+	printf (" | GPIO | Name | Mode | V | GPIO | Name | Mode | V | GPIO | Name | Mode | V | GPIO | Name | Mode | V | GPIO | Name | Mode | V | GPIO | Name | Mode | V |\n");
+	printf (" +------+------+------+---+------+------+------+---+------+------+------+---+------+------+------+---+------+------+------+---+------+------+------+---+\n");
+
+#elif defined(CONFIG_CLOCKWORKPI_A06)
+
 	printf (" +------+------+---+------+------+---+------+------+---+------+------+---+------+------+---+\n");
 	printf (" | GPIO | Mode | V | GPIO | Mode | V | GPIO | Mode | V | GPIO | Mode | V | GPIO | Mode | V |\n");
 	printf (" +------+------+---+------+------+---+------+------+---+------+------+---+------+------+---+\n");
@@ -136,6 +196,8 @@ void CPiReadAllRaw(void)
 	printf (" | GPIO | Mode | V | GPIO | Mode | V | GPIO | Mode | V | GPIO | Mode | V | GPIO | Mode | V |\n");
 	printf (" +------+------+---+------+------+---+------+------+---+------+------+---+------+------+---+\n");
 
+#endif
+
 	wiringPiDebug = tmp;
 }
 

+ 186 - 129
Code/devterm_wiringpi_cpi/wiringPi/wiringCPi.c

@@ -30,22 +30,53 @@ static int wpimode = -1 ;
 
 #ifdef CONFIG_CLOCKWORKPI_A04
 
-int CPI_PIN_MASK[12][32] =  //[BANK]  [INDEX]
+int bcmToGpioCPi[64] =
+{
+	58,  57,      // 0, 1
+	167, 0,      // 2, 3
+	1, 2,      // 4  5
+	3,  4,      // 6, 7
+	5,  6,      // 8, 9
+	7,  8,      //10,11
+	15,  54,      //12,13
+	134,  135,      //14,15
+
+	137, 136,      //16,17
+	139,  138,      //18,19
+	141,  140,      //20,21
+	128,  129,      //22,23
+	130,  131,      //24,25
+	132, 133,      //26,27
+	9,  201,    //28,29
+	196,   199,    //30,31
+
+	161,  160,      //32,33
+	227,  198,      //34,35
+	163, 166,      //36,37
+	165,  164,      //38,39
+	228,  224,      //40,41
+	225, 226,      //42,43
+	56,  55,      //44,45
+	-1, -1,      //46,47
+
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63
+};
+
+int CPI_PIN_MASK[8][32] =  //[BANK]  [INDEX]
 {
-	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA
-	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PB
-	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC
-	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,15,16,-1,18,-1,-1,21,22,23,24,25,26,-1,-1,-1,-1,-1,},//PD
-	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE
-	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PF
-	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG
-	{-1,-1,-1, 3, 4, 5, 6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH
-	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PI
-	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PJ
-    {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PK
-    {-1,-1, 2, 3,-1,-1,-1,-1, 8,-1,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PL
+	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,},//PC	0
+	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,},//PD	32
+	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE		64
+	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PF		96
+	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,},//PG	128
+	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,},//PH	160
+	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,},//PL	192
+	{ 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PM	224
 };
 
+volatile uint32_t *gpio_base;
+volatile uint32_t *gpioL_base;
+
 #endif
 
 #ifdef CONFIG_CLOCKWORKPI_A06
@@ -84,11 +115,11 @@ int bcmToGpioCPi[64] =
 
   int CPI_PIN_MASK[5][32] =  //[BANK]	[INDEX]
   {
-   { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PA
-   { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PB
-   { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PC
-   { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PD
-   { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PD
+   { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//GPIO0
+   { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//GPIO1
+   { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//GPIO2
+   { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//GPIO3
+   { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//GPIO4
   };
 
 volatile uint32_t *cru_base;
@@ -132,8 +163,17 @@ static unsigned int readR(unsigned int addr)
 	return val;
 
 #elif (defined CONFIG_CLOCKWORKPI_A04)
+
 	uint32_t val = 0;
+	uint32_t mmap_base = (addr & ~MAP_MASK);
+	uint32_t mmap_seek = ((addr - mmap_base) >> 2);
+
+	if (addr >= GPIOL_BASE)
+		val = *(gpioL_base + mmap_seek);
+	else
+		val = *(gpio_base + mmap_seek);
 	return val;
+
 #endif
 }
 
@@ -165,6 +205,14 @@ static void writeR(unsigned int val, unsigned int addr)
 
 #elif (defined CONFIG_CLOCKWORKPI_A04)
 
+	unsigned int mmap_base = (addr & ~MAP_MASK);
+	unsigned int mmap_seek = ((addr - mmap_base) >> 2);
+
+	if (addr >= GPIOL_BASE)
+		*(gpioL_base + mmap_seek) = val;
+	else
+		*(gpio_base + mmap_seek) = val;
+
 #endif
 }
 
@@ -175,6 +223,9 @@ int CPi_get_gpio_mode(int pin)
 	unsigned int index  = pin - (bank << 5);
 	unsigned int phyaddr = 0;
 	unsigned char mode = -1;
+
+	if (CPI_PIN_MASK[bank][index] < 0)
+		return -1;
 	
 #ifdef CONFIG_CLOCKWORKPI_A06
 
@@ -202,32 +253,30 @@ int CPi_get_gpio_mode(int pin)
 		ddr_phyaddr = GPIO4_BASE + GPIO_SWPORTA_DDR_OFFSET;
 	}
 
-	if (CPI_PIN_MASK[bank][index] != -1) {
-		regval = readR(grf_phyaddr);
-		mode = (regval >> (offset << 1)) & 0x3;
-		if(mode == 0){
-			regval = readR(ddr_phyaddr);
-			return (regval >> index) & 1;
-		}
-		return mode + 1;
+	regval = readR(grf_phyaddr);
+	mode = (regval >> (offset << 1)) & 0x3;
+
+	if(mode == 0){
+		regval = readR(ddr_phyaddr);
+		return (regval >> index) & 1;
 	}
 
+	return mode + 1;
+
 #elif (defined CONFIG_CLOCKWORKPI_A04)
 
 	int offset = ((index - ((index >> 3) << 3)) << 2);
 
-	if (bank == 11) {
-		phyaddr = GPIOL_BASE + ((index >> 3) << 2);
+	if (bank >= 6) {
+		phyaddr = GPIOL_BASE + (bank -6) * 0x24 + ((index >> 3) << 2);
 	}
-	else
-		phyaddr = GPIO_BASE_MAP + (bank * 36) + ((index >> 3) << 2);
-
-	/* Ignore unused gpio */
-	if (CPI_PIN_MASK[bank][index] != -1) {
-		regval = readR(phyaddr);
-		mode = (regval >> offset) & 7;
+	else {
+		phyaddr = GPIO_BASE_MAP + (bank * 0x24) + ((index >> 3) << 2);
 	}
 
+	regval = readR(phyaddr);
+	mode = (regval >> offset) & 7;
+
 	return mode;
 
 #endif
@@ -243,21 +292,23 @@ int CPi_set_gpio_mode(int pin, int mode)
     unsigned int index  = pin - (bank << 5);
     unsigned int phyaddr = 0;
 
-#ifdef CONFIG_CLOCKWORKPI_A06
-	int offset = ((index - ((index >> 3) << 3)));
-	unsigned int cru_phyaddr, grf_phyaddr, gpio_phyaddr;
-#elif (defined CONFIG_CLOCKWORKPI_A04)
+#ifdef CONFIG_CLOCKWORKPI_A04
+
 	int offset = ((index - ((index >> 3) << 3)) << 2);
 
-	if (bank == 11) {
-		phyaddr = GPIOL_BASE + ((index >> 3) << 2);
+	if (bank >= 6) {
+		phyaddr = GPIOL_BASE + (bank -6) * 0x24 + ((index >> 3) << 2);
 	} else {
-		phyaddr = GPIO_BASE_MAP + (bank * 36) + ((index >> 3) << 2);
+		phyaddr = GPIO_BASE_MAP + (bank * 0x24) + ((index >> 3) << 2);
 	}
+
 #endif
 
 #ifdef CONFIG_CLOCKWORKPI_A06
 
+	int offset = ((index - ((index >> 3) << 3)));
+	unsigned int cru_phyaddr, grf_phyaddr, gpio_phyaddr;
+
 	if(bank == 0){
 		cru_phyaddr = PMUCRU_BASE + PMUCRU_CLKGATE_CON1_OFFSET;
 		grf_phyaddr = PMUGRF_BASE + ((index >> 3) << 2);
@@ -286,38 +337,37 @@ int CPi_set_gpio_mode(int pin, int mode)
 
 #endif
 
-    if (CPI_PIN_MASK[bank][index] != -1) {
+	if (CPI_PIN_MASK[bank][index] != -1) {
 #ifdef CONFIG_CLOCKWORKPI_A04
 		regval = readR(phyaddr);
-			if (wiringPiDebug)
-				printf("Before read reg val: 0x%x offset:%d\n",regval,offset);
+		if (wiringPiDebug)
+			printf("Before read reg val: 0x%x offset:%d\n",regval,offset);
 #endif
-        if (wiringPiDebug)
-            printf("Register[%#x]: %#x index:%d\n", phyaddr, regval, index);
+		if (wiringPiDebug)
+		    printf("Register[%#x]: %#x index:%d\n", phyaddr, regval, index);
 
-        /* Set Input */
-        if (INPUT == mode) {
+		if (INPUT == mode) {
 #ifdef CONFIG_CLOCKWORKPI_A06
-		writeR(0xffff0180, cru_phyaddr);
-		regval = readR(grf_phyaddr);
-		regval |= 0x3 << ((offset << 1) | 0x10);
-		regval &= ~(0x3 << (offset << 1));
-		writeR(regval, grf_phyaddr);
-		regval = readR(gpio_phyaddr);
-		regval &= ~(1 << index);
-		writeR(regval, gpio_phyaddr);
-		if (wiringPiDebug){
+			writeR(0xffff0180, cru_phyaddr);
+			regval = readR(grf_phyaddr);
+			regval |= 0x3 << ((offset << 1) | 0x10);
+			regval &= ~(0x3 << (offset << 1));
+			writeR(regval, grf_phyaddr);
 			regval = readR(gpio_phyaddr);
-			printf("Input mode set over reg val: %#x\n",regval);
-		}
+			regval &= ~(1 << index);
+			writeR(regval, gpio_phyaddr);
+			if (wiringPiDebug){
+				regval = readR(gpio_phyaddr);
+				printf("Input mode set over reg val: %#x\n",regval);
+			}
 #else
-		regval &= ~(7 << offset);
-		writeR(regval, phyaddr);
-	            regval = readR(phyaddr);
-            if (wiringPiDebug)
-                printf("Input mode set over reg val: %#x\n",regval);
+			regval &= ~(7 << offset);
+			writeR(regval, phyaddr);
+			regval = readR(phyaddr);
+			if (wiringPiDebug)
+				printf("Input mode set over reg val: %#x\n",regval);
 #endif
-        } else if (OUTPUT == mode) { /* Set Output */
+		} else if (OUTPUT == mode) {
 #ifdef CONFIG_CLOCKWORKPI_A06
 			writeR(0xffff0180, cru_phyaddr);
 			regval = readR(grf_phyaddr);
@@ -332,19 +382,19 @@ int CPi_set_gpio_mode(int pin, int mode)
 				printf("Out mode get value: 0x%x\n",regval);
 			}
 #else
-		regval &= ~(7 << offset);
-		regval |=  (1 << offset);
-		if (wiringPiDebug)
-			printf("Out mode ready set val: 0x%x\n",regval);
-		writeR(regval, phyaddr);
-            regval = readR(phyaddr);
-            if (wiringPiDebug)
-                printf("Out mode get value: 0x%x\n",regval);
+			regval &= ~(7 << offset);
+			regval |=  (1 << offset);
+			if (wiringPiDebug)
+				printf("Out mode ready set val: 0x%x\n",regval);
+			writeR(regval, phyaddr);
+			regval = readR(phyaddr);
+			if (wiringPiDebug)
+				printf("Out mode get value: 0x%x\n",regval);
 #endif
-        }else 
-            printf("Unknow mode\n");
-    } else
-        printf("unused pin\n");
+		} else 
+			printf("Unknow mode\n");
+	} else
+		printf("unused pin\n");
 }
 
 int CPi_set_gpio_alt(int pin, int mode)
@@ -356,10 +406,10 @@ int CPi_set_gpio_alt(int pin, int mode)
 	unsigned int phyaddr = 0;
 	int offset = ((index - ((index >> 3) << 3)) << 2);
 
-	if (bank == 11) {
+	if (bank >= 6) {
 		phyaddr = GPIOL_BASE + ((index >> 3) << 2);
 	}else
-		phyaddr = GPIO_BASE_MAP + (bank * 36) + ((index >> 3) << 2);
+		phyaddr = GPIO_BASE_MAP + (bank * 0x24) + ((index >> 3) << 2);
 
 	/* Ignore unused gpio */
 	if (CPI_PIN_MASK[bank][index] != -1) {
@@ -382,56 +432,56 @@ int CPi_set_gpio_alt(int pin, int mode)
  */
 void CPi_digitalWrite(int pin, int value)
 {
-    unsigned int bank   = pin >> 5;
-    unsigned int index  = pin - (bank << 5);
-    unsigned int phyaddr = 0;
-#ifdef CONFIG_CLOCKWORKPI_A06
+	unsigned int bank   = pin >> 5;
+	unsigned int index  = pin - (bank << 5);
+	unsigned int phyaddr = 0;
 	unsigned int regval = 0;
-	unsigned int cru_phyaddr = 0;
 
-#else
-    unsigned int regval = 0;
+#ifdef CONFIG_CLOCKWORKPI_A04
 	
-	if (bank == 11) {
-		phyaddr = GPIOL_BASE + 0x10;
+	if (bank >= 6) {
+		phyaddr = GPIOL_BASE + (bank -6) * 0x24 + 0x10;
+	} else {
+		phyaddr = GPIO_BASE_MAP + (bank * 0x24) + 0x10;
 	}
-	else
-		phyaddr = GPIO_BASE_MAP + (bank * 36) + 0x10;
+
 #endif
 
 #ifdef CONFIG_CLOCKWORKPI_A06
 
-		if(bank == 0){
-			phyaddr = GPIO0_BASE + GPIO_SWPORTA_DR_OFFSET;
-			cru_phyaddr = PMUCRU_BASE + PMUCRU_CLKGATE_CON1_OFFSET;
-		}
-		else if(bank == 1){
-			phyaddr = GPIO1_BASE + GPIO_SWPORTA_DR_OFFSET;
-			cru_phyaddr = PMUCRU_BASE + PMUCRU_CLKGATE_CON1_OFFSET;
-		}
-		else if(bank == 2){
-			phyaddr = GPIO2_BASE + GPIO_SWPORTA_DR_OFFSET;			
-			cru_phyaddr = CRU_BASE + CRU_CLKGATE_CON31_OFFSET;
-		}
-		else if(bank == 3){
-			phyaddr = GPIO3_BASE + GPIO_SWPORTA_DR_OFFSET;
-			cru_phyaddr = CRU_BASE + CRU_CLKGATE_CON31_OFFSET;
-		}
-		else if(bank == 4){
-			phyaddr = GPIO4_BASE + GPIO_SWPORTA_DR_OFFSET;			
-			cru_phyaddr = CRU_BASE + CRU_CLKGATE_CON31_OFFSET;
-		}
+	unsigned int cru_phyaddr = 0;
+
+	if(bank == 0){
+		phyaddr = GPIO0_BASE + GPIO_SWPORTA_DR_OFFSET;
+		cru_phyaddr = PMUCRU_BASE + PMUCRU_CLKGATE_CON1_OFFSET;
+	}
+	else if(bank == 1){
+		phyaddr = GPIO1_BASE + GPIO_SWPORTA_DR_OFFSET;
+		cru_phyaddr = PMUCRU_BASE + PMUCRU_CLKGATE_CON1_OFFSET;
+	}
+	else if(bank == 2){
+		phyaddr = GPIO2_BASE + GPIO_SWPORTA_DR_OFFSET;			
+		cru_phyaddr = CRU_BASE + CRU_CLKGATE_CON31_OFFSET;
+	}
+	else if(bank == 3){
+		phyaddr = GPIO3_BASE + GPIO_SWPORTA_DR_OFFSET;
+		cru_phyaddr = CRU_BASE + CRU_CLKGATE_CON31_OFFSET;
+	}
+	else if(bank == 4){
+		phyaddr = GPIO4_BASE + GPIO_SWPORTA_DR_OFFSET;			
+		cru_phyaddr = CRU_BASE + CRU_CLKGATE_CON31_OFFSET;
+	}
 
 #endif
 
-    if (CPI_PIN_MASK[bank][index] != -1) {
+	if (CPI_PIN_MASK[bank][index] != -1) {
 
-	#ifdef CONFIG_CLOCKWORKPI_A06
+#ifdef CONFIG_CLOCKWORKPI_A06
 		writeR(0xffff0180, cru_phyaddr);
-	#endif
+#endif
 
-	if (wiringPiDebug)
-		printf("pin: %d, bank: %d, index: %d, phyaddr: 0x%x\n", pin, bank, index, phyaddr);
+		if (wiringPiDebug)
+			printf("pin: %d, bank: %d, index: %d, phyaddr: 0x%x\n", pin, bank, index, phyaddr);
 
 		regval = readR(phyaddr);
 		if (wiringPiDebug)
@@ -450,9 +500,7 @@ void CPi_digitalWrite(int pin, int value)
 				printf("HIGH val set over reg val: 0x%x\n", regval);
 		}
 
-    } else
-        printf("unused pin\n");
-
+	} 
 }
 
 /*
@@ -463,19 +511,20 @@ int CPi_digitalRead(int pin)
 	int bank = pin >> 5;
 	int index = pin - (bank << 5);
 	int val;
+	unsigned int phyaddr;
+
 #ifdef CONFIG_CLOCKWORKPI_A04
 
-	unsigned int phyaddr;
-	
-	if (bank == 11) {
-		phyaddr = GPIOL_BASE + 0x10;
+	if (bank >= 6) {
+		phyaddr = GPIOL_BASE + (bank -6) * 0x24 + 0x10;
 	} else {
-		phyaddr = GPIO_BASE_MAP + (bank * 36) + 0x10;
+		phyaddr = GPIO_BASE_MAP + (bank * 0x24) + 0x10;
 	}
+
 #endif
 
 #ifdef CONFIG_CLOCKWORKPI_A06
-	unsigned int phyaddr;
+
 	if(bank == 0)
 		phyaddr = GPIO0_BASE + GPIO_EXT_PORTA_OFFSET;
 	else if(bank == 1)
@@ -486,6 +535,7 @@ int CPi_digitalRead(int pin)
 		phyaddr = GPIO3_BASE + GPIO_EXT_PORTA_OFFSET;
 	else if(bank == 4)
 		phyaddr = GPIO4_BASE + GPIO_EXT_PORTA_OFFSET;
+
 #endif
 
 	if (CPI_PIN_MASK[bank][index] != -1) {
@@ -493,7 +543,7 @@ int CPi_digitalRead(int pin)
 		val = val >> index;
 		val &= 1;
 		if (wiringPiDebug)
-			printf("Read reg val: 0x%#x, bank:%d, index:%d\n", val, bank, index);
+			printf("Read reg val: 0x%#x, bank:%d, index:%d phyaddr: 0x%x\n", val, bank, index, phyaddr);
 		return val;
 	}
 	return 0;
@@ -504,9 +554,15 @@ int CPiSetup(int fd)
 {
 #ifdef CONFIG_CLOCKWORKPI_A04
 
-
+	gpio_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIOA_BASE);
+	if ((int32_t)(unsigned long)gpio_base == -1)
+		return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror(errno));
+	gpioL_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIOL_BASE);
+	if ((int32_t)(unsigned long)gpioL_base == -1)
+		return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror(errno));
 
 #elif defined(CONFIG_CLOCKWORKPI_A06)
+
 	gpio0_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO0_BASE);
 	if ((int32_t)(unsigned long)gpio0_base == -1)
 		return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (GPIO0_BASE) failed: %s\n", strerror(errno));
@@ -535,6 +591,7 @@ int CPiSetup(int fd)
 	pmugrf_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, PMUGRF_BASE);
 	if ((int32_t)(unsigned long)pmugrf_base == -1)
 		return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (PMUGRF_BASE) failed: %s\n", strerror(errno));
+
 #endif
 	wpimode = WPI_MODE_BCM;
 }
@@ -620,12 +677,12 @@ void CPiBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
 #ifdef CONFIG_CLOCKWORKPI_A04
 	*model = CPI_MODEL_A04; 
 	*rev = PI_VERSION_1; 
-	*mem = 3; 
+	*mem = 3;
 	*maker = 3;
 #elif defined(CONFIG_CLOCKWORKPI_A06)
 	*model = CPI_MODEL_A06; 
 	*rev = PI_VERSION_1; 
-	*mem = 4; 
+	*mem = 4;
 	*maker = 3;
 #endif
 }

+ 22 - 26
Code/devterm_wiringpi_cpi/wiringPi/wiringCPi.h

@@ -2,37 +2,33 @@
 #define _WIRING_CPI_H
 
 #ifdef CONFIG_CLOCKWORKPI_A04
-#define GPIOA_BASE                         (0x0300B000)
-#define GPIO_NUM                           (0x40)
-#define GPIO_BASE_MAP                      (0x0300B000)
-#define MEM_INFO                           (1024)
-#define GPIOL_BASE                         (0x07022000)
-#define GPIOL_BASE_MAP                     (0x07022000)  
-#define MAP_SIZE_L                         (4096 * 1)
-#define GPIO_PWM_OP			   (0x0300A000)
+#define GPIOA_BASE		0x0300B000
+#define GPIO_BASE_MAP	(GPIOA_BASE + 0x24 * 2)
+#define GPIOL_BASE		(0x07022000)
+#define GPIO_PWM_OP		(0x0300A000)
+#define GPIO_NUM			(256)
 #endif
 
 #ifdef CONFIG_CLOCKWORKPI_A06
-#define GPIO0_BASE 							0xff720000
-#define GPIO1_BASE 							0xff730000
-#define GPIO2_BASE 							0xff780000
-#define GPIO3_BASE 							0xff788000
-#define GPIO4_BASE 							0xff790000
-#define GPIO_NUM                          	(160)
-#define GPIO_SWPORTA_DR_OFFSET 				0x00
-#define GPIO_SWPORTA_DDR_OFFSET 			0x04
-#define GPIO_EXT_PORTA_OFFSET				0x50
-#define PMUGRF_BASE 	     0xff320000	 
-#define GRF_BASE 					0xff77e000
-#define CRU_BASE 					0xff760000
-#define PMUCRU_BASE 	0xff750000
-#define CRU_CLKGATE_CON31_OFFSET 			0x037c    //bit 3 4 5
-#define PMUCRU_CLKGATE_CON1_OFFSET 			0x0104
+#define GPIO0_BASE						0xff720000
+#define GPIO1_BASE						0xff730000
+#define GPIO2_BASE						0xff780000
+#define GPIO3_BASE						0xff788000
+#define GPIO4_BASE						0xff790000
+#define GPIO_SWPORTA_DR_OFFSET			0x00
+#define GPIO_SWPORTA_DDR_OFFSET		0x04
+#define GPIO_EXT_PORTA_OFFSET			0x50
+#define PMUGRF_BASE						0xff320000
+#define GRF_BASE							0xff77e000
+#define CRU_BASE							0xff760000
+#define PMUCRU_BASE						0xff750000
+#define CRU_CLKGATE_CON31_OFFSET		0x037c
+#define PMUCRU_CLKGATE_CON1_OFFSET		0x0104
+#define GPIO_NUM							(160)
 #endif
 
-#define MAP_SIZE_L                         (4*1024)
-#define MAP_SIZE           MAP_SIZE_L
-#define MAP_MASK           (MAP_SIZE - 1)
+#define MAP_SIZE		(4*1024)
+#define MAP_MASK	(MAP_SIZE - 1)
 
 extern int CPi_set_gpio_mode(int pin, int mode);
 extern int CPi_set_gpio_alt(int pin, int mode);

+ 1 - 1
Code/devterm_wiringpi_cpi/wiringPi/wiringPiSPI.c

@@ -109,7 +109,7 @@ int wiringPiSPISetupMode (int channel, int speed, int mode)
 // Channel can be anything - lets hope for the best
 //  channel &= 1 ;	// Channel is 0 or 1
 
-#ifdef CONFIG_CLOCKWORKPI
+#ifdef CONFIG_CLOCKWORKPI_A06
   snprintf (spiDev, 31, "/dev/spidev2.%d", channel) ;
 #else
   snprintf (spiDev, 31, "/dev/spidev0.%d", channel) ;

+ 1 - 1
Code/devterm_wiringpi_cpi/wiringPiD/drcNetCmd.h

@@ -35,7 +35,7 @@
 #define	DRCN_ANALOG_READ	9
 
 
-struct drcNetComStruct
+typedef struct drcNetComStruct
 {
   uint32_t pin ;
   uint32_t cmd ;

+ 5 - 5
Code/thermal_printer/Makefile

@@ -1,13 +1,13 @@
 CC = gcc
 
-CFLAGS  = -g -Wall
-LDFLAUS = 
-INCLUDES = 
-LIBS = -lwiringPi -lm -lcrypt -lpthread -lrt
+CFLAGS  = -O0 -g -Wall
+LDFLAGS = 
+INCLUDES =  -I /usr/include/freetype2
+LIBS = -lwiringPi -lm -lcrypt -lpthread -lfreetype -lrt
 
 MAIN = devterm_thermal_printer.elf
 
-SRCS = printer.c  devterm_thermal_printer.c  utils.c
+SRCS = printer.c  devterm_thermal_printer.c  utils.c ftype.c utf8-utils.c
 OBJS = $(SRCS:.c=.o)
 
 .PHONY: depend clean

BIN
Code/thermal_printer/NotoSansCJK-Regular.ttf


+ 108 - 106
Code/thermal_printer/config.h

@@ -1,7 +1,11 @@
 #ifndef CONFIG_H
 #define CONFIG_H
 
-///raspberry pi CM3 
+// clang-format off
+#include <freetype2/ft2build.h>
+#include <freetype/freetype.h>
+// clang-format on
+/// raspberry pi CM3
 
 #define BCM_GPIO_28 28
 #define BCM_GPIO_29 29
@@ -22,27 +26,28 @@
 #define BCM_GPIO_44 44
 #define BCM_GPIO_45 45
 
-//PA8-12 UART1
-//#define SPI1_NSS_PIN PA4    //SPI_1 Chip Select pin is PA4. //no use in DevTerm 
+// PA8-12 UART1
+//#define SPI1_NSS_PIN PA4    //SPI_1 Chip Select pin is PA4. //no use in
+//DevTerm
 
-#define VH_PIN BCM_GPIO_40 //ENABLE_VH required,PRT_EN
+#define VH_PIN BCM_GPIO_40 // ENABLE_VH required,PRT_EN
 
-#define LATCH_PIN BCM_GPIO_36  //18
-#define PEM_PIN  BCM_GPIO_34 // 1 [PS,PAPER]
+#define LATCH_PIN BCM_GPIO_36 // 18
+#define PEM_PIN BCM_GPIO_34   // 1 [PS,PAPER]
 
 /*
-#define PEM_CTL_PIN BCM_GPIO_32 //3 VPS 
+#define PEM_CTL_PIN BCM_GPIO_32 //3 VPS
 #define ENABLE_PEM digitalWrite(PEM_CTL_PIN,HIGH)
-#define DISABLE_PEM digitalWrite(PEM_CTL_PIN,LOW) 
+#define DISABLE_PEM digitalWrite(PEM_CTL_PIN,LOW)
 */
-//DevTerm no VPS IO
-//#define PEM_CTL_PIN 
-#define ENABLE_PEM 
-#define DISABLE_PEM 
+// DevTerm no VPS IO
+//#define PEM_CTL_PIN
+#define ENABLE_PEM
+#define DISABLE_PEM
 
 // https://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md
-//enable SPI0 ALT0 in CM3 first
-// in /boot/config.txt 
+// enable SPI0 ALT0 in CM3 first
+// in /boot/config.txt
 // dtparam=spi=on
 // dtoverlay=spi-gpio35-39
 // then we can see GPIO38 GPIO39 in ALT0 Mode by `gpio readall`
@@ -50,74 +55,68 @@
 #define MOSI_PIN BCM_GPIO_38
 #define CLK_PIN BCM_GPIO_39
 
-
 /**
-  *@brief STB_NUMBER stand for STROBE NUMBER of lines, which means how many lines
-  *        are going to be activated
-**/
-#define STB_NUMBER        1
-
-#define STB1_PIN  BCM_GPIO_37//13
-#define STB2_PIN  STB1_PIN 
-#define STB3_PIN  STB1_PIN 
-#define STB4_PIN  STB1_PIN 
-#define STB5_PIN  STB1_PIN 
-#define STB6_PIN  STB1_PIN 
-
+ *@brief STB_NUMBER stand for STROBE NUMBER of lines, which means how many lines
+ *        are going to be activated
+ **/
+#define STB_NUMBER 1
+
+#define STB1_PIN BCM_GPIO_37 // 13
+#define STB2_PIN STB1_PIN
+#define STB3_PIN STB1_PIN
+#define STB4_PIN STB1_PIN
+#define STB5_PIN STB1_PIN
+#define STB6_PIN STB1_PIN
 
 #define PH1_PIN BCM_GPIO_28
 #define PH2_PIN BCM_GPIO_29
 #define PH3_PIN BCM_GPIO_30
 #define PH4_PIN BCM_GPIO_31
 
-///0 1 3 2 mine
-#define PA_PIN  PH1_PIN //
+/// 0 1 3 2 mine
+#define PA_PIN PH1_PIN  //
 #define PNA_PIN PH2_PIN //
-#define PB_PIN  PH3_PIN //
+#define PB_PIN PH3_PIN  //
 #define PNB_PIN PH4_PIN //
 
-
-
 //#define ENABLE1_PIN  PA13
 //#define ENABLE2_PIN  PA14
 
-#define THERMISTORPIN BCM_GPIO_35  //ADC,14
-
+#define THERMISTORPIN BCM_GPIO_35 // ADC,14
 
 #define MOTOR_ENABLE1
-#define MOTOR_ENABLE2 
+#define MOTOR_ENABLE2
+
+#define MOTOR_DISABLE1
+#define MOTOR_DISABLE2
 
-#define MOTOR_DISABLE1  
-#define MOTOR_DISABLE2 
- 
 #define ENABLE_VH digitalWrite(VH_PIN, HIGH)
 #define DISABLE_VH digitalWrite(VH_PIN, LOW)
 
 #define LATCH_ENABLE digitalWrite(LATCH_PIN, LOW)
 #define LATCH_DISABLE digitalWrite(LATCH_PIN, HIGH)
 
-#define ASK4PAPER  digitalRead(PEM_PIN)
+#define ASK4PAPER digitalRead(PEM_PIN)
 
+#define ERROR_FEED_PITCH ((uint8_t)0x01)
+#define IS_PAPER 0x00
+#define NO_PAPER 0x01
+#define HOT_PRINTER 0x02
 
-#define ERROR_FEED_PITCH  ((uint8_t) 0x01)
-#define IS_PAPER          0x00
-#define NO_PAPER          0x01
-#define HOT_PRINTER       0x02
-
-#define FORWARD           0x01
-#define BACKWARD          0x00
+#define FORWARD 0x01
+#define BACKWARD 0x00
 
 #define HOT 64
 
-#define BCoefficent       3950
-#define RthNominal        30000
-#define TempNominal       25 
-#define ADCResolution     1024
-#define SeriesResistor    30000
-#define NumSamples        1
+#define BCoefficent 3950
+#define RthNominal 30000
+#define TempNominal 25
+#define ADCResolution 1024
+#define SeriesResistor 30000
+#define NumSamples 1
 
-#define KELVIN            1
-#define CELSIUS           0
+#define KELVIN 1
+#define CELSIUS 0
 
 #define ADC_FILE_PAT "/tmp/devterm_adc"
 
@@ -126,28 +125,26 @@
 #define BAT_CAP "/sys/class/power_supply/axp20x-battery/capacity"
 #define BAT_THRESHOLD 14 // %14 battery = low power
 
-#define int16               uint16_t
-#define int8                uint8_t
-
-#define asciistart          ((uint8_t)'A')
-#define netxcharacter       ((uint8_t)24)
-#define Fontrows            ((uint8_t)24)
-#define FontColums          ((uint8_t)16)
-
-#define nextcharactercolum  ((uint8_t)Fontrows/8) // = 3
+#define int16 uint16_t
+#define int8 uint8_t
 
+#define asciistart ((uint8_t)'A')
+#define netxcharacter ((uint8_t)24)
+#define Fontrows ((uint8_t)24)
+#define FontColums ((uint8_t)16)
 
+#define nextcharactercolum ((uint8_t)Fontrows / 8) // = 3
 
 #define ASCII_TAB '\t' // Horizontal tab
-#define ASCII_LF  '\n' // Line feed,10
-#define ASCII_FF  '\f' // Form feed
-#define ASCII_CR  '\r' // Carriage return
-#define ASCII_EOT   4  // End of Transmission
-#define ASCII_DLE  16  // Data Link Escape
-#define ASCII_DC2  18  // Device control 2 //0x12
-#define ASCII_ESC  27  // Escape //0x1b
-#define ASCII_FS   28  // Field separator//0x1c
-#define ASCII_GS   29  // Group separator //0x1d
+#define ASCII_LF '\n'  // Line feed,10
+#define ASCII_FF '\f'  // Form feed
+#define ASCII_CR '\r'  // Carriage return
+#define ASCII_EOT 4    // End of Transmission
+#define ASCII_DLE 16   // Data Link Escape
+#define ASCII_DC2 18   // Device control 2 //0x12
+#define ASCII_ESC 27   // Escape //0x1b
+#define ASCII_FS 28    // Field separator//0x1c
+#define ASCII_GS 29    // Group separator //0x1d
 
 #define PRINT_STATE 0
 #define ESC_STATE 1
@@ -161,7 +158,6 @@
 
 #define BITS8 8
 
-
 #define MAX_DOTS 384
 #define PRINTER_BITS MAX_DOTS
 #define MAXPIXELS 48
@@ -172,75 +168,81 @@
 #define MAXPIXELS 72
 #endif
 
+#define FONT_MODE_0 0 // Internal
+#define FONT_MODE_1 1 // External
 
-//extract bits 
-#define LAST(k,n) ((k) & ((1<<(n))-1))
-#define MID(k,m,n) LAST((k)>>(m),((n)-(m)))
+// extract bits
+#define LAST(k, n) ((k) & ((1 << (n)) - 1))
+#define MID(k, m, n) LAST((k) >> (m), ((n) - (m)))
 
-
-typedef struct _Margin{
+typedef struct _Margin {
   uint16_t width;
   uint8_t esgs;
-}Margin;
-
+} Margin;
 
 typedef struct _FONT {
 
-  uint8_t width;//in bits
+  uint8_t width; // in bits
   uint8_t height;
+  uint8_t mode; // 0 internal pcf font array,1 external ttf font file
   const uint8_t *data;
-}FONT;
+  char *file;
+} FONT;
+
+typedef struct _ImageCache {
 
-typedef struct _ImageCache{
-  
   uint16_t idx;
   uint16_t num;
   uint16_t width;
   uint16_t height;
-  uint8_t need_print:1;
-  uint8_t revert_bits:1;//MSB OR LSB
+  uint8_t need_print : 1;
+  uint8_t revert_bits : 1;  // MSB OR LSB
   uint8_t cache[IMAGE_MAX]; // 48x192bytes(384x192 pixels) ,max
-  
-}ImageCache;
 
-typedef struct _CONFIG
-{  
+} ImageCache;
+
+typedef struct _CONFIG {
   uint8_t state;
   uint8_t line_space;
   uint8_t align;
-  uint8_t reverse; //reverse print   
+  uint8_t reverse; // reverse print
   uint8_t orient;
   uint8_t under_line;
   uint8_t feed_pitch;
-  uint8_t density:4; //0-f,300+density*46 HEAT_TIME
+  uint8_t density : 4; // 0-f,300+density*46 HEAT_TIME
 
-  uint16_t wordgap:10;//1023 max
-  uint8_t max_pts;// max pts in print_dots_8bit_split
+  uint16_t wordgap : 10; // 1023 max
+  uint8_t max_pts;       // max pts in print_dots_8bit_split
   uint8_t lock;
-  
+  int16_t degree; // char rotate 0,90,180,270, -90,-180,-270
+
   Margin margin;
-  FONT*font;
+  FONT *font;
   ImageCache *img;
-  FILE*fp;
+  FILE *fp;
 
-  int (*printf)(struct _CONFIG*, char*, ...);
+  FT_Face face;
+  FT_Library ft;
 
-}CONFIG;
+  int (*printf)(struct _CONFIG *, char *, ...);
 
+} CONFIG;
 
-typedef struct _SerialCache{
+typedef struct _SerialCache {
   uint8_t idx;
-  uint8_t data[77];//384/5
-}SerialCache;
+  uint8_t utf8idx; // 0-4
+  //  uint8_t data[77];//384/5, minium size font 5 pixel
+  uint32_t data[MAX_DOTS]; // uint32_t for utf8 characters
+} SerialCache;
 
-typedef struct _TimeRec{
+typedef struct _TimeRec {
   unsigned int time;
   uint8_t last_status;
   uint8_t check;
-  
-}TimeRec;
 
-void PrintDots8bit(uint8_t *Array, uint8_t characters,uint8_t feed_num);
+} TimeRec;
+
+void PrintDots8bit(uint8_t *Array, uint8_t characters, uint8_t feed_num);
 
 uint8_t invert_bit(uint8_t a);
 

File diff suppressed because it is too large
+ 553 - 442
Code/thermal_printer/devterm_thermal_printer.c


+ 1 - 0
Code/thermal_printer/etc/systemd/system/devterm-printer.service

@@ -4,6 +4,7 @@ After=devterm-socat
 
 [Service]
 Type=simple
+EnvironmentFile=/usr/local/etc/devterm-printer
 StandardOutput=file:/tmp/devterm_printer.log
 StandardError=file:/tmp/devterm_printer.err.log
 ExecStart=/usr/local/bin/devterm_thermal_printer.elf

+ 106 - 0
Code/thermal_printer/ftype.c

@@ -0,0 +1,106 @@
+#include "ftype.h"
+
+#include "utf8-utils.h"
+
+static const UTF32 utf32_space[2] = {' ', 0};
+
+bool init_ft(const char *ttf_file, FT_Face *face, FT_Library *ft,
+             int req_size_w, int req_size_h, char **error) {
+
+  bool ret = false;
+  if (FT_Init_FreeType(ft) == 0) {
+    if (FT_New_Face(*ft, ttf_file, 0, face) == 0) {
+
+      if (FT_Set_Pixel_Sizes(*face, req_size_w, req_size_h) == 0) {
+        ret = true;
+      } else {
+        if (error)
+          *error = strdup("Can't set font size");
+      }
+
+    } else {
+      if (error)
+        *error = strdup("Can't load TTF file");
+    }
+
+  } else {
+    if (error)
+      *error = strdup("Can't init freetype library");
+  }
+
+  return ret;
+}
+
+bool change_ft_size(FT_Face face, int req_size_w, int req_size_h) {
+  bool ret = false;
+  if (FT_Set_Pixel_Sizes(face, req_size_w, req_size_h) == 0) {
+    ret = true;
+  } else {
+    printf("Can't set font size");
+  }
+
+  return ret;
+}
+/*===========================================================================
+  done_ft
+  Clean up after we've finished wih the FreeType librar
+  =========================================================================*/
+void done_ft(FT_Library ft) { FT_Done_FreeType(ft); }
+
+/*===========================================================================
+
+  face_get_line_spacing
+
+  Get the nominal line spacing, that is, the distance between glyph
+  baselines for vertically-adjacent rows of text. This is "nominal" because,
+  in "real" typesetting, we'd need to add extra room for accents, etc.
+
+  =========================================================================*/
+int face_get_line_spacing(FT_Face face) {
+  return face->size->metrics.height / 64;
+  // There are other possibilities the give subtly different results:
+  // return (face->bbox.yMax - face->bbox.yMin)  / 64;
+  // return face->height / 64;
+}
+
+int get_slice_len(const char lb) {
+
+  if ((lb & 0x80) == 0)
+    return 1;
+  else if ((lb & 0xE0) == 0xC0)
+    return 2;
+  else if ((lb & 0xF0) == 0xE0)
+    return 3;
+  else if ((lb & 0xF8) == 0xF0)
+    return 4;
+  return 1;
+}
+
+UTF32 *cjk_utf8_to_utf32(const char *word) {
+  assert(word != NULL);
+  int l = strlen(word);
+  int u8l = utf8_strlen(word);
+
+  char buf[5];
+
+  UTF32 *ret = malloc((u8l + 1) * sizeof(UTF32));
+  int i = 0, j = 0;
+  int bskip = 1;
+
+  while (i < l) {
+
+    bskip = get_slice_len(word[i]);
+    strncpy(buf, &word[i], bskip);
+    if (bskip > 1) {
+      ret[j] = (UTF32)utf8_to_utf32(buf);
+    } else {
+      ret[j] = (UTF32)buf[0];
+    }
+
+    j++;
+    i += bskip;
+  }
+
+  ret[u8l] = 0;
+  return ret;
+}

+ 29 - 0
Code/thermal_printer/ftype.h

@@ -0,0 +1,29 @@
+#ifndef FTYPE_H
+#define FTYPE_H
+// clang-format off
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <freetype2/ft2build.h>
+
+#include <freetype/freetype.h>
+// clang-format on
+#ifndef UTF8
+typedef unsigned char UTF8;
+#endif
+
+#ifndef UTF32
+typedef int32_t UTF32;
+#endif
+
+bool init_ft(const char *ttf_file, FT_Face *face, FT_Library *ft,
+             int req_size_w, int req_size_h, char **error);
+
+bool change_ft_size(FT_Face face, int req_size_w, int req_size_h);
+
+int face_get_line_spacing(FT_Face face);
+
+int get_slice_len(const char lb);
+
+#endif

+ 547 - 379
Code/thermal_printer/printer.c

@@ -1,14 +1,13 @@
+#include <glob.h>
+#include <math.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdint.h> 
 #include <string.h>
-#include <math.h>
-#include <glob.h>
 
 #include <wiringPi.h>
 #include <wiringPiSPI.h>
 
-
 #include "config.h"
 
 #include "utils.h"
@@ -18,7 +17,7 @@
 extern FONT current_font;
 extern SerialCache ser_cache;
 
-uint16_t STBx[] = {STB1_PIN,STB2_PIN,STB3_PIN,STB4_PIN,STB5_PIN,STB6_PIN};
+uint16_t STBx[] = {STB1_PIN, STB2_PIN, STB3_PIN, STB4_PIN, STB5_PIN, STB6_PIN};
 uint8_t as;
 
 static unsigned int printer_vps_time;
@@ -27,333 +26,311 @@ static uint8_t printer_temp_check;
 
 static char adc_file_path[128];
 
-
-void printer_send_data8(uint8_t w)
-{
+void printer_send_data8(uint8_t w) {
   /*
-  digitalWrite(SPI1_NSS_PIN, LOW); // manually take CSN low for SPI_1 transmission
-  SPI.transfer(w); //Send the HEX data 0x55 over SPI-1 port and store the received byte to the <data> variable.
+  digitalWrite(SPI1_NSS_PIN, LOW); // manually take CSN low for SPI_1
+  transmission SPI.transfer(w); //Send the HEX data 0x55 over SPI-1 port and
+  store the received byte to the <data> variable.
   //SPI.transfer16(w);
-  digitalWrite(SPI1_NSS_PIN, HIGH); // manually take CSN high between spi transmissions
+  digitalWrite(SPI1_NSS_PIN, HIGH); // manually take CSN high between spi
+  transmissions
   */
-  wiringPiSPIDataRW (0, &w, 1);
-  
+  wiringPiSPIDataRW(0, &w, 1);
 }
 
+void clear_printer_buffer() {
+  uint8_t i = 0;
+
+  for (i = 0; i < 48; i++)
+    printer_send_data8(0x00);
 
-void clear_printer_buffer()
-{
-  uint8_t i= 0;
-  
-   for(i=0;i<48;i++)
-     printer_send_data8(0x00);
-  
   LATCH_ENABLE;
   delayus(1);
   LATCH_DISABLE;
   delayus(1);
 }
 
-
-uint8_t IsPaper()
-{
+uint8_t IsPaper() {
   uint8_t status;
   uint8_t tmp;
   return IS_PAPER;
- 
-  if(  millis() - printer_vps_time > 10) {
+
+  if (millis() - printer_vps_time > 10) {
     ENABLE_PEM;
-    if(ASK4PAPER==LOW) // * LOW is what we want**
-    {status = IS_PAPER;}
-    else
-    {status = NO_PAPER; PRINTF("Error:NO PAPER\n"); }
+    if (ASK4PAPER == LOW) // * LOW is what we want**
+    {
+      status = IS_PAPER;
+    } else {
+      status = NO_PAPER;
+      PRINTF("Error:NO PAPER\n");
+    }
     DISABLE_PEM;
 
-    if(printer_temp_check > 20) {
+    if (printer_temp_check > 20) {
       tmp = temperature();
-    
-      if (tmp >= HOT){
+
+      if (tmp >= HOT) {
         PRINTF("Printer too Hot\n");
         status |= HOT_PRINTER;
       }
 
-     printer_temp_check = 0;
+      printer_temp_check = 0;
 
-    }else {
-     printer_temp_check++;
+    } else {
+      printer_temp_check++;
     }
 
-  }else {
+  } else {
     status = printer_vps_last_status;
   }
-  
- 
+
   printer_vps_last_status = status;
   printer_vps_time = millis();
-  
+
   return status;
 }
 
-
 uint8_t header_init() {
-  
+
   uint8_t pin[] = {THERMISTORPIN};
-  
+
   uint8_t x;
-  pinMode(LATCH_PIN,OUTPUT);
+  pinMode(LATCH_PIN, OUTPUT);
 
-  for(x=0; x < STB_NUMBER; x++){
-    pinMode(STBx[x],OUTPUT);
-    digitalWrite(STBx[x],LOW);
+  for (x = 0; x < STB_NUMBER; x++) {
+    pinMode(STBx[x], OUTPUT);
+    digitalWrite(STBx[x], LOW);
   }
-  
+
   LATCH_DISABLE;
 
-  pinMode(VH_PIN,OUTPUT);
-  digitalWrite(VH_PIN,LOW);
+  pinMode(VH_PIN, OUTPUT);
+  digitalWrite(VH_PIN, LOW);
+
+  pinMode(PEM_PIN, INPUT);
+  // pinMode(PEM_CTL_PIN,OUTPUT);
 
-  pinMode(PEM_PIN,INPUT);
-  //pinMode(PEM_CTL_PIN,OUTPUT);
+  // adc.setChannels(pin, 1); //this is actually the pin you want to measure
+
+  pinMode(THERMISTORPIN, INPUT); // 数字io没有 模拟接口。adc 读温度暂时不搞
 
-  
-  //adc.setChannels(pin, 1); //this is actually the pin you want to measure
-  
-  pinMode(THERMISTORPIN,INPUT); // 数字io没有 模拟接口。adc 读温度暂时不搞 
-  
   /*
   //SPI.begin(); //Initialize the SPI_1 port.
   SPI.setBitOrder(MSBFIRST); // Set the SPI_1 bit order
   SPI.setDataMode(SPI_MODE0); //Set the  SPI_1 data mode 0
-  SPI.setClockDivider(SPI_CLOCK_DIV16);      // Slow speed (72 / 16 = 4.5 MHz SPI_1 speed)
-  SPI.setDataSize(DATA_SIZE_8BIT);
-  SPI.begin(); //Initialize the SPI_1 port.
+  SPI.setClockDivider(SPI_CLOCK_DIV16);      // Slow speed (72 / 16 = 4.5 MHz
+  SPI_1 speed) SPI.setDataSize(DATA_SIZE_8BIT); SPI.begin(); //Initialize the
+  SPI_1 port.
   */
-  if (!wiringPiSPISetup (0,  4500000 )) {
-	  PRINTF("SPI init failed,exiting...\n");
+  if (!wiringPiSPISetup(0, 4500000)) {
+    PRINTF("SPI init failed,exiting...\n");
   }
-  
+
   /*
-  pinMode(SPI1_NSS_PIN, OUTPUT);  
+  pinMode(SPI1_NSS_PIN, OUTPUT);
   digitalWrite(SPI1_NSS_PIN,HIGH);
   */
-  
+
   printer_vps_time = 0;
   printer_vps_last_status = IS_PAPER;
-  printer_temp_check= 0;
+  printer_temp_check = 0;
 
   glob_file(ADC_FILE_PAT);
-
 }
 
-
 #if 1
 
-uint8_t current_pos = 1; 
+uint8_t current_pos = 1;
 
 uint8_t header_init1() {
-  
-  pinMode(PA_PIN,OUTPUT);
-  pinMode(PNA_PIN,OUTPUT);
-  pinMode(PB_PIN,OUTPUT);
-  pinMode(PNB_PIN,OUTPUT);
+
+  pinMode(PA_PIN, OUTPUT);
+  pinMode(PNA_PIN, OUTPUT);
+  pinMode(PB_PIN, OUTPUT);
+  pinMode(PNB_PIN, OUTPUT);
 
   as = 0;
 
   return ASK4PAPER;
 }
 
-void motor_stepper_pos2(uint8_t position)//forward
+void motor_stepper_pos2(uint8_t position) // forward
 {
-//  position = 9 - position;
-//  position = (position+1)/2;
+  //  position = 9 - position;
+  //  position = (position+1)/2;
   delayMicroseconds(6700);
-  switch(position){
-    case 0:
-      digitalWrite(PA_PIN,LOW);
-      digitalWrite(PNA_PIN,LOW);
-      digitalWrite(PB_PIN,LOW);
-      digitalWrite(PNB_PIN,LOW);
-      break;   
-    case 1:
-      digitalWrite(PA_PIN,HIGH);
-      digitalWrite(PNA_PIN,LOW);
-      digitalWrite(PB_PIN,LOW);
-      digitalWrite(PNB_PIN,HIGH);
-      break;
-    case 2:
-      digitalWrite(PA_PIN,HIGH);
-      digitalWrite(PNA_PIN,LOW);
-      digitalWrite(PB_PIN,HIGH);
-      digitalWrite(PNB_PIN,LOW);
+  switch (position) {
+  case 0:
+    digitalWrite(PA_PIN, LOW);
+    digitalWrite(PNA_PIN, LOW);
+    digitalWrite(PB_PIN, LOW);
+    digitalWrite(PNB_PIN, LOW);
     break;
-    case 3:
-      digitalWrite(PA_PIN,LOW);
-      digitalWrite(PNA_PIN,HIGH);
-      digitalWrite(PB_PIN,HIGH);
-      digitalWrite(PNB_PIN,LOW);
+  case 1:
+    digitalWrite(PA_PIN, HIGH);
+    digitalWrite(PNA_PIN, LOW);
+    digitalWrite(PB_PIN, LOW);
+    digitalWrite(PNB_PIN, HIGH);
     break;
-    case 4:
-      digitalWrite(PA_PIN,LOW);
-      digitalWrite(PNA_PIN,HIGH);
-      digitalWrite(PB_PIN,LOW);
-      digitalWrite(PNB_PIN,HIGH);
+  case 2:
+    digitalWrite(PA_PIN, HIGH);
+    digitalWrite(PNA_PIN, LOW);
+    digitalWrite(PB_PIN, HIGH);
+    digitalWrite(PNB_PIN, LOW);
+    break;
+  case 3:
+    digitalWrite(PA_PIN, LOW);
+    digitalWrite(PNA_PIN, HIGH);
+    digitalWrite(PB_PIN, HIGH);
+    digitalWrite(PNB_PIN, LOW);
+    break;
+  case 4:
+    digitalWrite(PA_PIN, LOW);
+    digitalWrite(PNA_PIN, HIGH);
+    digitalWrite(PB_PIN, LOW);
+    digitalWrite(PNB_PIN, HIGH);
     break;
-
   }
 }
 
-uint8_t feed_pitch1(uint64_t lines, uint8_t forward_backward)
-{
+uint8_t feed_pitch1(uint64_t lines, uint8_t forward_backward) {
   uint8_t pos = current_pos;
-  uint8_t restor =  ~forward_backward;
-  
+  uint8_t restor = ~forward_backward;
+
   restor &= 0x01;
-  
-  if(lines>0)
-  {
+
+  if (lines > 0) {
     MOTOR_ENABLE1;
     MOTOR_ENABLE2;
     ENABLE_VH;
-    while(lines>0)
-    {
-      motor_stepper_pos2(pos);     /* 0.0625mm */
-      
-      if(pos >= 1 && pos <= 4)
-        pos = pos + (1 - 2*forward_backward); // adding or subtracting
-      if(pos < 1 || pos > 4)
-        pos = pos + (4 - 8*restor); // restoring pos
+    while (lines > 0) {
+      motor_stepper_pos2(pos); /* 0.0625mm */
+
+      if (pos >= 1 && pos <= 4)
+        pos = pos + (1 - 2 * forward_backward); // adding or subtracting
+      if (pos < 1 || pos > 4)
+        pos = pos + (4 - 8 * restor); // restoring pos
 
       lines--;
     }
     MOTOR_DISABLE1;
     MOTOR_DISABLE2;
     DISABLE_VH;
-    
-  }
-  else
-  {
+
+  } else {
     return ERROR_FEED_PITCH;
   }
   current_pos = pos;
   return 0;
-
 }
 
-void print_dots_8bit_split(CONFIG*cfg,uint8_t *Array, uint8_t characters) 
-{
-  uint8_t i=0,y=0, MAX=MAXPIXELS;
+void print_dots_8bit_split(CONFIG *cfg, uint8_t *Array, uint8_t characters) {
+  uint8_t i = 0, y = 0, MAX = MAXPIXELS;
   uint8_t blank;
   uint16_t pts;
   uint8_t temp[MAXPIXELS];
   uint8_t _array[MAXPIXELS];
   pts = 0;
-  memcpy(_array,Array,MAXPIXELS);
-  
-  while( (i< characters) && (i < MAX)) {
+  memcpy(_array, Array, MAXPIXELS);
+
+  while ((i < characters) && (i < MAX)) {
 
     pts = pts + bits_number(Array[i]);
-    
-    if(pts > cfg->max_pts) {
-      memset(temp,0,MAXPIXELS);
-      memcpy(temp,_array,i);
-      print_dots_8bit(cfg,temp,characters,0);
+
+    if (pts > cfg->max_pts) {
+      memset(temp, 0, MAXPIXELS);
+      memcpy(temp, _array, i);
+      print_dots_8bit(cfg, temp, characters, 0);
       pts = bits_number(_array[i]);
-      memset(_array,0,i);
-    }else if(pts==cfg->max_pts) {
-      memset(temp,0,MAXPIXELS);
-      memcpy(temp,_array,i+1);      
-      print_dots_8bit(cfg,temp,characters,0);
-      pts=0;
-      memset(_array,0,i+1);
+      memset(_array, 0, i);
+    } else if (pts == cfg->max_pts) {
+      memset(temp, 0, MAXPIXELS);
+      memcpy(temp, _array, i + 1);
+      print_dots_8bit(cfg, temp, characters, 0);
+      pts = 0;
+      memset(_array, 0, i + 1);
     }
     i++;
   }
 
-  if(pts >0){
-    print_dots_8bit(cfg,_array,characters,0);
+  if (pts > 0) {
+    print_dots_8bit(cfg, _array, characters, 0);
     pts = 0;
   }
 
-  feed_pitch1(cfg->feed_pitch,cfg->orient);
+  feed_pitch1(cfg->feed_pitch, cfg->orient);
 
   return;
 }
 
-void print_dots_8bit(CONFIG*cfg,uint8_t *Array, uint8_t characters,uint8_t feed_num) 
-{
-  uint8_t i=0,y=0, MAX=MAXPIXELS;
+void print_dots_8bit(CONFIG *cfg, uint8_t *Array, uint8_t characters,
+                     uint8_t feed_num) {
+  uint8_t i = 0, y = 0, MAX = MAXPIXELS;
   uint8_t blank;
-  
-      ENABLE_VH;
 
-      if(cfg->align == 0) {
-        while((i<characters) && (i < MAX))
-        {
-          printer_send_data8(Array[i]);
-          i++;
-        }  
-        while( i < MAX)
-        {
-          printer_send_data8(0x00);
-          i++;
-        }
-      }else if(cfg->align==1){// center
-         blank = 0;
-         blank = (MAX-characters)/2;
-         
-         for(i=0;i<blank;i++){
-          printer_send_data8(0x00);
-         }
-         for(i=0;i<characters;i++){
-          printer_send_data8(Array[i]);
-         }
-         for(i=0;i<(MAX-characters-blank);i++){
-          printer_send_data8(0x00);
-         }
-      }else if(cfg->align==2){
-        blank = MAX-characters;
-        for(i=0;i<blank;i++){
-          printer_send_data8(0x00);
-        }
-        for(i=0;i<characters;i++){
-          printer_send_data8(Array[i]);
-        }      
-      }
-      
-      LATCH_ENABLE;
-      delayus(1);
-      LATCH_DISABLE;
-      delayMicroseconds(1);
-      
-      i =0;
-      
-      while(y<STB_NUMBER)
-      {
-        
-          while(i <10)
-          {
-
-                 
-            digitalWrite(STBx[y],HIGH); 
-            delayus(HEAT_TIME+cfg->density*46);
-            digitalWrite(STBx[y],LOW);
-            delayus(14);
-            i++;
-          }
-         
-          y++;
-      }
+  ENABLE_VH;
+
+  if (cfg->align == 0) {
+    while ((i < characters) && (i < MAX)) {
+      printer_send_data8(Array[i]);
+      i++;
+    }
+    while (i < MAX) {
+      printer_send_data8(0x00);
+      i++;
+    }
+  } else if (cfg->align == 1) { // center
+    blank = 0;
+    blank = (MAX - characters) / 2;
+
+    for (i = 0; i < blank; i++) {
+      printer_send_data8(0x00);
+    }
+    for (i = 0; i < characters; i++) {
+      printer_send_data8(Array[i]);
+    }
+    for (i = 0; i < (MAX - characters - blank); i++) {
+      printer_send_data8(0x00);
+    }
+  } else if (cfg->align == 2) {
+    blank = MAX - characters;
+    for (i = 0; i < blank; i++) {
+      printer_send_data8(0x00);
+    }
+    for (i = 0; i < characters; i++) {
+      printer_send_data8(Array[i]);
+    }
+  }
 
+  LATCH_ENABLE;
+  delayus(1);
+  LATCH_DISABLE;
+  delayMicroseconds(1);
 
-    feed_pitch1(feed_num,cfg->orient);
+  i = 0;
 
-      
-    DISABLE_VH;
+  while (y < STB_NUMBER) {
+
+    while (i < 10) {
 
-    return;
+      digitalWrite(STBx[y], HIGH);
+      delayus(HEAT_TIME + cfg->density * 46);
+      digitalWrite(STBx[y], LOW);
+      delayus(14);
+      i++;
+    }
+
+    y++;
+  }
+
+  feed_pitch1(feed_num, cfg->orient);
+
+  DISABLE_VH;
+
+  return;
 }
 
-uint16_t read_adc(char*adc_file) {
+uint16_t read_adc(char *adc_file) {
   long ret;
   char c[16];
   FILE *fptr;
@@ -363,275 +340,466 @@ uint16_t read_adc(char*adc_file) {
     return 0;
   }
   fscanf(fptr, "%[^\n]", c);
-  //printf("Data from the file:\n%s", c);
+  // printf("Data from the file:\n%s", c);
   fclose(fptr);
 
   ret = strtol(c, NULL, 10);
-  //printf("the number ret %d\n",ret);
+  // printf("the number ret %d\n",ret);
 
   return (uint16_t)ret;
 }
 
-
 uint16_t temperature() {
-  
-  
+
   double Rthermistor = 0, TempThermistor = 0;
-  uint16_t ADCSamples=0;
+  uint16_t ADCSamples = 0;
   int Sample = 1;
   uint16_t ADCConvertedValue;
 
- 
-  while(Sample<=NumSamples)
-  {
-      //ADCSamples += analogRead(THERMISTORPIN); //stm32
-      ADCSamples += read_adc(adc_file_path);
-      Sample++;
+  while (Sample <= NumSamples) {
+    // ADCSamples += analogRead(THERMISTORPIN); //stm32
+    ADCSamples += read_adc(adc_file_path);
+    Sample++;
   }
-  //Thermistor Resistance at x Kelvin
-  ADCConvertedValue = (double)ADCSamples/NumSamples;
-  Rthermistor = ( (double)ADCResolution/ ADCConvertedValue) - 1;
-  Rthermistor =  (double)SeriesResistor/Rthermistor;
-  //Thermistor temperature in Kelvin
-  TempThermistor =  Rthermistor / RthNominal ;
-  TempThermistor =  log(TempThermistor);
+  // Thermistor Resistance at x Kelvin
+  ADCConvertedValue = (double)ADCSamples / NumSamples;
+  Rthermistor = ((double)ADCResolution / ADCConvertedValue) - 1;
+  Rthermistor = (double)SeriesResistor / Rthermistor;
+  // Thermistor temperature in Kelvin
+  TempThermistor = Rthermistor / RthNominal;
+  TempThermistor = log(TempThermistor);
   TempThermistor /= BCoefficent;
-  TempThermistor +=  (1/(TempNominal + 273.15));
-  TempThermistor = 1/TempThermistor;
+  TempThermistor += (1 / (TempNominal + 273.15));
+  TempThermistor = 1 / TempThermistor;
+
+  return (uint16_t)(TempThermistor - 273.15);
 
-  return  (uint16_t)(TempThermistor - 273.15);
-  
-  
-  //return  (uint16_t)(0);
+  // return  (uint16_t)(0);
 }
 
-int glob_file(char*av) {
+int glob_file(char *av) {
 
   glob_t globlist;
 
-  if (glob(av, GLOB_PERIOD|GLOB_NOSORT, NULL, &globlist) == GLOB_NOSPACE || glob(av, GLOB_PERIOD|GLOB_NOSORT, NULL, &globlist) == GLOB_NOMATCH)
+  if (glob(av, GLOB_PERIOD | GLOB_NOSORT, NULL, &globlist) == GLOB_NOSPACE ||
+      glob(av, GLOB_PERIOD | GLOB_NOSORT, NULL, &globlist) == GLOB_NOMATCH)
     return -1;
-  if (glob(av, GLOB_PERIOD|GLOB_NOSORT, NULL, &globlist) == GLOB_ABORTED)
+  if (glob(av, GLOB_PERIOD | GLOB_NOSORT, NULL, &globlist) == GLOB_ABORTED)
     return 1;
 
-  if(globlist.gl_pathc > 0) {
-    strcpy(adc_file_path,globlist.gl_pathv[0]);
+  if (globlist.gl_pathc > 0) {
+    strcpy(adc_file_path, globlist.gl_pathv[0]);
   }
   return 0;
+}
+
+#endif
+uint16_t get_serial_cache_font_width(CONFIG *cfg) {
 
+  int i;
+  uint8_t *ch;
+  uint32_t codename;
+  int w;
+  w = 0;
+  i = 0;
+  while (i < ser_cache.idx) {
+    ch = (uint8_t *)&ser_cache.data[i];
+    codename = utf8_to_utf32(ch);
+    FT_UInt gi = FT_Get_Char_Index(cfg->face, codename);
+    FT_Load_Glyph(cfg->face, gi, FT_LOAD_NO_BITMAP);
+    w += cfg->face->glyph->metrics.horiAdvance / 64;
+    i++;
+  }
+  return w + cfg->font->width;
 }
 
+// print with freetype font dots glyph
+uint8_t print_lines_ft(CONFIG *cfg) {
+  uint8_t i, j, k;
+  int8_t w;
+  uint8_t dot_line_data[MAXPIXELS];
+  uint8_t dot_line_idx = 0;
+  uint8_t dot_line_bitsidx = 0;
 
-#endif
+  uint8_t lastidx, lastw, lastj;
+  uint8_t row, row_cnt;
+  uint16_t line_bits;
 
-uint8_t print_lines8(CONFIG*cfg) {
-  uint8_t i,j,k;
+  int8_t left = ser_cache.idx;
+  uint8_t rv;
+
+  line_bits = cfg->margin.width;
+  dot_line_idx = line_bits / 8;
+  dot_line_bitsidx = line_bits % 8;
+
+  lastidx = 0;
+  lastw = 0;
+  lastj = 0;
+
+  uint32_t codename;
+  uint8_t *ch;
+  printf("left = %d\n", left);
+  int line_height = (cfg->face->size->metrics.ascender -
+                     cfg->face->size->metrics.descender) >>
+                    6;
+  int baseline_height =
+      abs(cfg->face->descender) * current_font.height / cfg->face->units_per_EM;
+  int dpx = 64;
+  FT_Matrix matrix;
+
+  while (left > 0) {
+    i = lastidx;
+    row_cnt = 0;
+    row = 0;
+    while (row < line_height) {
+      line_bits = cfg->margin.width;
+      dot_line_idx = line_bits / 8;
+      dot_line_bitsidx = line_bits % 8;
+      memset(dot_line_data, 0, MAXPIXELS);
+      // line by line bitmap dots to print
+      i = lastidx;
+
+      while (i < ser_cache.idx) {
+        ch = (uint8_t *)&ser_cache.data[i];
+        codename = utf8_to_utf32(ch);
+
+        matrix.xx = (FT_Fixed)(cos(((double)cfg->degree / 360) * 3.14159 * 2) *
+                               0x10000L);
+        matrix.xy = (FT_Fixed)(-sin(((double)cfg->degree / 360) * 3.14159 * 2) *
+                               0x10000L);
+        matrix.yx = (FT_Fixed)(sin(((double)cfg->degree / 360) * 3.14159 * 2) *
+                               0x10000L);
+        matrix.yy = (FT_Fixed)(cos(((double)cfg->degree / 360) * 3.14159 * 2) *
+                               0x10000L);
+        FT_Set_Transform(cfg->face, &matrix, NULL);
+
+        FT_UInt gi = FT_Get_Char_Index(cfg->face, codename);
+        FT_Load_Glyph(cfg->face, gi, FT_LOAD_DEFAULT);
+        int y_off = line_height - baseline_height -
+                    cfg->face->glyph->metrics.horiBearingY / dpx;
+        int glyph_width = cfg->face->glyph->metrics.width / dpx;
+        int glyph_height = cfg->face->glyph->metrics.height / dpx;
+        int advance = cfg->face->glyph->metrics.horiAdvance / dpx;
+
+        int x_off = (advance - glyph_width) / 2;
+
+        int bitmap_rows = cfg->face->glyph->bitmap.rows;
+        int bitmap_width = cfg->face->glyph->bitmap.width;
+        // FT_Render_Glyph(cfg->face->glyph, FT_RENDER_MODE_NORMAL);
+        FT_Render_Glyph(cfg->face->glyph, FT_RENDER_MODE_MONO); // disable AA
+
+        j = 0;
+        w = 0;
+        if (lastj != 0) {
+          j = lastj;
+        }
+        if (lastw != 0) {
+          w = lastw;
+        }
+        while (w < advance) {
+          // if(w > 0 && (w%8) == 0) j++;
+          if (dot_line_bitsidx > 7) {
+            dot_line_idx++;
+            dot_line_bitsidx = 0;
+          }
+
+          // unsigned char p = cfg->face->glyph->bitmap.buffer[row *
+          // cfg->face->glyph->bitmap.pitch + w];
+          unsigned char p = 0;
+          int pitch = abs(cfg->face->glyph->bitmap.pitch);
+
+          if (w >= x_off && row >= y_off) {
+            row_cnt = row - y_off;
+            if (row_cnt < bitmap_rows) {
+              // p =
+              // (cfg->face->glyph->bitmap.buffer[row_cnt*cfg->face->glyph->bitmap.pitch+j]
+              // >> (7-w%8)) & 1;//disable AA
+              j = (w - x_off) / 8;
+              p = cfg->face->glyph->bitmap.buffer[row_cnt * pitch + j];
+              p = p & (128 >> ((w - x_off) & 7));
+            }
+          }
+
+          if (p) {
+            printf("#");
+            dot_line_data[dot_line_idx] |= 1 << (7 - dot_line_bitsidx);
+          } else {
+            printf("0");
+          }
+
+          dot_line_bitsidx++;
+          w++;
+          line_bits++;
+          if (line_bits >= MAX_DOTS)
+            break;
+        }
+        // word gap
+        k = 0;
+        while (k < cfg->wordgap) {
+          if (dot_line_bitsidx > 7) {
+            dot_line_idx++;
+            dot_line_bitsidx = 0;
+          }
+          k++;
+          dot_line_bitsidx++;
+          line_bits++;
+          if (line_bits >= MAX_DOTS)
+            break;
+        }
+
+        if (line_bits < MAX_DOTS) {
+          i++;
+        }
+
+        if (line_bits >= MAX_DOTS || i >= ser_cache.idx) {
+
+          if (row == (line_height - 1)) { // last of the row loop
+            if (w >= advance) {
+              lastidx = i + 1;
+              lastw = 0;
+              lastj = 0;
+            } else {
+              lastidx = i;
+              lastw = w;
+              lastj = j;
+            }
+          }
+
+          break;
+        }
+      }
+      rv = IsPaper();
+      if (rv == IS_PAPER) {
+        // DEBUG("dot_line_idx",dot_line_idx);
+        // DEBUG("dot_line_bits",dot_line_bitsidx);
+        print_dots_8bit_split(cfg, dot_line_data, dot_line_idx + 1);
+      }
+      row++;
+      printf("\n");
+    }
+    left = left - lastidx;
+    row = 0;
+    /*
+    if(cfg->line_space > cfg->font->height){
+      feed_pitch1(cfg->line_space - cfg->font->height,cfg->orient);
+    }
+    */
+  }
+}
+
+uint8_t print_lines8(CONFIG *cfg) {
+
+  if (cfg->font->mode == FONT_MODE_1) {
+    return print_lines_ft(cfg);
+  }
+  uint8_t i, j, k;
   int8_t w;
   uint8_t *data;
-  uint8_t row,pad;
+  uint8_t row, pad;
   uint16_t addr;
-  
+
   uint16_t line_bits;
-  
+
   uint8_t dot_line_data[MAXPIXELS];
-  uint8_t dot_line_idx=0;
-  uint8_t dot_line_bitsidx=0;
+  uint8_t dot_line_idx = 0;
+  uint8_t dot_line_bitsidx = 0;
 
-  uint8_t lastidx,lastw,lastj;
+  uint8_t lastidx, lastw, lastj;
   int8_t left;
   uint8_t rv;
 
-  pad = current_font.width %BITS8;
-  
-  if(pad > 0){
+  pad = current_font.width % BITS8;
+
+  if (pad > 0) {
     pad = 1;
   }
 
   i = 0;
-  i = current_font.width/BITS8;
-  
-  pad = i+pad;
-  
+  i = current_font.width / BITS8;
+
+  pad = i + pad;
+
   row = 0;
   rv = IsPaper();
-  
-  data = (uint8_t*)malloc(sizeof(uint8_t)*(pad+1));
-  i=0;
-
-  
-  line_bits=cfg->margin.width;
-   
-  dot_line_idx = line_bits/8;
-  dot_line_bitsidx = line_bits%8;
+
+  data = (uint8_t *)malloc(sizeof(uint8_t) * (pad + 1));
+  i = 0;
+
+  line_bits = cfg->margin.width;
+
+  dot_line_idx = line_bits / 8;
+  dot_line_bitsidx = line_bits % 8;
   left = ser_cache.idx;
-  lastidx=0;
-  lastw=0;
-  lastj=0;
+  lastidx = 0;
+  lastw = 0;
+  lastj = 0;
 
-  //DEBUG("left",left);  
-  while(left>0){
+  // DEBUG("left",left);
+  while (left > 0) {
     i = lastidx;
-    while(row<current_font.height){
-    
-      line_bits=cfg->margin.width;
-      dot_line_idx = line_bits/8;
-      dot_line_bitsidx = line_bits%8;
-      memset(dot_line_data,0,MAXPIXELS);
+    while (row < current_font.height) {
+
+      line_bits = cfg->margin.width;
+      dot_line_idx = line_bits / 8;
+      dot_line_bitsidx = line_bits % 8;
+      memset(dot_line_data, 0, MAXPIXELS);
       i = lastidx;
-      //DEBUG("i",i)
-      //DEBUG("ser_cache.idx",ser_cache.idx)
-      while( i <ser_cache.idx){
-        addr = pad*ser_cache.data[i]*current_font.height;
-        for(j=0;j<pad;j++){
-          data[j] = current_font.data[addr+row*pad+j];
+      // DEBUG("i",i)
+      // DEBUG("ser_cache.idx",ser_cache.idx)
+      while (i < ser_cache.idx) {
+        addr = pad * (uint8_t)ser_cache.data[i] * current_font.height;
+        for (j = 0; j < pad; j++) {
+          data[j] = current_font.data[addr + row * pad + j];
         }
-        j=0; w=0;
-        if(lastj !=0){j= lastj;}
-        if(lastw !=0) { w = lastw;}
-        
-          while(w < current_font.width){
-            if(w > 0 && ( w%8) == 0)j++;
-            if(dot_line_bitsidx > 7){
-              dot_line_idx++;
-              dot_line_bitsidx=0;
-            }
-          
-            k = (data[j] >> (7-(w%8))) &1;
-            //Serial.print(data[j],HEX);
-            if( k > 0){
-              dot_line_data[dot_line_idx] |= 1 << (7-dot_line_bitsidx);
-              //Serial.print("1");
-            }
-          
-            dot_line_bitsidx++;
-            w++;
-            line_bits++;
-            if(line_bits >= MAX_DOTS)break;
+        j = 0;
+        w = 0;
+        if (lastj != 0) {
+          j = lastj;
+        }
+        if (lastw != 0) {
+          w = lastw;
+        }
+
+        while (w < current_font.width) {
+          if (w > 0 && (w % 8) == 0)
+            j++;
+          if (dot_line_bitsidx > 7) {
+            dot_line_idx++;
+            dot_line_bitsidx = 0;
           }
 
-          ///word gap
-          k=0;
-          while( k < cfg->wordgap ){
-            if(dot_line_bitsidx > 7){
-              dot_line_idx++;
-              dot_line_bitsidx=0;
-            }
+          k = (data[j] >> (7 - (w % 8))) & 1;
+          // Serial.print(data[j],HEX);
+          if (k > 0) {
+            dot_line_data[dot_line_idx] |= 1 << (7 - dot_line_bitsidx);
+            // Serial.print("1");
+          }
+
+          dot_line_bitsidx++;
+          w++;
+          line_bits++;
+          if (line_bits >= MAX_DOTS)
+            break;
+        }
 
-            k++;
-            dot_line_bitsidx++;
-            line_bits++;
-            if(line_bits >= MAX_DOTS)break;
+        /// word gap
+        k = 0;
+        while (k < cfg->wordgap) {
+          if (dot_line_bitsidx > 7) {
+            dot_line_idx++;
+            dot_line_bitsidx = 0;
           }
-         
-        if(line_bits < MAX_DOTS){
+
+          k++;
+          dot_line_bitsidx++;
+          line_bits++;
+          if (line_bits >= MAX_DOTS)
+            break;
+        }
+
+        if (line_bits < MAX_DOTS) {
           i++;
         }
-        
-        if(line_bits >= MAX_DOTS || i >=ser_cache.idx){
-          
-          if(row == (current_font.height-1)) {// last of the row loop         
-            if(w >= current_font.width){
-              lastidx = i+1;
-              lastw =0;
-              lastj =0;
-            }else {              
+
+        if (line_bits >= MAX_DOTS || i >= ser_cache.idx) {
+
+          if (row == (current_font.height - 1)) { // last of the row loop
+            if (w >= current_font.width) {
+              lastidx = i + 1;
+              lastw = 0;
+              lastj = 0;
+            } else {
               lastidx = i;
               lastw = w;
               lastj = j;
             }
           }
-          
+
           break;
         }
       }
       rv = IsPaper();
-      if( rv == IS_PAPER){
-        //DEBUG("dot_line_idx",dot_line_idx);
-        //DEBUG("dot_line_bits",dot_line_bitsidx);
-        print_dots_8bit_split(cfg,dot_line_data,dot_line_idx+1);
-      }        
+      if (rv == IS_PAPER) {
+        // DEBUG("dot_line_idx",dot_line_idx);
+        // DEBUG("dot_line_bits",dot_line_bitsidx);
+        print_dots_8bit_split(cfg, dot_line_data, dot_line_idx + 1);
+      }
       row++;
     }
     left = left - lastidx;
     row = 0;
-    
-    if(cfg->line_space > cfg->font->height){
-      feed_pitch1(cfg->line_space - cfg->font->height,cfg->orient);
+
+    if (cfg->line_space > cfg->font->height) {
+      feed_pitch1(cfg->line_space - cfg->font->height, cfg->orient);
     }
-    
   }
-  
-  //Serial.println("print ever");
+
+  // Serial.println("print ever");
 
   free(data);
 
   return rv;
 }
 
-
-uint8_t print_image8(CONFIG*cfg){
+uint8_t print_image8(CONFIG *cfg) {
 
   uint16_t height;
-  uint16_t x,y,addr;
-  
+  uint16_t x, y, addr;
+
   uint8_t rv;
   uint8_t LinePixels[MAXPIXELS];
 
-  uint8_t maxchars= PRINTER_BITS/8;
-  height  = cfg->img->num / cfg->img->width;
-  y=0;
+  uint8_t maxchars = PRINTER_BITS / 8;
+  height = cfg->img->num / cfg->img->width;
+  y = 0;
   addr = 0;
-  
+
   rv = IsPaper();
 
-  while(y < height )
-  {
-    x=0;
-    while( x < cfg->img->width )
-    {
-      addr  = x+y*cfg->img->width;
+  while (y < height) {
+    x = 0;
+    while (x < cfg->img->width) {
+      addr = x + y * cfg->img->width;
 
-     
-      if(cfg->img->revert_bits > 0)//LSB
+      if (cfg->img->revert_bits > 0) // LSB
         LinePixels[x] = invert_bit(cfg->img->cache[addr]);
       else
         LinePixels[x] = cfg->img->cache[addr];
-      
+
       x++;
     }
     rv = IsPaper();
-    if( rv == IS_PAPER) {
-    	print_dots_8bit_split(cfg,LinePixels,x);
+    if (rv == IS_PAPER) {
+      print_dots_8bit_split(cfg, LinePixels, x);
     }
-    
-    //feed_pitch1(FEED_PITCH,cfg->orient);
+
+    // feed_pitch1(FEED_PITCH,cfg->orient);
     y++;
   }
-  //feed_pitch1(cfg->feed_pitch,cfg->orient);
-  cfg->img->need_print= 0;
-  
+  // feed_pitch1(cfg->feed_pitch,cfg->orient);
+  cfg->img->need_print = 0;
+
   cfg->img->num = 0;
   cfg->img->idx = 0;
   cfg->img->width = 0;
-  
+
   return rv;
 }
 
-void print_cut_line(CONFIG*cfg){
-  uint8_t bs,i;
+void print_cut_line(CONFIG *cfg) {
+  uint8_t bs, i;
+
+  bs = PRINTER_BITS / cfg->font->width;
+  bs -= 1;
 
-  bs= PRINTER_BITS/ cfg->font->width;
-  bs-=1;
- 
   reset_cmd();
-  
-  for(i=0;i<bs;i++){
-    if(i%2==0){
-      parse_serial_stream(cfg,'=');
-    }else{
-      parse_serial_stream(cfg,'-');
+
+  for (i = 0; i < bs; i++) {
+    if (i % 2 == 0) {
+      parse_serial_stream(cfg, '=');
+    } else {
+      parse_serial_stream(cfg, '-');
     }
   }
-  parse_serial_stream(cfg,ASCII_FF);
-  
+  parse_serial_stream(cfg, ASCII_FF);
 }

+ 16 - 13
Code/thermal_printer/printer.h

@@ -3,8 +3,8 @@
 
 #include "config.h"
 
-//#define PRINT_SPLIT 6 // max points printed at the same time, 384/PRINT_SPLIT==96
-//#define MAX_PRINT_PTS 2
+//#define PRINT_SPLIT 6 // max points printed at the same time,
+//384/PRINT_SPLIT==96 #define MAX_PRINT_PTS 2
 
 void printer_send_data8(uint8_t);
 
@@ -21,24 +21,27 @@ void motor_stepper_pos2(uint8_t Position);
 uint8_t feed_pitch1(uint64_t lines, uint8_t forward_backward);
 
 uint8_t bits_number(uint8_t n);
- 
-void print_dots_8bit_split(CONFIG*cfg,uint8_t *Array, uint8_t characters);
 
-void print_dots_8bit(CONFIG*cfg,uint8_t *Array, uint8_t characters,uint8_t feed_num);
+void print_dots_8bit_split(CONFIG *cfg, uint8_t *Array, uint8_t characters);
 
-uint16_t read_adc(char*);
-uint16_t temperature();
-int glob_file(char*);
+void print_dots_8bit(CONFIG *cfg, uint8_t *Array, uint8_t characters,
+                     uint8_t feed_num);
 
-uint8_t print_lines8(CONFIG*);
+uint16_t read_adc(char *);
+uint16_t temperature();
+int glob_file(char *);
+uint16_t get_serial_cache_font_width(CONFIG *);
+uint8_t print_lines_ft(CONFIG *);
+uint8_t print_lines8(CONFIG *);
 
 uint8_t invert_bit(uint8_t a);
 
-uint8_t print_image8(CONFIG*);
-void print_cut_line(CONFIG*);
+uint8_t print_image8(CONFIG *);
+void print_cut_line(CONFIG *);
 
-void printer_set_font(CONFIG*cfg,uint8_t fnbits);
-void parse_serial_stream(CONFIG*cfg,uint8_t input_ch);
+void printer_set_font_mode(CONFIG *cfg, int);
+void printer_set_font(CONFIG *cfg, uint8_t fnbits);
+void parse_serial_stream(CONFIG *cfg, uint8_t input_ch);
 
 void reset_cmd();
 

+ 12 - 0
Code/thermal_printer/test.txt

@@ -0,0 +1,12 @@
+“励志一生”网站精心挑选汇集了60句宋词佳句,转载过来与大家分享,也很值得收藏!
+
+1. 一ada;场消黯,永日无言,却下层楼。——柳永〈曲玉管〉
+
+2. 可惜流asdfsad年,忧愁风雨,树犹如此。——辛弃疾〈水龙吟.登建康赏心亭〉
+
+3. 十年生死两茫茫,不dsafadsf思量,自难忘。——苏轼〈江城子〉
+
+4. 纵使相逢应不识,尘满面,鬓nbqga&*(如霜。——苏轼〈江城子〉
+
+5. 相顾无言,惟有泪千行。——苏轼〈江城子〉
+

+ 1 - 0
Code/thermal_printer/usr/local/etc/devterm-printer

@@ -0,0 +1 @@
+TTF=/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc

+ 83 - 0
Code/thermal_printer/utf8-utils.c

@@ -0,0 +1,83 @@
+/* Freetype GL - A C OpenGL Freetype engine
+ *
+ * Distributed under the OSI-approved BSD 2-Clause License.  See accompanying
+ * file `LICENSE` for more details.
+ */
+#include <string.h>
+#include "utf8-utils.h"
+
+// ----------------------------------------------------- utf8_surrogate_len ---
+size_t
+utf8_surrogate_len( const char* character )
+{
+    size_t result = 0;
+    char test_char;
+
+    if (!character)
+        return 0;
+
+    test_char = character[0];
+
+    if ((test_char & 0x80) == 0)
+        return 1;
+
+    while (test_char & 0x80)
+    {
+        test_char <<= 1;
+        result++;
+    }
+
+    return result;
+}
+
+// ------------------------------------------------------------ utf8_strlen ---
+size_t
+utf8_strlen( const char* string )
+{
+    const char* ptr = string;
+    size_t result = 0;
+
+    while (*ptr)
+    {
+        ptr += utf8_surrogate_len(ptr);
+        result++;
+    }
+
+    return result;
+}
+
+uint32_t
+utf8_to_utf32( const char * character )
+{
+    if( !character )
+    {
+        return -1;
+    }
+
+    if( ( character[0] & 0x80 ) == 0x0 )
+    {
+        return character[0];
+    }
+
+    if( ( character[0] & 0xE0 ) == 0xC0 )
+    {
+        return ( ( character[0] & 0x3F ) << 6 ) | ( character[1] & 0x3F );
+    }
+
+    if( ( character[0] & 0xF0 ) == 0xE0 )
+    {
+        return ( ( character[0] & 0x1F ) << ( 6 + 6 ) ) | ( ( character[1] & 0x3F ) << 6 ) | ( character[2] & 0x3F );
+    }
+
+    if( ( character[0] & 0xF8 ) == 0xF0 )
+    {
+        return ( ( character[0] & 0x0F ) << ( 6 + 6 + 6 ) ) | ( ( character[1] & 0x3F ) << ( 6 + 6 ) ) | ( ( character[2] & 0x3F ) << 6 ) | ( character[3] & 0x3F );
+    }
+
+    if( ( character[0] & 0xFC ) == 0xF8 )
+    {
+        return ( ( character[0] & 0x07 ) << ( 6 + 6 + 6 + 6 ) ) | ( ( character[1] & 0x3F ) << ( 6 + 6 + 6 ) ) | ( ( character[2] & 0x3F ) << ( 6 + 6 ) ) | ( ( character[3] & 0x3F ) << 6 ) | ( character[4] & 0x3F );
+    }
+
+    return 0xFFFD; // invalid character
+}

+ 68 - 0
Code/thermal_printer/utf8-utils.h

@@ -0,0 +1,68 @@
+/* Freetype GL - A C OpenGL Freetype engine
+ *
+ * Distributed under the OSI-approved BSD 2-Clause License.  See accompanying
+ * file `LICENSE` for more details.
+ */
+#ifndef __UTF8_UTILS_H__
+#define __UTF8_UTILS_H__
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+
+namespace ftgl {
+#endif
+
+/**
+ * @file    utf8-utils.h
+ * @author  Marcel Metz <mmetz@adrian-broher.net>
+ *
+ * defgroup utf8-utils UTF-8 Utilities
+ *
+ * @{
+ */
+
+  /**
+   * Returns the size in bytes of a given UTF-8 encoded character surrogate
+   *
+   * @param character  An UTF-8 encoded character
+   *
+   * @return  The length of the surrogate in bytes.
+   */
+  size_t
+  utf8_surrogate_len( const char* character );
+
+  /**
+   * Return the length of the given UTF-8 encoded and
+   * NULL terminated string.
+   *
+   * @param string  An UTF-8 encoded string
+   *
+   * @return  The length of the string in characters.
+   */
+  size_t
+  utf8_strlen( const char* string );
+
+  /**
+   * Converts a given UTF-8 encoded character to its UTF-32 LE equivalent
+   *
+   * @param character  An UTF-8 encoded character
+   *
+   * @return  The equivalent of the given character in UTF-32 LE
+   *          encoding.
+   */
+  uint32_t
+  utf8_to_utf32( const char * character );
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+}
+#endif
+
+#endif /* #define __UTF8_UTILS_H__ */

+ 13 - 17
Code/thermal_printer/utils.c

@@ -1,24 +1,20 @@
 #include "utils.h"
 
-void delayus(unsigned int _us){
-  delayMicroseconds(_us);
-}
+void delayus(unsigned int _us) { delayMicroseconds(_us); }
 
-uint8_t invert_bit(uint8_t a){
+uint8_t invert_bit(uint8_t a) {
 
-  return ((a&0x01)<<7)|((a&0x02)<<5)|((a&0x04)<<3)|((a&0x08)<<1)|((a&0x10)>>1)|((a&0x20)>>3)|((a&0x40)>>5)|((a&0x80)>>7);
-  
+  return ((a & 0x01) << 7) | ((a & 0x02) << 5) | ((a & 0x04) << 3) |
+         ((a & 0x08) << 1) | ((a & 0x10) >> 1) | ((a & 0x20) >> 3) |
+         ((a & 0x40) >> 5) | ((a & 0x80) >> 7);
 }
 
-uint8_t bits_number(uint8_t n)//count bits "1"
-{ 
-    uint8_t count = 0; 
-    while (n) { 
-        count += n & 1; 
-        n >>= 1; 
-    } 
-    return count; 
+uint8_t bits_number(uint8_t n) // count bits "1"
+{
+  uint8_t count = 0;
+  while (n) {
+    count += n & 1;
+    n >>= 1;
+  }
+  return count;
 }
-
-
-

+ 10 - 4
Code/thermal_printer/utils.h

@@ -1,19 +1,26 @@
 #ifndef UTILS_H
 #define UTILS_H
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdint.h> 
 #include <string.h>
 
 #include <wiringPi.h>
 
 #define SEP printf(" ");
 // a is string, b is number
-#define DEBUG(a,b) printf(a);SEP;printf("%d\n",b);
+#define DEBUG(a, b)                                                            \
+  printf(a);                                                                   \
+  SEP;                                                                         \
+  printf("%d\n", b);
 
 #define ALINE printf("\n");
 
-#define PRINTF(...) { printf(__VA_ARGS__);fflush(stdout);}
+#define PRINTF(...)                                                            \
+  {                                                                            \
+    printf(__VA_ARGS__);                                                       \
+    fflush(stdout);                                                            \
+  }
 
 void delayus(unsigned int _us);
 
@@ -21,5 +28,4 @@ uint8_t invert_bit(uint8_t a);
 
 uint8_t bits_number(uint8_t n);
 
-
 #endif

Some files were not shown because too many files changed in this diff