Как правильно расставить биты

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

хочу в библиотеку для дисплея добавить шилд на меге128, все работает как надо, но выход в PB1 в 128 это sck, хочу передвинуть PB0 PB1 на PB4 PB5, уже весь мозг сломал

//#define USE_SPECIAL             //check for custom drivers
//#if defined(USE_SPECIAL)
//#include "mcufriend_special.h"
//#if !defined(USE_SPECIAL_FAIL)
//#warning WE ARE USING A SPECIAL CUSTOM DRIVER
//#endif
//#endif
//#if !defined(USE_SPECIAL) || defined (USE_SPECIAL_FAIL)

#if 0
#elif defined(__AVR_ATmega328P__)       //regular UNO shield on UNO
#define RD_PORT PORTC
#define RD_PIN  0
#define WR_PORT PORTC
#define WR_PIN  1
#define CD_PORT PORTC
#define CD_PIN  2
#define CS_PORT PORTC
#define CS_PIN  3
#define RESET_PORT PORTC
#define RESET_PIN  6

#define DMASK         0x03
#define NMASK         ~DMASK
#define write_8(x)    { PORTB = (PORTB & NMASK) | ((x) & DMASK); PORTD = (PORTD & DMASK) | ((x) & NMASK); }
#define read_8()      ( (PINB & DMASK) | (PIND & NMASK) )
#define setWriteDir() { DDRB = (DDRB & NMASK) | DMASK; DDRD = (DDRD & DMASK) | NMASK;  }
#define setReadDir()  { DDRB = (DDRB & NMASK) & NMASK; DDRD = (DDRD & DMASK) & DMASK;  }
#define write8(x)     { write_8(x); WR_STROBE; }
#define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst)   { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define PIN_LOW(p, b)        (p) &= ~(1<<(b))
#define PIN_HIGH(p, b)       (p) |= (1<<(b))
#define PIN_OUTPUT(p, b)     *(&p-1) |= (1<<(b))

#elif defined(__AVR_ATmega128__)       //ATmega128
#define RD_PORT PORTF
#define RD_PIN  0
#define WR_PORT PORTF
#define WR_PIN  1
#define CD_PORT PORTF
#define CD_PIN  2
#define CS_PORT PORTF
#define CS_PIN  3
#define RESET_PORT PORTF
#define RESET_PIN  4

#define EMASK         0x03 //B00000011
                      // ~DMASK //B11111100
#define BMASK         0x30 //B00110000       PB5,PB4,PE7,PE6,PE5,PE4,PE3,PE2
                      //~BMASK //B11001111
#define write_8(x)    { PORTB = (PORTB & ~BMASK) | ((x) & BMASK); PORTE = (PORTE & EMASK) | ((x) & ~EMASK); }
#define read_8()      ( (PINB & BMASK) | (PINE & ~EMASK) )
#define setWriteDir() { DDRB = (DDRB & ~BMASK) | BMASK; DDRE = (DDRE & EMASK) | ~EMASK;  }
#define setReadDir()  { DDRB = (DDRB & ~BMASK) & ~BMASK; DDRE = (DDRE & EMASK) & EMASK;  }
#define write8(x)     { write_8(x); WR_STROBE; }
#define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst)   { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define PIN_LOW(p, b)        (p) &= ~(1<<(b))
#define PIN_HIGH(p, b)       (p) |= (1<<(b))
#define PIN_OUTPUT(p, b)     *(&p-1) |= (1<<(b))

#elif defined(__AVR_ATmega2560__)       //regular UNO shield on MEGA2560
#define RD_PORT PORTF
#define RD_PIN  0
#define WR_PORT PORTF
#define WR_PIN  1
#define CD_PORT PORTF
#define CD_PIN  2
#define CS_PORT PORTF
#define CS_PIN  3
#define RESET_PORT PORTF
#define RESET_PIN  4

#define EMASK         0x38 // B00111000
#define GMASK         0x20 // B00100000
#define HMASK         0x78 // B01111000 // PH6,PH5,PH4,PH3,PE3,PG5,PE5,PE4
#define write_8(x)   {  PORTH &= ~HMASK; PORTG &= ~GMASK; PORTE &= ~EMASK; \
                        PORTH |= (((x) & (3<<0)) << 5); \
                        PORTE |= (((x) & (3<<2)) << 2); \
                        PORTG |= (((x) & (1<<4)) << 1); \
                        PORTE |= (((x) & (1<<5)) >> 2); \
                        PORTH |= (((x) & (3<<6)) >> 3); \
					 }

