#include "spi_matrix.h" #define DIGITS 8 void matrix_init(matrix_t *matrix, buffered_transceiver_t *transceiver, uint32_t shift_period) { matrix->transceiver = transceiver; matrix->shift_period = shift_period; matrix->slot = MATRIX_SLOT0; matrix->state = MATRIX_OFF; matrix->state_cycle = 0; matrix->cycle = 0; matrix->intensity = 1; } void matrix_setup(matrix_t *matrix) { matrix->state = MATRIX_OFF; matrix->slot = MATRIX_SLOT0; } void matrix_enable(matrix_t *matrix, bool enable) { matrix->state = MATRIX_STABLE; matrix->slot = MATRIX_SLOT0; matrix_send(matrix, MATRIX_REG_SHUTDOWN, enable ? 1 : 0); matrix_send(matrix, MATRIX_REG_DECODE_MODE, 0); matrix_send(matrix, MATRIX_REG_INTENSITY, matrix->intensity); matrix_send(matrix, MATRIX_REG_SCAN_LIMIT, 0x7); } void matrix_increase_intensity(matrix_t *matrix) { if (matrix->intensity < 0xF) { matrix->intensity++; } matrix_send(matrix, MATRIX_REG_INTENSITY, matrix->intensity); } void matrix_decrease_intensity(matrix_t *matrix) { if (matrix->intensity > 0x0) { matrix->intensity--; } matrix_send(matrix, MATRIX_REG_INTENSITY, matrix->intensity); } void matrix_send(matrix_t *matrix, matrix_register_t reg, uint8_t value) { uint16_t data = (((uint16_t)reg) << 8) | (uint16_t)value; buffered_transceiver_transmit(matrix->transceiver, (void*)&data, 1); } void matrix_set_buffer(matrix_t *matrix, matrix_slot_t slot, uint8_t *buffer) { if (slot == MATRIX_SLOT_OTHER) { if (matrix->slot == MATRIX_SLOT0) { slot = MATRIX_SLOT1; } else { slot = MATRIX_SLOT0; } } matrix->buffers[slot] = buffer; } void matrix_swap(matrix_t *matrix) { if (matrix->slot == MATRIX_SLOT0) { matrix->slot = MATRIX_SLOT1; } else { matrix->slot = MATRIX_SLOT0; } } void matrix_animate_swap(matrix_t *matrix) { matrix->state_cycle = 0; matrix->cycle = 0; matrix->state = MATRIX_ANIMATING; } void matrix_update(matrix_t *matrix, buffered_transceiver_t *transceiver) { uint8_t* buffer = matrix->buffers[matrix->slot]; uint8_t* other_buffer = matrix->buffers[1 - matrix->slot]; switch (matrix->state) { case MATRIX_OFF: // all digits 0 for (uint8_t digit = 0; digit < DIGITS; digit++) { matrix_send(matrix, MATRIX_REG_DIGIT0 + digit, 0); } break; case MATRIX_STABLE: // send all digits for (uint8_t digit = 0; digit < DIGITS; digit++) { matrix_send(matrix, MATRIX_REG_DIGIT0 + digit, buffer[digit]); } break; case MATRIX_ANIMATING: // update the cycle matrix->cycle++; if (matrix->cycle >= matrix->shift_period) { matrix->cycle = 0; matrix->state_cycle++; } if (matrix->state_cycle == DIGITS) { matrix->state = MATRIX_STABLE; matrix_swap(matrix); } for (uint8_t digit = 0; digit < DIGITS - matrix->state_cycle; digit++) { matrix_send(matrix, MATRIX_REG_DIGIT0 + digit, buffer[digit + matrix->state_cycle]); } for (uint8_t digit = DIGITS - matrix->state_cycle; digit < DIGITS; digit++) { matrix_send(matrix, MATRIX_REG_DIGIT0 + digit, other_buffer[digit - (DIGITS - matrix->state_cycle)]); } break; } }