document the LED1642GW and ledcontroller modules
This commit is contained in:
		
							
								
								
									
										77
									
								
								led1642gw.c
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								led1642gw.c
									
									
									
									
									
								
							@@ -13,15 +13,29 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include "led1642gw.h"
 | 
					#include "led1642gw.h"
 | 
				
			||||||
#include <util/delay.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "led1642gw_config.h"
 | 
					#include "led1642gw_config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NUM_LED1642GW_CHANNELS (16)
 | 
					#define NUM_LED1642GW_CHANNELS (16) // number of LED channels per IC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//total numer of channels. needed to calculate the buffer size.
 | 
				
			||||||
#define NUM_LED_CHANNELS (NUM_LED1642GW_CHANNELS*NUM_LED1642GW_ICs)
 | 
					#define NUM_LED_CHANNELS (NUM_LED1642GW_CHANNELS*NUM_LED1642GW_ICs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* The buffer to hold the LED values.
 | 
				
			||||||
 | 
					 * The data in this buffer can be manipulated with
 | 
				
			||||||
 | 
					 * e.g. led1642gw_set().
 | 
				
			||||||
 | 
					 * calling led1642gw_flush() sends the data in this buffer
 | 
				
			||||||
 | 
					 * the data registers of the LED1642 ICs.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