#define read_8()      ( ((PINH & (3<<5)) >> 5)\
                      | ((PINE & (3<<4)) >> 2)\
                      | ((PING & (1<<5)) >> 1)\
                      | ((PINE & (1<<3)) << 2)\
                      | ((PINH & (3<<3)) << 3)\
                      )
#define setWriteDir() { DDRH |=  HMASK; DDRG |=  GMASK; DDRE |=  EMASK;  }
#define setReadDir()  { DDRH &= ~HMASK; DDRG &= ~GMASK; DDRE &= ~EMASK;  }
#define write8(x)     { write_8(x); WR_STROBE; }
#define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst)   { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define PIN_LOW(p, b)        (p) &= ~(1<<(b))
#define PIN_HIGH(p, b)       (p) |= (1<<(b))
#define PIN_OUTPUT(p, b)     *(&p-1) |= (1<<(b))

#elif defined(__SAMD21G18A__)   //regular UNO shield on ZERO or M0_PRO
#include "sam.h"
 // configure macros for the control pins
#define RD_PORT PORT->Group[0]
#define RD_PIN  2
#define WR_PORT PORT->Group[1]
#define WR_PIN  8
#define CD_PORT PORT->Group[1]
#define CD_PIN  9
#define CS_PORT PORT->Group[0]
#define CS_PIN  4
#define RESET_PORT PORT->Group[0]
#define RESET_PIN  5
 // configure macros for data bus
#define DMASK 0x0030C3C0
 //  #define write_8(x) PORT->Group[0].OUT.reg = (PORT->Group[0].OUT.reg & ~DMASK)|(((x) & 0x0F) << 6)|(((x) & 0x30) << 10)|(((x) & 0xC0)<<14)
#if defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_ZERO)   // American ZERO
#define write_8(x) {\
	PORT->Group[0].OUTCLR.reg = DMASK;\
	PORT->Group[0].OUTSET.reg = (((x) & 0x0B) << 6)\
                               |(((x) & (1<<2)) << 12)\
	                           |(((x) & (1<<4)) << 4)\
	                           |(((x) & (1<<5)) << 10)\
	                           |(((x) & 0xC0) << 14);\
                   }
#define read_8()   (((PORT->Group[0].IN.reg >> 6) & 0x0B)\
                   |((PORT->Group[0].IN.reg >> 12) & (1<<2))\
                   |((PORT->Group[0].IN.reg >> 4) &  (1<<4))\
                   |((PORT->Group[0].IN.reg >> 10) & (1<<5))\
                   |((PORT->Group[0].IN.reg >> 14) & 0xC0))
#else   //default to an M0_PRO on v1.6.5 or 1.7.6
#define write_8(x) {\
	PORT->Group[0].OUTCLR.reg = DMASK;\
	PORT->Group[0].OUTSET.reg = (((x) & 0x0F) << 6)\
                               |(((x) & 0x30) << 10)\
                               |(((x) & 0xC0) << 14);\
                   }
#define read_8()   (((PORT->Group[0].IN.reg >> 6) & 0x0F)|((PORT->Group[0].IN.reg >> 10) & 0x30)|((PORT->Group[0].IN.reg >> 14) & 0xC0))
#endif
#define setWriteDir() { PORT->Group[0].DIRSET.reg = DMASK; \
	                  PORT->Group[0].WRCONFIG.reg = (DMASK & 0xFFFF) | (0<<22) | (1<<28) | (1<<30); \
	                  PORT->Group[0].WRCONFIG.reg = (DMASK>>16) | (0<<22) | (1<<28) | (1<<30) | (1<<31); \
                        }
#define setReadDir()  { PORT->Group[0].DIRCLR.reg = DMASK; \
	                  PORT->Group[0].WRCONFIG.reg = (DMASK & 0xFFFF) | (1<<17) | (1<<28) | (1<<30); \
	                  PORT->Group[0].WRCONFIG.reg = (DMASK>>16) | (1<<17) | (1<<28) | (1<<30) | (1<<31); \
                        }
#define write8(x)     { write_8(x); WR_STROBE; }
#define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst)   { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
 // Shield Control macros.
