123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- /*
- * hd44780_i2c_lcd.c
- *
- * Copyright 2022 dh33ex <dh33ex@riseup.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA or see <http://www.gnu.org/licenses/>.
- *
- *
- */
- #ifndef __msp430_h_
- #include <msp430.h>
- #endif
- #include "hd44780_i2c_lcd.h"
- /*
- * P0 - RS
- * P1 - R/W
- * P2 - E
- * P3 - LIGHT
- * P4 - DB4
- * P5 - DB5
- * P6 - DB6
- * P7 - DB7
- */
- #define PCF8574_RS 0x01
- #define PCF8574_RW 0x02
- #define PCF8574_E 0x04
- #define PCF8574_LIGHT 0x08
- #define PCF8574_DB4 0x10
- #define PCF8574_DB5 0x20
- #define PCF8574_DB6 0x40
- #define PCF8574_DB7 0x80
- #define HD44780_CLEARDISPLAY 0x01
- #define HD44780_RETURNHOME 0x02
- #define HD44780_ENTRYMODESET 0x04
- #define HD44780_ID 0x02
- #define HD44780_S 0x01
- #define HD44780_DISPLAYCONTROL 0x08
- #define HD44780_D 0x04
- #define HD44780_C 0x02
- #define HD44780_B 0x01
- #define HD44780_SHIFTSETUP 0x10
- #define HD44780_SC 0x08
- #define HD44780_RL 0x04
- #define HD44780_FUNCTIONSET 0x20
- #define HD44780_F 0x04
- #define HD44780_N 0x08
- #define HD44780_DL 0x10
- #define HD44780_DDRAM_ADDRESS 0x80
- #define HD44780_CGRAM_ADDRESS 0x40
- #define HD44780_DATA 1
- #define HD44780_INSTRUCTION 0
- char i2c_buffer;
- void PCF8574_send(unsigned char byte);
- void HD44780_send(HD44780 *disp, unsigned char type, unsigned char data);
- void PCF8574_send(unsigned char byte) {
- while (UCB0STAT & UCBUSY); /* wait until I2C is free */
- i2c_buffer = byte;
- IFG2 &= ~UCB0TXIFG; /* clear transmit interrupt flag */
- UCB0CTL1 |= UCTXSTT; /* send start message manually */
- UCB0TXBUF = i2c_buffer; /* load TX buffer */
- while (!(IFG2 & UCB0TXIFG));
- UCB0CTL1 |= UCTXSTP; /* send stop message manually */
- while (UCB0CTL1 & UCTXSTP); /* wait until stop message sent */
- __delay_cycles(1500);
- }
- void HD44780_send(HD44780 *disp, unsigned char type, unsigned char data) {
- PCF8574_send((data & 0xF0) | (type ? PCF8574_RS : 0) | PCF8574_E);
- PCF8574_send((data & 0xF0) | (type ? PCF8574_RS : 0));
- PCF8574_send((data << 4) | (type ? PCF8574_RS : 0) | PCF8574_E);
- PCF8574_send((data << 4) | (type ? PCF8574_RS : 0) | PCF8574_LIGHT * disp->light);
- }
- void LCD_init(HD44780 *disp) {
- /* setup B0 for I2C */
- UCB0CTL1 |= UCSWRST; /* put B0 in SW RST */
- UCB0CTL1 |= UCSSEL_2; /* choose SMCLK */
- UCB0BR0 = 10; /* set presalar to 10 */
- UCB0BR1 = 0;
- UCB0CTL0 |= UCMODE_3; /* put into I2C mode */
- UCB0CTL0 |= UCMST; /* set as master */
- UCB0I2CSA = disp->address; /* set slave address */
- /* setup ports */
- P1SEL |= BIT7; /* P1.7 = SDA */
- P1SEL2 |= BIT7;
- P1SEL |= BIT6; /* P1.6 = SCL */
- P1SEL2 |= BIT6;
- UCB0CTL1 |= UCTR; /* set transmit mode */
- UCB0CTL1 &= ~UCSWRST; /* take B0 out of SW RST */
- /* init display */
- __delay_cycles(40000); /* delay 40 ms */
- PCF8574_send(PCF8574_DB5 | PCF8574_DB4 | PCF8574_E);
- PCF8574_send(PCF8574_DB5 | PCF8574_DB4);
- __delay_cycles(4100); /* delay 4.1 ms */
- PCF8574_send(PCF8574_DB5 | PCF8574_DB4 | PCF8574_E);
- PCF8574_send(PCF8574_DB5 | PCF8574_DB4);
- __delay_cycles(1000); /* delay 1 us */
- PCF8574_send(PCF8574_DB5 | PCF8574_DB4 | PCF8574_E);
- PCF8574_send(PCF8574_DB5 | PCF8574_DB4);
- PCF8574_send(PCF8574_DB5 | PCF8574_E);
- PCF8574_send(PCF8574_DB5);
- HD44780_send(disp, HD44780_INSTRUCTION, HD44780_FUNCTIONSET | (disp->rows == 1 ? 0 : HD44780_N));
- HD44780_send(disp, HD44780_INSTRUCTION, HD44780_DISPLAYCONTROL | HD44780_D | (disp->cursor == HD44780_NO_CURSOR ? 0 : (disp->cursor == HD44780_BLINK_CURSOR ? HD44780_B : HD44780_C)));
- HD44780_send(disp, HD44780_INSTRUCTION, HD44780_CLEARDISPLAY);
- HD44780_send(disp, HD44780_INSTRUCTION, HD44780_ENTRYMODESET | HD44780_ID);
- }
- void LCD_clear(HD44780 *disp) {
- HD44780_send(disp, HD44780_INSTRUCTION, HD44780_CLEARDISPLAY);
- }
- void LCD_backlight(HD44780 *disp, unsigned char state) {
- disp->light = state;
- PCF8574_send(PCF8574_LIGHT*disp->light);
- }
- void LCD_write(HD44780 *disp, char *string) {
- PCF8574_send(0x0);
- while (*string != '\0') {
- HD44780_send(disp, HD44780_DATA, *(string++));
- }
- __delay_cycles(10);
- PCF8574_send(disp->light * PCF8574_LIGHT);
- }
- void LCD_set_address(HD44780 *disp, unsigned char x, unsigned char y) {
- unsigned char x_start[] = {0x00, 0x40, disp->columns, 0x40+disp->columns};
- HD44780_send(disp, HD44780_INSTRUCTION, HD44780_DDRAM_ADDRESS | (x_start[y] + x));
- }
- #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
- #pragma vector = USCIAB0TX_VECTOR
- __interrupt void USCIAB0TX_I2C_ISR(void) {
- #elif defined(__GNUC__)
- void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_I2C_ISR (void) {
- #else
- #error Compiler not supported!
- #endif
- UCB0TXBUF = i2c_buffer; /* load TX buffer */
- while (!(IFG2 & UCB0TXIFG));
- IE2 &= ~UCB0TXIE; /* disable interrupts */
- IFG2 &= ~UCB0TXIFG; /* clear USCI_B0 TX int flag */
- __bic_SR_register_on_exit(LPM0_bits); /* exit LPM0 */
- }
|