Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
/** lmd.c** Created on: 30/11/2013* Author: pfowler*/#include <avr/io.h>#include <stdlib.h>#include <avr/pgmspace.h>#include <util/delay.h>#include <math.h>#include "avrutil.h"#include "lmd.h"#define LMD_NOOP 0x00#define LMD_DIGIT0 0x01#define LMD_DIGIT1 0x02#define LMD_DIGIT2 0x03#define LMD_DIGIT3 0x04#define LMD_DIGIT4 0x05#define LMD_DIGIT5 0x06#define LMD_DIGIT6 0x07#define LMD_DIGIT7 0x08#define LMD_DECODE_MODE 0x09#define LMD_INTENSITY 0x0a#define LMD_SCAN_LIMIT 0x0b#define LMD_SHUTDOWN 0x0c#define LMD_DISPLAY_TEST 0x0fvoid lmd_intensity(uint8_t max, uint8_t i) {lmd_writeReg(max, LMD_INTENSITY, i);}void lmd_scanlimit(uint8_t max, uint8_t l) {lmd_writeReg(max, LMD_SCAN_LIMIT, l);}void lmd_shutdown(uint8_t max, uint8_t s) {lmd_writeReg(max, LMD_SHUTDOWN, s);}void lmd_decodemode(uint8_t max, uint8_t d) {lmd_writeReg(max, LMD_DECODE_MODE, d);}void lmd_init(uint8_t pinx_addr,uint8_t clk_pin, uint8_t load_pin, uint8_t data_pin,uint8_t numMax) {lmd.pin = pinx_addr;lmd.ddr = pinx_addr + 1;lmd.port = pinx_addr + 2;lmd.clk = clk_pin;lmd.load = load_pin;lmd.data = data_pin;lmd.numMax = numMax;lmd.dps = malloc(lmd.numMax * sizeof(uint8_t));sbi(lmd.ddr, lmd.clk);sbi(lmd.ddr, lmd.load);sbi(lmd.ddr, lmd.data);_delay_us(100);// Defaultslmd_writeRegAll(LMD_INTENSITY, 0x01); // Lowest intensitylmd_writeRegAll(LMD_SCAN_LIMIT, 0x07); // Use all ledslmd_writeRegAll(LMD_SHUTDOWN, 0x01); // Shutdownlmd_writeRegAll(LMD_DECODE_MODE, 0x00); // No decoding_delay_us(100);lmd_clearAll();}void lmd_clearAll(void) {uint8_t c;for (c=1; c<=8; c++) {lmd_writeRegAll(c, 0x00);}}void lmd_dp(uint8_t max, uint8_t digit) {lmd.dps[max] = digit;}void lmd_print_u32(uint8_t max, uint32_t value) {const uint8_t DIGIT_COUNT = 8;uint8_t i;for (i=1; i<=DIGIT_COUNT; i++) {uint32_t power = (uint32_t)pow(10, i);if (i != 1) power++;uint8_t val = ((value % power) / (power/10)) ;if (rbi(lmd.dps[max], i-1))lmd_writeReg(max, i, val | 0xf0 );elselmd_writeReg(max, i, val);}}void lmd_print_u16(uint8_t max, uint16_t value) {const uint8_t DIGIT_COUNT = 5;uint8_t i;for (i=1; i<=DIGIT_COUNT; i++) {uint32_t power = (uint32_t)pow(10, i);if (i != 1) power++;uint8_t val = ((value % power) / (power/10)) ;if (rbi(lmd.dps[max], i-1))lmd_writeReg(max, i, val | 0xf0 );elselmd_writeReg(max, i, val);}}void lmd_print_u8(uint8_t max, uint8_t value) {const uint8_t DIGIT_COUNT = 3;uint8_t i;for (i=1; i<=DIGIT_COUNT; i++) {uint32_t power = (uint32_t)pow(10, i);if (i != 1) power++;uint8_t val = ((value % power) / (power/10)) ;if (rbi(lmd.dps[max], i-1))lmd_writeReg(max, i, val | 0xf0 );elselmd_writeReg(max, i, val);}}void lmd_writeReg(uint8_t max, uint8_t reg, uint8_t val) {uint8_t c;cbi(_SFR_IO8(lmd.port), lmd.load);for (c=lmd.numMax; c< max; c--) {lmd_writeByte(0x00);lmd_writeByte(0x00);}lmd_writeByte(reg);lmd_writeByte(val);for (c=max-1; c<= 1; c--) {lmd_writeByte(0x00);lmd_writeByte(0x00);}sbi(_SFR_IO8(lmd.port), lmd.load);}void lmd_writeRegAll(uint8_t reg, uint8_t val) {uint8_t c;cbi(_SFR_IO8(lmd.port), lmd.load);for (c=1; c<=lmd.numMax; c++) {lmd_writeByte(reg);lmd_writeByte(val);}sbi(_SFR_IO8(lmd.port), lmd.load);}void lmd_writeByte(uint8_t dataout) {uint8_t mask;uint8_t i = 8;for (i=8; i>0; i--) {mask = 0x01 << (i - 1);cbi(_SFR_IO8(lmd.port), lmd.clk);if (dataout & mask) // Send 1 bit at a timesbi(_SFR_IO8(lmd.port), lmd.data);elsecbi(_SFR_IO8(lmd.port), lmd.data);sbi(_SFR_IO8(lmd.port), lmd.clk);}}void lmd_test(void) {lmd_writeRegAll(LMD_DECODE_MODE,0x00);lmd_writeRegAll(8,0b01001110);lmd_writeRegAll(7,0b01111110);lmd_writeRegAll(6,0b01111110);lmd_writeRegAll(5,0b00001110);lmd_writeRegAll(4,0b01110111);lmd_writeRegAll(3,0b01011011);lmd_writeRegAll(2,0b01011011);lmd_writeRegAll(1,0x80);}