#define PIN_LOW(port, pin)    (port).OUTCLR.reg = (1<<(pin))
#define PIN_HIGH(port, pin)   (port).OUTSET.reg = (1<<(pin))
#define PIN_OUTPUT(port, pin) (port).DIR.reg |= (1<<(pin))

#elif defined(__SAM3X8E__)      //regular UNO shield on DUE
 // configure macros for the control pins
#define RD_PORT PIOA
#define RD_PIN  16
#define WR_PORT PIOA
#define WR_PIN  24
#define CD_PORT PIOA
#define CD_PIN  23
#define CS_PORT PIOA
#define CS_PIN  22
#define RESET_PORT PIOA
#define RESET_PIN  6
 // configure macros for data bus
#define BMASK         (1<<25)
#define CMASK         (0xBF << 21)
#define write_8(x)   {  PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; \
                        PIOC->PIO_SODR = (((x) & (1<<0)) << 22); \
                        PIOC->PIO_SODR = (((x) & (1<<1)) << 20); \
                        PIOB->PIO_SODR = (((x) & (1<<2)) << 23); \
                        PIOC->PIO_SODR = (((x) & (1<<3)) << 25); \
                        PIOC->PIO_SODR = (((x) & (1<<4)) << 22); \
                        PIOC->PIO_SODR = (((x) & (1<<5)) << 20); \
                        PIOC->PIO_SODR = (((x) & (1<<6)) << 18); \
                        PIOC->PIO_SODR = (((x) & (1<<7)) << 16); \
					 }

#define read_8()      ( ((PIOC->PIO_PDSR & (1<<22)) >> 22)\
                      | ((PIOC->PIO_PDSR & (1<<21)) >> 20)\
                      | ((PIOB->PIO_PDSR & (1<<25)) >> 23)\
                      | ((PIOC->PIO_PDSR & (1<<28)) >> 25)\
                      | ((PIOC->PIO_PDSR & (1<<26)) >> 22)\
                      | ((PIOC->PIO_PDSR & (1<<25)) >> 20)\
                      | ((PIOC->PIO_PDSR & (1<<24)) >> 18)\
                      | ((PIOC->PIO_PDSR & (1<<23)) >> 16)\
                      )
#define setWriteDir() { PIOB->PIO_OER = BMASK; PIOC->PIO_OER = CMASK; }
#define setReadDir()  { \
                          PMC->PMC_PCER0 = (1 << ID_PIOB)|(1 << ID_PIOC);\
						  PIOB->PIO_ODR = BMASK; PIOC->PIO_ODR = CMASK;\
						}
#define write8(x)     { write_8(x); WR_ACTIVE; WR_STROBE; WR_IDLE; }
#define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst)   { RD_STROBE; RD_ACTIVE; dst = read_8(); RD_IDLE; RD_IDLE; }
#define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
 // Shield Control macros.
#define PIN_LOW(port, pin)    (port)->PIO_CODR = (1<<(pin))
#define PIN_HIGH(port, pin)   (port)->PIO_SODR = (1<<(pin))
#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin))

#elif defined(__AVR_ATmega32U4__)       //regular UNO shield on Leonardo
#define RD_PORT PORTF
#define RD_PIN  7
#define WR_PORT PORTF
#define WR_PIN  6
#define CD_PORT PORTF
#define CD_PIN  5
#define CS_PORT PORTF
#define CS_PIN  4
#define RESET_PORT PORTF
#define RESET_PIN  1

#define BMASK         (3<<4)
#define CMASK         (1<<6)
#define DMASK         ((1<<7)|(1<<4)|(3<<0))
#define EMASK         (1<<6)
static inline                   //hope we use r24
void write_8(uint8_t x)
{
    PORTB &= ~BMASK;
    PORTC &= ~CMASK;
    PORTD &= ~DMASK;
    PORTE &= ~EMASK;
    PORTB |= (((x) & (3 << 0)) << 4);
    PORTD |= (((x) & (1 << 2)) >> 1);
    PORTD |= (((x) & (1 << 3)) >> 3);
    PORTD |= (((x) & (1 << 4)) << 0);
    PORTC |= (((x) & (1 << 5)) << 1);
    PORTD |= (((x) & (1 << 6)) << 1);
    PORTE |= (((x) & (1 << 7)) >> 1);
}

