Skip to content

Instantly share code, notes, and snippets.

@46bit
Created February 8, 2014 21:41
Show Gist options
  • Save 46bit/8890761 to your computer and use it in GitHub Desktop.
Save 46bit/8890761 to your computer and use it in GitHub Desktop.
Library to make using LPC17xx easier. Not freely licensed, may not be mine to give away. Here for https://gist.github.com/46bit/8890681
#include "lpc17xx_i2c.h"
#include "lpc17xx_pinsel.h"
#include "lpc17xx_uart.h"
#include "lpc17xx_gpio.h"
#include "lpc17xx_nvic.h"
#include "lpc17xx_gpdma.h"
#include "lpc17xx_adc.h"
#include "lpc17xx_dac.h"
#include <math.h>
#include <string.h>
#define I2CDEV_M LPC_I2C1
#define I2CDEV_S_ADDR 0x21
#define BUFFER_SIZE 0x40
#define ASCII_OFFSET 0x80
#define MCB_LPC_1768
//#define IAR_LPC_1768
#ifdef MCB_LPC_1768
#define _ADC_INT ADC_ADINTEN2
#define _ADC_CHANNEL ADC_CHANNEL_2
#elif defined(IAR_LPC_1768)
#define _ADC_INT ADC_ADINTEN5
#define _ADC_CHANNEL ADC_CHANNEL_5
#endif
#define DMA_SIZE 1
const char ch[4][4] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
const unsigned long led_mask[] = { 1<<18, 1<<20, 1<<21, 1<<23 };
int led_init_run = 0;
int led_value = 0;
void tty_init(void);
void led_init(void);
void i2c_init(void);
void led_init(void) {
led_init_run = 1;
int l;
for (l = 0; l < 4; l++) {
GPIO_SetDir(1, led_mask[l], 1);
GPIO_ClearValue(1, led_mask[l]);
}
}
void led_write_binary(int n) {
if (led_init_run == 0) return;
int k = 0;
for(k = 0; k < 4; k++) {
GPIO_ClearValue(1, led_mask[k]);
if ((n & ( 1 << k)) >> k == 1) {
GPIO_SetValue(1, led_mask[k]);
}
}
}
void tty_init(void) {
UART_CFG_Type UARTConfigStruct;
UART_FIFO_CFG_Type UARTFIFOConfigStruct;
PINSEL_CFG_Type PinCfg;
PinCfg.Funcnum = 1;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 0;
PinCfg.Portnum = 0;
PinCfg.Pinnum = 2;
PINSEL_ConfigPin(&PinCfg);
PinCfg.Pinnum = 3;
PINSEL_ConfigPin(&PinCfg);
UART_ConfigStructInit(&UARTConfigStruct);
UART_FIFOConfigStructInit(&UARTFIFOConfigStruct);
UART_Init((LPC_UART_TypeDef *)LPC_UART0, &UARTConfigStruct);
UART_FIFOConfig((LPC_UART_TypeDef *)LPC_UART0, &UARTFIFOConfigStruct);
UART_TxCmd((LPC_UART_TypeDef *)LPC_UART0, ENABLE);
}
void i2c_init(void) {
PINSEL_CFG_Type PinCfg;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 0;
PinCfg.Funcnum = 3;
PinCfg.Pinnum = 0;
PinCfg.Portnum = 0;
PINSEL_ConfigPin(&PinCfg);
PinCfg.Pinnum = 1;
PINSEL_ConfigPin(&PinCfg);
I2C_Init(I2CDEV_M, 100000);
I2C_Cmd(I2CDEV_M, ENABLE);
}
int lcd_init(void) {
i2c_init();
uint8_t buf[12];
buf[0] = 0x00; // Control byte for Instruction
buf[1] = 0x34; // DL: 8 bits, M: 16 by two line display, SL: 1:18, H: normal instruction set
buf[2] = 0x0E; // D: Display on, C: curser off, B: blink off
buf[3] = 0x06; // I/D: increment, S: no shift
buf[4] = 0x35; // DL: 8 bits, M: 16 by two line, SL: 1:18, H: extended instruction set
buf[5] = 0x04; // P: left to right, Q: top to bottom
buf[6] = 0x10; // TC1: 0, TC2: 0
buf[7] = 0x42; // HV Stages 3
buf[8] = 0x9f; // set Vlcd, store to VA
buf[9] = 0x34; // DL: 8 bits, M: two line, SL: 1:18, H: normal instruction set
buf[10] = 0x80; // DDRAM Address set to 00hex
buf[11] = 0x02; // return home
I2C_M_SETUP_Type transferMCfg;
transferMCfg.tx_data = buf;
transferMCfg.tx_length = sizeof(buf);
transferMCfg.rx_data = NULL;
transferMCfg.rx_length = 0;
transferMCfg.retransmissions_max = 3;
transferMCfg.sl_addr7bit = 0x3b;
int success = I2C_MasterTransferData(I2CDEV_M, &transferMCfg, I2C_TRANSFER_POLLING);
return success;
}
int write_usb_serial_blocking(char *buf,int length){
return(UART_Send((LPC_UART_TypeDef *)LPC_UART0,(uint8_t *)buf,length, BLOCKING));
}
void tty_write(char *buf){
led_write_binary(++led_value);
int length = 0;
uint8_t chr = buf[0];
while(chr != '\0'){
length++;
chr = buf[length];
}
write_usb_serial_blocking(buf, length);
}
void tty_writeln(char *buf){
tty_write(buf);
write_usb_serial_blocking("\n\r", 2);
}
void tty_write_binary(uint32_t n) {
int k = 0;
char chars[13];
chars[0] = '0';
chars[1] = 'b';
chars[12] = 0;
for(k = 0; k < 32; k++) {
if ((n & ( 1 << k)) >> k == 1) {
chars[11-k] = '1';
} else {
chars[11-k] = '0';
}
}
tty_writeln(chars);
}
void tty_write_int(int n) {
char chars[30];
int i;
for (i = 0; i < 29; i++) {
chars[i] = ' ';
}
chars[29] = 0;
i = 0;
while (n > 0 || i == 0) {
i++;
chars[29 - i] = (n % 10) + '0';
n = n / 10;
}
tty_writeln(chars);
}
// @TODO: Only supports floats from 0 to 1.
void tty_write_float (float percent) {
char digits[17];
int digiti;
for (digiti = 0; digiti < 16; digiti++) {
digits[digiti] = '0';
}
digits[16] = 0;
int k = 2;
if (percent > 1) {
for (digiti = 0; digiti < 16; digiti++) {
digits[digiti] = '?';
}
} else if (percent == 1) {
digits[0] = '1';
digits[1] = '.';
} else {
digits[0] = '0';
digits[1] = '.';
float t = percent;
while (t > 0 && k <= 13) {
t = t * 10;
int ti = (int) t;
t -= ti;
digits[k] = ti + '0';
k++;
}
}
tty_writeln(digits);
}
char ascii_to_lcd(char ch)
{
// c = 0xA0; // default: white space (nbsp)
char c;
if(ch < 30 || ch > 127){
c = 0xA0;
}
else{
c = ASCII_OFFSET + ch;
}
return c;
}
int read_keyboard_once(int mask_code) {
uint8_t write_buffer[1], read_buffer[1];
write_buffer[0] = mask_code;
I2C_M_SETUP_Type transferMCfg;
transferMCfg.tx_data = write_buffer;
transferMCfg.tx_length = sizeof(write_buffer);
transferMCfg.rx_data = read_buffer;
transferMCfg.rx_length = sizeof(read_buffer);
transferMCfg.retransmissions_max = 3;
transferMCfg.sl_addr7bit = 0x21;
int success;
success = I2C_MasterTransferData(I2CDEV_M, &transferMCfg, I2C_TRANSFER_POLLING);
if (success == 1) {
return read_buffer[0];
} else {
return -1;
}
}
char read_keyboard(void){
int keymasks[4];
keymasks[0] = read_keyboard_once(0b01111111);
keymasks[1] = read_keyboard_once(0b10111111);
keymasks[2] = read_keyboard_once(0b11011111);
keymasks[3] = read_keyboard_once(0b11101111);
int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
if ((keymasks[i] & 1<<j) >> j == 0) {
return ch[3 - j][i];
}
}
}
return ' ';
}
int lcd_raw_read (uint8_t *lcd_write_buffer, int lcd_write_buffer_size, uint8_t *lcd_read_buffer, int lcd_read_buffer_size) {
I2C_M_SETUP_Type transferMCfg;
transferMCfg.tx_data = lcd_write_buffer;
transferMCfg.tx_length = lcd_write_buffer_size;
transferMCfg.rx_data = lcd_read_buffer;
transferMCfg.rx_length = lcd_read_buffer_size;
transferMCfg.retransmissions_max = 3;
transferMCfg.sl_addr7bit =0x3b;
int success;
success = I2C_MasterTransferData(I2CDEV_M, &transferMCfg, I2C_TRANSFER_POLLING);
return (success == 1);
}
int lcd_raw_write(uint8_t *lcd_buffer, int lcd_buffer_size){
if (!lcd_init()) {
led_write_binary(8);
return 0;
}
I2C_M_SETUP_Type transferMCfg;
transferMCfg.tx_data = lcd_buffer;
transferMCfg.tx_length = lcd_buffer_size;
transferMCfg.rx_data = NULL;
transferMCfg.rx_length = 0;
transferMCfg.retransmissions_max = 3;
transferMCfg.sl_addr7bit = 0x3b;
int success;
success = I2C_MasterTransferData(I2CDEV_M, &transferMCfg, I2C_TRANSFER_POLLING);
return (success == 1);
}
int lcd_busy(void) {
uint8_t busy_lcd_write_buffer[2], busy_lcd_read_buffer[2];
busy_lcd_write_buffer[0] = 0;
lcd_raw_read(&busy_lcd_write_buffer[0], sizeof(busy_lcd_write_buffer), &busy_lcd_read_buffer[0], sizeof(busy_lcd_read_buffer));
return busy_lcd_read_buffer[0] >> 7;
}
void lcd_clear(void) {
uint8_t clear_lcd_buffer[2];
clear_lcd_buffer[0] = 0;
clear_lcd_buffer[1] = 1;
lcd_raw_write(&clear_lcd_buffer[0], sizeof(clear_lcd_buffer));
while (lcd_busy()) {}
}
void lcd_blank(uint8_t *chars) {
int i;
for (i = 0; i < 32; i++) {
chars[i] = ' ';
}
}
void lcd_write(uint8_t *chars) {
uint8_t buf[57];
buf[0] = 0x40;
// Loop over buffer. Put provided 32-element chars in correct
// memory addresses (there are 24 bytes of memory between the rows).
int i, v;
for (i = 0; i < 56; i++) {
if (i < 16) {
v = chars[i];
} else if (i >= 40) {
v = chars[i - 24];
} else {
v = ' ';
}
buf[i + 1] = ASCII_OFFSET + v;
}
lcd_raw_write(buf, sizeof(buf));
}
void lcd_goto(int row, int column) {
uint8_t buf[2];
buf[0] = 0x00;
buf[1] = 0x80 + (row * 0x40) + column;
lcd_raw_write(buf, sizeof(buf));
}
void a2d_init() {
PINSEL_CFG_Type PinCfg;
/* Because the potentiometer on different boards (MCB & IAR) connect
* with different ADC channel, so we have to configure correct ADC channel
* o while(adc_value==0);n each board respectively.
* If you want to check other ADC channels, you have to wire this ADC pin directly
* to potentiometer pin (please see schematic doc for more reference)
*/
#ifdef MCB_LPC_1768
/* If using MCB1700 v.1 board
* select P0.25 as AD0.2
*/
PinCfg.Funcnum = 1;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 0;
PinCfg.Pinnum = 25;
PinCfg.Portnum = 0;
PINSEL_ConfigPin(&PinCfg);
#elif defined(IAR_LPC_1768)
/* If using IAR LPC1768 KS v.A board:
* select P1.31 as AD0.5
*/
PinCfg.Funcnum = 3;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 0;
PinCfg.Pinnum = 31;
PinCfg.Portnum = 1;char digits[15];
int digiti;
for (digiti = 0; digiti < 14; digiti++) {
digits[digiti] = '0';
}
digits[14] = 0;
int k = 2;
if (percent >= 1) {
digits[0] = '1';
} else {
digits[0] = '0';
digits[1] = '.';
float t = percent;
while (t > 0 && k <= 13) {
t = t * 10;
int ti = (int) t;
t -= ti;
digits[k] = ti + '0';
k++;
}
}
tty_writeln(digits);
PINSEL_ConfigPin(&PinCfg);
#endif
}
int get_int_bit(int v, int n) {
return (v & 1<<n) >> n;
}
void d2a_init() {
PINSEL_CFG_Type PinCfg;
PinCfg.Funcnum = 2;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 0;
PinCfg.Pinnum = 26;
PinCfg.Portnum = 0;
PINSEL_ConfigPin(&PinCfg);
}
float sucapp_to_percent(uint32_t sucapp) {
int b;
float percent = 0;
float m = 0.5;
for (b = 11; b >= 0; b--) {
int bit = get_int_bit(sucapp, b);
if (bit == 1) {
percent += m;
}
if (percent < 0) percent = 0;
m = m / 2.0;
}
return percent;
}
uint32_t percent_to_sucapp(double percent) {
uint32_t sucapp = 0;
double m = 0.5;
int i;
if (percent >= 1) {
percent = 0.99;
}
for (i = 7; i >= 0; i--) {
if (percent >= m) {
sucapp += 1<<i;
percent -= m;
}
m = m / 2.0;
}
return sucapp;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment