166 lines
3.9 KiB
C
166 lines
3.9 KiB
C
|
#include "system/includes.h"
|
||
|
|
||
|
|
||
|
|
||
|
static const u8 SPI1_DO[2] = {
|
||
|
IO_PORTB_01,//'A'
|
||
|
IO_PORTC_05 //'B'
|
||
|
};
|
||
|
static const u8 SPI2_DO[2] = {
|
||
|
IO_PORTB_07,//'A'
|
||
|
IO_PORT_DM //'B'
|
||
|
};
|
||
|
#define LED_SPI JL_SPI1
|
||
|
#define LED_SPI_PORT 'B'
|
||
|
#define LED_SPI_DAT_BAUD 8000000
|
||
|
#define LED_SPI_REST_BAUD 1000000
|
||
|
#define LED_SPI_CLOCK_BASE clk_get("lsb")
|
||
|
|
||
|
static OS_SEM led_spi_sem;
|
||
|
static u32 spi_do = 0;
|
||
|
static u8 led_spi_busy = 0;
|
||
|
static u8 led_spi_sus = 0;
|
||
|
|
||
|
___interrupt
|
||
|
void led_spi_isr()
|
||
|
{
|
||
|
LED_SPI->CON &= ~BIT(13); //关闭中断
|
||
|
LED_SPI->CON |= BIT(14); //清pnding
|
||
|
os_sem_post(&led_spi_sem);
|
||
|
led_spi_busy = 0;
|
||
|
}
|
||
|
|
||
|
void led_spi_init(void)
|
||
|
{
|
||
|
if ((u32)LED_SPI == (u32)JL_SPI1) {
|
||
|
spi_do = SPI1_DO[LED_SPI_PORT - 'A'];
|
||
|
SFR(JL_IOMAP->CON1, 4, 1, LED_SPI_PORT - 'A');
|
||
|
request_irq(IRQ_SPI1_IDX, 0, led_spi_isr, 0);
|
||
|
} else {
|
||
|
spi_do = SPI2_DO[LED_SPI_PORT - 'A'];
|
||
|
SFR(JL_IOMAP->CON1, 16, 1, LED_SPI_PORT - 'A');
|
||
|
request_irq(IRQ_SPI2_IDX, 0, led_spi_isr, 0);
|
||
|
}
|
||
|
gpio_set_die(spi_do, 1);
|
||
|
gpio_set_direction(spi_do, 0);
|
||
|
gpio_set_pull_up(spi_do, 0);
|
||
|
gpio_set_pull_down(spi_do, 0);
|
||
|
gpio_write(spi_do, 0);
|
||
|
|
||
|
os_sem_create(&led_spi_sem, 1);
|
||
|
|
||
|
LED_SPI->CON = 0x4021;
|
||
|
}
|
||
|
|
||
|
void led_spi_rgb_to_24byte(u8 r, u8 g, u8 b, u8 *buf, int idx)
|
||
|
{
|
||
|
buf = buf + idx * 24;
|
||
|
u32 dat = ((g << 16) | (r << 8) | b);
|
||
|
for (u8 i = 0; i < 24; i ++) {
|
||
|
if (dat & BIT(23 - i)) {
|
||
|
*(buf + i) = 0x7c;
|
||
|
} else {
|
||
|
*(buf + i) = 0x60;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void led_spi_rest()
|
||
|
{
|
||
|
u8 tmp_buf[16] = {0};
|
||
|
LED_SPI->BAUD = LED_SPI_CLOCK_BASE / LED_SPI_REST_BAUD - 1;
|
||
|
LED_SPI->CON |= BIT(14);
|
||
|
LED_SPI->ADR = (u32)tmp_buf;
|
||
|
LED_SPI->CNT = 16;
|
||
|
while (!(LED_SPI->CON & BIT(15)));
|
||
|
LED_SPI->CON |= BIT(14);
|
||
|
}
|
||
|
|
||
|
void led_spi_send_rgbbuf(u8 *rgb_buf, u16 led_num) //rgb_buf的大小 至少要等于 led_num * 24
|
||
|
{
|
||
|
if (!led_num) {
|
||
|
return;
|
||
|
}
|
||
|
while (led_spi_sus) {
|
||
|
os_time_dly(1);
|
||
|
}
|
||
|
led_spi_busy = 1;
|
||
|
led_spi_rest();
|
||
|
LED_SPI->BAUD = LED_SPI_CLOCK_BASE / LED_SPI_DAT_BAUD - 1;
|
||
|
LED_SPI->CON |= BIT(14);
|
||
|
LED_SPI->ADR = (u32)rgb_buf;
|
||
|
LED_SPI->CNT = led_num * 24;
|
||
|
while (!(LED_SPI->CON & BIT(15)));
|
||
|
LED_SPI->CON |= BIT(14);
|
||
|
led_spi_busy = 0;
|
||
|
}
|
||
|
|
||
|
void led_spi_send_rgbbuf_isr(u8 *rgb_buf, u16 led_num) //rgb_buf的大小 至少要等于 led_num * 24
|
||
|
{
|
||
|
if (!led_num) {
|
||
|
return;
|
||
|
}
|
||
|
while (led_spi_sus) {
|
||
|
os_time_dly(1);
|
||
|
}
|
||
|
led_spi_busy = 1;
|
||
|
os_sem_pend(&led_spi_sem, 0);
|
||
|
led_spi_rest();
|
||
|
LED_SPI->BAUD = LED_SPI_CLOCK_BASE / LED_SPI_DAT_BAUD - 1;
|
||
|
LED_SPI->CON |= BIT(14);
|
||
|
LED_SPI->ADR = (u32)rgb_buf;
|
||
|
LED_SPI->CNT = led_num * 24;
|
||
|
LED_SPI->CON |= BIT(13);//打开中断
|
||
|
}
|
||
|
|
||
|
u8 led_spi_suspend(void)
|
||
|
{
|
||
|
if (led_spi_sus) {
|
||
|
return 1;
|
||
|
}
|
||
|
if (led_spi_busy) {
|
||
|
return 1;
|
||
|
}
|
||
|
LED_SPI->CON |= BIT(14);
|
||
|
LED_SPI->CON &= ~BIT(0);
|
||
|
led_spi_sus = 1;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
u8 led_spi_resume(void)
|
||
|
{
|
||
|
if (!led_spi_sus) {
|
||
|
return 0;
|
||
|
}
|
||
|
gpio_set_die(spi_do, 1);
|
||
|
gpio_set_direction(spi_do, 0);
|
||
|
gpio_set_pull_up(spi_do, 0);
|
||
|
gpio_set_pull_down(spi_do, 0);
|
||
|
gpio_write(spi_do, 0);
|
||
|
LED_SPI->CON = 0x4021;
|
||
|
led_spi_sus = 0;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static u8 spi_dat_buf[24 * 2] __attribute__((aligned(4)));
|
||
|
extern void wdt_clear();
|
||
|
void led_spi_test(void)
|
||
|
{
|
||
|
printf("****************** led spi test *******************\n");
|
||
|
led_spi_init();
|
||
|
u8 cnt = 0;
|
||
|
u8 pulse = 0;
|
||
|
while (1) {
|
||
|
cnt ++;
|
||
|
led_spi_rgb_to_24byte(cnt, 255 - cnt, 0, spi_dat_buf, 0);
|
||
|
led_spi_rgb_to_24byte(0, 0, cnt, spi_dat_buf, 1);
|
||
|
#if 1
|
||
|
led_spi_send_rgbbuf(spi_dat_buf, 2); //等待的方式,建议用在发的数据量小的场合
|
||
|
#else
|
||
|
led_spi_send_rgbbuf_isr(spi_dat_buf, 2); //中断的方式,建议用在发的数据量大的场合
|
||
|
#endif
|
||
|
os_time_dly(2);
|
||
|
wdt_clear();
|
||
|
}
|
||
|
}
|