#define read_8()      ( ((PINB & (3<<4)) >> 4)\
| ((PIND & (1<<1)) << 1)\
| ((PIND & (1<<0)) << 3)\
| ((PIND & (1<<4)) >> 0)\
| ((PINC & (1<<6)) >> 1)\
| ((PIND & (1<<7)) >> 1)\
| ((PINE & (1<<6)) << 1)\
)
#define setWriteDir() { DDRB |=  BMASK; DDRC |=  CMASK; DDRD |=  DMASK; DDRE |=  EMASK;  }
#define setReadDir()  { DDRB &= ~BMASK; DDRC &= ~CMASK; DDRD &= ~DMASK; DDRE &= ~EMASK;  }
#define write8(x)     { write_8(x); WR_STROBE; }
#define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst)   { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define PIN_LOW(p, b)        (p) &= ~(1<<(b))
#define PIN_HIGH(p, b)       (p) |= (1<<(b))
#define PIN_OUTPUT(p, b)     *(&p-1) |= (1<<(b))

#else
#error MCU unsupported
#endif                          // regular UNO shields on Arduino boards

//#endif                          //!defined(USE_SPECIAL) || defined (USE_SPECIAL_FAIL)

#define RD_ACTIVE  PIN_LOW(RD_PORT, RD_PIN)
#define RD_IDLE    PIN_HIGH(RD_PORT, RD_PIN)
#define RD_OUTPUT  PIN_OUTPUT(RD_PORT, RD_PIN)
#define WR_ACTIVE  PIN_LOW(WR_PORT, WR_PIN)
#define WR_IDLE    PIN_HIGH(WR_PORT, WR_PIN)
#define WR_OUTPUT  PIN_OUTPUT(WR_PORT, WR_PIN)
#define CD_COMMAND PIN_LOW(CD_PORT, CD_PIN)
#define CD_DATA    PIN_HIGH(CD_PORT, CD_PIN)
#define CD_OUTPUT  PIN_OUTPUT(CD_PORT, CD_PIN)
#define CS_ACTIVE  PIN_LOW(CS_PORT, CS_PIN)
#define CS_IDLE    PIN_HIGH(CS_PORT, CS_PIN)
#define CS_OUTPUT  PIN_OUTPUT(CS_PORT, CS_PIN)
#define RESET_ACTIVE  PIN_LOW(RESET_PORT, RESET_PIN)
#define RESET_IDLE    PIN_HIGH(RESET_PORT, RESET_PIN)
#define RESET_OUTPUT  PIN_OUTPUT(RESET_PORT, RESET_PIN)

 // General macros.   IOCLR registers are 1 cycle when optimised.
#define WR_STROBE { WR_ACTIVE; WR_IDLE; }       //PWLW=TWRL=50ns
#define RD_STROBE RD_IDLE, RD_ACTIVE, RD_ACTIVE, RD_ACTIVE      //PWLR=TRDL=150ns, tDDR=100ns

#define CTL_INIT()   { RD_OUTPUT; WR_OUTPUT; CD_OUTPUT; CS_OUTPUT; RESET_OUTPUT; }
#define WriteCmd(x)  { CD_COMMAND; write16(x); }
#define WriteData(x) { CD_DATA; write16(x); }

подскажите как правильно раставить биты чтоб получилось PB5,PB4,PE7,PE6,PE5,PE4,PE3,PE2 

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

забыл что 1 пост нельзя редактировоать

128 c 38 строки, делал по аналогии как на 328 - PB1,PB0,PE7,PE6,PE5,PE4,PE3,PE2 все работает

подскажите как правильно раставить биты чтоб управлять портами PB5,PB4,PE7,PE6,PE5,PE4,PE3,PE2

не выходит аленький цветочек

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Ну из того, что бросается в глаза 50 строчка должна быть такой : #define EMASK 0xFC //B11111100

 

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