static uint16_t ledbuffer[NUM_LED_CHANNELS];
 | 
					static uint16_t ledbuffer[NUM_LED_CHANNELS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Write 16 bits of \data, with LE set high
 | 
				
			||||||
 | 
					 * for the number of clock cycles specified in \le_clocks.
 | 
				
			||||||
 | 
					 * MSB comes first, LSB is last.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
static void write_data(uint16_t data, uint8_t le_clocks)
 | 
					static void write_data(uint16_t data, uint8_t le_clocks)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  uint16_t mask = 0x8000;
 | 
					  uint16_t mask = 0x8000;
 | 
				
			||||||
@@ -43,7 +57,8 @@ static void write_data(uint16_t data, uint8_t le_clocks)
 | 
				
			|||||||
	SET_CLK_H();
 | 
						SET_CLK_H();
 | 
				
			||||||
    mask >>= 1;
 | 
					    mask >>= 1;
 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // set all pins to low after transmission
 | 
				
			||||||
  SET_CLK_L();
 | 
					  SET_CLK_L();
 | 
				
			||||||
  SET_LE_L();
 | 
					  SET_LE_L();
 | 
				
			||||||
  SET_SDI_L();
 | 
					  SET_SDI_L();
 | 
				
			||||||
@@ -51,46 +66,67 @@ static void write_data(uint16_t data, uint8_t le_clocks)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Write data to BRIGHTNESS DATA LATCH register.
 | 
				
			||||||
 | 
					 * that means setting LE high for 3 or 4 clock cycles
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
static void write_data_latch(uint16_t data)
 | 
					static void write_data_latch(uint16_t data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  write_data(data, 4);
 | 
					  write_data(data, 4);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Write data to BRIGHTNESS GLOBAL LATCH register.
 | 
				
			||||||
 | 
					 * that means setting LE high for 5 or 6 clock cycles
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
static void write_global_latch(uint16_t data)
 | 
					static void write_global_latch(uint16_t data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  write_data(data, 6);
 | 
					  write_data(data, 6);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This function shifts data through the 16bit shift
 | 
				
			||||||
 | 
					 * register of the LED1642GW, without writing the data
 | 
				
			||||||
 | 
					 * to any internal register of the IC.
 | 
				
			||||||
 | 
					 * This way, we can daisy chain an bunch of LED1642GW ICs,
 | 
				
			||||||
 | 
					 * and still get data through to any of those.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
static void write_no_command(uint16_t data)
 | 
					static void write_no_command(uint16_t data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  write_data(data, 0);
 | 
					  write_data(data, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Turn all channels on, so the data in the DATA LATCH 
 | 
				
			||||||
 | 
					 * register affects the LEDs attached to the IC.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void led1642gw_turn_all_on(void)
 | 
					void led1642gw_turn_all_on(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  write_data(0xffff, 2);
 | 
					  write_data(0xffff, 2);
 | 
				
			||||||
  _delay_us(10);
 | 
					 | 
				
			||||||
  write_data(0xffff, 2);
 | 
					  write_data(0xffff, 2);
 | 
				
			||||||
  _delay_us(10);
 | 
					 | 
				
			||||||
  write_data(0xffff, 2);
 | 
					  write_data(0xffff, 2);
 | 
				
			||||||
  _delay_us(10);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Turn all channels off,
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void led1642gw_turn_all_off(void)
 | 
					void led1642gw_turn_all_off(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  write_data(0x0000, 2);
 | 
					  write_data(0x0000, 2);
 | 
				
			||||||
  _delay_us(10);
 | 
					 | 
				
			||||||
  write_data(0x0000, 2);
 | 
					  write_data(0x0000, 2);
 | 
				
			||||||
  _delay_us(10);
 | 
					 | 
				
			||||||
  write_data(0x0000, 2);
 | 
					  write_data(0x0000, 2);
 | 
				
			||||||
  _delay_us(10);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Initialize the pins of the ATMega processor
 | 
				
			||||||
 | 
					 * to drive the data signals to the ICs
 | 
				
			||||||
 | 
					 * and initialize the LED buffer to zero.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void led1642gw_init(void)
 | 
					void led1642gw_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -105,19 +141,42 @@ void led1642gw_init(void)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Transmit data from the ledbuffer to the BRIGHTNESS latches of
 | 
				
			||||||
 | 
					 * the LED driver ICs.
 | 
				
			||||||
 | 
					 * Let's assume, we have n LED1642GW ICs daisy chained. Then
 | 
				
			||||||
 | 
					 * we write n-1 times with write_no_command, to shift all
 | 
				
			||||||
 | 
					 * data through the 16bit shift registers of each of the ICs.
 | 
				
			||||||
 | 
					 * Then we once write with write_data_latch to store the data
 | 
				
			||||||
 | 
					 * in the BRIGHTNESS DATA registers of the respective ICs.
 | 
				
			||||||
 | 
					 * We do this for all but the last set of brightness data,
 | 
				
			||||||
 | 
					 * where we don't write to the DATA LATCH, but to the GLOBAL DATA LATCH.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void led1642gw_flush(void)
 | 
					void led1642gw_flush(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  uint8_t channel;
 | 
					  uint8_t channel;
 | 
				
			||||||
  uint8_t ic;
 | 
					  uint8_t ic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // for each of the first 15 channels, do the following:
 | 
				
			||||||
  for (channel=0; channel<NUM_LED1642GW_CHANNELS-1; channel++) {
 | 
					  for (channel=0; channel<NUM_LED1642GW_CHANNELS-1; channel++) {
 | 
				
			||||||
 | 
						  // shift data throught the first n-1 ICs with write_no_command
 | 
				
			||||||
	  for (ic=0; ic<(NUM_LED1642GW_ICs-1); ic++) {
 | 
						  for (ic=0; ic<(NUM_LED1642GW_ICs-1); ic++) {
 | 
				
			||||||
		  write_no_command(ledbuffer[channel+(NUM_LED1642GW_CHANNELS*ic)]);
 | 
							  write_no_command(ledbuffer[channel+(NUM_LED1642GW_CHANNELS*ic)]);
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
 | 
						  // then, when the brightness data has propagated through the
 | 
				
			||||||
 | 
						  // shift registers, write all data into the DATA LATCH of
 | 
				
			||||||
 | 
						  // all of the ICs.
 | 
				
			||||||
	  write_data_latch(ledbuffer[channel+(ic*NUM_LED1642GW_CHANNELS)]);
 | 
						  write_data_latch(ledbuffer[channel+(ic*NUM_LED1642GW_CHANNELS)]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  // for the 16th channel, we don't write to the DATA LATCH, but
 | 
				
			||||||
 | 
					  // to the CLOBAL data latch.
 | 
				
			||||||
 | 
					  // once more, we do the trick with write_no_command, to 
 | 
				
			||||||
 | 
					  // shift data through all the ICs
 | 
				
			||||||
  for (ic=1; ic<NUM_LED1642GW_ICs; ic++) {
 | 
					  for (ic=1; ic<NUM_LED1642GW_ICs; ic++) {
 | 
				
			||||||
	  write_no_command(ledbuffer[(ic*NUM_LED1642GW_CHANNELS)-1]);
 | 
						  write_no_command(ledbuffer[(ic*NUM_LED1642GW_CHANNELS)-1]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  // than, at last, write data to the global latch, to force 
 | 
				
			||||||
 | 
					  // the ICs to update their brightness data from the DATA LATCHES.
 | 
				
			||||||
  write_global_latch(ledbuffer[(ic*NUM_LED1642GW_CHANNELS)-1]);
 | 
					  write_global_latch(ledbuffer[(ic*NUM_LED1642GW_CHANNELS)-1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,10 @@
 | 
				
			|||||||
#include "ledcontroller.h"
 | 
					#include "ledcontroller.h"
 | 
				
			||||||
#include "led1642gw.h"
 | 
					#include "led1642gw.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Application specific mapping of LEDs and there respective color channels
 | 
				
			||||||
 | 
					 * to the respective channels of the three LED1642GW ICs.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
static int8_t map_lednum_to_channels(uint8_t lednum, uint8_t *channel_r, uint8_t *channel_g, uint8_t *channel_b)
 | 
					static int8_t map_lednum_to_channels(uint8_t lednum, uint8_t *channel_r, uint8_t *channel_g, uint8_t *channel_b)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  uint8_t ret=0;
 | 
					  uint8_t ret=0;
 | 
				
			||||||
@@ -107,7 +110,12 @@ static int8_t map_lednum_to_channels(uint8_t lednum, uint8_t *channel_r, uint8_t
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * set one RGB LED to a RGB value.
 | 
				
			||||||
 | 
					 * This only changes the Red, Green and Blue values in the
 | 
				
			||||||
 | 
					 * internal LED buffer, the physical LED will still remain in its previous
 | 
				
			||||||
 | 
					 * state, until you call led_flush().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void led_set(uint8_t lednum, uint16_t red, uint16_t green, uint16_t blue)
 | 
					void led_set(uint8_t lednum, uint16_t red, uint16_t green, uint16_t blue)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint8_t c_r, c_g, c_b;
 | 
						uint8_t c_r, c_g, c_b;
 | 
				
			||||||
@@ -120,24 +128,41 @@ void led_set(uint8_t lednum, uint16_t red, uint16_t green, uint16_t blue)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Write the data stored in the LED buffers via led_set().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void led_flush(void)
 | 
					void led_flush(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	led1642gw_flush();
 | 
						led1642gw_flush();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Clear the LED buffer.
 | 
				
			||||||
 | 
					 * This function only affects the LED buffer, but not the LEDs, until
 | 
				
			||||||
 | 
					 * you call led_flush().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void led_clear(void)
 | 
					void led_clear(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	led1642gw_clear();
 | 
						led1642gw_clear();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Initialize the leddriver.
 | 
				
			||||||
 | 
					 * Must be called before any other function in this module.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void led_init(void)
 | 
					void led_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	led1642gw_init();
 | 
						led1642gw_init();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Turn all channels on on every LED1642GW IC.
 | 
				
			||||||
 | 
					 * If you don't turn the channels on, led_set
 | 
				
			||||||
 | 
					 * won't have any effect, and the LEDs will remain dark.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void led_turn_all_on(void)
 | 
					void led_turn_all_on(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	led1642gw_turn_all_on();
 | 
						led1642gw_turn_all_on();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user