не работает:(

с BMASK = 0x03 порты PB0 PB1 все работает но их надо освободить 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Valera19701, дайте ссылку на оригинальный файл.

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015
dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Valera19701,  как я понял рабочий бит порта  в маске - ноль, а единицами прикрывают остальные биты.   Тогда 50 строка пусть как было (0x03), а 52 строка значит получается  0xCF //B11001111

И непонятно зачем вы сделали выборочно инверсию BMASK из 56-57  строках, в примере для 328 меги, по аналогии которой говорите делали -никаких инверсий маски нет, не считая "юмора" автора в 24 строке, наверное ему проще было нарисовать знак инверсии, хотя логичнее было бы написать 0xFC .

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

dimax пишет:

Valera19701,  как я понял рабочий бит порта  в маске - ноль, а единицами прикрывают остальные биты.   Тогда 50 строка пусть как было (0x03), а 52 строка значит получается  0xCF //B11001111

И непонятно зачем вы сделали выборочно инверсию BMASK из 56-57  строках, в примере для 328 меги, по аналогии которой говорите делали -никаких инверсий маски нет, не считая "юмора" автора в 24 строке, наверное ему проще было нарисовать знак инверсии, хотя логичнее было бы написать 0xFC .

я за два дня что только не пробовал, и BMASK = 0xFC тоже, не работает

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Должно заработать при правильных 55-57 строках. Сейчас там полная путаница.

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

dimax пишет:

Должно заработать при правильных 55-57 строках. Сейчас там полная путаница.

сделал чтобы не путаться

#define EMASK         0x03//B00000011
                      // ~EMASK //B11111100
#define BMASK         0xCF // B11001111      PB5,PB4,PE7,PE6,PE5,PE4,PE3,PE2
                      //~BMASK // B00110000
#define write_8(x)    { PORTB = (PORTB & BMASK) | ((x) & ~BMASK); PORTE = (PORTE & EMASK) | ((x) & ~EMASK); }
#define read_8()      ( (PINB & ~BMASK) | (PINE & ~EMASK) )
#define setWriteDir() { DDRB = (DDRB & BMASK) | ~BMASK; DDRE = (DDRE & EMASK) | ~EMASK;  }
#define setReadDir()  { DDRB = (DDRB & BMASK) & BMASK; DDRE = (DDRE & EMASK) & EMASK;  }

не работает :(

 

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

например строка #define read_8()      ( (PINB & ~BMASK) | (PINE & ~EMASK) ) при слиянии

получается накладка  PORTE - B11111100

                                     PORTB - B00110000

я уже пробовал сдвигать вправо на4, тоже не работает

#define read_8()      ( (PINB & ~BMASK)>>4 | (PINE & ~EMASK) )

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Это ж копия того, что было. У вас все дефайны с ошибками.  Делайте по примеру 328

#define write_8(x){ PORTB = (PORTB & BMASK) | ((x) & EMASK);
PORTD = (PORTE & EMASK) | ((x) & BMASK); }

и так далее..

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

так?

#define EMASK         0x03//B00000011
                      // ~EMASK //B11111100
#define BMASK         0xCF // B11001111      PB5,PB4,PE7,PE6,PE5,PE4,PE3,PE2
                      //~BMASK // B00110000
#define write_8(x)    { PORTB = (PORTB & BMASK) | ((x) & EMASK); PORTE = (PORTE & EMASK) | ((x) & BMASK); }
#define read_8()      ( (PINB & ~BMASK) | (PINE & ~EMASK) )
#define setWriteDir() { DDRB = (DDRB & BMASK) | EMASK; DDRE = (DDRE & EMASK) | BMASK;  }
#define setReadDir()  { DDRB = (DDRB & BMASK) & BMASK; DDRE = (DDRE & EMASK) & EMASK;  }

утро вечера мудренее. спать пора:)

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Valera19701, да, я это имел ввиду. Но к сожалению так тоже не заработает, я только сейчас, на свежую голову понял всю сложность задачи. Нельзя просто так взять другие биты, нужно привести их вес к тому, который должен быть. В общем  есть три варианта решения. Первый -самый простой. Выделить отдельный полный порт. Тогда макросы упростятся до вида: #define read_8() (PINB) #define write_8(x) (PORTB=x) и.т.п Второй способ -чуть сложнее, собссно это способ как для меги328.  Биты могут быть из разных портов, но должны не пересекаться, к примеру если берём 5 и 4 бит из порта Б, то в порту Е мы берём 7,6,3,2,1,0. Тогда должны работать способы как в #12, и третий способ, - биты в разнобой ( как ваш текущий вариант). Придётся дополнительно передвигать взад-вперёд, это будет жуткий пинг-понг, аналогично например строкам 230-250.

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

да, придется делать 3 вариант,  уже пытаюсь понять как, строка 81 и чувствую как мозг закипает :)